vue3+element-plus 高德地图路径巡航根据经纬度动态设置巡航路径

vue3+element=plus 高德地图路径巡航根据经纬度动态设置巡航路径

代码片段

<template>
	<div style="width: 100%;height: 100vh;position: relative">
		<div v-show="!data.isDes"
			style="position: absolute;left: 0;top: 0;bottom: 0;z-index: 99999;display: flex;flex-direction: row;align-items: center;justify-content: center">
			<div :class="['box', slideClass]" style="height: 100%">
				<div style="background: #fff;height: 100%;flex: 1;display: flex;flex-direction: column">
					<div style="padding: 10px">
						<!--            <el-input-->
						<!--                v-model="formData.keyword"-->
						<!--                placeholder="车牌号/姓名/电话/车辆位置"-->
						<!--            >-->
						<!--              <template #prepend>-->
						<!--                <el-select v-model="formData.select" placeholder="Select" style="width: 106px;" size="large">-->
						<!--                  <el-option label="全部(99)" value="0"/>-->
						<!--                  <el-option label="行驶(99)" value="1"/>-->
						<!--                  <el-option label="离线" value="2"/>-->
						<!--                  <el-option label="禁止" value="3"/>-->
						<!--                </el-select>-->
						<!--              </template>-->
						<!--            </el-input>-->
					</div>
					<div style="display: flex;flex-direction: row;align-items: center;padding: 4px 10px">
						<div style="display:flex;flex-direction: row;align-items: center">
							<div class="circle" />
							<span>空闲中</span>
						</div>
						<div style="display:flex;flex-direction: row;align-items: center;margin-left: 8px">
							<div class="circleRed" />
							<span>任务中</span>
						</div>
					</div>
					<div style="width: 95%;height: 100%;">
						<recursive-menu :menu-items="menu.list"></recursive-menu>
					</div>
				</div>
			</div>
			<div style="margin-left: -24px" @click="toggle">
				<div :class="['icon', data.show ? 'arrow-up' : 'arrow-down']">
					<img src="/static/icon_location_close.png" style="width: 50px;height: 50px">
				</div>
			</div>
		</div>
		<div v-show="data.isDes" style="position: absolute;left: 30px;top: 30px;z-index: 999999">
			<el-button type="primary" plain @click="closeDes">关闭轨迹</el-button>
		</div>
		<el-row>
			<el-col :span="24">
				<div class="grid-content ep-bg-purple-dark" />
				<div style="height: 100vh" id="container" ref="map"></div>
			</el-col>
		</el-row>

		<el-dialog v-model="data.dialogVisible" title="Tips" width="30%">
			<div style="display: flex;flex-direction: column">
				<el-form label-position="top" label-width="100px" style="max-width: 460px">
					<el-form-item label="起始日期">
						<el-date-picker v-model="formData.startDate" type="date" label="起始日期" placeholder="起始日期"
							style="width: 100%" />
					</el-form-item>
					<el-form-item label="开始时间">
						<el-time-picker v-model="formData.startTime" label="开始时间" placeholder="开始时间"
							style="width: 100%" />
					</el-form-item>
					<el-form-item label="截至日期">
						<el-date-picker v-model="formData.startDate" type="date" label="截至日期" placeholder="截至日期"
							style="width: 100%" />
					</el-form-item>
					<el-form-item label="结束时间">
						<el-time-picker v-model="formData.endTime" label="结束时间" placeholder="结束时间"
							style="width: 100%" />
					</el-form-item>
				</el-form>
			</div>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="data.dialogVisible = false">关闭</el-button>
					<el-button type="primary" @click="handleClose">
						查看轨迹
					</el-button>
				</span>
			</template>
		</el-dialog>

	</div>

</template>

<script setup>
	import RecursiveMenu from '../../components/RecursiveMenu.vue'; // 导入递归菜单组件
	import {
		reactive,
		computed,
		ref,
		watch,
		getCurrentInstance
	} from 'vue';
	import {
		ElMessage
	} from 'element-plus'
	const {
		proxy
	} = getCurrentInstance()
	import {
		useRouter
	} from 'vue-router'
	const router = useRouter();

	const handleClose = () => {
		console.log(1112222)
		data.dialogVisible = false
		console.log(routeList[0])
		data.isDes = true
		pathSimplifierIns.setData([routeList[0]]);
		// ElMessageBox.confirm('Are you sure to close this dialog?')
		//     .then(() => {
		//       console.log(11112222)
		//       console.log(routeList[0])
		//       pathSimplifierIns.setData([routeList[0]]);
		//     })
		//     .catch(() => {
		//       // catch error
		//     })
	}

	function closeDes() {
		doExpand()
		data.isDes = false
	}

	function handleBtn1Click() {
		console.log(1111)
		data.dialogVisible = true
		InfoWindow.close()
	}

	function handleBtn2Click() {
		console.log(22222)
		InfoWindow.close()
	}

	function handleBtn3Click() {
		console.log(33333)
		InfoWindow.close()
	}
	const formData = reactive({
		keyword: '',
		select: '0',
		startDate: '2023-12-14',
		startTime: new Date(2023, 12, 14, 0, 0),
		endDate: '2023-12-14',
		endTime: new Date(2023, 12, 14, 23, 59),
	});
	const data = reactive({
		dialogVisible: false,
		show: true,
		isDes: false,
		socket:null,
	});
	const menu = reactive({
		list: [{
				type: 'err',
				name: '离线车辆1'
			},
			{
				type: 'warring',
				name: '静止车辆2'
			},
			{
				type: 'success',
				name: '运动车辆2'
			},
			{
				type: 'success',
				name: '运动车辆2'
			}
		]
		// list: [
		//   {
		//     name: '模拟分组(8)',
		//     children: [
		//       {
		//         name: '定位监控组(3)',
		//         children: [
		//           {
		//             type: 'err',
		//             name: '离线车辆2'
		//           },
		//           {
		//             type: 'warring',
		//             name: '静止车辆2'
		//           },
		//           {
		//             type: 'success',
		//             name: '运动车辆2'
		//           }
		//         ]
		//       },
		//       {
		//         name: '油耗监控组(1)',
		//         children: [
		//           {
		//             type: 'success',
		//             name: '运动车辆2'
		//           }
		//         ]
		//       },
		//       {
		//         name: '视频监控组(4)',
		//         children: [
		//           {
		//             type: 'err',
		//             name: '离线车辆1'
		//           },
		//           {
		//             type: 'warring',
		//             name: '静止车辆2'
		//           },
		//           {
		//             type: 'success',
		//             name: '运动车辆2'
		//           },
		//           {
		//             type: 'success',
		//             name: '运动车辆2'
		//           }
		//         ]
		//       }
		//     ]
		//   }
		// ]
	});
	const slideClass = computed(() => {
		return data.show ? 'slide-enter-active' : 'slide-enter';
	});
	const toggle = () => {
		console.log(1112222)
		data.show = !data.show;
	};
	let InfoWindow = null
	window.AMapLoader.load({
		"key": "", // 申请好的Web端开发者Key,首次调用 load 时必填
		"version": "2.0", // 指定要加载的 JS API 的版本,缺省时默认为 1.4.15
		"plugins": ['AMap.Scale'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
		"AMapUI": { // 是否加载 AMapUI,缺省不加载
			"version": '1.1', // AMapUI 版本
			"plugins": ['overlay/SimpleMarker', 'misc/PathSimplifier'], // 需要加载的 AMapUI ui插件
		},
		"Loca": { // 是否加载 Loca, 缺省不加载
			"version": '2.0' // Loca 版本
		},
	}).then((AMap) => {
		var map = new AMap.Map('container');
		map.addControl(new AMap.Scale());
		InfoWindow = new window.AMap.InfoWindow
		aaaa(map)
	}).catch((e) => {
		console.error(e); //加载错误提示
	});
	let routeList = []
	let newRouteList = []
	let navgList = []
	let markerList = []
	// let infoList=[]
	let pathSimplifierIns = null
	let newObjList = []
	// eslint-disable-next-line no-unused-vars
	let endIdx = 0

	function aaaa(map) {
		console.log(window.AMapUI)
		// var emptyLineStyle = {
		//   lineWidth: 0,
		//   fillStyle: null,
		//   strokeStyle: null,
		//   borderStyle: null,
		// };
		var pathNavigatorStyle = {
			initRotateDegree: 0,
			width: 16,
			height: 16,
			autoRotate: true,
			lineJoin: 'round',
			content: 'defaultPathNavigator',
			fillStyle: '#087EC4',
			strokeStyle: '#116394', //'#eeeeee',
			lineWidth: 1,
			pathLinePassedStyle: {
				lineWidth: 0,
				strokeStyle: 'rgba(8, 126, 196, 1)',
				borderWidth: 0,
				borderStyle: '#eeeeee',
				dirArrowStyle: false
			}
		}

		// function showInfoM(e){
		//   console.log(e)
		// }

		pathSimplifierIns = new window.AMapUI.PathSimplifier({
			zIndex: 0,
			autoSetFitView: true,
			map: map, // 所属的地图实例

			getPath: function(pathData) {
				return pathData.path;
			},
			getHoverTitle: function(pathData, pathIndex, pointIndex) {
				if (pointIndex >= 0) {
					//point
					return pathData.name + ',点:' + pointIndex + '/' + pathData.path.length;
				}

				return pathData.name + ',点数量' + pathData.path.length;
			},

			renderOptions: {
				pathNavigatorStyle: pathNavigatorStyle,
				renderAllPointsIfNumberBelow: 100 // 绘制路线节点,如不需要可设置为-1
			}
		})

		window.pathSimplifierIns = pathSimplifierIns;


		fetch('https://a.amap.com/amap-ui/static/data/big-routes.json')
			.then(response => response.json())
			.then(routeData => {
				routeList = routeData
				for (let i = 0, len = routeData.length; i < len; i++) {
					let newItem = {
						name: routeList[i].name,
						path: routeList[i].path.slice(endIdx, 1)
					}
					newRouteList.push(newItem)
				}
				pathSimplifierIns.setData(newRouteList);
				//
				for (let i = 0, len = newRouteList.length; i < len; i++) {
					navgList[i] = pathSimplifierIns.createPathNavigator(0, {
						loop: true, // 循环播放
						speed: 54 // 巡航速度,单位千米/小时
					});
					// console.log(newRouteList[i].path)
					let markerContent = `
              <div style="display: flex;flex-direction: row;white-space: nowrap;background: #fff;border: 1px solid #000;border-radius: 4px;padding: 2px">
                  <div style="display:flex;flex-direction: row;align-items: center;margin-left: 8px;font-size: 12px">
                    <span>运动车辆-模拟司机7-54Km/h-22.12</span>
                  </div>
             </div>`
					let newMarler = new window.AMap.Marker({
						clickable: true,
						anchor: 'bottom-center',
						position: new window.AMap.LngLat(newRouteList[i].path[0][0], newRouteList[i].path[0][
							1]),
						content: markerContent,
						extData: {
							pathIndex: i
						}
					});
					newMarler.on('click', (e) => {
						// const extData = e.target.getExtData()
						let infoContent = `
           <div style="display: flex;flex-direction: column;padding: 5px">
              <div style="text-align: center">详情</div>
              <div style="display: flex;flex-direction: row;align-content: center;padding: 6px 2px;font-size: 14px">当前位置: 山东省青岛市************************</div>
              <div style="display: flex;flex-direction: row;align-content: center;padding: 6px 2px;font-size: 14px">司机信息: 模拟司机4•</div>
              <div style="display: flex;flex-direction: row;align-content: center;padding: 6px 2px;font-size: 14px">车牌号: 运动车辆7</div>
              <div style="display: flex;flex-direction: row;align-content: center;padding: 6px 2px;font-size: 14px">定位时间: 2023-12-13 05:39:33</div>
              <div style="display: flex;flex-direction: row;align-content: center;padding: 6px 2px;font-size: 14px">车辆状态: 行驶中 (46km/h)•油量 (66.6L)</div>
              <div style="display: flex;flex-direction: row;align-content: center;padding: 6px 2px;justify-content: space-around;margin-top: 20px">
				  <button οnclick="btn1()" id="btn1" style="flex: 1;margin-right: 10px;padding: 6px 0;border: 1px solid #007bff;background: #fff;border-radius: 4px">查看轨迹</button>
				  <button οnclick="btn2()" id="btn4" style="flex: 1;margin-right: 10px;padding: 6px 0;border: 1px solid #007bff;background: #fff;border-radius: 4px">关闭</button>

				</div>
			</div>
					  `
						// infoList[i]= new window.AMap.InfoWindow({
						//   position: new window.AMap.LngLat(newRouteList[i].path[0][0], newRouteList[i].path[0][1]),
						//   offset: new window.AMap.Pixel(0, -35),
						//   content: infoContent
						// });
						// infoList[extData.pathIndex].open(map,e.target.getPosition())
						InfoWindow.setContent(infoContent);
						InfoWindow.open(map, e.target.getPosition());
						console.log(e.target.getExtData())
					});
					window.btn1 = () => {
						handleBtn1Click()
					}
					window.btn2 = () => {
						handleBtn2Click()
					}
					window.btn3 = () => {
						handleBtn3Click()
					}
					map.add(newMarler)
					markerList[i] = newMarler

					navgList[i].start()
				}
				console.log(pathSimplifierIns.getPathNavigators())
				if (doExpand()) {
					setInterval(() => {
						console.log(data)
						if (!data.isDes) {
							console.log(111111)
							doExpand()
						}
					}, 2000)
				}
			})
	}

	function onload() {
		pathSimplifierIns.renderLater();
		// infoList[i]
	}
	// eslint-disable-next-line no-unused-vars
	function doExpand() {
		if (!data.isDes) {
			newObjList = []
			const objectList = pathSimplifierIns.getPathNavigators()
			for (let i = 0; i < objectList.length; i++) {
				newObjList.push({
					cursor: JSON.parse(JSON.stringify(objectList[i].getCursor())),
					status: objectList[i].getNaviStatus()
				})
			}
		}

		//  // 延展路径
		endIdx++;
		// if (endIdx >= myPath.length) {
		//   return false;
		// }
		for (let i = 0; i < navgList.length; i++) {
			newRouteList[i].path = routeList[i].path.slice(0, endIdx + 1);
			// 重新建立一个巡航器


		}
		pathSimplifierIns.setData(newRouteList);
		for (let i = 0; i < navgList.length; i++) {
			// var infoWindow = new window.AMap.InfoWindow({
			//   content: "这是一个信息窗口"
			// });
			navgList[i] = pathSimplifierIns.createPathNavigator(i, {
				speed: 54, // 巡航速度,单位千米/小时
				pathNavigatorStyle: {
					width: 16,
					height: 32,
					content: window.AMapUI.PathSimplifier.Render.Canvas.getImageContent('/static/carRed.png',
						onload, onerror),
					strokeStyle: null,
					fillStyle: null
				},
			});
			// var $markerContent = '<div class="markerInfo"></div>';

			// $markerContent.html(pathSimplifierIns.getPathData(i).name);

			navgList[i].on('move', function() {
				markerList[i].setPosition(navgList[i].getPosition());
				// InfoWindow.setPosition(navgList[i].getPosition());
			});
			if (newObjList[i].status !== 'stop') {
				navgList[i].start();
			}
			// 恢复巡航器的位置
			if (newObjList[i].cursor.idx >= 0) {
				navgList[i].moveToPoint(newObjList[i].cursor.idx, newObjList[i].cursor.tail);
			}
		}
		return true;
	}
	
	data.socket = new WebSocket('ws://192.168.3.40:8080/sockjs-node/160/10aoqxi4/websocket')
	  data.socket.addEventListener('open', () => {
	    console.log('WebSocket connected')
	  })
	
</script>
<style scoped>
	.box {
		overflow: hidden;
		transition: width 0.5s;
	}

	.slide-enter,
	.slide-leave-to {
		width: 0;
	}

	.slide-enter-active,
	.slide-leave-active {
		width: 500px;
	}

	.icon {
		display: inline-block;
		width: 50px;
		height: 50px;
		transition: transform 0.3s;
	}

	.arrow-up {
		transform: rotate(180deg);
	}

	.arrow-down {
		transform: rotate(0deg);
	}

	.circle {
		width: 11px;
		height: 11px;
		border: 3px solid #28a745;
		border-radius: 50%;
		position: relative;
		background-color: white;
	}

	.circle::before {
		content: "";
		position: absolute;
		top: 2px;
		left: 2px;
		right: 2px;
		bottom: 2px;
		background-color: #28a745;
		border-radius: 50%;
	}

	.circleRed {
		width: 11px;
		height: 11px;
		border: 3px solid #dc3545;
		border-radius: 50%;
		position: relative;
		background-color: white;
	}

	.circleRed::before {
		content: "";
		position: absolute;
		top: 2px;
		left: 2px;
		right: 2px;
		bottom: 2px;
		background-color: #dc3545;
		border-radius: 50%;
	}
</style>
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值