心酸制作历程
当刚接下这项目时,便开始研究如何实现轨迹回放的功能;而刚开始当然是直接查找百度的实例百度路书实例,如下图
但是我们的需求是需要通过进度,速度来进行调整(如下图),显然难以达到这个目标。
因此,在查看了多个文档后,选择了一个勉强达到需求的办法,就跟canvas的方式一样,每秒清除地图上的所有覆盖物,然后车重新定位地图中心点,画出运行到的轨迹,虽然可行,但是整个车运行的过程中,就宛如地图在移动,车一直钉在地图中心。
直到一位大佬把这问题迎刃而解(我打辅助,多多学习)
查找路书的源码
在找到一篇大佬的文档后,发现,需要从路书的源码下手,路书源码,推荐直接已CDN形式放在index.html中。
<script type="text/javascript" src="http://api.map.baidu.com/library/LuShu/1.2/src/LuShu_min.js"></script>
推荐看下路书源码, 你会了解很多东西,这样上手容易些。
下面直接进入我们的代码,废话不多说。
<!-- 地图容器开始 -->
<div id="mymap" style="width:100%;height:100%"></div>
// 在mounted处 实例化地图
mounted() {
var map = new BMap.Map("mymap"); //实例化地图
var point = new BMap.Point(116.404, 39.915); // 创建点坐标
map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别
map.enableScrollWheelZoom(true); // 允许缩放
map.centerAndZoom()
this.istranslate = true
this.infoWindow.contents = `<div style="text-align: center;line-height: 30px;font-size: 12px;font-weight:600;">
GSM信号:<i class="fa fa-signal" style="color:#42AEED"></i><br>
速度:${Number(this.speednum)} KM/H<br>
定位方式:卫星定位
</div>`
},
methods: {
// 获取轨迹点
allTrackData(val, index) {
const params = {
mcph: this.mcph,
datetime: val.time,
datetime1: val.startime,
}
this.path = [] // 轨迹点
this.temp = 0 // 进度条
getSlotDetail(params).then(res => { // 请求车辆轨迹点
res.data.forEach(item => {
this.path.push({
lng: item.longitude,
lat: item.latitude,
heading: item.heading,
speed: Number(item.speed)
})
})
this.initMap() // 初始化地图
this.isPlay = true // 播放键开始
this.lushu.start() // 路书开始
this.maxNum = this.path.length - 2
// 打开天窗
this.infoWindow.show = true
})
},
// 下面的两个方法 从路书源码中摘取 修改
// 初始化地图
initMap() {
var _this = this
var map = new BMap.Map("mymap");
var point = new BMap.Point(116.404, 39.915); // 创建点坐标
map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别
map.enableScrollWheelZoom(true);
map.centerAndZoom()
var arrPois = [];
for (let i = 0; i < this.path.length; i++) {
var p0 = this.path[i].lng;
var p1 = this.path[i].lat;
// var checksum = makerArry[i].checksum;
var point = new BMap.Point(p0, p1); //118.230272,33.482474
arrPois.push(point);
}
//画轨迹
var polyLine = new BMap.Polyline(arrPois, {
strokeColor: "red", //设置颜色
strokeWeight: 5, //宽度
strokeOpacity: 0.5 //透明度
});
map.addOverlay(polyLine);
//画轨迹结束
BMapLib.LuShu.prototype._move = function (initPos, targetPos, effect) {
var pointsArr = [initPos, targetPos]; //点数组
var me = this,
//当前的帧数
currentCount = 0,
//步长,米/秒
timer = 10,
step = this._opts.speed / (1000 / timer),
//初始坐标
init_pos = this._projection.lngLatToPoint(initPos),
//获取结束点的(x,y)坐标
target_pos = this._projection.lngLatToPoint(targetPos),
//总的步长
count = Math.round(me._getDistance(init_pos, target_pos) / step);
//显示折线 syj201607191107
//如果想显示小车走过的痕迹,放开这段代码就行
// this._map.addOverlay(
// new BMap.Polyline(pointsArr, {
// strokeColor: "#111",
// strokeWeight: 5,
// strokeOpacity: 0.5
// })
// ); // 画线
//如果小于1直接移动到下一点
if (count < 1) {
me._moveNext(++me.i);
return;
}
this._opts.defaultContent = `<div style="text-align: center;line-height: 30px;font-size: 12px;font-weight:600;">
GSM信号:<i class="fa fa-signal" style="color:#42AEED"></i><br>
速度:${_this.path[me.i].speed} KM/H<br>
定位方式:卫星定位
</div>`
_this.speednum = _this.path[me.i].speed
me._intervalFlag = setInterval(function () {
// _this.maxNum = me._path.length
_this.temp = me.i
//两点之间当前帧数大于总帧数的时候,则说明已经完成移动
if (currentCount >= count) {
clearInterval(me._intervalFlag);
//移动的点已经超过总的长度
if (me.i > me._path.length) {
return;
}
//运行下一个点
me._moveNext(++me.i);
} else {
currentCount++;
var x = effect(init_pos.x, target_pos.x, currentCount, count),
y = effect(init_pos.y, target_pos.y, currentCount, count),
pos = me._projection.pointToLngLat(new BMap.Pixel(x, y));
//设置marker
if (currentCount == 1) {
var proPos = null;
if (me.i - 1 >= 0) {
proPos = me._path[me.i - 1];
}
if (me._opts.enableRotation == true) {
me.setRotation(proPos, initPos, targetPos);
}
if (me._opts.autoView) {
if (!me._map.getBounds().containsPoint(pos)) {
me._map.setCenter(pos);
}
}
}
//正在移动
me._marker.setPosition(pos);
//设置自定义overlay的位置
me._setInfoWin(pos);
}
}, timer);
};
this.initLushu(map, arrPois, this.mycaiId);
},
initLushu(map, arrPois, mycaiId) {
this.lushu = new BMapLib.LuShu(map, arrPois, {
defaultContent: this.infoWindow.contents, //"从天安门到百度大厦"
autoView: true, //是否开启自动视野调整,如果开启那么路书在运动过程中会根据视野自动调整
icon: new BMap.Icon(
"http://developer.baidu.com/map/jsdemo/img/car.png",
new BMap.Size(52, 26), {
anchor: new BMap.Size(27, 13)
}
),
speed: this.speed,
enableRotation: true, //是否设置marker随着道路的走向进行旋转
landmarkPois: []
});
},
}
至此,我们的车就能移动了,而且当车超出地图的范围,自动回到地图中心,主要改变的就是路书原型链上_move的方法。
下面再添上需求的几个方法
// 改变播放的速度 快进形式
speedChange() {
this.lushu._opts.speed = this.speed
},
// 回放进度条 向前向后拉进度条
tempChange() {
this.lushu.i = this.temp
if (this.temp >= this.maxNum - 2) {
this.isPlay = false
}
},
// 开始&暂停
playChange() {
if (this.isPlay) {
this.lushu.pause();
this.isPlay = false
} else {
this.lushu.start();
this.isPlay = true
}
},
// 重置轨迹
reset() {
this.temp = 0
this.speed = 1000
this.isPlay = false
this.lushu.stop()
},
以上,便是一个满足需求的路书轨迹回放方法,此文仅为记录总结,仅供参考学习。