场景
Openlayers中使用Image的rotation实现车辆定位导航带转角(判断车辆图片旋转角度):
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/118635362
在上面实现一个图层中只有一个feature在移动。
如果有多个feature,即有多辆车时,怎样保证某一个feature,即某一辆车在最上面。
如果有多个feature,且不设置优先级的话会如下
如果要将本车放在最上面,可以将本车与其他车辆放在两个图层layer中,然后设置本车的layer位于最上面。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
1、声明两个图层
//定位图层的Source var positonSource = new ol.source.Vector({ features: [] }); // 定位图层 var positionLayer = new ol.layer.Vector({ source: positonSource }); //定位图层的Source-本车 var positonSourceBenche = new ol.source.Vector({ features: [] }); // 定位图层-本车 var positionLayerBenche = new ol.layer.Vector({ source: positonSourceBenche });
2、本车图层放在最上面,即数组最右边
var map = new ol.Map({ layers: [layer, positionLayer,positionLayerBenche], target: 'map', view: view });
3、将本车放在本车图层的source中
this.positonSourceBenche.addFeature(feature)
4、其他模拟车辆放在另一个图层的source中
//模拟车辆定位数据 var feature1 = new ol.Feature({ geometry: new ol.geom.Point([-11554039.941628069, 5531515.7834814]) }); //设置样式 feature1.setStyle(style); //添加feture this.positonSource.addFeature(feature1)
5、完整示例代码
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>本车图标在最上方</title> <link rel="stylesheet" href="lib/ol65/ol.css" type="text/css"> <style> html, body, #map { padding: 0; margin: 0; 100%; height: 100%; overflow: hidden; } </style> </head> <body> <div id="map"></div> <script type="text/javascript" src="lib/ol65/ol.js"></script> <script type="text/javascript"> //定位数据源 var positionData = [{ x: '-11560139.941628069', y: '5538515.7834814', carNumber: '霸道的程序猿' }, { x: '-11560039.941628069', y: '5537515.7834814', carNumber: '霸道的程序猿' }, { x: '-11559039.941628069', y: '5536515.7834814', carNumber: '霸道的程序猿' }, { x: '-11558039.941628069', y: '5535515.7834814', carNumber: '霸道的程序猿' }, { x: '-11557039.941628069', y: '5534515.7834814', carNumber: '霸道的程序猿' }, { x: '-11556039.941628069', y: '5533515.7834814', carNumber: '霸道的程序猿' }, { x: '-11555039.941628069', y: '5532515.7834814', carNumber: '霸道的程序猿' }, { x: '-11554039.941628069', y: '5531515.7834814', carNumber: '霸道的程序猿' }, { x: '-11553039.941628069', y: '5530515.7834814', carNumber: '霸道的程序猿' }, { x: '-11552039.941628069', y: '5529515.7834814', carNumber: '霸道的程序猿' }, { x: '-11551039.941628069', y: '5528515.7834814', carNumber: '霸道的程序猿' }, { x: '-11550039.941628069', y: '5527515.7834814', carNumber: '霸道的程序猿' }, { x: '-11549039.941628069', y: '5526515.7834814', carNumber: '霸道的程序猿' }, { x: '-11548039.941628069', y: '5525515.7834814', carNumber: '霸道的程序猿' }, { x: '-11547039.941628069', y: '5524515.7834814', carNumber: '霸道的程序猿' }, { x: '-11546039.941628069', y: '5523515.7834814', carNumber: '霸道的程序猿' } ]; var source = new ol.source.XYZ({ tileUrlFunction: function (xyz, obj1, obj2) { if (!xyz) return ""; var z = xyz[0]; var x = Math.abs(xyz[1]); var y = Math.abs(xyz[2]); var xyz_convert = self.convert_(z, x, y); x = xyz_convert[0]; y = xyz_convert[1]; z = xyz_convert[2]; var shift = z / 2; var half = 2 << shift; var digits = 1; if (half > 10) digits = parseInt(Math.log(half) / Math.log(10)) + 1; var halfx = parseInt(x / half); var halfy = parseInt(y / half); x = parseInt(x); y = parseInt(y) - 1; var url = "./images/EPSG_900913" + "_" + self.padLeft_(2, z) + "/" + self.padLeft_(digits, halfx) + "_" + self.padLeft_(digits, halfy) + "/" + self.padLeft_(2 * digits, x) + "_" + self.padLeft_(2 * digits, y) + "." + 'png'; return url; } }); //projections投影坐标系转换相关的操作 var projection = new ol.proj.Projection({ code: 'EPSG:900913', units: 'm', axisOrientation: 'neu' }); //Layers 图层管理类,用来管理图层信息。主要包括Tile,Image,Vector,VectorTile等图层。 var layer = new ol.layer.Tile({ source: source }); //定位图层的Source var positonSource = new ol.source.Vector({ features: [] }); // 定位图层 var positionLayer = new ol.layer.Vector({ source: positonSource }); //定位图层的Source-本车 var positonSourceBenche = new ol.source.Vector({ features: [] }); // 定位图层-本车 var positionLayerBenche = new ol.layer.Vector({ source: positonSourceBenche }); //View 视图管理器,主要用来管理地图视图,分辨率或旋转,中心、投影、分辨率、缩放级别等。 var view = new ol.View({ //中心点 center: [-11549894, 5533433], //缩放等级 zoom: 11, //投影坐标系 projection: projection, //边界 extent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34] }); //Map Openlayers的核心组件,包含图层、交互事件、UI控制元素等。 var map = new ol.Map({ layers: [layer, positionLayer,positionLayerBenche], target: 'map', view: view }); //单击获取地图坐标 map.on('singleclick', (evt) => { console.log(evt.coordinate); }); //xy行列转换 function convert_(zoomLevel, x, y) { var extent = Math.pow(2, zoomLevel); if (x < 0 || x > extent - 1) { console.log("The X coordinate is not sane: " + x); return; } if (y < 0 || y > extent - 1) { console.log("The Y coordinate is not sane: " + y); return; } // openlayers 6.0版本 var gridLoc = [x, extent - y, zoomLevel]; // openlayers 4.5版本 // var gridLoc = [x, extent - y + 1, zoomLevel]; return gridLoc; } //字符截取 function padLeft_(num, val) { return (new Array(num).join('0') + val).slice(-num); } //定时器循环模拟定位效果 var index = 0; setInterval(() => { //坐标数据到头了 就重新开始 if (index > this.positionData.length - 2) { index = 0; } //定义角度 var rotation = 0; //如果是最后一个点 if (index == this.positionData.length - 1) { rotation = setAngle(this.positionData[index], this.positionData[index]); } else { rotation = setAngle(this.positionData[index], this.positionData[index + 1]); } //根据索引获取数据 var item = this.positionData[index]; //清除上次的 if (this.positonSource) { this.positonSource.clear(); } if (this.positonSourceBenche) { this.positonSourceBenche.clear(); } var feature = new ol.Feature({ geometry: new ol.geom.Point([Number(item.x), Number(item.y)]) }); var style = new ol.style.Style({ image: new ol.style.Icon({ scale: 0.8, src: './icon/car.png', anchor: [0.48, 0.52], //设置旋转角度 rotation: -rotation, }), text: new ol.style.Text({ font: 'normal 12px 黑体', // // 对其方式 textAlign: 'center', // 基准线 textBaseline: 'middle', offsetY: -35, offsetX: 0, backgroundFill: new ol.style.Stroke({ color: 'rgba(0,0,255,0.7)', }), // 文本填充样式 fill: new ol.style.Fill({ color: 'rgba(236,218,20,1)' }), padding: [5, 5, 5, 5], text: `${item.carNumber}`, }) }); //本车样式 var styleBenche= new ol.style.Style({ image: new ol.style.Icon({ scale: 0.8, src: './icon/house.png', anchor: [0.48, 0.52], //设置旋转角度 rotation: -rotation, }), text: new ol.style.Text({ font: 'normal 12px 黑体', // // 对其方式 textAlign: 'center', // 基准线 textBaseline: 'middle', offsetY: -35, offsetX: 0, backgroundFill: new ol.style.Stroke({ color: 'rgba(0,0,255,0.7)', }), // 文本填充样式 fill: new ol.style.Fill({ color: 'rgba(236,218,20,1)' }), padding: [5, 5, 5, 5], text: `本车`, }) }); //以当前点为中心 this.flyToPoint([Number(item.x), Number(item.y)]) //本车 //设置样式 feature.setStyle(styleBenche); //添加feture this.positonSourceBenche.addFeature(feature) //模拟车辆定位数据 var feature1 = new ol.Feature({ geometry: new ol.geom.Point([-11554039.941628069, 5531515.7834814]) }); //设置样式 feature1.setStyle(style); //添加feture this.positonSource.addFeature(feature1) //模拟车辆定位数据 var feature2 = new ol.Feature({ geometry: new ol.geom.Point([-11554039.941628069, 5531515.7834814]) }); //设置样式 feature2.setStyle(style); //添加feture this.positonSource.addFeature(feature2) //移到下个点 index++; }, 1000); //设置以当前点位为中心 function flyToPoint(point) { var to = point var view = this.map.getView() view.animate({ center: to, duration: 45 }) } // 点位转角 function setAngle(first, second) { var dx = second.x - first.x var dy = second.y - first.y var rotation = Math.atan2(dy, dx) return rotation } </script> </body> </html>
6、效果