From 29d29e11c4d85922f6615de7676fabbaeb19f450 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Mon, 07 Apr 2025 17:24:00 +0800
Subject: [PATCH] feat: 历史任务详情

---
 src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue |  118 ++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 81 insertions(+), 37 deletions(-)

diff --git a/src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue b/src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue
index c09e9cc..75e3fc3 100644
--- a/src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue
+++ b/src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue
@@ -2,14 +2,16 @@
 	<div id="deviceJobDetailsMap" />
 </template>
 <script setup>
-import { Cartesian3, Terrain, Viewer } from 'cesium'
 import * as Cesium from 'cesium'
+import { Cartesian3, Math as CesiumMath, Terrain, Viewer } from 'cesium'
 import AmapMercatorTilingScheme from '@/utils/cesium/AmapMercatorTilingScheme'
 import { analyzeKmzFile, removeTextKey, XMLToJSON } from '@/utils/cesium/kmz'
 import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial'
+import lineImg from '@/assets/images/arrow-right-blue.png'
+import uavImg from '@/assets/images/home/useUavHome/uavImg.png'
+import { getCenterPoint } from '@/utils/cesium/mapUtil'
 
 const props = defineProps(['detailsData'])
-
 
 const imageryProvider_ammapSL = new Cesium.UrlTemplateImageryProvider({
 	url: 'https://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
@@ -23,7 +25,7 @@
 	credit: 'amap_SL',
 })
 let viewer = null
-const init = () => {
+const initMap = () => {
 	viewer = new Viewer('deviceJobDetailsMap', {
 		terrain: Terrain.fromWorldTerrain(),
 		infoBox: false, // 禁用沙箱,解决控制台报错
@@ -40,56 +42,98 @@
 	})
 	viewer.imageryLayers.addImageryProvider(imageryProvider_ammapSL)
 	viewer.scene.morphTo2D(0)
+	//设置默认点
+	viewer.camera.setView({
+		destination: Cartesian3.fromDegrees(115.763819, 28.787374),
+	})
 }
-import  imgtst from '@/assets/images/arrow-right-blue.png'
-const renderingLine = (lineObj) =>{
-	console.log(lineObj)
+
+// 渲染线和点
+const renderingLine = lineObj => {
 	const positions = lineObj.Placemark.map(item => {
-		const [lon,lat] = item.Point.coordinates.split(',')
-		return Cartesian3.fromDegrees(Number(lon), Number(lat) )
+		const [lon, lat] = item.Point.coordinates.split(',')
+		return Cartesian3.fromDegrees(Number(lon), Number(lat))
 	})
 	viewer.entities.add({
-		name: 'ls_wayline',
-		id: 'ls_wayline',
+		position: positions[0],
+		billboard: {
+			image: new Cesium.ConstantProperty(uavImg),
+			width: 24,
+			height: 24,
+		},
+	})
+	viewer.entities.add({
 		polyline: {
 			width: 4,
 			positions: positions,
 			material: new ImageTrailMaterial({
-				color: {
-					alpha: 1,
-					blue: 1,
-					green: 1,
-					red: 1
-				},
+				color: { alpha: 1, blue: 1, green: 1, red: 1 },
 				speed: 20,
-				image: imgtst,
-				repeat: { x: Math.floor(40), y: 1 }
+				image: lineImg,
+				repeat: { x: Math.floor(40), y: 1 },
 			}),
-			clampToGround: false
+			clampToGround: false,
+		},
+	})
+}
+
+// 飞到中心点
+function flyToPoints(lngLatArr) {
+	if (!Array.isArray(lngLatArr) || lngLatArr.length === 0) return
+	const positions = lngLatArr.map(([lon, lat]) =>
+		Cesium.Cartesian3.fromDegrees(Number(lon), Number(lat))
+	)
+	// 计算包围盒 BoundingSphere(所有点的外接球)
+	const boundingSphere = Cesium.BoundingSphere.fromPoints(positions)
+	viewer.camera.flyToBoundingSphere(boundingSphere, {
+		duration: 0,
+		offset: new Cesium.HeadingPitchRange(0, 0, boundingSphere.radius * 2),
+	})
+}
+
+// 异步解析kmz文件
+const analysis = async url => {
+	return new Promise(async resolve => {
+		const res = await analyzeKmzFile(`${url}?_t=${new Date().getTime()}`)
+		const templateXML = await res.fileInfoObj['wpmz/template.kml']
+		const templateXMLJSON = XMLToJSON(templateXML)?.['Document']
+		const templateXMLObj = removeTextKey(templateXMLJSON.Folder)
+		resolve(templateXMLObj)
+	})
+}
+
+// 绘制线和飞行
+const drawLine = async () => {
+	const res = await Promise.all(props.detailsData.way_lines.map(item => analysis(item.url)))
+	res.map(item => renderingLine(item))
+	const allPoint = res
+		.flatMap(item => item.Placemark)
+		.map(item => item.Point.coordinates.split(','))
+	flyToPoints(allPoint)
+}
+
+const removeMap = () => {
+	console.log('yichu')
+	viewer.entities.removeAll()
+	viewer.destroy()
+}
+
+watch(
+	() => props.detailsData,
+	(newValue, oldValue) => {
+		if (newValue) {
+			drawLine()
 		}
-	})
-}
-
-const drawLine = () => {
-	props.detailsData.way_lines.forEach(item => {
-		analyzeKmzFile(`${item.url}?_t=${new Date().getTime()}`).then(async res => {
-			const templateXML = await res.fileInfoObj['wpmz/template.kml']
-			const templateXMLJSON = XMLToJSON(templateXML)?.['Document']
-			const templateXMLObj = removeTextKey(templateXMLJSON.Folder)
-			renderingLine(templateXMLObj)
-		})
-	})
-}
-
-watch(() => props.detailsData, (newValue, oldValue) => {
-	if(newValue){
-		drawLine()
 	}
+)
+
+onBeforeUnmount(() => {
+	removeMap()
 })
 
 onMounted(() => {
 	nextTick(() => {
-		init()
+		initMap()
 	})
 })
 </script>

--
Gitblit v1.9.3