Leaflet实现轨迹播放动画效果

效果图如下:

<!DOCTYPE html>
<html>

<head>
	<title>轨迹</title>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />

	<!-- 引入样式 -->
	<!-- <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> -->
	<link rel="stylesheet" href="../../lib/element-ui@2.13.0/index.css" />
	<style>
		html,
		body,
		#map {
			height: 100%;
			padding: 0;
			margin: 0;
		}

		.menuBar {
			position: absolute;
			text-align: center;
			top: 10px;
			margin: 0 50px;
			padding: 5px;
			border-radius: 3px;
			z-index: 999;
			color: #ffffff;
			background-color: rgba(0, 168, 0, 1);
		}

		.timeslider {
			position: absolute;
			z-index: 999;
			width: 100%;
			height: 100px;
			background: lightseagreen;
			bottom: 0px;
			display: flex;
			align-items: center;
			justify-content: center;
		}

		.block {
			width: 80%;
		}

		.timeslider .slider-demo-block {
			display: flex;
			align-items: center;
		}

		.slider-demo-block .el-slider {
			margin-top: 0;
			margin-left: 12px;
		}

		.el-slider__marks-text {
			position: absolute;
			-webkit-transform: translateX(-50%);
			transform: translateX(-50%);
			font-size: 14px;
			color: #fff;
			margin-top: 15px;
		}
	</style>
	<script src="../../lib/vue@2.6.11/vue.js"></script>
	<!-- <script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script> -->
	<!-- 引入组件库 -->
	<!-- <script src="https://unpkg.com/element-ui@2.13.0/lib/index.js"></script> -->
	<script src="../../lib/element-ui@2.13.0/index.js"></script>
	<script src="../../js/prjconfig.js" maptype="leaflet"></script>
	<!-- 引入插件 -->
	<script src="../../lib/leaflet/plugins/leaflet.polylineDecorator.js"></script>
	<script src="../../lib/leaflet/plugins/Leaflet.AnimatedMarker.js"></script>
</head>

<body>
	<div id="map"></div>
	<div class="menuBar">
		<input type="button" value="开始" onclick="startClick()" />
		<input type="button" value="暂停" onclick="pauseClick()" />
		<input type="button" value="加速" onclick="speetUp()" />
		<input type="button" value="减速" onclick="speetDown()" />
		<input type="button" value="停止" onclick="stopClick()" />
	</div>
	<div id="app" class="timeslider">
		<div class="block">
			<el-slider v-model="value" :max="120" :step="10" :marks="marks" :show-tooltip="false" @change="change">
			</el-slider>
		</div>
	</div>
	<script>
		//'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
		var map = L.map("map", {
			crs: L.CRS.EPSG4326, //L.CRS.EPSG3857
			center: [MAPINIT.Location.lat, MAPINIT.Location.lon], //[40.76339, 106.9477844],
			zoom: MAPINIT.Location.zoom,
			minZoom: MAPINIT.zoomsExtent[0],
			maxZoom: MAPINIT.zoomsExtent[1],
			zoomControl: true,
		});
		// 使用WMTS Key-Value加载地图服务
		let _getc =
			"http://192.168.1.212:8095/server/default/getTile/wmts?request=GetCapabilities&service=wmts&layer=yx";
		MAPCONFIG.MAPWMTS_IMG =
			"http://192.168.1.212:8095/server/vtile/getTile/wmts";
		let ls =
			"http://192.168.1.212:8095/server/vtile/getTile/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=yx&STYLE=default&TILEMATRIXSET=w&FORMAT=image/png&TILEMATRIX={z}&TILECOL={x}&TILEROW={y}&tk=''";
		L.tileLayer(ls, {
			zoomOffset: 1,
		}).addTo(map);
		map.setView(L.latLng(37.550339, 104.114129), 4); //设置缩放级别及中心点

		let speetX = 1; // 默认速度倍数
		// 加速
		function speetUp() {
			speetX = speetX * 2;
			animatedMarker.setSpeetX(speetX);
		}

		// 减速
		function speetDown() {
			speetX = speetX / 2;
			animatedMarker.setSpeetX(speetX);
		}

		// 开始
		function startClick() {
			animatedMarker.start();
		}

		// 暂停
		function pauseClick() {
			animatedMarker.pause();
		}

		// 停止
		function stopClick() {
			newLatlngs = [];
			animatedMarker.stop();
		}

		var routeLine;
		var realRouteLine;
		var decorator;
		var animatedMarker;
		var newLatlngs;
		// 初始化轨迹
		function initTrack(coor) {
			let latlngs = coor;
			// 小车速度
			var speedList = [
				1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 4, 4, 4, 3, 2, 2, 1, 1,
				1,
			];
			// 轨迹线
			routeLine = L.polyline(latlngs, {
				weight: 8,
			}).addTo(map);
			// 实时轨迹线
			realRouteLine = L.polyline([], {
				weight: 8,
				color: "#FF9900",
			}).addTo(map);
			// 轨迹方向箭头
			decorator = L.polylineDecorator(routeLine, {
				patterns: [
					{
						repeat: 50,
						symbol: L.Symbol.arrowHead({
							pixelSize: 5,
							headAngle: 75,
							polygon: false,
							pathOptions: {
								stroke: true,
								weight: 2,
								color: "#FFFFFF",
							},
						}),
					},
				],
			}).addTo(map);

			var carIcon = L.icon({
				iconSize: [37, 26],
				iconAnchor: [19, 13],
				iconUrl: "../../image/car.png",
			});
			// 动态marker
			animatedMarker = L.animatedMarker(routeLine.getLatLngs(), {
				speedList: speedList,
				interval: 200, // 默认为100mm
				icon: carIcon,
				playCall: updateRealLine,
			}).addTo(map);

			newLatlngs = [routeLine.getLatLngs()[0]];

			// 绘制已行走轨迹线(橙色那条)
			function updateRealLine(latlng) {
				newLatlngs.push(latlng);
				realRouteLine.setLatLngs(newLatlngs);
			}
		}

		// 清除polyline线
		function clearPolylineGroup(polyline_group) {
			latlngs = [];
			if (polyline_group) {
				map.removeLayer(polyline_group);
			}
		}

		// 清除轨迹方向箭头
		function clearArrow() {
			map.removeLayer(decorator);
		}

		// 清除marker
		function clearMarker() {
			map.removeLayer(animatedMarker);
		}

		// 重置清空地图上的轨迹、marker
		function resetMap() {
			clearPolylineGroup(routeLine);
			clearArrow(decorator);
			clearMarker(animatedMarker);
		}

		let app = new Vue({
			el: "#app",
			data: {
				message: "Hello Vue!",
				value: 0,
				marks: {
					0: "2023-01",
					10: "2023-02",
					20: "2023-03",
					30: "2023-04",
					40: "2023-05",
					50: "2023-06",
					60: "2023-07",
					70: "2023-08",
					80: "2023-09",
					90: "2023-10",
					100: "2023-11",
					110: "2023-12",
				},
				latlngs: [
					[39.898457, 116.391844],
					[39.898595, 116.377947],
					[39.898341, 116.368001],
					[39.898063, 116.357144],
					[39.899095, 116.351934],
					[39.905871, 116.35067],
					[39.922329, 116.3498],
					[39.931017, 116.349671],
					[39.939104, 116.349225],
					[39.942233, 116.34991],
					[39.947263, 116.366892],
					[39.947568, 116.387537],
					[39.947764, 116.401988],
					[39.947929, 116.410824],
					[39.947558, 116.42674],
					[39.9397, 116.427338],
					[39.932404, 116.427919],
					[39.923109, 116.428377],
					[39.907094, 116.429583],
					[39.906858, 116.41404],
					[39.906622, 116.405321],
					[39.906324, 116.394954],
					[39.906308, 116.391264],
					[39.916611, 116.390748],
				],
			},
			mounted() {
				this.getMonth();
				initTrack(this.latlngs);
			},
			methods: {
				change(e) {
					let step = e.toString();
					// console.log(Object.keys(this.marks));
					if (Object.keys(this.marks).indexOf(step) > -1) {
						console.log(this.marks[step]);
					}
					// console.log(this.value);
					if (this.value == 20) {
						resetMap();
					} else {
						resetMap();
						initTrack(this.latlngs);
					}
				},
				getMonth() {
					let dataArr = [];
					let data = new Date();
					let year = data.getFullYear();
					data.setMonth(data.getMonth() + 1, 1); //获取到当前月份,设置月份
					for (let i = 0; i < 12; i++) {
						data.setMonth(data.getMonth() - 1); //每次循环一次,月份值减1
						let m = data.getMonth() + 1;
						m = m < 10 ? "0" + m : m;
						dataArr.push(data.getFullYear() + "-" + m);
					}
					let list = dataArr.reverse();
					let obj = {};
					let labelArr = Object.keys(this.marks);
					labelArr.forEach((item, index) => {
						obj[item] = list[index];
					});
					this.marks = obj;
				},
			},
		});
	</script>
</body>

</html>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Sentinel 授权规则 (AuthorityRule)

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 SpringbootDubboNacos 集成 Sentinel&…

基于深度学习的文本分类

通过构建更复杂的深度学习模型可以提高分类的准确性&#xff0c;即分别基于TextCNN、TextRNN和TextRCNN三种算法实现中文文本分类。 项目地址&#xff1a;zz-zik/NLP-Application-and-Practice: 本项目将《自然语言处理与应用实战》原书中代码进行了实现&#xff0c;并在此基础…

Connect-The-Dots_2

Connect-The-Dots_2 一、主机发现和端口扫描 主机发现&#xff0c;靶机地址192.168.80.148 arp-scan -l端口扫描 nmap -A -p- -sV 192.168.80.148开放端口 21/tcp open ftp vsftpd 2.0.8 or later 80/tcp open http Apache httpd 2.4.38 ((Debian)) 111/tcp …

前缀和——DP34 【模板】前缀和

文章目录 &#x1f34b;1. 题目&#x1f348;2. 算法原理&#x1f348;3. 代码实现 &#x1f34b;1. 题目 题目链接&#xff1a;【模板】前缀和_牛客题霸_牛客网 (nowcoder.com) 描述 给定一个长度为n的数组a1,a2,…an. 接下来有q次查询, 每次查询有两个参数l, r. 对于每个询…

基于ZLMediaKit的GB28181视频平台demo

GB28181 主要内容 国标的20位id是按照标准来定的&#xff0c;前8位是地域信息&#xff0c;9-10位是行业信息&#xff0c;11-13是设备类型、14是网络标识、后6位为序号 约定以SIP协议作为会话通道的使用标准&#xff0c;以RTP作为语言和视频的载体。联网系统在进行音视频传输及…

ui设计师简历自我评价的范文(合集)

ui设计师简历自我评价的范文篇一 本人毕业于艺术设计专业&#xff0c;具有较高的艺术素养&#xff0c;平时注重设计理论知识的积累&#xff0c;并将理论应用到作品中。了解当下设计的流行趋势&#xff0c;设计注重细节、重视用户体验&#xff0c;对色彩搭配有着浓厚的兴趣&…

简墨的进化之路:打造大模型数据计算系统的云存储底座

10月24日程序员节&#xff0c;「大模型数据计算系统」2023拓数派年度技术论坛在上海圆满落幕&#xff0c;拓数派大模型数据计算系统&#xff08;PieDataComputingSystem&#xff0c;缩写&#xff1a;πDataCS&#xff09;如约而至&#xff01;πDataCS 以云原生技术重构数据存储…

私有化敏感词检测API服务wordscheck

之前有网友在找敏感词检测的应用&#xff0c;这个应该能满足他的需求&#xff1b; 什么是 wordscheck &#xff1f; wordscheck 是敏感词检测 API&#xff0c;提供文本识别、智能鉴黄、涉政检测、谩骂等等敏感词检测过滤服务。 简介 敏感词库从大量样本库整理出来&#xff0c;…

Java 编码

编码: 加密: 通过加密算法和密钥进行 也可通过码表进行加密 对称加密: 缺点:可被截获 元数据---加密算法密钥密文 ----> 解密算法密钥元数据 算法:DES(短 56位),AES(长 128位)破解时间加长 非对称加密: 元数据-加密算法加密密钥 密文 --->加密算法解密密钥元数据 …

1.Qt5.15及其以上的下载

Qt5.15及其以上的下载 简介&#xff1a; ​ Qt是一个跨平台的C库&#xff0c;允许开发人员创建在不同操作系统&#xff08;如Windows、macOS、Linux/Unix&#xff09;和设备上具有本地外观和感觉的应用程序。Qt提供了一套工具和库&#xff0c;用于构建图形用户界面&#xff0…

CNVD-2023-12632:泛微E-cology9 browserjsp SQL注入漏洞复现 [附POC]

文章目录 泛微E-cology9 browserjsp SQL注入漏洞(CNVD-2023-12632)漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 泛微E-cology9 browserjsp SQL注入漏洞(CNVD-2023-12632)漏洞复现 [附POC] 0x…

JavaEE 多线程01

为什么引入多线程? 首先进程已经能很好的完成多任务这个情景下的并发编程了,那为什么又引入多线程呢? 这是因为在一些情景下,我么需要大量的创建和销毁进程来完成一些任务,此时多进程对系统的开销就会很大了. 假设有这样一个场景,服务器同时接收到很多个服务请求,这个时候服务…

数据挖掘 K近邻

什么时候用K近邻&#xff1f; 交叉验证的时候。最常见的交叉验证方法是K折交叉验证&#xff0c;其中数据集被均匀分成K个子集&#xff0c;称为折&#xff0c;然后执行K次训练和测试&#xff0c;每次选择不同的折作为测试集&#xff0c;其余的作为训练集。最后&#xff0c;将K次…

windows11快速输入时间和日期

windows11快速输入时间和日期 〇、赶时间的看这里 任务栏微软输入法图标右键 | 设置 | 词库和自学习 | 用户自定义短语 |添加或编辑自定义短语| 添加日期设置 %yyyy%-%MM%-%dd%时间设置 %yyyy%-%MM%-%dd% %HH%:%mm%:%ss%-------------------------------------------------…

ROS1创建自定义服务并使用

1.首先在功能包创建一个srv文件夹 如上图所示&#xff0c;vehicle_control是我的功能包&#xff0c;创建一个srv文件夹 2.使用touch指令创建服务文件 touch Ranging.srv3.在文件内输入服务数据 横线代表分割符&#xff0c;上面的是客户端发送的数据&#xff0c;下面是服务器…

【开源】基于Vue.js的民宿预定管理系统

项目编号&#xff1a; S 058 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S058&#xff0c;文末获取源码。} 项目编号&#xff1a;S058&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用例设计2.2 功能设计2.2.1 租客角色…

NX二次开发UF_CAM_set_clear_plane_data 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CAM_set_clear_plane_data Defined in: uf_cam_planes.h int UF_CAM_set_clear_plane_data(tag_t object_tag, double origin [ 3 ] , double normal [ 3 ] ) overview 概述 De…

Altium Designer学习笔记9

忽视了一个最大的问题&#xff0c;就是元器件的封装&#xff0c;不应该是根据AD系统的封装走&#xff0c;而应该是根据立创商城上的规格书&#xff0c;确认每个封装的大小&#xff0c;画出封装图&#xff0c;然后才是布局和走线。 1、确认电容的封装采用0805&#xff0c;贴片电…

360:流氓or保家卫国的勇士?

你曾用过360吗&#xff0c;这个在国内名声不好的杀毒软件&#xff0c;却是令国外黑客闻风丧胆的存在。 首先&#xff0c;在电脑病毒刚兴起的年代&#xff0c;杀毒软件是要收费的&#xff0c;当时盛行的瑞星和金山就是采用的付费模式&#xff0c;而就在2006年&#xff0c;奇虎…

C++三大特性——继承

目录 一.继承的概念及定义 1.1继承的概念 1.2 继承定义 1.2.1定义格式 1.2.2继承关系和访问限定符​编辑 1.2.3继承基类成员访问方式的变化 二.基类和派生类对象赋值转换 三.继承中的作用域 四.派生类的默认成员函数 五.继承与友元 六.继承与静态成员 一.继承的概念及…