vue+高德地圖實現軌跡回放並實現播放進度條/倍數/時間

需求:
1:軌跡回放:播放,暫停,繼續播放
2:進度條,軌跡回放,進度條也要播放,軌跡中止播放,進度條也要暫停。
3:倍數:未播放選擇倍數,正在播放選擇倍數,暫停選擇倍數。
4:播放時間javascript

高德api示例裏面只有需求一最簡單的播放,暫停,繼續播放。
因此要根據高德地圖參考手冊給出的現有的類與方法進行實現功能java

廢話很少說。git

1:引入高德地圖web

<script
      type="text/javascript"
      src="https://webapi.amap.com/maps?v=1.4.0&key=你的key*&plugin=AMap.Autocomplete"
    >
</script>

模版api

<template>
  <div>
   // map
    <div id="container"></div>
    // 倍數
    <div class="speed">
      <span
        :class="{multiple: true, milActive: muiltipleIndex == index}"
        v-for="(item,index)  in speedList"
        @click="selectMultiple(index, item)"
      >{{item}}X</span>
      <span class="bs_title">倍數播放</span>
    </div>
    
    <div class="input-card">
      <div class="plar-cnp">
      // 進度條
        <van-slider
          class="slider-i"
          v-model="value"
          @change="onChange"
          :button-size="15"
          :step="step"
        />
        // 時間
        <span class="progress_time">{{progressTime}}</span>
        // 播放,暫停,繼續按鈕
        <div class="p_icon">
          <van-icon v-if="palyStayus == 0" @click="startAnimation(0, [])" name="play-circle-o" />
          <van-icon v-if="palyStayus == 1" @click="pauseAnimation()" name="pause-circle-o" />
          <van-icon v-if="palyStayus == 2" @click="resumeAnimation()" name="play-circle-o" />
        </div>
      </div>
  </div>
</template>

變量數組

let TIME_VARIABLE;




data() {
    return {
      progressTime: 0,  // 時間
      palyStayus: 0, //0->未開始  1->行駛中  2->暫停
      value: 0,  // 進度條初始化
      speedList: [1, 2, 3, 4, 5], // 倍數數據
      markerSpeed: 100, // 初始化速度
      marker: null, // 標記點
      lineArr: [], // 軌跡點數組
      passedPolyline: null, 
      positionIndex: [], //軌跡起始點--車輛所在的位置
      speedCount: 1, // 目前選擇的倍數
      passedPath: 0, // 存放(播放時點擊倍數)抓取到的位置
      int: null, // 定時器--進度條
      timeInt: null // 定時器--時間
      curreGDPath: null,  //存放(播放時點擊倍數)抓取到的經緯度
      polyline: null, // 軌跡線路
      map: null //map地圖
    };
  },

2:獲取數據(這一步就不寫了,數據數量字段簡化了一下)ide

this.lineArr = [
{"gpsTime":"2020-02-06 14:37:56","longitude":109.07048","latitude":34.405327},

{"gpsTime":"2020-02-06 14:37:58","longitude":109.07059,"latitude":34.4055,},

{"gpsTime":"2020-02-06 14:38:00","longitude":109.07078,"latitude":34.40565},

{"gpsTime":"2020-02-06 14:38:02","longitude":109.07087,"latitude":34.405704},

{"gpsTime":"2020-02-06 14:38:06","longitude":109.07122,"latitude":34.40582},

{"gpsTime":"2020-02-06 14:38:07","longitude":109.0714,"latitude":34.405876},]

// 備份一組原始數據,後面初始化要用
this.standLineArr = this.lineArr

顯示地圖(數據請求到以後就回調顯示地圖)ui

this.map = new AMap.Map("container", {
    center: [116.478935, 39.997761],
    zoom: 20
});
this.marker = new AMap.Marker({
    map: this.map,
    //軌跡點的第一個點
    //this.positionIndex = new AMap.LngLat(
        //this.lineArr[0].longitude,
        //this.lineArr[0].latitude
    //);
    position: this.positionIndex, 
    icon: new AMap.Icon({
      size: new AMap.Size(40, 40), // 圖標尺寸
      image: huoche, //絕對路徑
      imageSize: new AMap.Size(40, 40)
    }),
    offset: new AMap.Pixel(-26, -13),
    autoRotation: true,
    angle: 90
 });
 // 初始化回放路線
 this.initPolyline();
 
 // 關鍵---獲取軌跡點播放完所須要的時間(單位:s)
 //this.polyline.getLength()/1000 ---是總路程(km)
 //this.markerSpeed * this.speedCount --- 速度
 TIME_VARIABLE =
        (this.polyline.getLength() /
          1000 /
          (this.markerSpeed * this.speedCount)) *
        60 *
        60; //行駛時間(s)
 
 this.marker.on("moving", e => {
    this.passedPolyline.setPath(e.passedPath);
 });
 
 this.map.setFitView();
 
 
// 這裏面的都是高德解析出更細緻的經緯度點
 AMap.event.addListener(this.marker, "moving", e => {
    // console.log("當前已回放: " + e.passedPath);
    //這裏是關鍵,車輛播放的時候,走的每個點進行抓取(高德解析的更細緻的點)以便更新倍數時及時的更新未走完的數據,後面會用到
    this.curreGDPath = new AMap.LngLat(
      e.passedPath[e.passedPath.length - 1].lng,
      e.passedPath[e.passedPath.length - 1].lat
    );
    // 行走到具體的第幾個點
    this.passedPath = e.passedPath.length;
 });

播放結束後回調---初始化變量this

// 播放結束後回調--初始化各種數據
 this.marker.on("movealong", e => {
    this.palyStayus = 0; //播放/暫停按鈕顯示狀態的改變
    this.speedCount = 1; // 播放倍數初始化爲1
    this.markerSpeed = 100; // 播放速度初始化爲100
    // 取消定時器(時間,進度條)
    clearInterval(this.int); 
    clearInterval(this.timeInt);
    this.lineArr = this.standLineArr;  // 數據初始化
    this.initPolyline(); // 數據再次更新到線條上。
  });

初始化回放路線spa

// 初始化回放路線
    initPolyline() {
      this.polyline = new AMap.Polyline({
        map: this.map,
        path: this.lineArr,
        showDir: true,
        strokeColor: "#28F", //線顏色
        strokeWeight: 6 //線寬
      });
      this.passedPolyline = new AMap.Polyline({
        map: this.map,
        strokeColor: "#AF5", //線顏色
        strokeWeight: 6 //線寬
      });
    },

點擊開始播放按鈕

startAnimation(status, arr) {
      //速度 = 初始速度 * 倍數
      let markerSpeed = this.markerSpeed * this.speedCount;
      
      if (status == 0) {
        // 初始時間爲00:00
        this.progressTime = formatSeconds(0); 
        this.value = 0; // 進度條歸0
        this.palyStayus = 1; // icon狀態爲播放
        arr = this.lineArr; 
        //計時器--- 開始監聽時間和進度條
        this.monitorInterval(); 
      }
      // 仍是播放---請查看高德地圖api
      this.marker.moveAlong(arr, markerSpeed);
    },
    
    formatSeconds(value) {
        var secondTime = parseInt(value);// 秒
        var minuteTime = 0;// 分
        var hourTime = 0;// 小時
        if(secondTime > 60) {
            minuteTime = parseInt(secondTime / 60);
            secondTime = parseInt(secondTime % 60);
            if(minuteTime > 60) {
                hourTime = parseInt(minuteTime / 60);
                minuteTime = parseInt(minuteTime % 60);
            }
        }
        var result = parseInt(secondTime)< 10?("0" + parseInt(secondTime)): ("" + parseInt(secondTime));
        result =parseInt(minuteTime)< 10?("0" + parseInt(minuteTime))+ ":" + result : ("" + parseInt(minuteTime)) + ":" + result;
        return result;
    }

監聽進度條和時間

monitorInterval() {
  // 進度條
  當(TIME_VARIABLE / 100) * 1000時間 每循環一次 進度條走一個倍數,等播放完進度條也恰好走完
  this.int = setInterval(() => {
    this.value += 1 * this.speedCount;
  }, (TIME_VARIABLE / 100) * 1000);
  
  // 時間
  this.timeInt = setInterval(() => {
    this.ptm += 1;
    this.progressTime = formatSeconds(this.ptm);
  }, 1000);
},

點擊倍數

selectMultiple(e, data) {
  this.muiltipleIndex = e;
  this.speedCount = data; //倍數
  // 若是正在行駛中點擊倍數
  if (this.palyStayus == 1) { 
    this.marker.pauseMove(); // 先暫停車
    // 截取到車輛未走的經緯度數組
    this.lineArr = this.lineArr.slice(this.passedPath); 
    
    //並把暫停住車輛時,車輛正好所在的經緯度拼接到未走的經緯度數組裏面-------當前未回放的經緯度
    //this.curreGDPath這個很關鍵--在前面的代碼中有交代
    //this.lineArr如今這個數據截取到了點擊倍數時未走的路程
    this.lineArr.unshift(this.curreGDPath);
    //並把this.lineArr更新到線條裏面,,要不線條顏色不一樣步
    this.initPolyline();
    // 剛纔暫停了一下,就要再次開啓播放
    this.startAnimation(1, this.lineArr);
  }
},

暫停。繼續。中止

// 暫停
pauseAnimation() {
  this.palyStayus = 2; // icon狀態爲2
  // 中止計時器
  clearInterval(this.int); 
  clearInterval(this.timeInt);
  this.marker.pauseMove();
},
// 繼續
resumeAnimation() {
  this.palyStayus = 1;  // icon狀態爲2
  this.monitorInterval();
  this.marker.resumeMove();
},
// 中止
stopAnimation() {
  this.marker.stopMove();
},
相關文章
相關標籤/搜索