openlayer 车辆跟着轨迹移动
1.环境
1.1. openalyer 版本6.3.1
1.2. jquery 版本 3.1.1
2.逻辑描述
2.1 首先根据点位划线。
2.2 坐标点位之间计算距离。
2.4 距离根据一个默认间距计算每个间距下的坐标进行保存。
2.5 创建图标。
2.6 创建定时器,进行图标位置设置,这样就出现一种移动的效果了。
3.效果
4.代码:
//地图服务 var mapServer; //移动车辆图标layer var carOverLay; //移动车辆图标路径 var carImageUrl = "./js/car.png"; //移动车辆速度 var moveSpeed = 30;//移动速度 //所有移动的坐标 var allMovePoints; //所有移动的坐标索引 var allMovePointsIndex = 0; 4.1 创建地图: /*geoserver配置*/ //地图默认层级 var gzoom =13; //地图可缩最小层级 var gminZoom =1; //地图可放大最大层级 var gmaxZoom =16; //地图中心点位 var gcenter=[114.025705,22.68988]; //地图加载瓦片地址 var gispath="http://127.0.0.1:8082/map/{z}/{n}/{x}_{y}.png"; //地图可拖动边界 var extentPoint ; function createMapServer(){ mapServer = new ol.Map({ layers: [Thai], view: new ol.View({ center:gcenter, projection: 'EPSG:4326', zoom: gzoom, minZoom: gminZoom, maxZoom: gmaxZoom //extent:extentPoint }), logo : false, controls : new ol.control.defaults({ zoom : false // 隐藏缩放按钮 }), //地图放置div层 target: document.getElementById('sitemap') }); } 4.2: 创建图标在地图上 function createCarIcon(x1,y1,x2,y2){ var carDiv = document.createElement('div'); carDiv.id = "car"; var html=""; html+='<div style="float:left;"><img src="'+carImageUrl+'" id="carImage" style="float:left;transform:rotate('+getAngle(x1,y1,x2,y2)+'deg);"/></div>'; carDiv.innerHTML = html; document.body.appendChild(carDiv); carOverLay = new ol.Overlay({ position: point, positioning: 'bottom-center', offset:[6,-1], element:document.getElementById('car') }); mapServer.addOverlay(carOverLay); } /** * 根据坐标获取角度数,以正上方为0度作为参照 */ function getAngle(lng_a,lat_a, lng_b, lat_b){ var a = (90 - lat_b) * Math.PI / 180; var b = (90 - lat_a) * Math.PI / 180; var AOC_BOC = (lng_b - lng_a) * Math.PI / 180; var cosc = Math.cos(a) * Math.cos(b) + Math.sin(a) * Math.sin(b) * Math.cos(AOC_BOC); var sinc = Math.sqrt(1 - cosc * cosc); var sinA = Math.sin(a) * Math.sin(AOC_BOC) / sinc; var A = Math.asin(sinA) * 180 / Math.PI; var res = 0; if (lng_b > lng_a && lat_b > lat_a) res = A; else if (lng_b > lng_a && lat_b < lat_a) res = 180 - A; else if (lng_b < lng_a && lat_b < lat_a) res = 180 - A; else if (lng_b < lng_a && lat_b > lat_a) res = 360 + A; else if (lng_b > lng_a && lat_b == lat_a) res = 90; else if (lng_b < lng_a && lat_b == lat_a) res = 270; else if (lng_b == lng_a && lat_b > lat_a) res = 0; else if (lng_b == lng_a && lat_b < lat_a) res = 180; console.log(res); res = res - 88;//减去图片默认角度 return res; } 4.3 根据坐标点位获取中间距离 /** * 计算坐标2点之间的距离 * @param {Array} coordinates 传入坐标坐标系必须和地图坐标系一致 {[144,33],[144,37]} * @return length */ function formatLength(pointArray){ var length = 0; if(mapServer.getView().getProjection().code_ == "EPSG:4326"){ for (var i = 0, ii = pointArray.length - 1; i < ii; ++i) { var c1 = pointArray[i]; var c2 =pointArray[i+1]; length += ol.sphere.getDistance(c1, c2); } }else if(mapServer.getView().getProjection().code_ == "EPSG:3857"){ for (var i = 0, ii = pointArray.length - 1; i < ii; ++i) { var c1 = pointArray[i]; var c2 =pointArray[i+1]; c1 = ol.proj.transform(c1, 'EPSG:3857', 'EPSG:4326'); c2 = ol.proj.transform(c2, 'EPSG:3857', 'EPSG:4326'); length += ol.sphere.getDistance(c1, c2); } } return length; } 4.4 根据距离,间距计算中间所有点位坐标 /** * 计算两点之间的中间点 * @param {Array} pointDoubleArray 二维数组坐标 * @param {num} cell 每个点之间的距离 */ function getCenterPoint(pointDoubleArray,cell){ cell = cell == undefined ? 5 : cell; var twolength = formatLength(pointDoubleArray); var rate = twolength/cell; //比例 默认5m/点 var step = Math.ceil(rate); //步数(向上取整) var arr = new Array(); //定义存储中间点数组 var c1 = pointDoubleArray[0];//头部点 var c2 = pointDoubleArray[1];//尾部点 var x1 = c1.x,y1 = c1.y; var x2 = c2.x,y2 = c2.y; for (var i = 1;i<step;i++) { var coor = {}; coor.x = (x2-x1)*i/rate+x1; coor.y = (y2-y1)*i/rate+y1; arr.push(coor); //此时arr为中间点的坐标 } arr.push(c2); return arr; } 4.5 得到所有点位坐标 /*得到所有要移动的点位*/ function getAllMovePoint(pointArray,cell){ cell = cell ==undefined ? 5 :cell; var brr = new Array(); brr.push(pointArray[0]); //添加起点 for (i = 0;i < pointArray.length-1; i++) { var coor1 = pointArray[i]; var coor2 = pointArray[i + 1]; var crr = this.centerPoint([coor1,coor2],cell); for(var a=0;a<crr.length;a++){ brr.push(crr[a]); } } return brr; } 4.6 移动轨迹 function showPoint(){ //每次移动,根据两点坐标,图标旋转角度 if(allMovePointsIndex+1 != allMovePoints.length){ firstPoint = allMovePoints[allMovePointsIndex]; secondPoint = allMovePoints[allMovePointsIndex+1]; var transRotate = getAngle(firstPoint.x,firstPoint.y,secondPoint.x,secondPoint.y); $('#carImage').attr("style","float:left;transform:rotate("+transRotate+"deg)"); carOverLay.setPosition([allMovePoints[allMovePointsIndex].x,allMovePoints[allMovePointsIndex].y]); //设置小车位置 allMovePointsIndex++; } } 4.7调用: function move(pointArray){ //创建汽车初始点位,首先传2个坐标,为了将图标按照轨迹路线,进行旋转,让车头与路线对齐 createCarLayer(pointArray[0],pointArray[1]); //获取所有点位 allMovePoints = getAllMovePoint(pointArray,5); //进行移动 setInterval(showPoint, moveSpeed); }