当前位置:网站首页>Openlayers customize bubble boxes and navigate to bubble boxes
Openlayers customize bubble boxes and navigate to bubble boxes
2022-07-01 17:11:00 【Southejor】
Openlayers Customize the bubble box and navigate to the bubble box
OpenLayers course
Openlayers Bubble box function , It is mainly used to display attribute information of map elements , Also known as Bubble 、 card 、 pop-up wait , I used to call it bubble box .
Bubble box function is very common , The scenario is generally , When superimposing points, lines and surfaces on the map, the current elements (Feature) Basic information of , such as name 、 Number 、 Address etc. ; There is also a bubble box that pops up when you click the map overlay element , To show information .
The bubble box is limited by the size of the container , Generally, only Brief information , If you want to show details , Often through new pages or pop-up large div Container display .
Generally speaking , Bubble boxes belong to map overlays (Overlay), Belong to dom Elements , Not in the canvas Inside , The level is above the layer , Exists as a top-level element ; Bubble boxes usually contain close icons or buttons , You can click Close , There are also special scenes , It is not allowed to close , But if you don't close it , Use it directly dom Element implementation can .
One of the benefits of loading bubble boxes as map object elements , You can follow the map , The effect is more in line with usage habits .
This paper mainly introduces , Initialization of bubble box 、 Bubble boxes display information 、 Bubble box style 、 Bubble box positioning .
Openlayers Customize the bubble box and navigate to the bubble box
<html lang="en">
<head>
<meta charSet="utf-8">
<!-- Be careful :openlayers The original version is slow , Here cause your own server version -->
<link rel="stylesheet" href="http://openlayers.vip/examples/css/ol.css" type="text/css">
<style> /* Be careful : There must be a height here , Otherwise, the map will not be displayed after initialization ; Generally, the height is calculated , Then initialize the map */ .map {
height: 700px; width: 100%; float: left; } /* Bubble box container style */ .leaflet-container {
position: absolute; -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); bottom: -12px; } /* Bubble box close button style */ .leaflet-container a.leaflet-popup-close-button {
position: absolute; top: 0; right: 0; padding: 4px 4px 0 0; width: 18px; height: 14px; background: 0; color: #ffffff; text-align: center; text-decoration: none; font: 1pc/14px Tahoma, Verdana, sans-serif; font-weight: 700 } /* Bubble box content style */ .common-popup .leaflet-popup-content-wrapper {
background: transparent; box-shadow: none; padding: 0; border-radius: 0; } /* Lower corner of bubble box */ .common-popup .leaflet-popup-tip {
margin-left: 120px } .leaflet-popup-tip-container {
position: relative; overflow: hidden; margin: 0; height: 28px } .leaflet-popup-tip {
margin: -10px auto 0; padding: 1px; width: 17px; height: 18px; -webkit-transform: rotate(45deg); transform: rotate(45deg); -ms-transform: rotate(45deg) } .leaflet-popup-content-wrapper, .leaflet-popup-tip {
background: #fff; box-shadow: 0 3px 14px rgba(0, 0, 0, .4) } /* Customize bubble box style */ .customer-popup-southejor-style {
border: 1px solid #fff; border-radius: 5px; background: #1a90c587; color: #fff; box-shadow: inset 0 0 4px 2px #fff; } /* Customize the bubble box title style */ .customer-popup-southejor-title {
height: 10%; background-color: #03a9f48f; padding: 2px; font-size: 20px; text-align: center; } </style>
<!-- Be careful :openlayers The original version is slow , Here cause your own server version -->
<script src="http://openlayers.vip/examples/resources/ol.js"></script>
<script src="http://openlayers.vip/examples/resources/jquery-3.5.1.min.js"></script>
<script src="./tiandituLayers.js"></script>
<title>OpenLayers example</title>
</head>
<body>
<h2>OpenLayers Popup</h2>
<!-- Map container , You need to specify the id -->
<div id="map" class="map"></div>
<script type="text/javascript"> var map = new ol.Map({
// Map container target: 'map', // map layer , For example, the base map 、 Vector graphs, etc layers: [ getIMG_CLayer(), getIBO_CLayer(), getCIA_CLayer(), ], // Map view view: new ol.View({
projection: "EPSG:4326", // location center: [115.67724700667199, 37.73879478106912], // The zoom zoom: 6, maxZoom: 18, minZoom: 1, }) }); // Open the graphic element click event map.on('click', function (event) {
this.forEachFeatureAtPixel(event.pixel, function (feature) {
// For clicking feature Send custom click news feature.dispatchEvent && feature.dispatchEvent({
type: 'click', event: event}); }); }); // Initialize bubble box createPopup(); // Default style var defaultStyle = new ol.style.Style({
// Border style stroke: new ol.style.Stroke({
color: 'white', width: 2, }), // Fill the style fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.7)', }), // Point style image: new ol.style.Icon({
// Allow cross-domain , If not set , Printing a map does not print crossOrigin: 'anonymous', // Mark the distance between picture and text anchor: [0.5, 0], // The offset of the picture offset: [0, 0], // The anchor of the picture , Generally speaking , It's all in the lower right corner anchorOrigin: 'bottom-right', // Icon's url src: "http://api.tianditu.gov.cn/v4.0/image/marker-icon.png", scale: 1, }) }) // Initialize layers var layer = initVectorLayer(); // Face and dot var feature = undefined, featurePoint = undefined; addFeatures(); // Add points, lines and faces function addFeatures() {
featurePoint = getFeatureByWKT("POINT(116.17983834030585 39.98298600752048)"); feature = getFeatureByWKT("POLYGON((115.13540462521966 37.877850766866445,116.31094173459466 39.042401548116445,117.23379329709466 38.130536313741445,117.10195735959466 37.295575376241445,115.64077571896966 36.976971860616445,115.26724056271966 37.174725766866445,115.13540462521966 37.877850766866445))"); // Set display properties feature.set('content: Content ', ' This is a faceted graphic element '); feature.set('other: Other attributes ', ' There are other faceted attributes '); featurePoint.set('content: Content ', ' This is a point graphic element '); featurePoint.set('other: Other attributes ', ' There are other attributes '); // Define binding events let clickFunc = function (e) {
// Get the attribute information to be displayed let popupStr = getPopupHtml(e.target); // Get map object let temp = '<div class="customer-popup-southejor-style">' + ' <div class="customer-popup-southejor-title">\n' + ' <span> Bubble box </span>\n' + ' </div>\n' + ' <div style="font-size: 16px; padding: 5px;">' + ' <div class="customer-popup-southejor-index" style="padding-left: 10px;">' + popupStr.content + ' </div>' + ' </div>\n' + ' </div>' // Open the bubble box openInfoWindowHtml(e.target, temp) } // The binding event feature.on('click', clickFunc); featurePoint.on('click', clickFunc); layer.getSource().addFeatures([feature, featurePoint]); } /** * @todo The vector layer * @returns {VectorLayer} * @constructor */ function initVectorLayer() {
// Instantiate a vector layer Vector As a drawing layer let source = new ol.source.Vector(); // Create a layer let customVectorLayer = new ol.layer.Vector({
source: source, zIndex: 2, // Set the style style: defaultStyle, }); // Add a drawing layer to the map container map.addLayer(customVectorLayer); return customVectorLayer; } /** * @todo wkt Convert format data into graphic objects * @param {string} wkt "POINT(112.7197265625,39.18164062499999)" Format data * @param {string|Projection} sourceCode Source projection coordinate system * @param {string|Projection} targetCode Target projection coordinate system * @returns {Feature} */ function getFeatureByWKT(wkt, sourceCode, targetCode) {
try {
let view = map.getView(); if (!wkt) {
return null; } let format = new ol.format.WKT(); let feature; feature = format.readFeature(wkt, {
featureProjection: targetCode || view.getProjection(), dataProjection: sourceCode || view.getProjection(), }); return feature; } catch (e) {
console.log(e); return null; } } /** * todo establish popup Bubble box element * @param */ function createPopup() {
// Bubble box container string var popupStr = "<div id='popup-leaflet-container-southejor' class=\"leaflet-container\" > \n" + " <div class=\"leaflet-popup-pane\">\n" + " <div class=\"leaflet-popup common-popup\">\n" + " <a id='popup-closer' class=\"leaflet-popup-close-button\" href=\"JavaScript:void(0)\">×</a>\n" + " <div class=\"leaflet-popup-content-wrapper\">\n" + " </div>\n" + " <div class=\"leaflet-popup-tip-container\">\n" + " <div class=\"leaflet-popup-tip\"></div>\n" + " </div>\n" + " </div>\n" + " </div>\n" + " </div>"; // Create a bubble box container let popupDiv = document.createElement("div"); // Create a div label // Set up id popupDiv.id = "mapPopup"; // Initialization does not show popupDiv.style.display = 'none'; // Initialize container popupDiv.innerHTML = popupStr; // Only one bubble box can appear on the page if (document.getElementsByTagName('body')[0].contains(popupDiv)) {
document.getElementsByTagName('body')[0].removeChild(popupDiv); } document.getElementsByTagName('body')[0].appendChild(popupDiv); return initPopup(popupDiv); } // Bubble box , The main body , close button var popup, contentBody, closerPopup; /** * todo Initialize bubble box * @returns {Overlay} */ function initPopup(popupContainer) {
// Bubble box - Content ID contentBody = $('#popup-leaflet-container-southejor .leaflet-popup-content-wrapper')[0]; // Bubble box - close ID closerPopup = document.getElementById('popup-closer'); // Set to show popupContainer.style.display = 'block'; // Bubble box overlay popup = new ol.Overlay({
// Containers element: popupContainer, // When Popup Beyond the map boundary , in order to Popup All visible , Automatically move to the visible range autoPan: true, autoPanAnimation: {
// When Popup Beyond the map boundary , in order to Popup All visible , The speed at which the map moves . duration: 250 } }); return popup; } function openInfoWindowHtml(featureTemp, content) {
try {
// If there are no drawing feature parameters , Then open the default bubble box if (!featureTemp) {
contentBody.innerHTML.trim() ? map.addOverlay(popup) : alert(' Please click on graphic elements first ( Face or point )!'); return; } // Update display properties contentBody.innerHTML = content; // Get the center point of graphic elements var center = ol.extent.getCenter(featureTemp.getGeometry().getExtent()); // The bubble box sets the center point popup.setPosition(center); // Remove the previous bubble box map.removeOverlay(popup); // Get the drawing feature type let featureType = featureTemp.getGeometry().getType(); // this Inside, the line figure is different from the point figure ; If it is a point layer ( Icon ), Then the bubble box moves up // Bubble framed setOffset It can be adjusted according to the actual situation if (featureType == 'Point') {
let styleTemp = featureTemp.getStyle() || layer.getStyle(); if (styleTemp && styleTemp.getImage()) {
let size = styleTemp.getImage().getSize(); let scale = styleTemp.getImage().getScale(); if (size && size.length > 1) {
popup.setOffset([-10, -size[1] * scale]); } else {
popup.setOffset([0, -40]); } } else {
popup.setOffset([0, -5]); } // Other graphics are normal } else {
popup.setOffset([-10, 0]); } // Add bubble box map.addOverlay(popup); // Bind close button event closerPopup.onclick = function () {
map.removeOverlay(popup); }; // Bubble box width let popupWidth = 300; // Adjusting position let popupPointLeft = (popupWidth / 2); // Adjust the lateral offset $(map.getTargetElement()).find(".leaflet-container").width(popupWidth + "px"); $(map.getTargetElement()).find(".leaflet-container").css('right', -popupPointLeft + "px"); $(map.getTargetElement()).find(".leaflet-popup-tip-container .leaflet-popup-tip").css("margin-left", popupPointLeft + "px"); return popup; } catch (e) {
console.log(e) } } // Get bubble box properties function getPopupHtml(feature) {
if (!feature) {
return; } let popup = {
}; // Definition table Containers let content = "<table class='popup-table-html-show-southejor' style='width: 100%;color:white'>"; // Get all attributes of graphic elements let featureProperties = feature.getProperties(); // Set field and attribute widths let tdColumn = '35%', tdField = '65%'; for (let featureElement in featureProperties) {
// Here we need to follow the front feature Attribute definition correspondence ; // The preceding definition is : Field : value if (featureElement && featureElement.indexOf(":") != -1) {
let featureElementArr = featureElement.split(":"); content += "<tr style='height: 25px;'>"; // Splice attribute information content += "<td style='border-width: 0px 0px 1px 0px;word-wrap:break-word;" + "word-break:break-all;width: " + tdColumn + "'><div>" + featureElementArr[1] + " : </div></td>" + "<td style='border-width: 0px 0px 1px 0px;word-wrap:break-word;word-break:break-all;" + "width: " + tdField + "'><div class='popupIdentity-" + featureElementArr[0] + "'>" + featureProperties[featureElement] + "</div></td>"; content += "</tr>"; } } popup.content = content += "</table>"; return popup; } /** * todo Navigate to the bubble box */ function moveToPopup() {
// For positioning [x,y] let xy; // Types of graphic elements ; Surface line and point acquisition xy In a different way let type = feature.getGeometry().getType(); // Get surface lines and points xy if ('Polygon' == type || 'LineString' == type) {
xy = ol.extent.getCenter(feature.getGeometry().getExtent()); } else {
xy = feature.getGeometry().getCoordinates(); } // Positioning position (y Axis ) let init = 500; // Get the bubble box Height let heightTemp = init + $('#popup-leaflet-container-southejor').height() - 40; heightTemp = heightTemp || 680; // Calculation y Axial spacing let gap = map.getCoordinateFromPixel([300, heightTemp])[1] - map.getCoordinateFromPixel([300, init])[1]; xy && xy.length > 1 && (xy[1] = xy[1] - gap); // location ; Location , Positioning duration let flyTo = function (location, time) {
let duration = time ? time : 2000; let zoom = map.getView().getZoom(); let parts = 2; let called = false; // Positioning callback function callback(complete) {
--parts; if (called) {
return; } if (parts === 0 || !complete) {
called = true; } } // Positioning action map.getView().animate({
center: location, duration: duration }, callback); // Positioning action map.getView().animate({
zoom: zoom - 1, duration: duration / 2 }, {
zoom: zoom, duration: duration / 2 }, callback); } flyTo(xy, 1000); } /** * todo Close the bubble box * @param _map */ function closeInfoWindowHtml() {
map.removeOverlay(popup); } </script>
<button id="openInfoWindowHtml" onClick="openInfoWindowHtml()"> Open the bubble box </button>
<button id="moveToPopup" onClick="moveToPopup()"> Navigate to the bubble box </button>
<button id="closeInfoWindowHtml" onClick="closeInfoWindowHtml()"> Close the bubble box </button>
</body>
</html>
Online example
Openlayers Custom bubble box :Openlayers feature popup
边栏推荐
- Vulnhub range hacksudo Thor
- unity3d扩展工具栏
- 走进微信小程序
- 在MeterSphere接口测试中如何使用JMeter函数和MockJS函数
- China BMS battery management system Market Research Report (2022 Edition)
- Determine whether the linked list is a palindrome linked list
- SQL question brushing 1050 Actors and directors who have worked together at least three times
- (1) CNN network structure
- Leetcode records - sort -215, 347, 451, 75
- sql刷题1050. 合作过至少三次的演员和导演
猜你喜欢
Roewe rx5's "a little more" product strategy
想做软件测试的女孩子看这里
Shenyu gateway development: enable and run locally
SQL question brushing 584 Looking for user references
String的trim()和substring()详解
There is a new breakthrough in quantum field: the duration of quantum state can exceed 5 seconds
(十六)ADC转换实验
SQL question brushing 1050 Actors and directors who have worked together at least three times
Official announcement! Hong Kong University of science and Technology (Guangzhou) approved!
Are you still using charged document management tools? I have a better choice! Completely free
随机推荐
GaussDB(for MySQL) :Partial Result Cache,通过缓存中间结果对算子进行加速
【splishsplash】关于如何在GUI和json上接收/显示用户参数、MVC模式和GenParam
RadHat搭建内网YUM源服务器
Transition technology from IPv4 to IPv6
Exclusive news: Alibaba cloud quietly launched RPA cloud computer and has opened cooperation with many RPA manufacturers
Sword finger offer 20 String representing numeric value
Mysql database - Advanced SQL statement (2)
C语言输入/输出流和文件操作
Report on research and investment prospects of China's silicon nitride ceramic substrate industry (2022 Edition)
中国乙腈市场预测与战略咨询研究报告(2022版)
China metallocene polyethylene (MPE) Industry Research Report (2022 Edition)
FRP intranet penetration, reverse proxy
Encryption and decryption of tinyurl in leetcode
可迭代对象与迭代器、生成器的区别与联系
Why should you consider using prism
Report on Market Research and investment prospects of ammonium dihydrogen phosphate industry in China (2022 Edition)
阿里云、追一科技抢滩对话式AI
In aks, use secret in CSI driver mount key vault
Internet News: "20220222" get together to get licenses; Many products of Jimi have been affirmed by consumers; Starbucks was fined for using expired ingredients in two stores
剑指 Offer II 105. 岛屿的最大面积