基于vue+百度地图的多车实时运动及轨迹追踪实现(上帝视角篇)

开局两张图,剩下全靠吹

基于vue+百度地图的多车实时运动及轨迹追踪实现(上帝视角篇)_第1张图片

基于vue+百度地图的多车实时运动及轨迹追踪实现,共分为上下两篇,分别为上篇“心路历程篇”和下篇“上帝视角篇”,上篇是背景介绍和我实现过程中走的弯路,下篇是最终版的实现方案。其实并不存在上帝视角,只希望有一天,我们可以通过不断复盘,少走点弯路。
本篇是下篇,上帝视角篇。相关背景可查看上篇
不同于上篇内心戏满满,本篇内容过干,请自带水杯

剥离响应式数据和非响应式数据

除了页面上需要通过数据变化实时改变状态的数据,其他数据全部改为非响应式,直接在created生命周期中赋值即可。
created钩子函数是在vue完成数据拦截后调用的,所以这里定义的变量是不会自动被vue监听的。
例如websocket连接,缓存的车辆信息,定时器等变量,是不需要监听的,尤其是车辆信息,后端消息发送过来很快,如果每条消息过来引起车辆信息变化都触发vue的递归更新,是很慢的。这些信息均定义到created中。

created () {
   
    this.socket = null // 实时socket连接
    this.cachedCarArr = [] // 车辆信息
    this.removeDelayed = 3000 // 预设3秒后车辆消失
    this.carTimer = {
   } // 车辆消失前的计数器
    this.drawingLine = '' // 正在画实时轨迹的车
    this.carLineAnimation = [] // 记录车的requestAnimationFrame id,便于后续取消
    this.loopLineTimer = [] // 记录车的setTimeout id,便于后续取消
    this.carLineAniInstances = {
   } // 正在画实时轨迹的车的动画实例
    this.trackCar = '' // 用于debug某个车
  },

创建version变量来实现车辆列表的响应式

上面提到车辆信息存为了非响应式变量,那如何动态显示右侧的列表信息呢?这里有个变通的方法,在data()中定义一个top10List和一个version变量,当有新车过来的时候,version++,当一辆车消失的时候,version–。
同时监听version的变化,当version变化时,实时计算数组中前10个车,赋值给top10List。列表始终显示这10个车即可。

watch: {
   
    version: {
   
      handler () {
   
        this.top10List = this.cachedCarArr
              .filter((car) =>
              car.trace.find((t) => t.status === 'drawing' || t.status === 'drawed')
        )
        .slice(0, 10)
      }
    }
}

设计存储车辆信息的数据结构

把车辆的运动看成一个状态机,每个点的状态都从’undraw’->‘drawing’->‘drawed’单向改变。接收信息时,车辆的初始状态为’undraw’

// 对于新车
const newCar = {
   
      ...car,
      trace: [
            {
   
              lng: car.Longitude,
              lat: car.Latitude,
              rotation: car.PtcHeading,
              speed: car.speed,
              status: 'undraw',
              timestamp: car.Timestamp
            }
      ]
    }
this.cachedCarArr.push(newCar)
this.drawCar(item)
this.version++

// 对于已有的车
this.cachedCarArr = this.cachedCarArr.map((item) => {
   
      if (item.id === key) {
   
            item.trace.push({
   
              lng: car.Longitude,
              lat: car.Latitude,
              rotation: car.PtcHeading,
              speed: car.speed,
              status: 'undraw',
              timestamp: car.Timestamp
            })
        }
        return item
})

多车实时运动

1. 画车
const pointT = transform({
   
    lng: car.trace[0].lng,
  

你可能感兴趣的:(前端,vue)