From a7729ab954c949489fd6888fdecdd361d617c39e Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Mon, 21 Apr 2025 08:33:38 +0800
Subject: [PATCH] Merge branch 'master' of http://139.196.74.78:10010/r/drone/command-center-dashboard

---
 src/hooks/useTaskWayline/useTaskWayline.js |  258 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 229 insertions(+), 29 deletions(-)

diff --git a/src/hooks/useTaskWayline/useTaskWayline.js b/src/hooks/useTaskWayline/useTaskWayline.js
index 200de38..bd9214d 100644
--- a/src/hooks/useTaskWayline/useTaskWayline.js
+++ b/src/hooks/useTaskWayline/useTaskWayline.js
@@ -2,11 +2,11 @@
  * @Author: shuishen 1109946754@qq.com
  * @Date: 2025-04-19 14:24:34
  * @LastEditors: shuishen 1109946754@qq.com
- * @LastEditTime: 2025-04-19 15:23:57
+ * @LastEditTime: 2025-04-20 17:53:08
  * @FilePath: \command-center-dashboard\src\hooks\useTaskWayline\useTaskWayline.js
- * @Description: 
- * 
- * Copyright (c) 2025 by shuishen, All Rights Reserved. 
+ * @Description:
+ *
+ * Copyright (c) 2025 by shuishen, All Rights Reserved.
  */
 import lineImg from '@/assets/images/arrow-right-blue.png'
 import rwqfdImg from '@/assets/images/signMachineNest/rwqfd.png'
@@ -18,9 +18,24 @@
 
 import * as Cesium from 'cesium'
 import { Cartesian3 } from 'cesium'
+import aircraftGltf from '@/assets/gltf/aircraft.gltf'
+import CreateFrustum from '@/utils/cesium/frustum/CreateFrustum'
 
-export function useTaskWayline (viewer, taskDetails) {
-  const newViewer = unref(viewer)
+export function useTaskWayline () {
+  let viewer = null
+  let deviceOsdInfo = null
+  let flighttaskProgressInfo = null
+
+  // watch
+  let taskWatch = null
+  let flighttaskWatch = null
+  let deviceWatch = null
+
+  // 航线位置
+  let currentWaylinePostions = []
+  // 当前航点 下标
+  let currentWaypointIndex = null
+  let droneSpeedArr = []
 
   // 解析kmz文件
   const parsingFiles = async url => {
@@ -29,20 +44,23 @@
     const waylinesXMLJSON = XMLToJSON(waylinesXML)?.['Document']
     const waylinesXMLObj = removeTextKey(waylinesXMLJSON.Folder)
     if (!waylinesXMLObj.Placemark.length) return
-    const allPoint = waylinesXMLObj.Placemark.map(item => item.Point.coordinates.split(','))
-    flyVisual(allPoint, newViewer)
+    // const allPoint = waylinesXMLObj.Placemark.map(item => item.Point.coordinates.split(','))
+    // flyVisual(allPoint, viewer)
     drawWayline(waylinesXMLObj)
   }
 
   const drawWayline = lineObj => {
-    const positions = lineObj.Placemark.map(item => {
+    currentWaylinePostions = lineObj.Placemark.map(item => {
       const [lon, lat] = item.Point.coordinates.split(',')
       return Cartesian3.fromDegrees(Number(lon), Number(lat))
     })
+
+    removeEntitys()
+
     // 起点
-    newViewer.entities.add({
+    viewer.entities.add({
       id: 'drone-job-wayline-start',
-      position: positions[0],
+      position: currentWaylinePostions[0],
       billboard: {
         image: new Cesium.ConstantProperty(rwqfdImg),
         width: 70,
@@ -51,9 +69,9 @@
     })
 
     // 终点
-    newViewer.entities.add({
+    viewer.entities.add({
       id: 'drone-job-wayline-end',
-      position: positions[positions.length - 1],
+      position: currentWaylinePostions[currentWaylinePostions.length - 1],
       billboard: {
         image: new Cesium.ConstantProperty(endPointImg),
         width: 30,
@@ -63,11 +81,11 @@
     })
 
     // 路径线
-    newViewer.entities.add({
+    let polylineEntity = viewer.entities.add({
       id: 'drone-job-wayline-polyline',
       polyline: {
         width: 4,
-        positions: positions,
+        positions: currentWaylinePostions,
         material: new ImageTrailMaterial({
           color: { alpha: 1, blue: 1, green: 1, red: 1 },
           speed: 20,
@@ -77,27 +95,209 @@
         clampToGround: false,
       },
     })
-  }
 
-  watch(taskDetails, () => {
-    if (taskDetails.value?.way_lines?.length) {
-      parsingFiles(taskDetails.value.way_lines[0].url)
-    }
-  }, { immediate: true })
-
-  const removeEntitys = () => {
-    const entitiesIDs = newViewer?.entities.values.map(i => i.id)
-
-    entitiesIDs.forEach(item => {
-      item.includes('drone-job-wayline-') && newViewer?.entities.removeById(item)
+    viewer.flyTo(polylineEntity, {
+      offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-60), 0),
+      duration: 0.5,
     })
   }
 
+  let viewInfoFrustum
+  // 设置视椎
+  const setCreateFrustum = (host) => {
+    if (!host) return
+    viewInfoFrustum?.clear()
+
+    const attitude_head = 180 + host?.attitude_head
+    const gimbal_pitch = 90 - Number(host?.payloads[0]?.gimbal_pitch) || 0
+
+    viewInfoFrustum = new CreateFrustum(viewer, {
+      position: {
+        longitude: host?.longitude,
+        latitude: host?.latitude,
+        altitude: host?.height,
+      },
+      width: 30,
+      height: 30,
+      fov: 20.0,
+      near: 3.0,
+      far: 250.0,
+      roll: gimbal_pitch,
+      pitch: 0,
+      heading: attitude_head,
+    })
+  }
+
+  function setAircraftGltf () {
+    const host = deviceOsdInfo.value?.data?.host
+
+    const aircraftEntity = viewer?.entities.getById('aircraftGltf')
+    const position = Cesium.Cartesian3.fromDegrees(host?.longitude, host?.latitude, host?.height)
+
+    if (aircraftEntity) {
+      aircraftEntity.position = new Cesium.ConstantPositionProperty(position)
+
+      const homeDistance = Math.floor(host?.home_distance) || 0
+
+      // 距离下一个航点
+      const nextPoint = currentWaylinePostions[currentWaypointIndex]
+
+      if (!nextPoint) {
+        aircraftEntity.label = {}
+        return
+      }
+
+      const devicePosition = Cesium.Cartesian3.fromDegrees(
+        Number(host.longitude),
+        Number(host.latitude),
+        0,
+      )
+
+      // 距离下个点位的距离
+      let distance = Cesium.Cartesian3.distance(
+        devicePosition,
+        nextPoint,
+      )
+
+      // 本次航线平面里程
+      let totalDistance = 0
+      currentWaylinePostions.map((cartesian3, index) => {
+        // 两点之间的距离
+        let deviceCurPosition = null
+        if (index === 0) {
+          deviceCurPosition = devicePosition
+        } else {
+          deviceCurPosition = currentWaylinePostions[index - 1]
+        }
+
+        let distance = Cesium.Cartesian3.distance(
+          deviceCurPosition,
+          cartesian3,
+        )
+        totalDistance += distance
+        return Math.round(distance)
+      })
+
+      // 速度
+      let horizontalSpeed = host.horizontal_speed || 0
+      if (
+        !droneSpeedArr.includes(horizontalSpeed) &&
+        horizontalSpeed > 1
+      ) {
+        droneSpeedArr.push(horizontalSpeed)
+      }
+      if (horizontalSpeed < 5) {
+        horizontalSpeed = 10
+      }
+
+      // 预计到达下一个航点时间
+      let arrivalTime = distance / horizontalSpeed
+      if (arrivalTime === Infinity || isNaN(arrivalTime)) {
+        arrivalTime = 0
+      }
+      if (arrivalTime > 60) {
+        const minute = Math.floor(arrivalTime / 60)
+        const second = Math.round(arrivalTime % 60)
+        arrivalTime = `${minute}m${second}s`
+      } else {
+        arrivalTime = Math.round(arrivalTime) + 's'
+      }
+
+      aircraftEntity.label = new Cesium.LabelGraphics({
+        text: `距离机场水平距离:${homeDistance}m\n距离下一个航点:${Math.round(distance)}m\n预计到达下一航点时间:${arrivalTime}\n本次航线平面里程:${Math.round(totalDistance)}m`,
+        font: '13px monospace',
+        showBackground: true,
+        horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
+        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+        disableDepthTestDistance: Number.POSITIVE_INFINITY,
+        pixelOffset: new Cesium.Cartesian2(0, -40),
+        show: true,
+      })
+
+      return
+    }
+
+    viewer?.entities.add({
+      id: 'aircraftGltf',
+      position,
+      label: {},
+      model: {
+        uri: aircraftGltf, // 或 .glb
+        scale: 1.0, // 缩放比例
+        minimumPixelSize: 64, // 最小像素尺寸(保证模型远处可见)
+        maximumScale: 128, // 最大缩放(可选)
+      },
+    })
+  }
+
+  const mapEntityRemove = () => {
+    viewInfoFrustum?.clear()
+
+    viewer?.entities.removeById('aircraftGltf')
+  }
+
+  const removeEntitys = () => {
+    const entitiesIDs = viewer?.entities.values.map(i => i.id)
+
+    Array.isArray(entitiesIDs) && entitiesIDs.forEach(item => {
+      item.includes('drone-job-wayline-') && viewer?.entities.removeById(item)
+    })
+  }
+
+  const removeWatchs = () => {
+    taskWatch?.()
+    flighttaskWatch?.()
+    deviceWatch?.()
+  }
+
+  const init = (v, wsInfo, taskDetails) => {
+    viewer = v
+    deviceOsdInfo = computed(() => wsInfo.value?.device_osd)
+    flighttaskProgressInfo = computed(() => wsInfo.value?.flighttask_progress)
+
+    removeWatchs()
+
+    taskWatch = watch(taskDetails,
+      () => {
+        if (taskDetails.value?.way_lines?.length) {
+          parsingFiles(taskDetails.value.way_lines[0].url)
+        }
+      },
+      { immediate: true }
+    )
+
+    flighttaskWatch = watch(flighttaskProgressInfo, async () => {
+      const output = flighttaskProgressInfo.value?.data?.output
+
+      currentWaypointIndex = output.ext['current_waypoint_index']
+    })
+
+    deviceWatch = watch(deviceOsdInfo, () => {
+      const host = deviceOsdInfo.value?.data?.host
+
+      if (!host) return
+
+      if ([14, 0].includes(host?.mode_code)) {
+        mapEntityRemove()
+        return
+      }
+
+      setCreateFrustum(host)
+      setAircraftGltf()
+    }
+    )
+  }
+
   onBeforeUnmount(() => {
+    mapEntityRemove()
     removeEntitys()
+
+    removeWatchs()
   })
 
   return {
-    removeEntitys
+    init,
+    removeEntitys,
+    mapEntityRemove,
   }
-}
\ No newline at end of file
+}

--
Gitblit v1.9.3