当前位置: 首页 > news >正文

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-selectv-model="selectSpeed"style="width: 140px"@change="changeSpeed"><el-optionv-for="item in options":key="item.value":label="item.label":value="item.value"/></el-select></div></div>
</template>

leaflet-plugin-trackplayback

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • BSV区块链上的覆盖网络服务现已开放公测
  • mysql DBA常用的sql
  • 【JS逆向分析】某药品网站价格(Price)解密
  • AI基础 L22 Uncertainty over Time I 时间的不确定性
  • ELK预警方案:API+XXLJob
  • python画图|同时输出二维和三维图
  • 学习使用在windows系统上安装vue前端框架以及环境配置图文教程
  • Python快速入门 —— 第二节:函数与控制语句
  • macOS上谷歌浏览器的十大隐藏功能
  • maya-vray渲染蒙版
  • 高级Java程序员必备的技术点:你准备好了吗?
  • 图数据库 neo4j 安装
  • Scrapy 2.6 Spider Middleware 爬虫页中间件基本使用
  • 优化安防视频监控的关键体验:视频质量诊断技术如何应用在监控系统中?
  • 【字符串】AC自动机+dp
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • javascript数组去重/查找/插入/删除
  • java第三方包学习之lombok
  • Otto开发初探——微服务依赖管理新利器
  • PHP那些事儿
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • Swift 中的尾递归和蹦床
  • vue-router 实现分析
  • vue中实现单选
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 跨域
  • 前端面试之闭包
  • 思考 CSS 架构
  • 为视图添加丝滑的水波纹
  • 在Unity中实现一个简单的消息管理器
  • 阿里云ACE认证学习知识点梳理
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • # C++之functional库用法整理
  • ######## golang各章节终篇索引 ########
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (70min)字节暑假实习二面(已挂)
  • (CPU/GPU)粒子继承贴图颜色发射
  • (JS基础)String 类型
  • (leetcode学习)236. 二叉树的最近公共祖先
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)关于pipe()的详细解析
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .gitignore
  • .Net IE10 _doPostBack 未定义
  • .Net 垃圾回收机制原理(二)
  • @JSONField或@JsonProperty注解使用
  • [Android Studio] 开发Java 程序
  • [C#] 如何调用Python脚本程序
  • [CERC2017]Cumulative Code