当前位置:网站首页>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
边栏推荐
- 判断链表是否是回文链表
- P2592 [zjoi2008] birthday party (DP)
- Object. fromEntries()
- 可迭代对象与迭代器、生成器的区别与联系
- China PBAT resin Market Forecast and Strategic Research Report (2022 Edition)
- LeetCode中等题之TinyURL 的加密与解密
- 开发那些事儿:EasyCVR集群设备管理页面功能展示优化
- Roewe rx5's "a little more" product strategy
- Mysql database - Advanced SQL statement (2)
- 如何使用 etcd 实现分布式 /etc 目录
猜你喜欢
(27) Open operation, close operation, morphological gradient, top hat, black hat
C语言输入/输出流和文件操作
SQL question brushing 586 Customers with the most orders
PETRv2:一个多摄像头图像3D感知的统一框架
[C language foundation] 12 strings
【牛客网刷题系列 之 Verilog快速入门】~ 优先编码器电路①
String class
SQL question brushing 1050 Actors and directors who have worked together at least three times
剑指 Offer 20. 表示数值的字符串
C language input / output stream and file operation
随机推荐
Report on research and investment prospects of China's silicon nitride ceramic substrate industry (2022 Edition)
Gold, silver and four want to change jobs, so we should seize the time to make up
Computed property “xxx“ was assigned to but it has no setter.
Borui data integrated intelligent observable platform was selected into the "Yunyuan production catalogue" of China Academy of communications in 2022
Girls who want to do software testing look here
China carbon disulfide industry research and investment strategy report (2022 Edition)
RadHat搭建内网YUM源服务器
Redis 分布式鎖
反射型XSS漏洞
Official announcement! Hong Kong University of science and Technology (Guangzhou) approved!
Cookies and session keeping technology
SQL question brushing 586 Customers with the most orders
P2893 [usaco08feb] making the grade g (DP & priority queue)
Sword finger offer II 015 All modifiers in the string
Hidden Markov model (HMM): model parameter estimation
Research Report on development monitoring and investment prospects of China's smart environmental protection industry (2022 Edition)
智能运维实战:银行业务流程及单笔交易追踪
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
SQL question brushing 1050 Actors and directors who have worked together at least three times
整形数组合并【JS】