最近项目要做一个轨迹管理模块
涉及功能:
1、展示该车辆一段时间内的轨迹线路
2、可进行播放、暂停、继续播放
3、倍速播放(难点在于播放过程中如果调整了倍速,要在对应位置继续播放)
4、拖动进度条播放(分为:拖动了进度条再开始在对应位置播放;和播放过程中拖动了进度条继续在相应位置播放)
5、播放过程中实时显示车辆相应位置信息
好的、废话不多说了,先看下效果吧~~~
以下倍速播放
以下进度条播放
以下部分代码~~~
<!-- 车辆动画控制进度条 -->
<div class="progressDiv" v-if="recordePathData.length">
<div class="progressDiv_playBtn">
<!-- //0->未开始 1->行驶中 2->暂停 -->
<img v-if="carPalyStayus == 0" @click="startAnimation([])" src="@/assets/imgs/fullview/progress_play.png"/>
<img v-if="carPalyStayus == 1" @click="pauseAnimation" src="@/assets/imgs/fullview/progress_pause.png"/>
<img v-if="carPalyStayus == 2" @click="resumeAnimation" src="@/assets/imgs/fullview/progress_play.png"/>
</div>
<div class="progressDiv_sliderDiv">
<!--进度条-->
<!-- {{sliderVal + '%'}} -->
<el-slider v-model="sliderVal" :step="1" @change="sliderChange" :show-tooltip="false"></el-slider>
</div>
<div class="progressDiv_speedDiv">
<el-select v-model="speedCount"
@change="speedCountChange($event)"
placeholder="倍速选择" :clearable="false">
<el-option v-for="(item,index) in speedCountArr"
:label="item.name"
:value="item.value"
:key="index" />
</el-select>
</div>
<div class="progressDiv_timeDiv">
{{times}}
</div>
</div>
js部分:
1、轨迹渲染(记得点位要去重)
// 1、先拿到轨迹数据
that.recordePathData = [
{"address":"河北省保定市涿州市东仙坡镇107国道优瑞通办公家具东北1米","locationTime":"2023-06-01 06:42:45","longitude":"115.977977","totalMileage":45829.6,"dir":20,"speed":35.0,"latitude":"39.541622"},
{"address":"河北省保定市涿州市东仙坡镇107国道七色光幼儿园南2米","locationTime":"2023-06-01 06:43:10","longitude":"115.979568","totalMileage":45829.9,"dir":36,"speed":40.0,"latitude":"39.543769"},
{"address":"河北省保定市涿州市东仙坡镇107国道鑫华家具城东北3米","locationTime":"2023-06-01 06:44:20","longitude":"115.986027","totalMileage":45830.8,"dir":39,"speed":46.0,"latitude":"39.549856"},
{"address":"河北省保定市涿州市码头镇影视城路未来星幼儿园西南4米","locationTime":"2023-06-01 06:53:55","longitude":"116.050132","totalMileage":45837.9,"dir":96,"speed":44.0,"latitude":"39.547945"},
{"address":"河北省保定市涿州市码头镇向阳商业街向阳之光西南5米","locationTime":"2023-06-01 06:55:50","longitude":"116.052696","totalMileage":45838.8,"dir":185,"speed":27.0,"latitude":"39.542336"},
{"address":"河北省保定市涿州市清凉寺街道涿码路冀安驾校北6米","locationTime":"2023-06-01 06:59:20","longitude":"116.046594","totalMileage":45840.5,"dir":179,"speed":48.0,"latitude":"39.52875"},
{"address":"河北省保定市涿州市清凉寺街道花田路中冶未来城西南7米","locationTime":"2023-06-01 07:02:05","longitude":"116.055632","totalMileage":45842.0,"dir":125,"speed":16.0,"latitude":"39.522454"},
{"address":"河北省保定市涿州市开发区腾飞大街中胶人才家园南8米","locationTime":"2023-06-01 07:07:45","longitude":"116.057421","totalMileage":45844.9,"dir":185,"speed":37.0,"latitude":"39.496563"},
{"address":"河北省保定市涿州市开发区腾飞大街涿州市统计局南9米","locationTime":"2023-06-01 07:09:55","longitude":"116.056483","totalMileage":45845.7,"dir":187,"speed":31.0,"latitude":"39.490092"},
{"address":"河北省保定市涿州市开发区润禾街凯兴花园西北10米","locationTime":"2023-06-01 07:15:15","longitude":"116.046196","totalMileage":45848.2,"dir":192,"speed":9.0,"latitude":"39.473553"},
]
that.dealRepeatArr(that.recordePathData); //处理下重复点位
that.dealShowPoline(); //处理数据并展示轨迹
//处理下重复点位
dealRepeatArr(tempArr) {
for (let i = 0; i < tempArr.length; i++) {
for (let j = i + 1; j < tempArr.length; j++) {
if (tempArr[i].longitude == tempArr[j].longitude && tempArr[i].latitude == tempArr[j].latitude) {
tempArr.splice(j, 1);
j--;
};
};
};
console.log(tempArr)
return tempArr;
},
2、开始回放、暂停、继续回放、倍速选择、进度条拖动
//开始回放
startAnimation (arr) {
var carDuration = this.initSpeed * this.speedCount
//
if (this.sliderVal > 0 && this.carPalyStayus == 0) { //未播放的情况下,直接从指定位置开始播放
this.map.setZoom(18);
this.reDrawPolyline(0); //倍数变化之后,需要从新绘制线
} else { //从头开始播放
this.carPalyStayus = 1; //0->未开始 1->行驶中 2->暂停
arr = this.carLineArr;
this.map.setZoom(18);
this.carMarker.moveAlong(arr, carDuration);
}
// carDuration:移动速度,单位:米/秒
},
//暂停回放
pauseAnimation () {
this.carMarker.pauseMove();
this.carPalyStayus = 2; //0->未开始 1->行驶中 2->暂停
},
//继续回放
resumeAnimation () {
var that = this;
//如果点击了暂停,并切换了倍数,从新绘制
if ((that.carPalyStayus == 2 && that.isSpeedCountChange) || (that.carPalyStayus == 2 && that.isSliderValChange)) {
that.isSpeedCountChange = false;
that.isSliderValChange = false;
that.reDrawPolyline(2); //倍数变化之后,需要从新绘制线
}
that.carMarker.resumeMove();
that.carPalyStayus = 1; //0->未开始 1->行驶中 2->暂停
},
//倍速选择
speedCountChange(e) {
var that = this;
// carPalyStayus //0->未开始 1->行驶中 2->暂停
// 如果正在行驶中点击倍数
if (that.carPalyStayus == 1) {
that.carMarker.pauseMove(); // 先暂停车
that.reDrawPolyline(1); //倍数变化之后,需要从新绘制线
} else if (that.carPalyStayus == 2) {
that.isSpeedCountChange = true;
}
},
//进度条拖动
sliderChange() {
//手动拖动进度条过程中触发:移动车辆,定位车辆回放位置
var that = this;
//计算拖动进度条后车辆对应轨迹新的索引值
var getIndex = Math.round(that.carLineArr.length * that.sliderVal / 100);
var currentIndex = 0
if (getIndex > 0) {
currentIndex = getIndex - 1;
}
var vehicleLocation = that.carLineArr[currentIndex];
that.carMarker.setPosition(new AMap.LngLat(vehicleLocation.lng, vehicleLocation.lat));
if (currentIndex == 0) {
that.progval = 1; //处理重新绘制线路时 that.progval-1 找不到值报错
} else {
that.progval = currentIndex;
}
that.progvalLength = that.progval;
// carPalyStayus //0->未开始 1->行驶中 2->暂停
if (that.carPalyStayus == 0) {
} else if (that.carPalyStayus == 1) {
that.carMarker.pauseMove(); // 先暂停车
that.reDrawPolyline(1); //倍数变化之后,需要从新绘制线
} else if (that.carPalyStayus == 2) {
that.isSliderValChange = true;
}
},
ok,最后总结下,就是无论改变倍速、拖动进度条,都要记录当时小车移动的索引,通过这个索引来从新绘制轨迹线路,以及重启小车动画
that.carMarker.on('moving', function (e) {
that.passedPolyline.setPath(e.passedPath);
that.map.setCenter(e.target.getPosition(),true)
var len = e.passedPath.length;
that.progval = (len - 1) + that.progvalLength;
});
完结啦,不容易~~~
有用的话就点个赞 点个赞 点个赞啦,哈哈哈~~~