openlayers是一个开源免费的js库,用于在网页中实现地图的动态显示和交互。
初始化地图
- 首先,引用ol.css和ol.js,因为我们已经下载了ol库,所以使用ol的本地路径就行了,如果网络方便,可以直接在从ol网站获取。
1 2 3
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css" type="text/css"> <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js"></script> <script src="decision/static/js/jquery.min.js"></script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
// 底图 高德地图 ol.layer.Tile 提供被切分为切片的图片地图数据 var gaodeMapLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}' }) }); this.map = new ol.Map({ target: "map", //图层 可以添加多个地图地图 layers: [gaodeMapLayer], controls:[scaleLineControl],//也可以this.map.addControl view: new ol.View({ center: [117.814635,36.402033], projection: 'EPSG:4326', zoom: 8,//地图缩放级别 minZoom:5, maxZoom:12 }) }); // 实例化比例尺控件 var scaleLineControl = new ol.control.ScaleLine({ // 设置比例尺单位为degrees、imperial、us、nautical或metric(度量单位) units: "metric" }); this.map.addControl(scaleLineControl);
|
- 这段代码的作用是在网页是显示一个地图;
- 和leaflet一样,地图必须显示在一个div中,因此首先创建一个div;
- target:’map’ 指定了地图要显示在id为map的div中;
- new ol.layer.Tile({ source: new ol.source.OSM() }) 定义了一个图层,数据来源是OpenStreetMap提供的切片数据;
- new ol.View({ center: ol.proj.fromLonLat([37.41, 8.82]), zoom: 4 }) 定义了地图的中心位置,范围和层级。
- ol.proj.fromLonLat([37.41, 8.82]) 是将一个经纬度坐标转换成当前地图投影的坐标;
openlayers自定义图层
1 2 3 4 5 6 7 8 9
|
//矢量标注的数据源 this.nodeSource.addFeature 添加标点 var nodeLayer 只是在地图上添加该图层 this.nodeSource = new ol.source.Vector({ features: [] }); // 矢量标注图层 也可以nodeLayer.addFeatures var nodeLayer = new ol.layer.Vector({ source: this.nodeSource, }); this.map.addLayer(nodeLayer);
|
获取自定义图层中的所有数据
- this.nodeSource.getFeatureById(id) 获取指定id的图层
1 2 3 4 5 6 7
|
var allNodeMarker = this.nodeSource.getFeatures(); //获取图层对应自定义名称的features删除掉 for (let i = 0; i < allStartMarker.length-1; i++) { if(allNodeMarker[i].values_.layerType == markerLayerName){ this.nodeSource.removeFeature(allStartMarker[i]); } }
|
创建图标
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
createNodeMarker(item, txt){ var newFeature = new ol.Feature({ geometry: new ol.geom.Point([item.longitude, item.latitude]), //几何信息 data: item, type: 'event',//设置键值对的集合私有属性 setProperties设置也可以 layerType:'自定义私有属性' // }); let data = newFeature.values_.data.eventType; //设置要素样式 坐标图片 newFeature.setStyle(this.createNodeStyle(imgurl)); //nodeSource数据标点图层添加数据 this.nodeSource.addFeature(newFeature); } createNodeStyle(imgurl,size='0.5') { return new ol.style.Style({ image: new ol.style.Icon({ anchor: [0.5, 60], //锚点 anchorOrigin: "top-right", //锚点源 anchorXUnits: "fraction", //锚点X值单位 anchorYUnits: "pixels", //锚点Y值单位 offsetOrigin: "top-right", //偏移原点 opacity: 1, scale:size, src: '/images/sign/'+imgurl+'.png' }), }) }
|
创建线
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
var lineData = [] // [ [lng,lat],[lng,lat],[lng,lat],[lng,lat],[lng,lat]] lineData.push(ol.proj.fromLonLat([points[i].longitude,points[i].latitude])); var lineFeature = new ol.Feature({ geometry: new ol.geom.LineString(lineData), layerType:type, }); var lineStyle = new ol.style.Style({ stroke: new ol.style.Stroke({ color: 'red', width: 2 }) }); lineFeature.setStyle(lineStyle); this.startAndEndMarker.addFeature(lineFeature);
|
openlayers添加鼠标右键
- openlayers没有右键操作 需要通过jq监听右键来实现效果
- 右键弹出的dom需要display:none否则会出现在地图上 操作的时候dom在显示出来
- 删除右键图层会造成dom丢失所以取消设置定位为null即可 self.menu_overlay.setPosition(null);
-
1 2 3 4 5 6 7 8 9
|
<div v-show="menuShow" id="contextmenu_container" class="contextmenu"> <ul> <div @click="creatNode">设置事件发生地点</div> <li v-for="(item,index) in this.addForm.pathPoints"> <div @click="setStart(index)">设置起点{{index+1}}</div> <div @click="setEnd(index)">设置终点{{index+1}}</div> </li> </ul> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
addMenu_over(){ var self = this; this.menuShow = true; this.menu_overlay= new ol.Overlay({ element: document.getElementById("contextmenu_container"), positioning: 'right-top' }); this.map.addOverlay(self.menu_overlay); $(self.map.getViewport()).unbind('contextmenu').on("contextmenu", function(event){ event.preventDefault();//屏蔽自带的右键事件 var pixel = [event.clientX,event.clientY]; let feature = self.map.forEachFeatureAtPixel(pixel, (feature, layer) => { return feature; }); var coordinate = self.map.getEventCoordinate(event.originalEvent); self.menu_overlay.setPosition(coordinate); }); },
|
openlayers中overlay 添加覆盖物
- overlay是覆盖物的意思,主要是放置一些和地图位置相关的元素,
- 如:infowindow、点标记、图片等,而这些覆盖物都是和html中的element等价的,
- 通过overlay的属性element和html元素绑定同时设定坐标参数——达到将html元素放到地图上的位置,在平移缩放的时候html元素也会随着地图的移动而移动。
鼠标悬浮添加提示框
-
1 2 3 4 5 6 7 8 9 10
|
<div id="popup"> <el-popover placement="top-start" title="RSU编号" width="200" trigger="manual" v-model="popoverVisible" :content="currentRsuSnHoverId"> </el-popover> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
var container = document.getElementById("popup1"); this.overlay1 = new ol.Overlay({ //设置弹出框的容器 element: container, //是否自动平移,即假如标记在屏幕边缘,弹出时自动平移地图使弹出框完全可见 autoPan: true, positioning: "top-center", offset: [-20, -120] }); //地图鼠标悬浮创建不同标注弹出层 this.map.on("pointermove", evt => { //https://www.zybuluo.com/mgsky1/note/1132768
|
点击某一图层添加覆盖物操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
<div id="popup" class="ol-popup"> <div id="popup-content"> <el-tooltip content="编辑点" effect="dark" placement="bottom" > <el-button icon="el-icon-edit primary" size="mini" circle @click="editPointSerial()" /> </el-tooltip> <el-tooltip :content="删除点" effect="dark" placement="bottom" > <el-button icon="el-icon-delete" size="mini" type="danger" circle @click="deletePoint()" /> </el-tooltip> </div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
this.pointSource = new ol.source.Vector({ features: [] }); var pointLayer = new ol.layer.Vector({ source: this.pointSource }); this.map.addLayer(pointLayer);
//添加popup覆盖物 var container = document.getElementById("popup"); this.overlay = new ol.Overlay({ //设置弹出框的容器 element: container, //是否自动平移,即假如标记在屏幕边缘,弹出时自动平移地图使弹出框完全可见 autoPan: true, positioning: "top-center", offset: [0, -48] }); let pointSelect = new ol.interaction.Select({ //condition: ol.events.condition.pointerMove, layers: [pointLayer],//选择哪个图层进行操作 style: feature => {//设置选中样式 return this.stylePointSelect(feature); }, multi: false //multi设置是否可以多选 }); //图层选中的一些操作 pointSelect.on("select", e => { if (e.selected.length > 0 && this.addPointWay === "") { var coodinate = e.selected[0].getGeometry().flatCoordinates; //设置弹出框内容,可以HTML自定义 // content.innerHTML = "<p>aaaaaAA</p>"; //设置overlay的显示位置 this.selectedPointSerial = e.selected[0].values_.id; this.overlay.setPosition(coodinate); //显示overlay this.map.addOverlay(this.overlay); } else { this.map.removeOverlay(this.overlay); } }); this.map.addInteraction(pointSelect);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
stylePointSelect(feature) { var fill = new ol.style.Fill({ color: "#EA5504" }); var stroke = new ol.style.Stroke({ color: "#EA5504", width: 1 }); return new ol.style.Style({ image: new ol.style.Circle({ fill: fill, stroke: stroke, radius: 12 }), text: new ol.style.Text({ textAlign: "center", //位置 textBaseline: "middle", //基准线 font: "normal 14px 微软雅黑", //文字样式 text: feature.values_.id + "", //文本内容 fill: new ol.style.Fill({ //文本填充样式(即文字颜色) color: "#DCDFE6" }), stroke: new ol.style.Stroke({ color: "#DCDFE6" }) }) }); },
|
动态切换瓦片地图
1 2 3 4 5 6 7 8 9 10
|
this.picLayer = new ol.layer.Tile({}); this.map = new ol.Map({ target: "map", layers: [gaodeMapLayer, this.picLayer], view: new ol.View({ zoom: 14, minZoom: 10, maxZoom: 21 }) });
|
- 通过setSource动态更换地图切片
1 2 3 4 5 6 7 8 9 10
|
this.picLayer.setSource( new ol.source.TileWMS({ url: mapUrl + this.currentProject.name + "/wms", params: { LAYERS: this.currentProject.name, //此处可以是单个图层名称,也可以是图层组名称,或多个图层名称 TILED: true }, serverType: "geoserver" //服务器类型 }) );
|
只能在切片地图上操作
地图平移动画
1 2 3 4
|
this.map.getView().animate({ center: this.translateInMap([longitude,latitude]), duration: 800 });
|
自动打点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
- startPointSerial 起始点号 - autoAddPointSerial 打点数 finishAddPoint() { if (this.addPointWay === "auto") { if (this.startPointSerial >= this.pointData.length) { this.$message.error("起始位置不合法"); return; } else { var newLineFeature = new ol.Feature({ geometry: new ol.geom.LineString([ this.pointSource .getFeatureById(parseInt(this.startPointSerial)) .getGeometry().flatCoordinates, this.pointSource .getFeatureById(parseInt(this.startPointSerial) + 1) .getGeometry().flatCoordinates ]) }); this.linkSource.addFeature(newLineFeature); let list = []; for (let i = 0; i < this.autoAddPointSerial; i++) { let pos = newLineFeature .getGeometry() .getCoordinateAt( (i + 1) / (parseInt(this.autoAddPointSerial) + 1) ); list.push(this.translatePosition(pos[0], pos[1])); } list.unshift(this.startPointSerial, 0); Array.prototype.splice.apply(this.pointData, list); this.linkSource.removeFeature(newLineFeature); } } this.updateLanePoints(); this.addPointWay = ""; if (this.linkSource.getFeatureById("newLane")) { this.linkSource.removeFeature( this.linkSource.getFeatureById("newLane") ); } },
|