MapBox添加带箭头的轨迹线

效果:
在这里插入图片描述

// 轨迹线
export const MAP_PATH_LINE = (values, layerId) => {// 箭头-右var svgXML = `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> <path d="M529.6128 512L239.9232 222.4128 384.7168 77.5168 819.2 512 384.7168 946.4832 239.9232 801.5872z" p-id="9085" fill="#ffffff"></path> </svg>`;//给图片对象写入base64编码的svg流var svgBase64 = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgXML)));let arrowIcon = new Image(20, 20);arrowIcon.src = svgBase64;arrowIcon.onload = function () {map.addImage('arrowIcon', arrowIcon);setRouteData();// map.loadImage('./car.png', function (error, carIcon) {//   if (carIcon) {//     map.addImage('carIcon', carIcon);//     setRouteData();//   }// });};var isPlay = true;var counter = 0;var steps = 0;let aLength = 0;let newRouteGeoJson;var routeGeoJson = values;var realRouteGeoJson = {type: 'FeatureCollection',features: [{type: 'Feature',geometry: {type: 'LineString',coordinates: [],},},],};var animatePointGeoJson = {type: 'FeatureCollection',features: [{type: 'Feature',properties: {},geometry: {type: 'Point',coordinates: [],},},],};// 获取轨迹边界var bbox = turf.bbox(routeGeoJson);map.fitBounds([[Number(bbox[0]), Number(bbox[1])],[Number(bbox[2]), Number(bbox[3])],],{padding: { top: 100, bottom: 100, left: 100, right: 100 },maxZoom: 16,},);// 获取轨迹数据function setRouteData() {animatePointGeoJson.features[0].geometry.coordinates = routeGeoJson.features[0].geometry.coordinates[0];aLength = routeGeoJson.features[0].geometry.coordinates.length;newRouteGeoJson = resetRoute(routeGeoJson.features[0], 1000, 'kilometers');steps = newRouteGeoJson.geometry.coordinates.length;addRouteBboxLayer(); // 添加轨迹边界图层addRoutelayer(); // 添加轨迹线图层// addRealRouteSource(); // 添加实时轨迹线图层addArrowlayer(); // 添加箭头图层// addAnimatePointSource(); // 添加动态点图层}// 添加轨迹边界图层function addRouteBboxLayer() {map.addLayer({id: 'routeBboxLayer',type: 'line',source: {type: 'geojson',data: turf.bboxPolygon(bbox),},paint: {'line-color': '#fbc219','line-width': 3,'line-dasharray': [1, 1],'line-offset': -10,},});}// 添加轨迹线图层function addRoutelayer() {map.addLayer({id: 'routeLayer',type: 'line',source: {type: 'geojson',lineMetrics: true,data: routeGeoJson,},paint: {'line-width': 10,'line-opacity': 1,'line-color': '#009EFF',},});}// 添加实时轨迹线function addRealRouteSource() {map.addLayer({id: 'realRouteLayer',type: 'line',source: {type: 'geojson',lineMetrics: true,data: realRouteGeoJson,},paint: {'line-width': 10,'line-opacity': 1,'line-color': '#FF9900',},});}// 添加箭头图层function addArrowlayer() {map.addLayer({id: 'arrowLayer',type: 'symbol',source: {type: 'geojson',data: routeGeoJson, //轨迹geojson格式数据},layout: {'symbol-placement': 'line','symbol-spacing': 50, // 图标间隔,默认为250'icon-image': 'arrowIcon', //箭头图标'icon-size': 0.5,},});}// 添加动态点图层function addAnimatePointSource() {map.addLayer({id: 'animatePointLayer',type: 'symbol',source: {type: 'geojson',data: animatePointGeoJson,},layout: {'icon-image': 'carIcon','icon-size': 0.5,'icon-rotate': ['get', 'bearing'],'icon-rotation-alignment': 'map','icon-allow-overlap': true,'icon-ignore-placement': true,},});animate();}function animate() {if (counter >= steps) {return;}var startPnt, endPnt;if (counter == 0) {realRouteGeoJson.features[0].geometry.coordinates = [];startPnt = newRouteGeoJson.geometry.coordinates[counter];endPnt = newRouteGeoJson.geometry.coordinates[counter + 1];} else if (counter !== 0) {startPnt = newRouteGeoJson.geometry.coordinates[counter - 1];endPnt = newRouteGeoJson.geometry.coordinates[counter];}animatePointGeoJson.features[0].properties.bearing = turf.bearing(turf.point(startPnt), turf.point(endPnt)) - 90;animatePointGeoJson.features[0].geometry.coordinates = newRouteGeoJson.geometry.coordinates[counter];realRouteGeoJson.features[0].geometry.coordinates.push(animatePointGeoJson.features[0].geometry.coordinates);map.getSource('animatePointLayer').setData(animatePointGeoJson);map.getSource('realRouteLayer').setData(realRouteGeoJson);if (isPlay) {requestAnimationFrame(animate);}counter = counter + 1;}function resetRoute(route, nstep, units) {var newroute = {type: 'Feature',geometry: {type: 'LineString',coordinates: [],},};var lineDistance = turf.lineDistance(route);var nDistance = lineDistance / nstep;for (let i = 0; i < aLength - 1; i++) {var from = turf.point(route.geometry.coordinates[i]);var to = turf.point(route.geometry.coordinates[i + 1]);let lDistance = turf.distance(from, to, {units: units,});if (i == 0) {newroute.geometry.coordinates.push(route.geometry.coordinates[0]);}if (lDistance > nDistance) {let rings = lineMore(from, to, lDistance, nDistance, units);newroute.geometry.coordinates = newroute.geometry.coordinates.concat(rings);} else {newroute.geometry.coordinates.push(route.geometry.coordinates[i + 1]);}}return newroute;}function lineMore(from, to, distance, splitLength, units) {var step = parseInt(distance / splitLength);var leftLength = distance - step * splitLength;var rings = [];var route = turf.lineString([from.geometry.coordinates, to.geometry.coordinates]);for (let i = 1; i <= step; i++) {let nlength = i * splitLength;let pnt = turf.along(route, nlength, {units: units,});rings.push(pnt.geometry.coordinates);}if (leftLength > 0) {rings.push(to.geometry.coordinates);}return rings;}
};

清除数据代码

// 清除轨迹
export const ClearTrackMap = () => {if (map?.hasImage('arrowIcon')) map?.removeImage('arrowIcon');if (map?.hasImage('carIcon')) map?.removeImage('carIcon');if (map.getLayer('routeBboxLayer')) map.removeLayer('routeBboxLayer');if (map.getSource('routeBboxLayer')) map.removeSource('routeBboxLayer');if (map.getLayer('routeLayer')) map.removeLayer('routeLayer');if (map.getSource('routeLayer')) map.removeSource('routeLayer');if (map.getLayer('realRouteLayer')) map.removeLayer('realRouteLayer');if (map.getSource('realRouteLayer')) map.removeSource('realRouteLayer');if (map.getLayer('arrowLayer')) map.removeLayer('arrowLayer');if (map.getSource('arrowLayer')) map.removeSource('arrowLayer');if (map.getLayer('animatePointLayer')) map.removeLayer('animatePointLayer');if (map.getSource('animatePointLayer')) map.removeSource('animatePointLayer');REMOVE_LAYER('vectorDataID');REMOVE_LAYER(`feature_0.1`);
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/739709.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

成都爱尔林江院长解析巩膜镜是什么?它适合哪些人群

巩膜镜&#xff0c;全称为硬性透氧性巩膜接触镜&#xff0c;它有着特殊设计&#xff0c;大直径镜片像桥梁一样呈拱形覆盖角膜及角巩膜缘&#xff0c;从角膜上方横跨而过完全无接触、无任何机械性摩擦&#xff0c;最终贴合于巩膜。 巩膜镜的作用原理 光学成像&#xff1a; 配戴…

嵌入式物联网项目实战-STM32F103实现外部中断EXIT事件(物联技术666)

EXIT中断测试 功能描述 外部中断/事件控制器由19个产生事件/中断要求的边沿检测器组成。每个输入线可以独立地配置输入类型&#xff08;脉冲或挂起&#xff09;和对应的触发事件&#xff08;上升沿或下降沿或者双边沿触发&#xff09;。每个输入线都可以被独立的屏蔽。挂起寄…

Unity L屏幕实现方式(已抛弃)

效果 右侧主要的参数&#xff1a;Line参数能够调整中间线的高度&#xff0c;PointXY能够调整整个下方弯曲图像的比例。 使用的是RenderTexture填充RawImage显示的方式&#xff0c;需要将一张RenderTexture设置位摄像机的输出内容。 ShaderGraph 由于这个采用了一定的数学模型…

HarmonyOS NEXT应用开发之多层嵌套类对象监听

介绍 本示例介绍使用Observed装饰器和ObjectLink装饰器来实现多层嵌套类对象属性变化的监听。 效果图预览 使用说明 加载完成后显示商品列表&#xff0c;点击刷新按钮可以刷新商品图片和价格。 实现思路 创建FistGoodsModel类&#xff0c;类对象是用Observed修饰的类Secon…

【C++】手把手教你模拟实现 list

目录 前提&#xff1a;list 的基本介绍 一、构造/析构/拷贝/赋值 1、构造函数 2、析构函数 3、拷贝构造函数 4、赋值 二、修改操作 1、push_back 2、insert 3、erase 4、clear 三、list iterator 的使用 1、operator * 2、operator 3、operator -- 4、operator &…

MATLAB中的矩阵的重构和重新排列

师从清风 矩阵的重构和重新排列 reshape函数 reshape函数可以改变矩阵的形状&#xff0c;其常用语法为reshape(A,m,n)或者reshape(A,[m,n]),这可以将矩阵A的形状更改为m行n列&#xff0c;前提是转化前后的两个矩阵的元素总数要相同。例如有一个矩阵A&#xff0c;它原来的大小是…

字节跳动也启动春季校园招聘了(含二面算法原题)

字节跳动 - 春招启动 随着各个大厂陆续打响春招的响头炮&#xff0c;字节跳动也官宣了春季校园招聘的正式开始。 还是那句话&#xff1a;连互联网大厂启动校招计划尚且争先恐后&#xff0c;你还有什么理由不马上行动&#xff1f;&#xff01; 先来扫一眼「春招流程」和「面向群…

掌握Redis,看完这篇文章就够了

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Redis是什么&#xff1f;二、Redis安装三、Redis相关数据类型 四、基础操作&#xff08;使用了python连接redis&#xff09;1.字符串2.键对应操作3.哈希&am…

2024.3.12

1. 要求&#xff1a;自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void sho…

[Unity3D]--更换天空盒子

我们原来的天空盒子是这样的。 感觉不是特别满意&#xff0c;想换一个更好看的。 去资源商店找个好看的 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 例如这个 然后在Window>Rendering>Lighting里的环境选项里更换材质 更换&#xff1a; ​ …

考察1学生学籍系统winform .net6 sqlserver

考察1学生学籍系统winform .net6 sqlserver 下载地址: 考察1学生学籍系统winform .net6 sqlserver winform(.net6)sqlserver数据库 只有数据库的表结构需要自己建表 启动程序 登录失败 进入主界面 项目获取&#xff1a; 项目获取&#xff1a;typora: typora/img (gitee.com…

【C语言程序设计】C语言求圆周率π(三种方法)

题目一&#xff1a; 利用公式①计求π的近似值&#xff0c;要求累加到最后一项小于10^(-6)为止。 程序代码&#xff1a; #include <stdio.h> #include <stdlib.h> #include <math.h> int main(){float s1;float pi0;float i1.0;float n1.0;while(fabs(i)&…

Java中的参数传递

程序设计语言将实参传递给方法&#xff08;或函数&#xff09;的方式分为两种&#xff1a; 值传递&#xff1a;方法接收的是实参值的拷贝&#xff0c;会创建副本。引用传递&#xff1a;方法接收的直接是实参所引用的对象在堆中的地址&#xff0c;不会创建副本&#xff0c;对形…

小家电显示驱动芯片SM1616特点与相关型号推荐

电饭煲、电磁炉、空调和机顶盒等等小家电通常需要使用显示驱动芯片来控制和驱动显示屏。这些显示驱动芯片的主要功能是将处理器的信号转换成显示屏能够理解的信号&#xff0c;从而显示出相应的文字和图像。 具体来说&#xff0c;电饭煲、电磁炉、空调等家等小家电通常会有一个或…

C语言 —— 图形打印

题目1&#xff1a; 思路&#xff1a; 如果我们要打印一个实心正方形&#xff0c;其实就是一个二维数组&#xff0c;i控制行&#xff0c;j控制列&#xff0c;行列不需要控制&#xff0c;arr[i][j]直接打印星号即可。 对于空心正方形&#xff0c;我们只需要控制行和列的条件&…

Igraph入门指南 6

3、make_系列&#xff1a;igraph的建图工具 按照定义&#xff0c;正则图是指各顶点的度均相同的无向简单图&#xff0c;因为我目前没有找到描述度相等的有向&#xff08;或自环图&#xff09;的标准名称&#xff0c;所以在本文中借用一下这个概念&#xff0c;并加上定语有向无…

3.1_3 连续分配管理方式

3.1_3 连续分配管理方式 连续分配&#xff1a;指为用户进程分配的必须是一个连续的内存空间。 &#xff08;一&#xff09;单一连续分配 在单一连续分配方式中&#xff0c;内存被分为系统区和用户区。 系统区通常位于内存的低地址部分&#xff0c;用于存放操作系统相关数据&am…

原生高性能抓包工具Proxyman,送给爱学习的你

现在的抓包工具可谓是五花八门&#xff0c;比如Fiddler&#xff0c;Charles&#xff0c;LightProxy等&#xff0c;各有各的优缺点&#xff0c;最近又看到一个新的抓包工具&#xff0c;像我这样一个有强烈好奇心的人&#xff0c;怎么能错过&#xff0c;我们一起来学习下吧&#…

Python 导入Excel三维坐标数据 生成三维曲面地形图(面) 4-2、线条平滑曲面(原始颜色)但不去除无效点

环境和包: 环境 python:python-3.12.0-amd64包: matplotlib 3.8.2 pandas 2.1.4 openpyxl 3.1.2 scipy 1.12.0 代码: import pandas as pd import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from scipy.interpolate import griddata fro…

3.8_理解代码(3)

fliplr函数 其中fliplr函数为flip array left to right&#xff0c;此处fliplr(i)的输出结果为[4 3 2 1] 我的代码实验 area1 fill(i,u_up(i),cyan,FaceAlpha,0.3);把我都弄得无语了&#xff0c;就实现fill怎么这么难 真是不知道向量长度哪里不同&#xff0c;知道了哈哈 终于…