Vue+Openlayer使用overlay实现弹窗弹出显示与关闭
場(chǎng)景
?
Vue+Openlayers實(shí)現(xiàn)地圖上繪制線:
Vue+Openlayers實(shí)現(xiàn)地圖上繪制線_BADAO_LIUMANG_QIZHI的博客-CSDN博客
在上面的基礎(chǔ)上實(shí)現(xiàn)點(diǎn)擊地圖,彈窗顯示并獲取點(diǎn)擊處的坐標(biāo),并實(shí)現(xiàn)坐標(biāo)轉(zhuǎn)換經(jīng)緯度。
效果
加載顯示地圖的流程
Vue中使用Openlayers加載Geoserver發(fā)布的TileWMS:
Vue中使用Openlayers加載Geoserver發(fā)布的TileWMS_BADAO_LIUMANG_QIZHI的博客-CSDN博客
注:
博客:
BADAO_LIUMANG_QIZHI的博客_霸道流氓氣質(zhì)_CSDN博客
關(guān)注公眾號(hào)
霸道的程序猿
獲取編程相關(guān)電子書、教程推送與免費(fèi)下載。
實(shí)現(xiàn)
1、頁(yè)面上添加彈窗的元素
<template><div id="app"><div id="map" class="map"></div><div id="popup" class="ol-popup"><a href="#" id="popup-closer" class="ol-popup-closer">X</a><div id="popup-content" class="popup-content"></div></div></div> </template>2、添加彈窗樣式
<style scoped> .map {width: 100%;height: 800px; } .ol-popup {position: absolute;background-color: white;-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));padding: 15px;border-radius: 10px;border: 1px solid #cccccc;bottom: 12px;left: -50px; } .popup-content {width: 400px; } .ol-popup-closer {text-decoration: none;position: absolute;top: 2px;right: 8px; } </style>3、導(dǎo)入相關(guān)模塊
//導(dǎo)入基本模塊 import "ol/ol.css"; import Map from "ol/Map"; import Overlay from "ol/Overlay"; import View from "ol/View"; import { Point,LineString } from "ol/geom"; import Feature from "ol/Feature"; import { Icon,Style,Stroke} from "ol/style"; //導(dǎo)入相關(guān)模塊 import { Tile as TileLayer , Vector as VectorLayer } from 'ol/layer' import { TileWMS ,Vector as VectorSource } from 'ol/source' import { toStringHDMS } from "ol/coordinate"; import { toLonLat } from "ol/proj";4、聲明overlay與容器
????? overlay: null,container: null, // 彈框5、在mounted中調(diào)用初始化地圖的方法
? mounted() {this.initMap();},在方法中獲取到彈窗的節(jié)點(diǎn)DOM
????? // 獲取到彈框的節(jié)點(diǎn)DOMvar container = document.getElementById("popup");var content = document.getElementById("popup-content");var closer = document.getElementById("popup-closer");然后創(chuàng)建一個(gè)彈窗Overlay對(duì)象
????? // 創(chuàng)建一個(gè)彈窗 Overlay 對(duì)象this.overlay = new Overlay({element: container, //綁定 Overlay 對(duì)象和 DOM 對(duì)象的autoPan: true, // 定義彈出窗口在邊緣點(diǎn)擊時(shí)候可能不完整 設(shè)置自動(dòng)平移效果autoPanAnimation: {duration: 250 //自動(dòng)平移效果的動(dòng)畫時(shí)間 9毫秒}});6、創(chuàng)建彈窗對(duì)象并將彈窗添加到地圖中
????? this.map = new Map({//地圖容器IDtarget: "map",//引入地圖layers: [this.layer,this.lightLayer,this.houseLayer,this.lineLayer],view: new View({//地圖中心點(diǎn)center: [987777.93778, 213834.81024],zoom: 12,minZoom:6, // 地圖縮放最小級(jí)別maxZoom:19,rotation: 0.76}),});// 將彈窗添加到 map 地圖中this.map.addOverlay(this.overlay);7、監(jiān)聽地圖的單擊事件,在回調(diào)函數(shù)中獲取坐標(biāo)值并將內(nèi)容賦值給dom
并且設(shè)置彈窗的位置就是當(dāng)前鼠標(biāo)點(diǎn)擊的位置
????? // 將彈窗添加到 map 地圖中this.map.addOverlay(this.overlay);//必須 要重新賦值this,不然再回調(diào)函數(shù)中指針會(huì)變,overlay會(huì)undefinedlet _that = this;// 監(jiān)聽singleclick事件this.map.on('singleclick', function(e) {let coordinate = e.coordinate// 點(diǎn)擊尺 (這里是尺(米),并不是經(jīng)緯度);let hdms = toStringHDMS(toLonLat(e.coordinate)); // 轉(zhuǎn)換為經(jīng)緯度顯示content.innerHTML = `<p>你點(diǎn)擊了這里:</p><p>經(jīng)緯度:<p><code> ${hdms}? </code> <p><p>坐標(biāo):</p>X:${coordinate[0]} Y: ${coordinate[1]}`;_that.overlay.setPosition(coordinate); //把 overlay 顯示到指定的 x,y坐標(biāo)console.log(e.coordinate)})8、這里尤其要注意的是,單擊事件的回調(diào)方法中要對(duì)overplay設(shè)置其顯示位置
這里不能再直接使用this.overplay.setPosition了,因?yàn)樵诨卣{(diào)函數(shù)中指針會(huì)變,
此時(shí)會(huì)提示overlay為undefined。所以先重新賦值再使用
let _that = this;_that.overlay.setPosition(coordinate); //把 overlay 顯示到指定的 x,y坐標(biāo)7、設(shè)置彈窗關(guān)閉事件
將overlay對(duì)象的setPosition賦值為undefined即可隱藏。
????? //彈窗關(guān)閉事件closer.onclick=function(){_that.overlay.setPosition(undefined);closer.blur();return false;};8、完整示例代碼
? <template><div id="app"><div id="map" class="map"></div><div id="popup" class="ol-popup"><a href="#" id="popup-closer" class="ol-popup-closer">X</a><div id="popup-content" class="popup-content"></div></div></div> </template><script> //導(dǎo)入基本模塊 import "ol/ol.css"; import Map from "ol/Map"; import Overlay from "ol/Overlay"; import View from "ol/View"; import { Point,LineString } from "ol/geom"; import Feature from "ol/Feature"; import { Icon,Style,Stroke} from "ol/style"; //導(dǎo)入相關(guān)模塊 import { Tile as TileLayer , Vector as VectorLayer } from 'ol/layer' import { TileWMS ,Vector as VectorSource } from 'ol/source' import { toStringHDMS } from "ol/coordinate"; import { toLonLat } from "ol/proj"; export default {name: "olMapImageWMSMulLayers",data() {return {map: null, // map地圖layer:null, //地圖圖層lightLayer:null, //燈圖層houseLayer:null, //房子圖層lineLayer:null, //線圖層lineSource:null, //線數(shù)據(jù)源overlay: null,container: null, // 彈框//紅綠燈數(shù)據(jù)lightData:[{x:"987798.93778", y:"213885.81024"},{x:"987710.93778", y:"213810.81024"},],//房子數(shù)據(jù)houseData:[{x:"986610.93778", y:"213885.81024"},{x:"986510.93778", y:"213810.81024"},],//線的數(shù)據(jù)lineData:[[986434.4063822062, 215782.0959711917],[989701.5290279881,217149.84072807242],[990613.3107184113,215946.4192185118],],};},mounted() {this.initMap();setInterval(() => {this.initLightData();}, 1000)},methods: {//初始化紅綠燈數(shù)據(jù)initLightData(){this.lightLayer.getSource().clear();this.lightData.forEach((item, index) => {var feature = new Feature({geometry: new Point([Number(item.x), Number(item.y)]),});let url = "images/light.png";const zoom = this.map.getView().getZoom();let style = new Style({image: new Icon({scale: 0.15 * (zoom -13) ,src: url,anchor: [0.48, 0.52],}),});feature.setStyle(style);this.lightLayer.getSource().addFeature(feature);});},//初始化房子數(shù)據(jù)initHouseData(){this.houseLayer.getSource().clear();this.houseData.forEach((item, index) => {var feature = new Feature({geometry: new Point([Number(item.x), Number(item.y)]),});let url = "images/house.png";let style = new Style({image: new Icon({scale: 0.3,src: url,anchor: [0.48, 0.52],}),});feature.setStyle(style);this.houseLayer.getSource().addFeature(feature);});},//畫線drawLine(){let pointData = this.lineData; // 所有點(diǎn)位信息//下邊來(lái)添加一線featurevar feature = new Feature({type: "lineStyle",geometry: new LineString(pointData // 線的坐標(biāo)),});let color = 'green';let lineStyle = new Style({stroke: new Stroke({color: color,width: 4,}),});// 添加線的樣式feature.setStyle(lineStyle);// 添加線的faturethis.lineSource.addFeature(feature);},initMap() {// 獲取到彈框的節(jié)點(diǎn)DOMvar container = document.getElementById("popup");var content = document.getElementById("popup-content");var closer = document.getElementById("popup-closer");//地圖圖層this.layer = new TileLayer({source: new TileWMS({//不能設(shè)置為0,否則地圖不展示。ratio: 1,url: "http://localhost:8000/geoserver/nyc/wms",params: {LAYERS: "nyc:nyc_roads",STYLES: "",VERSION: "1.1.1",tiled: true},serverType: "geoserver",}),});// 紅綠燈的圖層this.lightLayer = new VectorLayer({source: new VectorSource(),});//房子的圖層this.houseLayer = new VectorLayer({source: new VectorSource(),});//線的圖層this.lineSource = new VectorSource({ wrapX: false });this.lineLayer = new VectorLayer({source: this.lineSource,});// 創(chuàng)建一個(gè)彈窗 Overlay 對(duì)象this.overlay = new Overlay({element: container, //綁定 Overlay 對(duì)象和 DOM 對(duì)象的autoPan: true, // 定義彈出窗口在邊緣點(diǎn)擊時(shí)候可能不完整 設(shè)置自動(dòng)平移效果autoPanAnimation: {duration: 250 //自動(dòng)平移效果的動(dòng)畫時(shí)間 9毫秒}});this.map = new Map({//地圖容器IDtarget: "map",//引入地圖layers: [this.layer,this.lightLayer,this.houseLayer,this.lineLayer],view: new View({//地圖中心點(diǎn)center: [987777.93778, 213834.81024],zoom: 12,minZoom:6, // 地圖縮放最小級(jí)別maxZoom:19,rotation: 0.76}),});// 將彈窗添加到 map 地圖中this.map.addOverlay(this.overlay);//必須 要重新賦值this,不然再回調(diào)函數(shù)中指針會(huì)變,overlay會(huì)undefinedlet _that = this;// 監(jiān)聽singleclick事件this.map.on('singleclick', function(e) {let coordinate = e.coordinate// 點(diǎn)擊尺 (這里是尺(米),并不是經(jīng)緯度);let hdms = toStringHDMS(toLonLat(e.coordinate)); // 轉(zhuǎn)換為經(jīng)緯度顯示content.innerHTML = `<p>你點(diǎn)擊了這里:</p><p>經(jīng)緯度:<p><code> ${hdms}? </code> <p><p>坐標(biāo):</p>X:${coordinate[0]} Y: ${coordinate[1]}`;_that.overlay.setPosition(coordinate); //把 overlay 顯示到指定的 x,y坐標(biāo)console.log(e.coordinate)})//彈窗關(guān)閉事件closer.onclick=function(){_that.overlay.setPosition(undefined);closer.blur();return false;};this.initLightData();this.initHouseData();this.drawLine();},}, }; </script><style scoped> .map {width: 100%;height: 800px; } .ol-popup {position: absolute;background-color: white;-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));padding: 15px;border-radius: 10px;border: 1px solid #cccccc;bottom: 12px;left: -50px; } .popup-content {width: 400px; } .ol-popup-closer {text-decoration: none;position: absolute;top: 2px;right: 8px; } </style>?總結(jié)
以上是生活随笔為你收集整理的Vue+Openlayer使用overlay实现弹窗弹出显示与关闭的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Vue+Openlayers中实现地图旋
- 下一篇: Vue+Openlayer使用Draw实