吉安感知网项目-前端
shuishen
2026-02-03 89380e6260a75d1d3b94de687ebcc2f50d50659d
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<template>
    <div class="realTimeMap">
        <div id="currentTaskMap"></div>
    </div>
</template>
<script setup>
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'
import {
    basemapLayer0,
    basemapLayer1,
    basemapLayer2,
    basemapLayer3,
    polylineOptions0,
    polylineOptions1, polylineOptions2,
} from '@/const/leafletConst'
import 'leaflet-ant-path'
import droneIcon from '@/appDataSource/leafletMapIcon/drone-icon3.svg'
import sl from '@/appDataSource/leafletMapIcon/sl.svg'
import yx from '@/appDataSource/leafletMapIcon/yx.svg'
import { analysisPointLineKmz } from '@/views/RoutePlan/PointAirLine/pointWayLineUtils'
import startImg from '@/assets/images/signMachineNest/start.png'
import endPointImg from '@/assets/images/signMachineNest/end.png'
import { useAreaBoundary } from '@/hooks/useAreaBoundary'
import { useIdentificationAreaForApp } from '@ztzf/hooks'
 
const taskDetailsViewer = inject('taskDetailsViewer')
const showUpKeyPanel = inject('showUpKeyPanel')
const isMaxMap = inject('isMaxMap')
const taskDetails = inject('taskDetails')
const taskWayLineDetails = inject('taskWayLineDetails')
const currentWayLine = inject('currentWayLine')
const wsInfo = inject('wsInfo')
const isCurFlightTask = inject('isCurFlightTask')
let map = null
let markersLayer = null
let boundsGroup = []
const basemap0 = L.layerGroup([basemapLayer0, basemapLayer1])
const basemap1 = L.layerGroup([basemapLayer2, basemapLayer3])
const layers = [
    { src: sl, name: '天地图电子', key: 1, map: basemap0 },
    { src: yx, name: '天地图影像', key: 2, map: basemap1 },
]
let boundaryInstance = useAreaBoundary()
 
const {setArea,removeArea } = useIdentificationAreaForApp()
const initMap = async () => {
    map = L.map('currentTaskMap', {
        preferCanvas: true,
        crs: L.CRS.EPSG4326,
        zoomControl: false,
        attributionControl: false,
        doubleClickZoom: false,
        editable: true, //绘制控件
    }).setView([25.992338, 114.823254], 13)
    await boundaryInstance.initBoundary(map)
    markersLayer = L.layerGroup().addTo(map) // 创建一个标注层,便于管理和移除
    map.addLayer(layers[0].map)
    setArea(taskDetails.value.ai_types.split(','),map)
    // 渲染航线并且收集所有航线的边界
    boundsGroup = []
    const wayLines = taskWayLineDetails.value || []
    console.log(taskDetails?.value,'taskDetails?.value')
    if (taskDetails?.value?.rep_rule_type){
        const bounds = await renderRoutes(wayLines[0], 0)
        if (bounds) boundsGroup.push(bounds)
    }else{
        for (let i = 0; i < wayLines.length; i++) {
            const bounds = await renderRoutes(wayLines[i], i)
            if (bounds) boundsGroup.push(bounds)
        }
    }
    flyBounds()
}
 
// 合理显示范围
function flyBounds() {
// 统一调整视图
    if (boundsGroup.length > 0) {
        const combinedBounds = boundsGroup.reduce((acc, bounds) => acc.extend(bounds), L.latLngBounds(boundsGroup[0]))
        map.fitBounds(combinedBounds.pad(0.1))
    }
}
 
 
// 渲染航线
async function renderRoutes(row,index) {
    let { pointList } = await analysisPointLineKmz(row.url)
    const { latitude, longitude } = row || {}
    pointList[0] = { latitude, longitude }
    let points = pointList.map(item => [item.latitude, item.longitude])
    const colors = [polylineOptions0,polylineOptions1,polylineOptions2]
    let currentPolyline = L.polyline.antPath(points, colors[index]).addTo(markersLayer)
    const startIcon = L.icon({ iconUrl: startImg, iconSize: [30, 30] })
    const endIcon = L.icon({ iconUrl: endPointImg, iconSize: [30, 30] })
    L.marker(points[0], { icon: startIcon }).addTo(markersLayer)
    L.marker(points[points.length - 1], { icon: endIcon }).addTo(markersLayer)
    // map.fitBounds(currentPolyline.getBounds().pad(0.1))
 
    // 返回边界而不是直接调整地图视图
    return currentPolyline.getBounds()
}
 
 
 
const droneEntity = L.icon({ iconUrl: droneIcon, iconSize: [30, 30] })
let currentDronePosition = null
 
function updateDronePosition(deviceOsdInfo) {
    const { longitude, latitude } = deviceOsdInfo || {}
    if (!longitude) return
    if (!currentDronePosition) {
        currentDronePosition = L.marker([latitude, longitude], { icon: droneEntity }).addTo(markersLayer)
    }
    currentDronePosition.setLatLng([latitude, longitude])
}
 
watch(
    wsInfo,
    () => {
        isCurFlightTask.value && updateDronePosition(wsInfo.value?.device_osd?.data?.host)
    },
    { deep: true, immediate: true }
)
 
watch(isCurFlightTask,()=>{
    if (!isCurFlightTask.value){
        currentDronePosition.remove(); // 从地图上移除标记
        currentDronePosition = null;   // 清空引用,避免内存泄漏或误操作
    }
})
 
const removeMap = () => {}
 
function mapReset() {
    map.invalidateSize()
    flyBounds()
}
 
defineExpose({ mapReset })
 
onBeforeUnmount(() => {
    removeMap()
})
 
onMounted(() => {
    nextTick(() => {
        initMap()
    })
})
</script>
<style scoped lang="scss">
.realTimeMap {
    position: relative;
    z-index: 1;
    width: 100%;
    height: 100%;
 
    #currentTaskMap {
        width: 100%;
        height: 100%;
    }
}
</style>