/* * @Author: shuishen 1109946754@qq.com * @Date: 2025-04-19 14:24:34 * @LastEditors: shuishen 1109946754@qq.com * @LastEditTime: 2025-04-19 19:00:36 * @FilePath: \command-center-dashboard\src\hooks\useTaskWayline\useTaskWayline.js * @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' import endPointImg from '@/assets/images/EndPointicon.png' import { analyzeKmzFile, removeTextKey, XMLToJSON } from '@/utils/cesium/kmz' import { flyVisual } from '@/utils/cesium/mapUtil' import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial' 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 () { let viewer = null let deviceOsdInfo = null // 解析kmz文件 const parsingFiles = async url => { const res = await analyzeKmzFile(`${url}?_t=${new Date().getTime()}`) const waylinesXML = await res.fileInfoObj['wpmz/waylines.wpml'] 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, viewer) drawWayline(waylinesXMLObj) } const drawWayline = lineObj => { const positions = lineObj.Placemark.map(item => { const [lon, lat] = item.Point.coordinates.split(',') return Cartesian3.fromDegrees(Number(lon), Number(lat)) }) removeEntitys() // 起点 viewer.entities.add({ id: 'drone-job-wayline-start', position: positions[0], billboard: { image: new Cesium.ConstantProperty(rwqfdImg), width: 70, height: 70, }, }) // 终点 viewer.entities.add({ id: 'drone-job-wayline-end', position: positions[positions.length - 1], billboard: { image: new Cesium.ConstantProperty(endPointImg), width: 30, height: 30, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 底部对齐 }, }) // 路径线 viewer.entities.add({ id: 'drone-job-wayline-polyline', polyline: { width: 4, positions: positions, material: new ImageTrailMaterial({ color: { alpha: 1, blue: 1, green: 1, red: 1 }, speed: 20, image: lineImg, repeat: { x: Math.floor(40), y: 1 }, }), clampToGround: false, }, }) } 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) return } let entity = viewer?.entities.add({ id: 'aircraftGltf', position, label: {}, model: { uri: aircraftGltf, // 或 .glb scale: 1.0, // 缩放比例 minimumPixelSize: 64, // 最小像素尺寸(保证模型远处可见) maximumScale: 128, // 最大缩放(可选) }, }) const homeDistance = Math.floor(host?.home_distance) || 0 const distance = 1 const arrivalTime = 1 const totalDistance = 1 const usedTime = 1 entity.label = new Cesium.LabelGraphics({ text: `距离机场水平距离:${homeDistance}m\n距离下一个航点:${Math.round( distance, )}m\n预计到达下一航点时间:${arrivalTime}\n本次飞行时间:${usedTime}\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, }) } 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 init = (v, wsInfo, taskDetails) => { console.log(v, wsInfo, taskDetails) viewer = v deviceOsdInfo = computed(() => wsInfo.value?.device_osd) watch(taskDetails, () => { if (taskDetails.value?.way_lines?.length) { parsingFiles(taskDetails.value.way_lines[0].url) } }, { immediate: true } ) 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() }) return { init, removeEntitys, mapEntityRemove, } }