leaflet【十】实时增加轨迹点轨迹回放效果实现

实时轨迹回放

在前面有用leaflet-trackplayer实现了一个轨迹回放的效果,单击前往:轨迹回放效果&控制台控制轨迹运动效果

这篇文章主要是实现一下实时增加轨迹点,不改变原来运行轨迹和速度。这里是简易做了一个demo效果,大概讲述一下实现过程和一些注意的点。整个源码会贴在文章最后:

leaflet-trackplayer

插件npm地址,里面有对应API说明 leaflet-trackplayer

首先准备好一个路径的数据,这里简单循环模拟一下

const path = [];
for (let i = 0; i < 10; i++) {
  path.push(
      {
        lat: 34 + Math.random() * 0.5,
        lng: 108 + Math.random() * 0.5
      }
  );
}

然后创建一个track对象,也就是利用这个插件实例化一个路径回放的对象,里面的配置什么的就根据实际开发改一下就好了,并且在这里我抽离了一个方法出来,后面回来说这个有什么用。

const createTrack = (path) => {
  // 创建播放器对象并添加至地图
  track = new L.TrackPlayer(path,
      // 轨迹配置,都可以不要,保留markerIcon一个就可以了
      {
        markerIcon,
        speed: 500, // 播放速度
        weight: 10, // 轨迹线宽度
        passedLineColor: '#0eb0c9', // 已行驶轨迹部分的颜色
        notPassedLineColor: '#add5a2', // 未行驶轨迹部分的颜色
        panTo: true, // 地图跟随移动
        markerRotation: true // 是否开启marker的旋转
      }
  ).addTo(map);
  track.start();

  // 监听运动过程走了多少百分比
  track.on('progress', (progress, {lng, lat}, index) => {
    // 把这个值记录下来,然后给el-progress绑定,这样也就是一个进度条的可视化了。
    sliderProgress.value = progress * 100;
    console.log(`progress:${progress.toFixed(2)} - position:${lng.toFixed(2)},${lat.toFixed(2)} - trackIndex:${index}`);
  });
};

在这个里面有一个track.setProgress(0.5);方法用来设置整个运动的进度,取值在0-1之间,那么进度条反向绑定运动的效果就是这样实现的。

<el-slider v-model="sliderProgress" :format-tooltip="formatTooltip" @input="changeProgress"/>

const changeProgress = (val) => {
  track.setProgress(val / 100);
};

最后实时更新轨迹,因为这个插件并没有什么实现setPath改变路径数据的方法,那么实现的方法也只能是先删除轨迹,然后重新绘制轨迹,这也是为什么我把创建一个track对象抽成一个方法的原因(创建轨迹运动这一大段代码可以复用)。这里重点在于新增了点之后怎么计算他的一个进度值,在下面代码注释有说明可以理解一下。

// 删除轨迹对象
const deleteTrack = () => {
  track.remove();
};

// 模拟实时更新
const updatePath = () => {
  deleteTrack();
  const oldLength = path.length;
  for (let i = 0; i < 10; i++) {
    path.push(
        {
          lat: 34 + Math.random() * 0.5,
          lng: 108 + Math.random() * 0.5
        }
    );
  }
  createTrack(path);
  // 需要重新设置进度,除100是转成0-1之间的值,再除整个长度和旧数据的长度的比值
  // 相当于最开始一共十个点,运动到了第五个点,现在进度是50%
  // 这个时候实时增加了5个点,现在就是15个点,如果取15的百分之50就变成了运动到7.5这个点,就显然不对了
  // 15 / 10 = 1.5  这个时候再用50% / 1.5 得到的值是 1/3,那么也正好是第五个点相对于现在整个15个点的位置了。
  track.setProgress(sliderProgress.value / 100 / (path.length / oldLength));
};

到这里就是完成了,然后前后端交互就看什么时候调用接口就相当于走上面这个updatePath方法。

存在一个小缺陷就是,在更新数据的时候由于是先删再画就会有一点点闪烁。录制的效果不是很好,可以测试一下在点击增加轨迹点,当前这个图标运动的位置(也就是整体进度)是不会发生改变的

在这里插入图片描述

完整源码

<script lang="js" setup>
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import CAR from '@/assets/image/car.png';
import 'leaflet-trackplayer';

onMounted(() => {
  initMap();
});

let map;
const initMap = () => {
  map = L.map('map', {layers: []}).setView([30, 110], 5);
  const sourceUrl = 'https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png';
  const tileLayer = L.tileLayer(sourceUrl, {
    maxZoom: 18,
    minZoom: 2,
    attribution: '© modify'
  });
  tileLayer.addTo(map);
};

let track = null;
const path = [];
for (let i = 0; i < 10; i++) {
  path.push(
      {
        lat: 34 + Math.random() * 0.5,
        lng: 108 + Math.random() * 0.5
      }
  );
}

// 进度条,这个值在0-100之间
const sliderProgress = ref(0);

// 定义沿着轨迹移动的Icon
const markerIcon = L.icon({
  iconSize: [27, 54],
  iconUrl: CAR, // 前面导入的img资源
  iconAnchor: [13.5, 27]
});

const initPath = () => {
  createTrack(path);
};

// 创建track对象
const createTrack = (path) => {
  // 创建播放器对象并添加至地图
  track = new L.TrackPlayer(path,
      // 轨迹配置,都可以不要,保留markerIcon一个就可以了
      {
        markerIcon,
        speed: 500, // 播放速度
        weight: 10, // 轨迹线宽度
        passedLineColor: '#0eb0c9', // 已行驶轨迹部分的颜色
        notPassedLineColor: '#add5a2', // 未行驶轨迹部分的颜色
        panTo: true, // 地图跟随移动
        markerRotation: true // 是否开启marker的旋转
      }
  ).addTo(map);
  track.start();

  track.on('progress', (progress, {lng, lat}, index) => {
    sliderProgress.value = progress * 100;
    console.log(`progress:${progress.toFixed(2)} - position:${lng.toFixed(2)},${lat.toFixed(2)} - trackIndex:${index}`);
  });
};

// 轨迹删除
const deleteTrack = () => {
  track.remove();
};

const formatTooltip = (val) => {
  return val.toFixed(2);
};

const changeProgress = (val) => {
  track.setProgress(val / 100);
};

// 模拟实时更新
const updatePath = () => {
  deleteTrack();
  const oldLength = path.length;
  for (let i = 0; i < 10; i++) {
    path.push(
        {
          lat: 34 + Math.random() * 0.5,
          lng: 108 + Math.random() * 0.5
        }
    );
  }
  createTrack(path);
  track.setProgress(sliderProgress.value / 100 / (path.length / oldLength));
  // 如果速度也变了记得也一起更新
  track.setSpeed(500 * selectSpeed.value);
};

/**------------------------改变速度---------------------------------------*/
const selectSpeed = ref(1);
const options = [
  {
    value: 0.5,
    label: 'X0.5'
  },
  {
    value: 1,
    label: 'X1'
  },
  {
    value: 2,
    label: 'X2'
  },
  {
    value: 3,
    label: 'X3'
  },
  {
    value: 5,
    label: 'X5'
  }
];
const changeSpeed = (val) => {
  track.setSpeed(500 * val);
};
</script>

<template>
  <div id="map" ref="mapContainer" class="w-full h-4/6"></div>
  <div class="m-2">
    <el-button type="primary" @click="initPath">查询轨迹</el-button>
    <el-button type="primary" @click="track.start()">开始</el-button>
    <el-button type="primary" @click="track.pause()">暂停</el-button>
    <el-button type="primary" @click="deleteTrack">删除轨迹</el-button>
    <el-button type="primary" @click="updatePath">模拟接口更新</el-button>
  </div>

  <br/>
  <div class="m-2 bg-blue-200 p-2 rounded-md">
    <div class="font-bold">控制台</div>
    <div>进度条</div>
    <div class="w-[400px] ml-2">
      <el-slider v-model="sliderProgress" :format-tooltip="formatTooltip" @input="changeProgress"/>
    </div>
    <div>
      运动速度:
      <el-select
          v-model="selectSpeed"
          style="width: 140px"
          @change="changeSpeed"
      >
        <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item.value"
        />
      </el-select>
    </div>
  </div>
</template>

leaflet-plugin-trackplayback

然后还有这个轨迹回放的插件,这个插件就可以根据时间来进行控制,这个功能后续实现在更新一下这个文章,

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Modify_QmQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值