最近做了一個需求是:根據高德地圖,從後臺接口獲取經緯度數據,然後進行軌跡回放,從一個點跳到下一個點上,且底部有播放軌跡回放的按鈕,時間軸跟着軌跡回放一起動,右邊數據也跟着一起變化。 查閱了多方資料,在不懈努力的情況下,終於完成了次需求,再次給大家分享下:
做的效果圖如下:
首先得安裝高德地圖的插件,再次就不用說了
template的寫法模板如下:
<template>
<div class="map-outbox">
<!--地圖容器-->
<div id="container">
<div class="playTraceVedioInfo">
<div style="width:8%;display:flex;padding:7px 0px">
<img src="@/image/trace/noReplay.png">
<img v-if="playImg" src="@/image/trace/play.png" @click="playTraceInfo">
<img v-else src="@/image/trace/stopTrace.png" @click="stopTraceInfo">
</div>
<span>{{changeTime}}/</span>
<span style="margin-right:10px">{{totalTime}}</span>
<el-progress :percentage="progress" style="width:70%"></el-progress>
<el-dropdown @command="handleCommand">
<span class="el-dropdown-link">
{{speed}}
<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown" placement="top">
<el-dropdown-item command="正常">正常</el-dropdown-item>
<el-dropdown-item command="X16">X16</el-dropdown-item>
<el-dropdown-item command="X8">X8</el-dropdown-item>
<el-dropdown-item command="X4">X4</el-dropdown-item>
<el-dropdown-item command="X2">X2</el-dropdown-item>
<el-dropdown-item command="X0.5">X0.5</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
</template>
定義下高德地圖要插入的地方,以及下面進度條和播放暫停按鈕的位置。
接下來是<script>的代碼,也是關鍵的邏輯處理部分:
需要定義的全局變量,下面在構建地圖標記物,進行軌跡回放的時候需要:
var lineArr = traceReplayPath.tracePath; //獲取的假數據
var progressnuw = 0; // 控制數組的下標
let time; // 定時器的時間控制
let totalMillisecond; // 獲取總毫秒數
var marker; // 地圖上的標記物
let markers = []; // 存放地圖上的標記物的數組
let map; // 構建地圖
需要定義的數據交換變量,且在頁面加載完成的時候獲取到接口的數據: mounted註釋的代碼是通過後臺接口獲取數據的方法,註釋下面的一些代碼是通過前端設置的假數據來實現效果(假數據也是從後臺copy過來的)
data() {
return {
map: "",
playLength: "17/31/21",
playImg:true,
speed: "正常",
progress: 0,
traceLatLonPath: [],
copyTraceGpsTime:[],
totalTime: "",
changeTime:'00:00:00',
isActual: true,
isPlay: false
};
},
components: {},
mounted() {
// const url = requestUrl.traceTableContentInfos;
// let params = {};
// let requestBody = {};
// requestBody.vehicleId = "10112558";
// requestBody.startTime = "20190718000033";
// requestBody.endTime = "20190718155532";
// params.requestBody = requestBody;
// request.post(url,params,'json').then(
// res=>{
// if(res.data){
// let datDlength = res.data.vehicleTracings.length;
// let templateLatLon = [];
// for(let i=0;i<datDlength;i++){
// templateLatLon.push(res.data.vehicleTracings[i].lon);
// templateLatLon.push(res.data.vehicleTracings[i].lat);
// this.traceLatLonPath.push(templateLatLon);
// templateLatLon = [];
// }
// this.totalTime = timeDiffAlogrithm.timeDiff(res.data.vehicleTracings[0].gpsTime,res.data.vehicleTracings[datDlength-1].gpsTime);
// console.log(this.traceLatLonPath);
// this.init();
// }
// });
let dataLength = traceReplayPath.tracePath.length;
let templateLatLon = [];
let templateGpsTime = [];
for(let i=0;i<dataLength;i++){
templateLatLon.push(traceReplayPath.tracePath[i].lon);
templateLatLon.push(traceReplayPath.tracePath[i].lat);
templateGpsTime.push(traceReplayPath.tracePath[i].gpsTime);
this.traceLatLonPath.push(templateLatLon);
this.copyTraceGpsTime.push(templateGpsTime);
templateLatLon = [];
templateGpsTime = [];
}
this.totalTime = timeDiffAlogrithm.timeDiff(this.copyTraceGpsTime[0][0],this.copyTraceGpsTime[dataLength-1][0]);
totalMillisecond = timeDiffAlogrithm.totalMillisecond(this.copyTraceGpsTime[0][0],this.copyTraceGpsTime[dataLength-1][0]);
console.log(this.copyTraceGpsTime);
//console.log(timeDiffAlogrithm.changeTimeShow('00:02:23',123000));
this.init();
},
定義的templateLatLon = [],存放數據的經緯度座標,用於實現軌跡,let templateGpsTime = [];存放每個經緯度座標的時間,用於設置定時器隔多少秒進行跳轉到下一個軌跡。 this.init()是初始化構建出地圖的。
接下來就是最關鍵的部分:構建地圖以及軌跡回放的實現邏輯部分:
carInfo() {
if (markers.length > 0) {
map.remove(markers);
markers = [];
}
//變量一直++
marker = new AMap.Marker({
map: map,
position: this.traceLatLonPath[progressnuw]
//icon: "images/car.png",
// offset: new AMap.Pixel(-26, -13),
// autoRotation: true,
// angle:-10,
});
markers.push(marker);
map.setFitView();
progressnuw++;
if (progressnuw > 0) {
time = (timeDiffAlogrithm.timeSecondsDiff(this.copyTraceGpsTime[progressnuw-1][0],this.copyTraceGpsTime[progressnuw][0]))*1000;
}
this.changeTime = timeDiffAlogrithm.changeTimeShow(this.changeTime,time/1000);
this.progress = this.progress+(time/totalMillisecond)*100;
clearInterval(this.timer);
//清楚定時器
if (progressnuw < lineArr.length) {
this.timer = setInterval(this.carInfo, time);
}
},
init() {
let self = this;
map = new AMap.Map("container", {
resizeEnable: true,
center: [156.478935, 59.997761],
zoom: 14
});
// 繪製軌跡
var polyline = new AMap.Polyline({
map: map,
path: this.traceLatLonPath,
showDir: true,
strokeColor: "#28F", //線顏色
// strokeOpacity: 1, //線透明度
strokeWeight: 6, //線寬
strokeStyle: "solid" //線樣式
});
var passedPolyline = new AMap.Polyline({
map: map,
// path: lineArr,
strokeColor: "#AF5", //線顏色
strokeOpacity: 1, //線透明度
strokeWeight: 6 //線寬
// strokeStyle: "solid" //線樣式
});
map.setFitView();
},
init方法裏面定義的是構建出地圖,且根據經緯度先畫出軌跡路線。
carInfo()方法裏面是設置動態定時器,在定時器中在地圖上構建出相應的標記物marker,由於是建立下一個標記物後,需把上一個標記物給清空掉,因此這裏設置了一個markers數組,然後就是定時器的動態時間設置,動態時間設置裏面用到的轉換函數,自己寫下就可以,這裏就不共享了,軌跡回放簡單理解就是,先把軌跡路線構建出來,然後標記物在路線上行駛即可。
哦,差點給忘了。。。
this.changeTime = timeDiffAlogrithm.changeTimeShow(this.changeTime,time/1000); 控制前面時間不斷變化的
this.progress = this.progress+(time/totalMillisecond)*100; 控制進度條不斷變化的
接下來就是播放控制按鈕,去進行控制
playTraceInfo() {
let self = this;
self.playImg = false;
this.timer = setInterval(self.carInfo, 1000);
},
stopTraceInfo(){
this.playImg = true;
clearInterval(this.timer);
}