6

需求:
1:轨迹回放:播放,暂停,继续播放
2:进度条,轨迹回放,进度条也要播放,轨迹停止播放,进度条也要暂停。
3:倍数:未播放选择倍数,正在播放选择倍数,暂停选择倍数。
4:播放时间

高德api示例里面只有需求一最简单的播放,暂停,继续播放。
所以要根据高德地图参考手册给出的现有的类与方法进行实现功能

废话不多说。

1:引入高德地图

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

模版

<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:获取数据(这一步就不写了,数据数量字段简化了一下)

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

显示地图(数据请求到之后就回调显示地图)

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.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(); // 数据再次更新到线条上。
  });

初始化回放路线

    // 初始化回放路线
    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();
},

我不想学习了
45 声望4 粉丝

« 上一篇
发布npm包踩坑