无人机管理后台前端(已迁走)
张含笑
2025-06-10 e4c7bca105e64c047fbcd6bbb53ff5d32b0c5fd6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<template>
    <div id="deviceJobDetailsMap" class="ztzf-cesium" />
</template>
<script setup>
import * as Cesium from 'cesium'
import { Cartesian3, Terrain, Viewer } from 'cesium'
import { analyzeKmzFile, removeTextKey, XMLToJSON } from '@/utils/cesium/kmz'
import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial'
import lineImg from '@/assets/images/task/arrow-right-blue.png'
// import rwqfdImg from '@/assets/images/task/rwqfd.png'
import rwqfdImg from '@/assets/map_images/Startingpointicon.png'
import endPointImg from '@/assets/images/task/EndPointicon.png'
import { flyVisual } from '@/utils/cesium/mapUtil'
import { PublicCesium } from '@/utils/cesium/publicCesium'
 
const props = defineProps(['detailsData'])
 
let viewer = null
const initMap = () => {
    viewer = new PublicCesium({ dom: 'deviceJobDetailsMap' }).getViewer()
}
 
// 渲染线和点
const renderingLine = (lineObj,startPoint) => {
    const positions = lineObj.Placemark.map(item => {
        const [lon, lat] = item.Point.coordinates.split(',')
        return Cartesian3.fromDegrees(Number(lon), Number(lat))
    })
    // 向前插入起飞点
    positions.unshift(Cartesian3.fromDegrees(startPoint[0], startPoint[1]))
    // 起点
    viewer.entities.add({
        position: positions[0],
        billboard: {
            image: new Cesium.ConstantProperty(rwqfdImg),
            width: 30,
            height: 30,
        },
    })
    // 终点
    viewer.entities.add({
        position: positions[positions.length - 1],
        billboard: {
            image: new Cesium.ConstantProperty(endPointImg),
            width: 30,
            height: 30,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 底部对齐
        },
    })
    // 路径线
    viewer.entities.add({
        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,
        },
    })
}
 
// 异步解析kmz文件
const analysis = async item => {
    return new Promise(async resolve => {
        const res = await analyzeKmzFile(`${item.url}?_t=${new Date().getTime()}`)
        const waylinesXML = await res.fileInfoObj['wpmz/waylines.wpml']
        const waylinesXMLJSON = XMLToJSON(waylinesXML)?.['Document']
        const waylinesXMLObj = removeTextKey(waylinesXMLJSON.Folder)
        resolve({ waylinesXMLObj, takeOffRefPoint:[item.longitude,item.latitude] })
    })
}
 
// 绘制线和飞行
const drawLine = async () => {
    const res = await Promise.all(props.detailsData.way_lines.map(item => analysis(item)))
    // 渲染线
    res.forEach(({ waylinesXMLObj,takeOffRefPoint }) => renderingLine(waylinesXMLObj,takeOffRefPoint))
    // 收集所有起飞点
    const allTakeOffRefPoint = props.detailsData.way_lines.map(item => ([item.longitude,item.latitude]))
    // 收集所有点包括起飞点
    const allPoint = res.flatMap(({ waylinesXMLObj }) => waylinesXMLObj.Placemark)
        .map(item => item.Point.coordinates.split(',')).concat(allTakeOffRefPoint)
    flyVisual(allPoint, viewer,4)
}
 
const removeMap = () => {
    viewer.entities.removeAll()
    viewer.destroy()
}
 
watch(
    () => props.detailsData,
    (newValue, oldValue) => {
        if (newValue) {
            drawLine()
        }
    }
)
 
onBeforeUnmount(() => {
    removeMap()
})
 
onMounted(() => {
    nextTick(() => {
        initMap()
    })
})
</script>
<style scoped lang="scss">
#deviceJobDetailsMap {
    height: 100%;
}
</style>