From a2bb326dfbc6024916d360b89d021243f8502e33 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Fri, 12 Sep 2025 14:51:46 +0800
Subject: [PATCH] feat:空域录入相关调整
---
src/views/airspace/components/AirspaceMap.vue | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 158 insertions(+), 18 deletions(-)
diff --git a/src/views/airspace/components/AirspaceMap.vue b/src/views/airspace/components/AirspaceMap.vue
index cd2d1aa..89707c6 100644
--- a/src/views/airspace/components/AirspaceMap.vue
+++ b/src/views/airspace/components/AirspaceMap.vue
@@ -5,16 +5,35 @@
<div class="form-container">
<avue-form ref="formEle" :option="option" v-model="form"></avue-form>
</div>
+
<div class="map-container">
+ <div class="tool-tip warning" v-show="isShowWaringTip">
+ <span class="icon">
+ <el-icon>
+ <WarningFilled />
+ </el-icon>
+ </span>
+ <span>空域不支持交叉面,无法生成空域</span>
+ </div>
<div id="AirspaceMap" class="ztzf-cesium"></div>
+ </div>
+
+ <div class="btn-container">
+ <el-button icon="el-icon-check" type="primary" @click="handleSubmit">确定</el-button>
+ <el-button icon="el-icon-close" @click="dialogShow = false">取消</el-button>
</div>
</div>
</el-dialog>
</template>
<script setup>
+import _, { cloneDeep, throttle } from 'lodash'
+
import * as Cesium from 'cesium'
+import * as turf from '@turf/turf'
+import { DrawPolygon } from '@/utils/drawPolygon/drawPolygon'
import { PublicCesium } from '@/utils/cesium/publicCesium'
+import { ElMessageBox, ElMessage } from 'element-plus'
const props = defineProps({
title: {
@@ -23,6 +42,8 @@
},
})
+const emit = defineEmits(['submitClick'])
+
const dialogShow = defineModel('show')
const formEle = ref(null)
@@ -30,10 +51,11 @@
const option = ref({
submitBtn: false,
emptyBtn: false,
+ menuBtn: false,
column: [
{
label: '名称',
- prop: 'input',
+ prop: 'name',
type: 'input',
rules: [
{
@@ -46,7 +68,7 @@
{
label: '高度',
- prop: 'input',
+ prop: 'height',
type: 'input',
rules: [
{
@@ -59,18 +81,13 @@
{
label: '类型',
- prop: 'select',
+ prop: 'type',
type: 'select',
- dicData: [
- {
- label: '字典1',
- value: 0,
- },
- {
- label: '字典2',
- value: 1,
- },
- ],
+ dicUrl: `/blade-system/dict/dictionary?code=flow`,
+ props: {
+ label: 'dictValue',
+ value: 'dictKey',
+ },
rules: [
{
required: true,
@@ -97,21 +114,26 @@
},
{
- label: '备注',
- prop: 'input',
+ label: '管控原因',
+ prop: 'remark',
type: 'textarea',
span: 24,
rows: 1,
minRows: 1,
maxRows: 1,
- placeholder: '请输入备注',
+ placeholder: '请输入管控原因',
},
],
})
+let drawPolygonExample = null
let publicCesiumInstance = null
let viewer = null
// 地图
+const isShowWaringTip = ref(false)
+
+const curDrawPolygonData = ref([])
+
const initMap = () => {
if (!document.getElementById('AirspaceMap')) {
return
@@ -121,37 +143,155 @@
flatMode: false,
terrain: true,
layerMode: 4,
- contour: false,
+ contour: true,
+ flyToContour: true,
})
viewer = publicCesiumInstance.getViewer()
+ drawPolygonExample = new DrawPolygon()
+ drawPolygonExample.initHandler(viewer)
+
+ drawPolygonExample?.subscribe('getShowWaringTip', data => {
+ isShowWaringTip.value = 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) // 纬度
+
+ return {
+ lng: _.round(lng, 6),
+ lat: _.round(lat, 6),
+ }
+ })
+ })
}
watch(dialogShow, async (show) => {
if (show) {
await nextTick()
+ cesiumContextMenu()
initMap()
}
})
+const handleSubmit = () => {
+ if (ElMessage.value) {
+ ElMessage.warning('空域不支持交叉,请重新绘制或调整')
+ return
+ }
+
+ if (curDrawPolygonData.value.length === 0) {
+ ElMessage.warning('请绘制空域区域')
+ return
+ }
+
+ if (formEle.value) {
+ formEle.value.validate((valid, done, msg) => {
+ if (valid) {
+ let disposePolygon = curDrawPolygonData.value.map(i => [i.lng, i.lat])
+
+ let polygon = turf.polygon([
+ [
+ ...disposePolygon,
+ disposePolygon[0]
+ ]
+ ])
+
+ let area = turf.area(polygon)
+
+ emit('submitClick')
+ done()
+ } else {
+ return false
+ }
+ })
+ }
+}
+
const handleClose = () => {
+ isShowWaringTip.value = false
+ curDrawPolygonData.value = []
+ cesiumContextMenu(false)
+ drawPolygonExample?.destroy()
publicCesiumInstance?.viewerDestroy()
publicCesiumInstance = null
viewer = null
+ drawPolygonExample = null
form.value = {}
formEle.value.resetForm()
dialogShow.value = false
+}
+
+// 阻止右键默认行为
+const preventDefault = event => {
+ event.preventDefault()
+ return
+}
+
+const cesiumContextMenu = (isAdd = true) => {
+ let cesium = document.getElementById('AirspaceMap')
+ if (!cesium) return
+ if (isAdd) {
+ cesium.addEventListener('contextmenu', preventDefault)
+ } else {
+ cesium.removeEventListener('contextmenu', preventDefault)
+ }
}
</script>
<style scoped lang="scss">
.custom-container {
.map-container {
- height: 440px;
+ height: 620px;
#AirspaceMap {
+ position: relative;
width: 100%;
height: 100%;
+ overflow: hidden;
}
}
+
+ .btn-container {
+ margin-top: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+}
+
+.tool-tip {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: absolute;
+ width: 800px;
+ height: 64px;
+ font-family: Source Han Sans CN, Source Han Sans CN;
+ font-size: 18px;
+ color: #ffffff;
+
+ background: rgba(11, 31, 58, 0.7);
+ -moz-user-select: none;
+ -webkit-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ z-index: 9;
+}
+
+.warning {
+ top: 234px;
+ left: 50%;
+ transform: translateX(-50%);
+ color: #fff;
+ background: rgba(140, 0, 0, 0.4);
+
+ .icon {
+ display: flex;
+ align-items: center;
+ color: #ff1f1f;
+ }
}
</style>
--
Gitblit v1.9.3