实现思路:
首先 前置步骤 初始化地图 绘制 站点 线路
后端收集 司机端传回来的车辆实时经纬度组成的数组
前端每 15秒 轮询接口 拿到最新的数据
//轮询函数
pollingFunction() {
console.log("开始轮询");
this.getRealTimeData();
this.timer = window.setInterval(() => {
console.log(this.timer);
let timerr = setTimeout(() => {
this.getRealTimeData();
clearTimeout(timerr);
}, 0);
}, 15000);
},
获取到数据后 判断是否有新出发的车辆 和 是否有已到站的车辆 busList 是一个车辆集合
如果车牌号集合里面 没有这辆车说明是新出发车辆
如果车牌号集合里面有 但是返回数据里面没有这辆车 说明是这辆车已到站
如果以上两个条件都没满足 说明是正常行驶车辆
if (res.data.busGisList.length > 0) {
console.log("有" + res.data.busGisList.length + "辆车");
//判断 是否有发车的车辆 查看 busGisList 中是否有 busList不包含的 车辆
//newBusList 不包含的车辆集
let newBusList = res.data.busGisList.filter((bus) => {
return !this.busList.includes(bus.busNumber);
});
if (newBusList.length > 0) {
newBusList.forEach((bus) => {
console.log("出发一辆新车 车牌号为" + bus.busNumber);
//将新添加的每一辆车 加到当前车辆集合里
this.busList.push(bus.busNumber);
//在地图中 渲染车辆
this.addBusMarker(bus);
});
}
//判断 是否有跑完全程的 车辆 查看 busList 中是否有 busGisList不包含的车辆 获取到他的车牌号
// 获取现在返回的 所有车牌号
let temporarily_busNumber_list = res.data.busGisList.map((bus) => {
return bus.busNumber;
});
//deleteBusNumberList 准备去除的 不包含的车牌号集
let deleteBusNumberList = this.busList.filter((bus) => {
return !temporarily_busNumber_list.includes(bus);
});
//根据车牌号清除车辆覆盖物
temporarily_busNumber_list = null;
if (deleteBusNumberList.length > 0) {
this.removeBusMarker(deleteBusNumberList);
}
//最新的车辆 让车辆跑起来
let timer = setTimeout(() => {
res.data.busGisList.forEach((bus) => {
this.carPosition(bus);
});
clearTimeout(timer);
}, 200);
} else {
console.log("没车了");
this.removeBusMarker(this.busList);
}
如果有新车的话 添加新的车辆覆盖物 在高德地图JSAPI2.0 使用覆盖物动画必须先加载动画插件MoveAnimation 存了一个自定义属性为这个车的车牌号 当做暂时性的唯一标识
//添加 车辆覆盖物
async addBusMarker(pos) {
let that = this;
const AMap = await AMapLoader();
AMap.plugin("AMap.MoveAnimation", function () {
let maker = new AMap.Marker({
map: that.map,
content: `<div class="bus-icon" style="transform:rotate(-90deg)"><div>`,
position: [pos.lng, pos.lat],
zIndex: 10,
anchor: "center",
autoRotation: true,
// offset: [-31, -19],
extData: { busNumber: pos.busNumber },
});
that.map.add(maker);
that.markersArr.push(maker);
});
},
已到站的车辆 在地图上清除 因为到站车辆可能是多个 所以这里传入的是一个数组 通过添加覆盖物时定义的自定义属性 车牌号 找到对应的覆盖物 清除
//根据车牌号清除车辆覆盖物
removeBusMarker(busNumberList) {
console.log("清除", busNumberList);
if (busNumberList.length < 1) {
return;
}
let that = this;
//获取所有的 点覆盖物
let overlaysList = that.map.getAllOverlays("marker");
for (var i = 0; i < overlaysList.length; i++) {
let busNumber = overlaysList[i].getExtData().busNumber;
if (busNumberList.includes(busNumber)) {
console.log("清除一辆到达车 车牌号为" + busNumber);
this.busList.splice(this.busList.indexOf(busNumber), 1);
that.map.remove(overlaysList[i]);
}
}
},
该加的加上了 该清的清掉了 就可以 让最新的车辆集合 跑起来 计算车辆运行轨迹
//计算车辆运动轨迹
carPosition(bus) {
let that = this;
//获取到 车辆
let marker = null;
//获取所有的 点覆盖物
let overlaysList = that.map.getAllOverlays("marker");
for (var i = 0; i < overlaysList.length; i++) {
let busNumber = overlaysList[i].getExtData().busNumber;
if (busNumber === bus.busNumber) {
marker = overlaysList[i];
break;
}
}
console.log(bus, "bus");
if (bus.gpsList == null) bus.gpsList = [];
//获取到轨迹
let lineArr = bus.gpsList.map((item) => {
return new AMap.LngLat(item.lng, item.lat);
});
//开始让车辆动起来
if (marker && lineArr.length > 1) {
// 开始运行
this.busMarkerMoveLong(marker, lineArr);
}
},
//让车辆覆盖物动起来
busMarkerMoveLong(marker, lineArr, duration = 1500) {
marker.moveAlong(lineArr, {
// 每一段的时长
duration: duration, //可根据实际采集时间间隔设置
// JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置
autoRotation: true,
});
},
车辆就可以稳步运行在地图上了 在JSAPI 2.0 中 使用轨迹回放是可以 自动改变角度 车辆会按照你传入的轨迹 自动转向