From ea6e49ccb4d3bdb510ccf87844490823a96ebf08 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Fri, 12 Sep 2025 20:11:51 +0800
Subject: [PATCH] feat:空域录入完善,增删改查
---
src/views/airspace/components/AirspaceMap.vue | 145 ++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 126 insertions(+), 19 deletions(-)
diff --git a/src/views/airspace/components/AirspaceMap.vue b/src/views/airspace/components/AirspaceMap.vue
index 89707c6..828c467 100644
--- a/src/views/airspace/components/AirspaceMap.vue
+++ b/src/views/airspace/components/AirspaceMap.vue
@@ -6,7 +6,8 @@
<avue-form ref="formEle" :option="option" v-model="form"></avue-form>
</div>
- <div class="map-container">
+ <div class="map-container" v-loading="mapLoading" element-loading-text="地形初始化中,请稍后..."
+ element-loading-background="rgba(0, 0, 0, 0.7)">
<div class="tool-tip warning" v-show="isShowWaringTip">
<span class="icon">
<el-icon>
@@ -31,15 +32,33 @@
import * as Cesium from 'cesium'
import * as turf from '@turf/turf'
+
+import { getPointPositionsHeight } from '@/utils/cesium/mapUtil'
import { DrawPolygon } from '@/utils/drawPolygon/drawPolygon'
import { PublicCesium } from '@/utils/cesium/publicCesium'
import { ElMessageBox, ElMessage } from 'element-plus'
+
+import {
+ airspaceEnteringAdd,
+ airspaceEnteringUpdate
+} from '@/api/airspace/airspace'
+
const props = defineProps({
title: {
type: String,
default: '新增空域',
},
+
+ type: {
+ type: String,
+ default: 'add',
+ },
+
+ curEditRow: {
+ type: Object,
+ default: () => { },
+ }
})
const emit = defineEmits(['submitClick'])
@@ -47,7 +66,9 @@
const dialogShow = defineModel('show')
const formEle = ref(null)
-const form = ref({})
+const form = ref({
+ height: 120,
+})
const option = ref({
submitBtn: false,
emptyBtn: false,
@@ -70,23 +91,38 @@
label: '高度',
prop: 'height',
type: 'input',
+ value: 120,
+ min: 5,
+ max: 500,
+ type: 'number',
+ change ({ column, value }) {
+ drawPolygonExample?.setPolygonHeight?.(value)
+ },
rules: [
{
required: true,
message: '请输入高度',
trigger: 'blur'
+ },
+ {
+ pattern: /^(?:[5-9]|[1-9]\d|[1-4]\d{2}|500)$/, // 5-500
+ message: '高度需在5-500之间',
+ trigger: ['blur', 'change']
}
]
},
{
label: '类型',
- prop: 'type',
+ prop: 'flight_type',
type: 'select',
- dicUrl: `/blade-system/dict/dictionary?code=flow`,
+ dicUrl: `/drone-device-core/airspace/page?current=1&size=10000&typeName=`,
props: {
- label: 'dictValue',
- value: 'dictKey',
+ label: 'type_name',
+ value: 'id',
+ },
+ dicFormatter (res) {
+ return res.data.records
},
rules: [
{
@@ -98,7 +134,7 @@
},
{
label: '管控时段',
- prop: 'daterange',
+ prop: 'time_period',
type: 'daterange',
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
@@ -130,11 +166,13 @@
let publicCesiumInstance = null
let viewer = null
// 地图
+const mapLoading = ref(true)
+
const isShowWaringTip = ref(false)
const curDrawPolygonData = ref([])
-const initMap = () => {
+const initMap = async () => {
if (!document.getElementById('AirspaceMap')) {
return
}
@@ -145,24 +183,36 @@
layerMode: 4,
contour: true,
flyToContour: true,
+ terrainInit () {
+ setTimeout(async () => {
+ initDrawPolygon()
+ mapLoading.value = false
+ }, 1500)
+ }
})
+
viewer = publicCesiumInstance.getViewer()
+
drawPolygonExample = new DrawPolygon()
+
drawPolygonExample.initHandler(viewer)
- drawPolygonExample?.subscribe('getShowWaringTip', data => {
+ drawPolygonExample.subscribe('getShowWaringTip', data => {
isShowWaringTip.value = data
})
- drawPolygonExample?.subscribe('getPolygonPositions', data => {
+ drawPolygonExample.subscribe('getPolygonPositions', data => {
curDrawPolygonData.value = data.map(item => {
let cartographic = Cesium.Cartographic.fromCartesian(item)
+
let lng = Cesium.Math.toDegrees(cartographic.longitude) // 经度
let lat = Cesium.Math.toDegrees(cartographic.latitude) // 纬度
+ let height = cartographic.height
return {
lng: _.round(lng, 6),
lat: _.round(lat, 6),
+ height
}
})
})
@@ -170,11 +220,32 @@
watch(dialogShow, async (show) => {
if (show) {
+ if (props.type === 'edit') {
+ form.value = { ...props.curEditRow }
+ }
+
+ initDrawPolygon()
+
+ if (viewer) return
+
await nextTick()
cesiumContextMenu()
initMap()
}
})
+
+const initDrawPolygon = async () => {
+ if (props.type === 'edit' && drawPolygonExample) {
+ drawPolygonExample?.setPolygonHeight?.(props.curEditRow.height)
+
+ let polygon = JSON.parse(props.curEditRow.flight_range)
+
+ if (polygon.length > 0) {
+ const aslData = await getPointPositionsHeight(polygon, viewer)
+ drawPolygonExample?.initPolygon(viewer, aslData.map(item => ({ ...item, height: item.ASL })))
+ }
+ }
+}
const handleSubmit = () => {
if (ElMessage.value) {
@@ -201,8 +272,38 @@
let area = turf.area(polygon)
- emit('submitClick')
- done()
+ if (props.type === 'edit') {
+ airspaceEnteringUpdate({
+ id: props.curEditRow.id,
+ name: form.value.name,
+ flight_range: JSON.stringify(curDrawPolygonData.value),
+ height: form.value.height,
+ time_period: form.value.time_period.join('~'),
+ flight_type: form.value.flight_type,
+ remark: form.value.remark,
+ area: area
+ }).then(res => {
+ ElMessage.success('更新成功')
+ dialogShow.value = false
+ emit('submitClick')
+ done()
+ })
+ } else {
+ airspaceEnteringAdd({
+ name: form.value.name,
+ flight_range: JSON.stringify(curDrawPolygonData.value),
+ height: form.value.height,
+ time_period: form.value.time_period.join('~'),
+ flight_type: form.value.flight_type,
+ remark: form.value.remark,
+ area: area
+ }).then(res => {
+ ElMessage.success('新增成功')
+ dialogShow.value = false
+ emit('submitClick')
+ done()
+ })
+ }
} else {
return false
}
@@ -211,15 +312,12 @@
}
const handleClose = () => {
+ drawPolygonExample?.delPolygon()
isShowWaringTip.value = false
curDrawPolygonData.value = []
- cesiumContextMenu(false)
- drawPolygonExample?.destroy()
- publicCesiumInstance?.viewerDestroy()
- publicCesiumInstance = null
- viewer = null
- drawPolygonExample = null
- form.value = {}
+ form.value = {
+ height: 120
+ }
formEle.value.resetForm()
dialogShow.value = false
}
@@ -239,6 +337,15 @@
cesium.removeEventListener('contextmenu', preventDefault)
}
}
+
+onBeforeUnmount(() => {
+ drawPolygonExample?.destroy()
+ drawPolygonExample = null
+ cesiumContextMenu(false)
+ publicCesiumInstance?.viewerDestroy()
+ publicCesiumInstance = null
+ viewer = null
+})
</script>
<style scoped lang="scss">
--
Gitblit v1.9.3