From 8bb2f8984e684b6baa3b4cc335ac034192f58ea1 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Wed, 01 Apr 2026 15:43:28 +0800
Subject: [PATCH] feat: 恢复资源配置
---
applications/drone-command/src/views/resource/components/DrawPolygon.vue | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 312 insertions(+), 0 deletions(-)
diff --git a/applications/drone-command/src/views/resource/components/DrawPolygon.vue b/applications/drone-command/src/views/resource/components/DrawPolygon.vue
new file mode 100644
index 0000000..59428dd
--- /dev/null
+++ b/applications/drone-command/src/views/resource/components/DrawPolygon.vue
@@ -0,0 +1,312 @@
+<template>
+ <div></div>
+</template>
+
+<script setup>
+import * as Cesium from 'cesium';
+
+import { ElMessage } from 'element-plus';
+import { sdfwUpdate } from '@/api/home/territory';
+
+let curPolygonPosition = [];
+let savePolygonPosition = [];
+let curPolygon = null;
+let curPolygonEntity = null;
+let curPolygonObj = null;
+
+let menuPanel = null;
+let saveMenuPanel = null;
+
+const selectionIds = inject('selectionIds');
+const clearSelect = inject('clearSelect');
+const getTableList = inject('getTableList')
+
+const viewInstance = inject('viewInstance');
+const homeViewer = inject('homeViewer');
+watch(
+ () => selectionIds.value,
+ (newValue, oldValue) => {
+ if (newValue && oldValue && newValue !== oldValue) {
+ cancel();
+ }
+ }
+);
+function preventDefault(event) {
+ event.preventDefault();
+
+ return;
+}
+
+function init() {
+ // let draw = new Draw(homeViewer.value);
+ // draw.drawPlane();
+ curPolygon = new Cesium.PolygonHierarchy();
+ curPolygonEntity = new Cesium.Entity();
+ homeViewer.value.scene.globe.depthTestAgainstTerrain = true;
+
+ viewInstance.value.addLeftClickEvent(null, addPlanerPointEvent, 'drawCustomPolygon');
+ viewInstance.value.addRightClickEvent(null, addPlanarMenuEvent, 'drawCustomPolygon');
+ viewInstance.value.addMouseHandler(null, mouseMoveEvent, 'drawCustomPolygon');
+}
+
+function mouseMoveEvent(movement, viewer) {
+ const mouseInfo = viewInstance.value.getMouseInfoAll(movement.endPosition);
+
+ const { x, y } = mouseInfo.windowPosition;
+
+ if (!menuPanel) {
+ menuPanel = createMenuPanel();
+ viewer.container.appendChild(menuPanel);
+ }
+
+ menuPanel.style.transform = `translate3d(${x}px, ${y}px, 0)`;
+
+ if (
+ curPolygonObj &&
+ mouseInfo.surfacePosition &&
+ mouseInfo.surfacePosition != null &&
+ curPolygonPosition.length >= 1
+ ) {
+ curPolygonPosition.pop();
+ curPolygonPosition.push(mouseInfo.surfacePosition);
+
+ curPolygon.positions.pop();
+ curPolygon.positions.push(mouseInfo.surfacePosition);
+ }
+}
+
+function addPlanerPointEvent(click, pick) {
+ const { position } = click;
+
+ const mouseInfo = viewInstance.value.getMouseInfoAll(position);
+
+ if (mouseInfo.surfacePosition && mouseInfo.surfacePosition != null) drawCustomPolygon(mouseInfo);
+}
+
+function addPlanarMenuEvent(click, pick, viewer) {
+ if (savePolygonPosition.length <= 2) {
+ ElMessage.warning('当前绘制无法形成面,请继续绘制或取消绘制!!');
+
+ return;
+ }
+ const { position } = click;
+
+ const mouseInfo = viewInstance.value.getMouseInfoAll(position);
+
+ remove();
+ removeMenuPanel();
+
+ if (mouseInfo.surfacePosition && mouseInfo.surfacePosition != null) drawCustomPolygon(mouseInfo);
+
+ const { x, y } = position;
+ saveMenuPanel = createSaveMenuPanel();
+ saveMenuPanel.addEventListener('click', saveMenuClickEvent);
+ saveMenuPanel.style.transform = `translate3d(${x}px, ${y}px, 0)`;
+ viewer.container.appendChild(saveMenuPanel);
+}
+
+function createSaveMenuPanel() {
+ const menuPanel = document.createElement('div');
+ menuPanel.className = 'planar-menu-panel';
+
+ const arr = [
+ { title: '提交绘制', class: 'save-draw' },
+ { title: '重新绘制', class: 'anew-draw' },
+ ];
+
+ arr.forEach(item => {
+ const title = document.createElement('div');
+ title.innerText = item.title;
+ title.className = item.class;
+ menuPanel.appendChild(title);
+ });
+
+ return menuPanel;
+}
+
+function saveMenuClickEvent(e) {
+ const className = e.target.className;
+ if (className === 'save-draw') {
+ updatePolygon();
+ }
+ if (className == 'anew-draw') {
+ cancel();
+ }
+
+ removeSaveMenuPanel();
+}
+
+function removeSaveMenuPanel() {
+ if (saveMenuPanel) {
+ homeViewer.value.container?.removeChild(saveMenuPanel);
+ saveMenuPanel.removeEventListener('click', saveMenuClickEvent);
+ saveMenuPanel = null;
+ }
+}
+
+function createMenuPanel() {
+ const menuPanel = document.createElement('div');
+ menuPanel.className = 'planar-menu-panel';
+
+ const title = document.createElement('div');
+ title.innerText = '左击选择点位,右击结束';
+ title.className = 'proof-custom-add-polygon';
+ menuPanel.appendChild(title);
+
+ return menuPanel;
+}
+
+function removeMenuPanel() {
+ if (menuPanel) {
+ homeViewer.value.container?.removeChild(menuPanel);
+ menuPanel = null;
+ }
+}
+
+function drawCustomPolygon(point) {
+ if (curPolygonPosition.length == 0) {
+ curPolygonPosition.push(point.surfacePosition.clone());
+ curPolygon.positions.push(point.surfacePosition.clone());
+ }
+
+ savePolygonPosition.push(point.wgs84SurfacePosition);
+ curPolygonPosition.push(point.surfacePosition.clone());
+ curPolygon.positions.push(point.surfacePosition.clone());
+
+ if (!curPolygonObj) {
+ curPolygonEntity.polyline = {
+ width: 2,
+ material: Cesium.Color.WHITE,
+ clampToGround: true,
+ };
+
+ curPolygonEntity.polyline.positions = new Cesium.CallbackProperty(function () {
+ return curPolygonPosition;
+ }, false);
+
+ curPolygonEntity.polygon = {
+ hierarchy: new Cesium.CallbackProperty(function () {
+ return curPolygon;
+ }, false),
+
+ material: Cesium.Color.fromCssColorString('#00ffff').withAlpha(0.4),
+ clampToGround: false,
+ };
+ curPolygonEntity.name = 'customProofPolygon';
+
+ curPolygonEntity._id = 'customProofPolygon';
+ curPolygonObj = homeViewer.value.entities.add(curPolygonEntity);
+ }
+}
+
+function clearPlanar() {
+ homeViewer.value.entities.remove(curPolygonObj);
+ curPolygonObj = null;
+ curPolygon = null;
+ curPolygonEntity = null;
+ curPolygonPosition = [];
+ savePolygonPosition = [];
+}
+
+function remove() {
+ viewInstance.value.removeLeftClickEvent('drawCustomPolygon');
+ viewInstance.value.removeRightClickEvent('drawCustomPolygon');
+ viewInstance.value.removeMouseHandler('drawCustomPolygon');
+}
+
+const emit = defineEmits(['upDateDrawState',]);
+
+function updatePolygon() {
+ let polygon = savePolygonPosition.reduce((pre, cur) => {
+ pre.push(`${cur.lng} ${cur.lat}`);
+ return pre;
+ }, []);
+ polygon.push(polygon[0]);
+
+ // 接口
+ sdfwUpdate({
+ ids: selectionIds.value,
+ sdfw: `POLYGON((${polygon.join(',')}))`,
+ })
+ .then(res => {
+ if (selectionIds.value) {
+ emit('upDateDrawState')
+ selectionIds.value = null
+ clearSelect()
+ }
+
+ if (res.data.code !== 0) return ElMessage.error(res.message)
+ ElMessage.success('重新绘制图斑成功!!')
+ getTableList()
+ })
+ .catch(e => {
+ cancel()
+ })
+}
+
+
+function cancel() {
+ remove();
+ removeMenuPanel();
+ clearPlanar();
+ removeSaveMenuPanel();
+ init();
+}
+
+onMounted(() => {
+ document.addEventListener('contextmenu', preventDefault);
+
+ init();
+});
+
+onBeforeUnmount(() => {
+ document.removeEventListener('contextmenu', preventDefault);
+
+ remove();
+ removeMenuPanel();
+ removeSaveMenuPanel();
+ clearPlanar();
+
+ homeViewer.value.scene.globe.depthTestAgainstTerrain = false;
+});
+</script>
+
+<style lang="scss" scoped>
+p {
+ text-indent: 2em;
+ color: #ffffff;
+ font-size: 18px;
+}
+
+.export-btns {
+ margin-top: 44px;
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+
+ .el-button {
+ background-color: transparent !important;
+ }
+}
+.proof-custom-add-polygon {
+ position: absolute;
+ left: 20px;
+ background: rgba(0, 0, 0, 0.6);
+ white-space: nowrap;
+ border-radius: 4px;
+pointer-events: none;
+ &::after {
+ content: '';
+ position: absolute;
+ left: -3px;
+ top: calc(50% - 2px);
+ width: 0;
+ height: 0;
+ border-top: 4px solid rgba(0, 0, 0, 0.6);
+ border-left: 4px solid rgba(0, 0, 0, 0.6);
+ border-right: 4px solid transparent;
+ border-bottom: 4px solid transparent;
+ transform: rotate(-45deg);
+ }
+}
+</style>
--
Gitblit v1.9.3