Leaflet实现轨迹播放动画效果

news2025/1/14 18:20:36

效果图如下:

<!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>

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

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

相关文章

记录小白第一次EDUsrc:任意用户密码重置漏洞

一、漏洞说明&#xff1a; xxxx学院身份认证系统有严重的逻辑设计缺陷&#xff1a;账户登录、手机登录、密码找回三个接口找到n个逻辑漏洞包括任意账号密码修改、信息泄露&#xff08;应该还有更多&#xff0c;但是有很多重复的漏洞&#xff0c;没必要再找了&#xff09; edus…

Mybatis plus 简介

简介 MyBatis-Plus (opens new window)&#xff08;简称 MP&#xff09;是一个 MyBatis (opens new window)的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 官网:https://baomidou.com/pages/24112f/ 特性 无侵入&…

redis---主从复制及哨兵模式(高可用)

主从复制 主从复制&#xff1a;主从复制是redis实现高可用的基础&#xff0c;哨兵模式和集群都是在主从复制的基础之上实现高可用。 主从负责的工作原理 1、主节点&#xff08;master&#xff09; 从节点&#xff08;slave&#xff09;组成&#xff0c;数据复制是单向的&a…

七牛云产品使用介绍之Dora篇

上一篇介绍了七牛云的CDN服务用于实现对静态资源的访问加速&#xff0c;下一个产品该轮到我们可爱的Dora了 Dora全称&#xff1a;智能多媒体服务 介绍&#xff1a;是一种零运维、高可用、高性能的多媒体数据处理服务。提供图片处理、音视频转码、水印、截图、瘦身等基础功能&am…

HuggingFace-利用BERT预训练模型实现中文情感分类(下游任务)

准备数据集 使用编码工具 首先需要加载编码工具&#xff0c;编码工具可以将抽象的文字转成数字&#xff0c;便于神经网络后续的处理&#xff0c;其代码如下&#xff1a; # 定义数据集 from transformers import BertTokenizer, BertModel, AdamW # 加载tokenizer token Ber…

zookeeper单机版的搭建

一 zookeeper的搭建 1.1 上传zkjar包 1.2 搭建配置 1.解压压缩包 [rootlocalhost export]# tar -zxvf zookeeper-3.7.0-bin.tar.gz 2.创建data文件夹 [rootlocalhost export]# cd apache-zookeeper-3.7.0-bin/ [rootlocalhost apache-zookeeper-3.7.0-bin]# ls bin conf…

专业远程控制如何塑造安全体系?向日葵“全流程安全闭环”解析

安全是远程控制的重中之重&#xff0c;作为国民级远程控制品牌&#xff0c;向日葵远程控制就极为注重安全远控服务的塑造。近期向日葵发布了以安全和核心的新版“向日葵15”以及同步发布《贝锐向日葵远控安全标准白皮书》&#xff08;下简称《白皮书》&#xff09;&#xff0c;…

2023年危险化学品生产单位安全生产管理人员证模拟考试题库及危险化学品生产单位安全生产管理人员理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年危险化学品生产单位安全生产管理人员证模拟考试题库及危险化学品生产单位安全生产管理人员理论考试试题是由安全生产模拟考试一点通提供&#xff0c;危险化学品生产单位安全生产管理人员证模拟考试题库是根据危…

DDD神药:去哪儿结合DDD,实现架构大调优

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 谈谈你的DDD落地经验&#xff1f; 谈谈你对DDD的理解&#x…

苹果 CEO 库克在找接班人;大英图书馆确认被勒索软件攻击丨 RTE 开发者日报 Vol.90

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

Nginx配置Websocket

WebSocket 和HTTP虽然是不同协议&#xff0c;但是两者“握手”方式兼容。通过HTTP升级机制&#xff0c;使用HTTP的Upgrade和Connection协议头的方式可以将连接从HTTP升级为WebSocket。 Websocket 使用 ws 或 wss 的统一资源标志符&#xff0c;类似于 HTTPS&#xff0c;其中 wss…

【PyGIS】使用阿里AIEarth快速下载指定区域指定年份的土地利用数据

说明 中国逐年土地覆盖数据集(CLCD) 由武汉大学的杨杰和黄昕教授团队基于Landsat影像制作了中国逐年土地覆盖数据集(annual China Land Cover Dataset, CLCD),数据包含1985—2021年中国逐年土地覆盖信息。研究团队基于Landsat长时序卫星观测数据,构建时空特征,结合随机森…

JAVA毕业设计111—基于Java+Springboot+Vue的养老院管理系统(源码+数据库+12000字论文)

基于JavaSpringbootVue的养老院管理系统(源码数据库12000字论文)111 一、系统介绍 本系统前后端分离&#xff0c;本系统分为销售、人事、服务、餐饮、财务、超级管理员六种角色 系统主要功能如下&#xff1a; 首页统计&#xff1a;包括今日新增咨询、今日新增预定、今日新增…

java实现置顶功能

目录 一、需求描述 二、功能呈现 &#xff08;一&#xff09;需求分析 &#xff08;二&#xff09;关键设计披露 1、数据库字段 2、查询语句 一、需求描述 在查看公司列表数据时&#xff0c;我想最先看到我常用的公司。 也就是&#xff0c;我想把这个公司放在最前面&am…

攻防世界-web-Confusion1

1. 题目描述 打开链接&#xff0c;如图 点击Login和Rigister&#xff0c;都报错 但是有提示 指出了flag所在的位置&#xff0c;题目中直接能获取到的信息暂时就这么些了 2. 思路分析 既然告诉了我们flag文件的位置&#xff0c;那么要读取到这个文件&#xff0c;要么是任意文…

【EI会议征稿】第九届能源科学与化学工程国际学术研讨会 (ISESCE 2024)

第九届能源科学与化学工程国际学术研讨会 &#xff08;ISESCE 2024&#xff09; 2024 9th International Symposium on Energy Science and Chemical Engineering 第九届能源科学与化学工程国际学术研讨会&#xff08;ISESCE 2024&#xff09;定于2024年3月22-24日在中国南京…

时间序列预测建模的完整流程以及数据分析(新手科研必备)

一、本文介绍 本文给大家带来是时间序列建模的完整流程&#xff0c;大家在接触到这个领域的时候&#xff0c;往往都想将数据直接输入到模型中进行训练和预测&#xff0c;对于其中的一些参数都不太理解&#xff0c;这种情况是不可能得到一个好的结果的&#xff08;本文的内容是…

基于 Flink CDC 打造企业级实时数据集成方案

本文整理自Flink数据通道的Flink负责人、Flink CDC开源社区的负责人、Apache Flink社区的PMC成员徐榜江在云栖大会开源大数据专场的分享。本篇内容主要分为四部分&#xff1a; CDC 数据实时集成的挑战Flink CDC 核心技术解读基于 Flink CDC 的企业级实时数据集成方案实时数据集…

实现centos7与windows共享文件夹

第一步 点击设置 第二步 第三步 第四步 让共享文件夹挂载到hgfs目录下 输入如下命令: sudo vmhgfs-fuse .host:/ /mnt/hgfs -o subtypevmhgfs-fuse,allow_other完成共享

电脑桌面便签工具选择哪一款?

随着互联网时代的不断发展&#xff0c;电脑成为日常工作及办公中必不可少的工具&#xff0c;通过电脑这款工具&#xff0c;大家可以更好的进行工作、学习等方面的交流&#xff1b;电脑桌面便签由于可以为大家整合一些工作及学习方面的备忘事项及笔记等&#xff0c;因而深受大家…