Openlayers实例-加载天地图
<template> <div> <MapIndex v-on:getSelected="getSelected" ></MapIndex> <div id="popup" class="ol-popup"> <div id="popup-closer" class="ol-popup-closer"></div> <div id="popup-content"> </div> </div> <div id="map" style="width: 100vw; height: 100vh"> <div id="mouse-position"></div> <div id="layerControl" class="layerControl" v-show="showLayer"> <!-- <button type="button" aria-label="Close" class="el-message-box__headerbtn" @click="showLayerControl"><i class="el-dialog__close el-icon el-icon-close"></i></button> --> <!-- <div class="title"><label>图层列表</label></div> --> <ul id="layerTree" class="layerTree"> </ul> </div> <div class="layerSwitch" @click="showLayerControl"> <span class="iconfont icon-diqiu" style="font-size: 20px;color: #0075FF"></span> </div> </div> </div> </template> <script> import "ol/ol.css"; import TileLayer from "ol/layer/Tile"; import XYZ from "ol/source/XYZ"; import { Map, View, Feature } from "ol"; import OverviewMap from "ol/control/OverviewMap"; import addControl from "ol/Map"; import { Style } from "ol/style"; import Point from 'ol/geom/Point'; import addOverLay from "@/views/map/display/map_overLay.js"; import MapIndex from "@/views/map2"; import AddLayer from "@/views/map/display/add_geojson_layer"; import icon from "@/views/map/display/default_icon"; import text from "@/views/map/display/default_text"; import markLayer from "@/views/map/display/add_mark_layer"; import getIconByName, {getIconMapper} from "@/views/map/display/icon_mapper"; import getPoint from "@/views/map/display/load_point_location"; import {getGeoJson,getLocationAndZoom} from "@/views/map/display/load"; import layers_img_1 from "@/assets/images/vec.jpg"; import layers_img_2 from "@/assets/images/img.jpg"; export default { components: {MapIndex}, data() { return { map: {}, areaLayer: {}, vectorSource:{}, vectorLayerList:[], isChecked:[], showLayer:false, //map中的图层数组 layer : new Array(), //图层名称数组 layerName : new Array(), //图层可见属性数组 layerVisibility : new Array(), //地图样式弹出框 // showModal: false, }; }, mounted() { this.initMap().then((res)=>{//初始化地图方法 this.pointMove(); this.addGeoJsonLayer().then((res)=>{ this.initLayer(); }); //添加区域图层方法 addOverLay(this); //加载图层列表数据 this.loadLayersControl(this.map, "layerTree"); // this.addEagleViewControl(); }); }, methods: { showLayerControl(){ this.showLayer = !this.showLayer; //加载图层列表数据 // this.loadLayersControl(this.map, "layerTree"); }, /** * 加载图层列表数据 * @param {ol.Map} map 地图对象 * @param {string} id 图层列表容器ID */ loadLayersControl(map, id) { //图层目录容器 var treeContent = document.getElementById(id); //获取地图中所有图层 var layers = map.getLayers(); // console.log('选择',layers); for (var i = 0; i < layers.getLength() ; i++) { this.layer[i] = layers.item(i); if(this.layer[i].get('pkid')=='t2' || this.layer[i].get('pkid')=='t4'){ //获取每个图层的名称、是否可见属性 this.layerName[i] = this.layer[i].get('name'); this.layerVisibility[i] = this.layer[i].getVisible(); //新增li元素,用来承载图层项 var elementLi = document.createElement('li'); // 添加子节点 treeContent.appendChild(elementLi); //创建复选框元素 var elementInput = document.createElement('input'); elementInput.type = "checkbox"; elementInput.name = "layers"; elementInput.id = 'layers-'+i; elementLi.appendChild(elementInput); //创建label元素 var elementLable = document.createElement('label'); elementLable.className = "layer"; elementLable.htmlFor='layers-'+i; var elementImg = document.createElement('img'); if(i<2){ elementImg.src = layers_img_1; }else{ elementImg.src = layers_img_2; } elementLable.appendChild(elementImg); var elementP = document.createElement('p'); //设置图层名称 this.setInnerText(elementP, this.layerName[i]); elementLable.appendChild(elementP); elementLi.appendChild(elementLable); //设置图层默认显示状态 if (this.layerVisibility[i]) { elementInput.checked = true; elementLi.className = "active"; } //为checkbox添加变更事件 this.addChangeEvent(elementInput, this.layer[i],elementLi); } } }, /** * 为checkbox元素绑定变更事件 * @param {input} element checkbox元素 * @param {ol.layer.Layer} layer 图层对象 * @param imgElement checkbox元素绑定的img有无边框 */ addChangeEvent(element, layer ,imgElement) { var layers = this.map.getLayers(); var layers1; var layers3; for (var i = 0; i < layers.getLength() ; i++) { if(layers.item(i).get('pkid')=='t1') { layers1=layers.item(i); }else if(layers.item(i).get('pkid')=='t3'){ layers3=layers.item(i); } } element.onclick = function () { if(layer.get('pkid')=='t2'){ if (element.checked) { //显示图层 layer.setVisible(true); //layers1.setVisible(true); } else { //不显示图层 layer.setVisible(false); // layers1.setVisible(false); } }else{ if (element.checked) { //显示图层 layer.setVisible(true); layers3.setVisible(true); } else { //不显示图层 layer.setVisible(false); layers3.setVisible(false); } } if (!imgElement.classList.contains('active')) { //显示图层 imgElement.classList.add('active'); } else { //不显示图层 imgElement.classList.remove('active'); } }; }, /** * 动态设置元素文本内容(兼容) */ setInnerText(element, text) { if (typeof element.textContent == "string") { element.textContent = text; } else { element.innerText = text; } }, getSelected(value){ for (let element of this.vectorLayerList) { let e = value.filter(s=>s === element.name); if (e && e.length > 0 ) { if (!this.isChecked.includes(element.name)) { element.vector.setVisible(true); this.markByName(element.name); this.isChecked.push(element.name); } } else { this.removeVectorByType(element.name); this.isChecked = this.isChecked.filter(s=>s !== element.name); } } }, //------------------------------------------------------------- pointMove() { // 设置鼠标划过矢量要素的样式 this.map.on("pointermove", (e) => { const isHover = this.map.hasFeatureAtPixel(e.pixel); this.map.getTargetElement().style.cursor = isHover ? "pointer" : ""; }); }, //地图打点标记 markByName(type) { getPoint(type).then(point => { for (let e of point) { this.markPoint(type, e); } }); }, /** * 添加geoJson 数据图层 */ addGeoJsonLayer() { let geoJson = {}; return getGeoJson().then(res=>{ geoJson = res; AddLayer(geoJson,this); return res; }); }, removeVectorByType(type) { //根据type类型获取相应的vector 对象 let a = this.vectorLayerList.filter(s=> s.name === type); if ( a && a.length > 0 ) { for (let e of a) { let vectorLayer = e.vector; this.removeVector(vectorLayer); } } }, removeVector(vectorLayer){ vectorLayer.setVisible(false); let vectorSource = vectorLayer.getSource().getSource(); let currentFeatures = vectorSource.getFeatures(); if (currentFeatures.length !== 0) { //移除聚合标注数据源中的所有要素 vectorSource.clear(); //移除标注图层 this.map.removeLayer( vectorLayer.getSource()); } }, /** * 初始化点位的图层信息 */ initLayer(){ this.vectorLayerList = []; //获取所有的图标映射,并初始化所有类型的图标图层,此时图标图层不可见 let iconMapper = getIconMapper(); for (let ele of iconMapper) { let vectorLayer = markLayer(ele.src,this); let a = { name: ele.name, vector:vectorLayer } this.vectorLayerList.push(a); } }, markPoint(type,point) { //获取该点位的图层 let layer ; for (let ele of this.vectorLayerList) { if (ele.name && ele.name === type ) { layer = ele.vector; break; } } if (layer === null || layer === undefined) { let src = getIconByName(type); let vectorLayer = markLayer(src, this); let a = { name: type, vector: vectorLayer }; this.vectorLayerList(a); layer = vectorLayer; } //获取点位图层的数据源 let vectorSource = layer.getSource().getSource(); var baidu_point={lat:0,lon:0}; baidu_point.lat=point.pos[0]; baidu_point.lon=point.pos[1]; var ss=this.baiduTomars(baidu_point); //百度坐标转火星坐标 var sss=this.transformGCJ2WGS(ss.lat,ss.lon); //火星坐标系GCJ02转地球坐标系WGS84 point.pos[0]=sss.lat; point.pos[1]=sss.lon; this.addVectorLabel(vectorSource, point); layer.setVisible(true); }, //------------------------------------------------------------- transformGCJ2WGS(gcjLat, gcjLon) { let d = this.delta(gcjLat, gcjLon); return { 'lat': gcjLat - d.lat, 'lon': gcjLon - d.lon } }, delta(lat, lon) { var PI = 3.14159265358979324; let a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。 let ee = 0.00669342162296594323 ;// ee: 椭球的偏心率。 let dLat = this.transformLat(lon - 105.0, lat - 35.0); let dLon = this.transformLon(lon - 105.0, lat - 35.0); let radLat = lat / 180.0 * PI; let magic = Math.sin(radLat); magic = 1 - ee * magic * magic; let sqrtMagic = Math.sqrt(magic); dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI); dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI); return { 'lat': dLat, 'lon': dLon } }, transformLat(x, y) { var PI = 3.14159265358979324; let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0; ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0; return ret }, transformLon(x, y) { var PI = 3.14159265358979324; let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0; ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0; return ret }, //--------------------------------------------------------------------------- baiduTomars(baidu_point){ var x_pi=3.14159265358979324 * 3000.0 / 180.0; var mars_point={lon:0,lat:0}; var x=baidu_point.lon-0.0065; var y=baidu_point.lat-0.006; var z=Math.sqrt(x*x+y*y)- 0.00002 * Math.sin(y * x_pi); var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); mars_point.lon=z * Math.cos(theta); mars_point.lat=z * Math.sin(theta); return mars_point; }, //------------------------------------------------------------ /** * 添加点位图层的数据源信息 * @param vectorSource 数据源 * @paramy point 点位信息 */ addVectorLabel(vectorSource,point) { //新建一个要素 ol.Feature const newFeature = new Feature({ //几何信息 geometry: new Point(point.pos), name: point.name, desc: point.desc, img: point.img }); //设置要素的样式 /* newFeature.setStyle(this.createLabelStyle(newFeature));*/ //将新要素添加到数据源中 vectorSource.addFeature(newFeature); }, /** * 创建图标样式 * @returns {Style} */ createLabelStyle(feature) { return new Style({ image: icon(feature.get("img")), text: text( feature.get('name')) }); }, addEagleViewControl() { if (this.map != null) { let TiandiMap_img = new TileLayer({ name: '天地图影像图层', visible: true, source: new XYZ({ url: 'http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=key', wrapX: false, }), }); let TiandiMap_imgcia = new TileLayer({ name: '天地图影像注记图层', visible: true, source: new XYZ({ url: 'http://t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=key', wrapX: false, }), }); //实例化鹰眼控件(OverviewMap),自定义样式的鹰眼控件 var overviewMapControl = new OverviewMap({ //鹰眼控件样式(see in overviewmap-custom.html to see the custom CSS used) className: 'ol-overviewmap ol-custom-overviewmap', //鹰眼中加载同坐标系下不同数据源的图层 layers: [TiandiMap_img, TiandiMap_imgcia], //鹰眼控件展开时功能按钮上的标识(网页的JS的字符编码) collapseLabel: '\u00BB', //鹰眼控件折叠时功能按钮上的标识(网页的JS的字符编码) label: '\u00AB', //初始为展开显示方式 collapsed: false, }); this.map.addControl(overviewMapControl); } }, /** * 初始化地图 */ initMap() { let _this = this; let location = [116.477464559, 30.523468417]; let zoomIndex = 9; return getLocationAndZoom().then(res=>{ if (res && res.length > 0 ){ location[0] = res[0]; location[1] = res[1]; zoomIndex = res[2]; } _this.map = new Map({ target: "map", layers: [ new TileLayer({ name: "矢量图层", pkid:'t1', source:new XYZ({ url: 'http://t'+Math.round(Math.random()*7)+'.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=key', wrapX: false }) }), new TileLayer({ name: "矢量", pkid:'t2', source:new XYZ({ url: 'http://t'+Math.round(Math.random()*7)+'.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=key', wrapX: false }) }), new TileLayer({ name: "影像图层", pkid:'t3', source:new XYZ({ url: 'http://t'+Math.round(Math.random()*7)+'.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=key', wrapX: false }) }), new TileLayer({ name: "影像", pkid:'t4', source:new XYZ({ url: 'http://t'+Math.round(Math.random()*7)+'.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=key', wrapX: false }) }), ], //15°45′—117°44′ view: new View({ projection: "EPSG:4326", //117.05, 30.53 center: location, zoom: zoomIndex, }), }); return res; }); }, //------------------------------------------------------------ /** * 弹窗2021-12-21 */ // layerDetail() { // this.showModal = true; // }, // layerClose() { // this.showModal = false; // } }, }; </script> <style scoped> >>>.ol-overviewmap { left: 1.5em; bottom: 9.5em; } /*=S 自定义鹰眼样式 */ .ol-custom-overviewmap, .ol-custom-overviewmap.ol-uncollapsible { bottom: auto; left: auto; /* 右侧显示 */ right: 0; /* 顶部显示 */ top: 0; } /* 鹰眼控件展开时控件外框的样式 */ .ol-custom-overviewmap:not(.ol-collapsed) { border: 1px solid black; } /* 鹰眼控件中地图容器样式 */ >>>.ol-custom-overviewmap .ol-overviewmap-map { border: none; width: 260px; } /* 鹰眼控件中显示当前窗口中主图区域的边框 */ >>>.ol-custom-overviewmap .ol-overviewmap-box { border: 2px solid red; } /* 鹰眼控件展开时其控件按钮图标的样式 */ .ol-custom-overviewmap:not(.ol-collapsed) button{ bottom: auto; left: auto; right: 1px; top: 1px; } .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: 45px; left: -50px; width: 200px; } .ol-popup:after, .ol-popup:before { top: 100%; border: solid transparent; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; } .ol-popup:after { border-top-color: white; border-width: 10px; left: 48px; margin-left: -10px; } .ol-popup:before { border-top-color: #cccccc; border-width: 11px; left: 48px; margin-left: -11px; } .ol-popup-closer { text-decoration: none; position: absolute; top: 2px; right: 8px; } .ol-popup-closer:after { content: "✖"; } #popup-content { font-size: 14px; font-family: "微软雅黑"; } #popup-content .markerInfo { font-weight: bold; width: 200px; } /* 图层控件层样式设置 */ .layerSwitch{ position: absolute; right: 50px; bottom: 80px; z-index: 2001; padding: 10px; background-color: rgba(249, 249, 249, 0.87); cursor: pointer; -webkit-box-shadow: rgb(0 0 0 / 20%) 0 2px 4px, rgb(0 0 0 / 2%) 0 -1px 0; box-shadow: 0 2px 4px rgb(0 0 0 / 20%), 0 -1px 0 rgb(0 0 0 / 2%); border-radius: 4px } .layerControl { position: absolute; bottom: 5px; min-width: 190px; max-height: 75px; right: 105px; bottom: 60px; /*在地图容器中的层,要设置z-index的值让其显示在地图上层*/ z-index: 2001; color: rgba(0,0,0,0.85); background-color: rgba(249, 249, 249, 0.87); /*边缘的宽度*/ border-width: 0; /*圆角的大小 */ border-radius: 0; /*边框颜色*/ border-color: #000 #000 #000 #000; } .layerControl .title { font-weight: bold; font-size: 15px; margin: 10px; line-height: 30px; border-bottom: 1px solid #dbdbdb; text-align: left; } .layerTree{ display: flex; flex-wrap: wrap; text-align: center; padding: 0 5px; } >>>.layerTree li { list-style: none; margin: 10px 5px; border: 2px solid transparent; } >>>.layerTree li label{ display: block; cursor: pointer; position: relative; width: 78px; height: 55px; overflow:hidden; } >>>.layerTree li label p{ position: absolute; bottom: 0; left: 0; background-color: rgba(0,0,0,0.5); color: #fff; padding: 1px 5px; border-radius: 0 4px 0 0; } >>>.layerTree li input{ display: none; } >>>.layerTree li:hover img{ transform: scale(1.1); } >>>.layerTree li img{ width: 78px; height: 55px; position: absolute; left: 0; bottom: 0; } >>>.layerTree li.active{ border: 2px solid #0075ff; } >>>.layerTree li.active p{ background-color:#0075ff; } /* 鼠标位置控件层样式设置 */ #mouse-position { float: left; position: absolute; bottom: 5px; width: 330px; height: 20px; /*在地图容器中的层,要设置z-index的值让其显示在地图上层*/ z-index: 2000; } </style>
posted on 2022-02-21 15:01 ALWAYS☆REMIND 阅读(1231) 评论(0) 编辑 收藏 举报