cesium地图添加画空域的工具的编辑

This commit is contained in:
djhk 2025-10-15 17:49:29 +08:00 committed by zhulongchuan
parent e8b8d12623
commit 1a87cadb08
5 changed files with 910 additions and 11 deletions

View File

@ -177,7 +177,12 @@ const {
importAirspaceData, importAirspaceData,
importFromFile, importFromFile,
importFromGeoJSON, importFromGeoJSON,
getImportStatistics getImportStatistics,
isEditing,
editingDrawing,
startEditing,
finishEditing,
cancelEditing,
} = useDrawingManager(drawingTool); } = useDrawingManager(drawingTool);
@ -300,6 +305,19 @@ const showMessage = (message: string, type: 'success' | 'error' | 'info' = 'info
}; };
onMounted(() => { onMounted(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
if (isEditing.value) {
cancelEditing();
}
}
};
document.addEventListener('keydown', handleKeyDown);
onUnmounted(() => {
document.removeEventListener('keydown', handleKeyDown);
});
// //
setTimeout(() => { setTimeout(() => {
startCameraTracking(); startCameraTracking();

View File

@ -6,6 +6,29 @@
<div class="drawing-status" :class="{ active: isDrawing }"> <div class="drawing-status" :class="{ active: isDrawing }">
{{ getDrawingStatus() }} {{ getDrawingStatus() }}
</div> </div>
<div class="editing-status" v-if="isEditing">
编辑模式中
</div>
</div>
<!-- 编辑控制 -->
<div class="panel-section" v-if="isEditing">
<h4> 编辑控制</h4>
<div class="edit-controls">
<button @click="finishEditing" class="edit-btn save-btn">
💾 保存
</button>
<button @click="cancelEditing" class="edit-btn cancel-btn">
取消
</button>
<div class="edit-instructions">
<p><strong>操作说明:</strong></p>
<p> 拖动控制点调整空域形状</p>
<p> 圆形: 拖动红点移动圆心蓝点调整半径</p>
<p> 多边形: 拖动红点移动顶点</p>
<p> ESC 键取消编辑</p>
</div>
</div>
</div> </div>
<!-- 操作按钮组 --> <!-- 操作按钮组 -->
@ -41,7 +64,7 @@
<div class="panel-section"> <div class="panel-section">
<h4>绘制工具</h4> <h4>绘制工具</h4>
<div class="drawing-buttons"> <!-- <div class="drawing-buttons">
<button <button
class="drawing-btn circle-btn" class="drawing-btn circle-btn"
:class="{ active: isDrawing && currentDrawingType === 'circle' }" :class="{ active: isDrawing && currentDrawingType === 'circle' }"
@ -65,6 +88,29 @@
> >
取消绘制 取消绘制
</button> </button>
</div> -->
<div class="drawing-tools">
<button
@click="startCircleDrawing"
class="tool-btn circle-btn"
:disabled="isDrawing || isEditing"
>
绘制圆形
</button>
<button
@click="startPolygonDrawing"
class="tool-btn polygon-btn"
:disabled="isDrawing || isEditing"
>
🔷 绘制多边形
</button>
<button
@click="cancelDrawing"
class="tool-btn cancel-btn"
:disabled="!isDrawing"
>
取消绘制
</button>
</div> </div>
</div> </div>
@ -94,6 +140,9 @@
<button @click="handlePrintAllDrawingsInfo" class="action-btn" title="打印所有空域信息" :disabled="drawings.size === 0"> <button @click="handlePrintAllDrawingsInfo" class="action-btn" title="打印所有空域信息" :disabled="drawings.size === 0">
🖨 🖨
</button> </button>
<button @click="exportAllToJSON" class="icon-btn" title="导出全部">
📄
</button>
<button @click="clearAllDrawings" class="clear-btn" title="清除所有"> <button @click="clearAllDrawings" class="clear-btn" title="清除所有">
🗑 🗑
</button> </button>
@ -103,15 +152,18 @@
<div <div
v-for="[id, drawing] in drawings" v-for="[id, drawing] in drawings"
:key="id" :key="id"
:class="['drawing-item', { active: selectedDrawing === id }]" :class="['drawing-item', { active: selectedDrawing === id, editing: isEditing && editingDrawing?.id === id }]"
@click="selectDrawing(id)" @click="selectDrawing(id)"
> >
<div class="drawing-info"> <div class="drawing-info">
<div class="drawing-type"> <div class="drawing-type">
{{ drawing.type === 'circle' ? '⭕' : '🔷' }} <span class="icon">{{ drawing.type === 'circle' ? '⭕' : '🔷' }}</span>
{{ drawing.type === 'circle' ? '圆形空域' : '多边形空域' }} <span class="name">{{ drawing.type === 'circle' ? '圆形' : '多边形' }}</span>
<span v-if="isEditing && editingDrawing?.id === id" class="editing-badge">
编辑中
</span>
</div> </div>
<div class="drawing-props"> <div class="drawing-details">
<span v-if="drawing.type === 'circle'"> <span v-if="drawing.type === 'circle'">
半径: {{ (getCircleRadius(drawing) / 1000).toFixed(2) }}km 半径: {{ (getCircleRadius(drawing) / 1000).toFixed(2) }}km
</span> </span>
@ -121,7 +173,16 @@
</div> </div>
</div> </div>
<div class="drawing-actions"> <div class="drawing-actions">
<button
@click.stop="toggleEdit(id)"
class="action-btn edit-btn"
:class="{ active: isEditing && editingDrawing?.id === id }"
:title="isEditing && editingDrawing?.id === id ? '停止编辑' : '编辑'"
>
{{ isEditing && editingDrawing?.id === id ? '⏹️' : '✏️' }}
</button>
<button @click.stop="flyToDrawing(id)" title="飞向"></button> <button @click.stop="flyToDrawing(id)" title="飞向"></button>
<button @click.stop="exportDrawing(id)" class="action-btn" title="导出">📤</button>
<button @click.stop="handlePrintDrawingInfo(id)" title="打印信息">🖨</button> <button @click.stop="handlePrintDrawingInfo(id)" title="打印信息">🖨</button>
<button @click.stop="removeDrawing(id)" title="删除">🗑</button> <button @click.stop="removeDrawing(id)" title="删除">🗑</button>
</div> </div>
@ -291,6 +352,19 @@ const props = defineProps<{
drawingOptions: any; drawingOptions: any;
getDrawingStatus: () => string; getDrawingStatus: () => string;
getDrawingInfoText: () => string; getDrawingInfoText: () => string;
isEditing: boolean;
editingDrawing: any;
startCircleDrawing: () => void;
startPolygonDrawing: () => void;
cancelDrawing: () => void;
startEditing: (id: string) => void;
finishEditing: () => void;
cancelEditing: () => void;
selectDrawing: (id: string) => void;
removeDrawing: (id: string) => void;
flyToDrawing: (id: string) => void;
exportAllToJSON: () => void;
clearAllDrawings: () => void;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
@ -310,6 +384,10 @@ const emit = defineEmits<{
'print-all-drawings-info': []; 'print-all-drawings-info': [];
'print-drawing-info': [id: string]; 'print-drawing-info': [id: string];
'export-drawing-info': [id: string]; 'export-drawing-info': [id: string];
'export-drawing': [id: string];
'start-editing': [id: string];
'finish-editing': [];
'cancel-editing': [];
}>(); }>();
const activeTab = ref<'circle' | 'polygon'>('circle'); const activeTab = ref<'circle' | 'polygon'>('circle');
@ -327,9 +405,9 @@ const cancelDrawing = () => {
emit('cancel-drawing'); emit('cancel-drawing');
}; };
const selectDrawing = (id: string) => { // const selectDrawing = (id: string) => {
emit('select-drawing', id); // emit('select-drawing', id);
}; // };
const removeDrawing = (id: string) => { const removeDrawing = (id: string) => {
emit('remove-drawing', id); emit('remove-drawing', id);
@ -342,7 +420,9 @@ const clearAllDrawings = () => {
// //
const flyToDrawing = (id: string) => { const flyToDrawing = (id: string) => {
console.log('点击飞向空域按钮:', id); console.log('点击飞向空域按钮:', id);
emit('fly-to-drawing', id); // emit('fly-to-drawing', id);
console.log('点击飞向选中空域按钮');
emit('fly-to-selected-drawing',id);
}; };
@ -385,6 +465,59 @@ const flyToSelectedDrawing = () => {
emit('fly-to-selected-drawing'); emit('fly-to-selected-drawing');
}; };
//
const finishEditing = () => {
emit('finish-editing');
};
const cancelEditing = () => {
emit('cancel-editing');
};
//
const toggleEdit = (id: string) => {
if (props.isEditing && props.editingDrawing?.id === id) {
emit('finish-editing');
} else {
emit('start-editing', id);
}
};
const selectDrawing = (id: string) => {
if (props.isEditing) {
if (props.editingDrawing?.id !== id) {
emit('start-editing', id);
}
} else {
emit('select-drawing', id);
}
};
// //
// const toggleEdit = (id: string) => {
// if (props.isEditing && props.editingDrawing?.id === id) {
// props.finishEditing();
// } else {
// props.startEditing(id);
// }
// };
// //
// const selectDrawing = (id: string) => {
// if (props.isEditing) {
// //
// if (props.editingDrawing?.id !== id) {
// props.startEditing(id);
// }
// } else {
// props.selectDrawing(id);
// }
// };
//
const exportDrawing = (id: string) => {
emit('export-drawing', id);
};
// //
const getCircleRadius = (drawing: DrawingResult): number => { const getCircleRadius = (drawing: DrawingResult): number => {
if (drawing.type !== 'circle' || drawing.positions.length < 2) return 0; if (drawing.type !== 'circle' || drawing.positions.length < 2) return 0;
@ -593,5 +726,249 @@ const hexToColor = (hex: string): Cesium.Color => {
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.1);
} }
.drawing-tool-panel {
position: absolute;
top: 20px;
left: 20px;
background: rgba(42, 42, 42, 0.95);
color: white;
padding: 15px;
border-radius: 10px;
min-width: 280px;
max-height: 80vh;
overflow-y: auto;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.status-indicators {
display: flex;
flex-direction: column;
gap: 5px;
}
.drawing-status, .editing-status {
padding: 4px 8px;
border-radius: 12px;
font-size: 11px;
text-align: center;
}
.drawing-status {
background: rgba(255, 255, 255, 0.1);
color: #ccc;
}
.drawing-status.active {
background: rgba(24, 144, 255, 0.3);
color: #1890ff;
}
.editing-status {
background: rgba(255, 152, 0, 0.3);
color: #ff9800;
}
.edit-controls {
display: flex;
flex-direction: column;
gap: 10px;
}
.edit-btn {
padding: 8px 12px;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 6px;
color: white;
cursor: pointer;
font-size: 12px;
}
.save-btn {
background: rgba(76, 175, 80, 0.3);
}
.save-btn:hover {
background: rgba(76, 175, 80, 0.5);
}
.cancel-btn {
background: rgba(244, 67, 54, 0.3);
}
.cancel-btn:hover {
background: rgba(244, 67, 54, 0.5);
}
.edit-instructions {
background: rgba(255, 255, 255, 0.05);
padding: 10px;
border-radius: 6px;
font-size: 11px;
line-height: 1.4;
}
.edit-instructions p {
margin: 5px 0;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.icon-btn {
background: none;
border: none;
color: white;
cursor: pointer;
padding: 4px;
border-radius: 4px;
font-size: 14px;
}
.icon-btn:hover {
background: rgba(255, 255, 255, 0.1);
}
.drawings-list {
max-height: 300px;
overflow-y: auto;
}
.drawing-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px;
margin-bottom: 5px;
background: rgba(255, 255, 255, 0.05);
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
}
.drawing-item:hover {
background: rgba(255, 255, 255, 0.1);
}
.drawing-item.active {
background: rgba(24, 144, 255, 0.2);
border: 1px solid #1890ff;
}
.drawing-item.editing {
background: rgba(255, 152, 0, 0.2);
border: 1px solid #ff9800;
}
.drawing-info {
flex: 1;
}
.drawing-type {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
font-weight: bold;
margin-bottom: 4px;
}
.drawing-type .icon {
font-size: 14px;
}
.editing-badge {
background: #ff9800;
color: white;
padding: 2px 6px;
border-radius: 8px;
font-size: 10px;
}
.drawing-details {
font-size: 11px;
color: #ccc;
}
.drawing-actions {
display: flex;
gap: 4px;
}
.action-btn {
background: none;
border: none;
color: white;
cursor: pointer;
padding: 4px;
border-radius: 4px;
font-size: 12px;
}
.action-btn:hover {
background: rgba(255, 255, 255, 0.1);
}
.action-btn.edit-btn.active {
background: rgba(255, 152, 0, 0.3);
}
.action-btn.delete-btn:hover {
background: rgba(244, 67, 54, 0.2);
}
.drawing-tools {
display: flex;
flex-direction: column;
gap: 8px;
}
.tool-btn {
padding: 10px 12px;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 6px;
color: white;
cursor: pointer;
font-size: 12px;
transition: all 0.2s ease;
}
.tool-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.tool-btn:not(:disabled):hover {
transform: translateY(-1px);
}
.circle-btn {
background: rgba(255, 193, 7, 0.3);
}
.circle-btn:not(:disabled):hover {
background: rgba(255, 193, 7, 0.5);
}
.polygon-btn {
background: rgba(0, 188, 212, 0.3);
}
.polygon-btn:not(:disabled):hover {
background: rgba(0, 188, 212, 0.5);
}
.cancel-btn {
background: rgba(244, 67, 54, 0.3);
}
.cancel-btn:not(:disabled):hover {
background: rgba(244, 67, 54, 0.5);
}
/* ... 其他样式代码保持不变 ... */ /* ... 其他样式代码保持不变 ... */
</style> </style>

View File

@ -0,0 +1,388 @@
// src/utils/cesium/AirspaceEditor.ts
import * as Cesium from 'cesium';
export interface EditHandle {
id: string;
type: 'vertex' | 'center' | 'radius';
position: Cesium.Cartesian3;
entity: Cesium.Entity;
index?: number;
}
export class AirspaceEditor {
private viewer: Cesium.Viewer;
private handler: Cesium.ScreenSpaceEventHandler;
private isEditing: boolean = false;
private currentDrawing: any = null;
private editHandles: EditHandle[] = [];
private originalPositions: Cesium.Cartesian3[] = [];
constructor(viewer: Cesium.Viewer) {
this.viewer = viewer;
this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
}
/**
*
*/
startEditing(drawing: any): void {
console.log('开始编辑空域:', drawing);
if (this.isEditing) {
this.finishEditing();
}
this.isEditing = true;
this.currentDrawing = drawing;
this.originalPositions = [...drawing.positions];
// 创建编辑控制点
this.createEditHandles(drawing);
// 设置事件监听
this.setupEventListeners();
// 高亮显示编辑中的空域
this.highlightDrawing(true);
}
/**
*
*/
private createEditHandles(drawing: any): void {
this.clearEditHandles();
if (drawing.type === 'circle') {
this.createCircleHandles(drawing);
} else if (drawing.type === 'polygon') {
this.createPolygonHandles(drawing);
}
}
/**
*
*/
private createCircleHandles(drawing: any): void {
const center = drawing.positions[0];
// 圆心控制点
const centerHandle = this.createHandle(center, 'center', 'red', 15);
this.editHandles.push(centerHandle);
// 半径控制点
if (drawing.positions.length > 1) {
const radiusPoint = drawing.positions[1];
const radiusHandle = this.createHandle(radiusPoint, 'radius', 'blue', 12);
this.editHandles.push(radiusHandle);
} else {
// 如果没有半径点,创建一个默认的
const radius = drawing.properties?.radius || 1000;
const radiusPoint = this.calculateRadiusPoint(center, radius);
const radiusHandle = this.createHandle(radiusPoint, 'radius', 'blue', 12);
this.editHandles.push(radiusHandle);
drawing.positions[1] = radiusPoint;
}
}
/**
*
*/
private createPolygonHandles(drawing: any): void {
drawing.positions.forEach((position: Cesium.Cartesian3, index: number) => {
const handle = this.createHandle(position, 'vertex', 'red', 12, index);
this.editHandles.push(handle);
});
}
/**
*
*/
private createHandle(
position: Cesium.Cartesian3,
type: 'vertex' | 'center' | 'radius',
color: string,
size: number,
index?: number
): EditHandle {
const id = `handle_${type}_${Date.now()}_${Math.random()}`;
const entity = this.viewer.entities.add({
id: id,
position: position,
point: {
pixelSize: size,
color: Cesium.Color.fromCssColorString(color),
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY
}
});
return {
id,
type,
position,
entity,
index
};
}
/**
*
*/
private calculateRadiusPoint(center: Cesium.Cartesian3, radius: number): Cesium.Cartesian3 {
const cartographic = Cesium.Cartographic.fromCartesian(center);
const newLat = cartographic.latitude + (radius / 6371000.0);
return Cesium.Cartesian3.fromRadians(
cartographic.longitude,
newLat,
cartographic.height
);
}
/**
*
*/
private setupEventListeners(): void {
let draggedHandle: EditHandle | null = null;
// 鼠标按下
this.handler.setInputAction((event: any) => {
const pickedObject = this.viewer.scene.pick(event.position);
if (!pickedObject?.id) return;
// 检查是否点击了控制点
const handle = this.editHandles.find(h => h.entity === pickedObject.id);
if (handle) {
draggedHandle = handle;
this.viewer.scene.screenSpaceCameraController.enableInputs = false;
}
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
// 鼠标移动
this.handler.setInputAction((event: any) => {
if (!draggedHandle) return;
const newPosition = this.viewer.scene.pickPosition(event.endPosition);
if (!newPosition) return;
// 更新控制点位置
draggedHandle.position = newPosition;
draggedHandle.entity.position = newPosition;
// 更新空域几何
this.updateDrawingGeometry(draggedHandle, newPosition);
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 鼠标释放
this.handler.setInputAction(() => {
if (draggedHandle) {
this.viewer.scene.screenSpaceCameraController.enableInputs = true;
draggedHandle = null;
}
}, Cesium.ScreenSpaceEventType.LEFT_UP);
// ESC键取消
const escapeHandler = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
this.cancelEditing();
}
};
document.addEventListener('keydown', escapeHandler);
}
/**
*
*/
private updateDrawingGeometry(handle: EditHandle, newPosition: Cesium.Cartesian3): void {
if (!this.currentDrawing) return;
if (this.currentDrawing.type === 'circle') {
this.updateCircleGeometry(handle, newPosition);
} else if (this.currentDrawing.type === 'polygon') {
this.updatePolygonGeometry(handle, newPosition);
}
// 更新空域实体
this.updateDrawingEntity();
}
/**
*
*/
private updateCircleGeometry(handle: EditHandle, newPosition: Cesium.Cartesian3): void {
if (handle.type === 'center') {
// 移动圆心
this.currentDrawing.positions[0] = newPosition;
} else if (handle.type === 'radius') {
// 更新半径点
this.currentDrawing.positions[1] = newPosition;
}
}
/**
*
*/
private updatePolygonGeometry(handle: EditHandle, newPosition: Cesium.Cartesian3): void {
if (handle.type === 'vertex' && handle.index !== undefined) {
this.currentDrawing.positions[handle.index] = newPosition;
}
}
/**
*
*/
private updateDrawingEntity(): void {
if (!this.currentDrawing?.entity) return;
if (this.currentDrawing.type === 'circle') {
this.updateCircleEntity();
} else if (this.currentDrawing.type === 'polygon') {
this.updatePolygonEntity();
}
}
/**
*
*/
private updateCircleEntity(): void {
const center = this.currentDrawing.positions[0];
let radius = 1000;
if (this.currentDrawing.positions.length > 1) {
radius = Cesium.Cartesian3.distance(center, this.currentDrawing.positions[1]);
}
this.currentDrawing.entity.position = center;
if (this.currentDrawing.entity.ellipse) {
this.currentDrawing.entity.ellipse.semiMinorAxis = radius;
this.currentDrawing.entity.ellipse.semiMajorAxis = radius;
}
// 更新标签
if (this.currentDrawing.entity.label) {
this.currentDrawing.entity.label.text = `圆形空域\n半径: ${(radius / 1000).toFixed(2)}km`;
}
}
/**
*
*/
private updatePolygonEntity(): void {
if (this.currentDrawing.entity.polygon) {
this.currentDrawing.entity.polygon.hierarchy = new Cesium.PolygonHierarchy(
this.currentDrawing.positions
);
}
}
/**
*
*/
private highlightDrawing(highlight: boolean): void {
if (!this.currentDrawing?.entity) return;
const color = highlight ? Cesium.Color.RED : Cesium.Color.YELLOW;
if (this.currentDrawing.entity.ellipse) {
this.currentDrawing.entity.ellipse.outlineColor = color;
this.currentDrawing.entity.ellipse.outlineWidth = highlight ? 4 : 2;
} else if (this.currentDrawing.entity.polygon) {
this.currentDrawing.entity.polygon.outlineColor = color;
this.currentDrawing.entity.polygon.outlineWidth = highlight ? 4 : 2;
}
}
/**
*
*/
finishEditing(): void {
if (!this.isEditing) return;
console.log('完成编辑');
this.cleanup();
}
/**
*
*/
cancelEditing(): void {
if (!this.isEditing) return;
console.log('取消编辑');
// 恢复原始位置
if (this.currentDrawing) {
this.currentDrawing.positions = [...this.originalPositions];
this.updateDrawingEntity();
}
this.cleanup();
}
/**
*
*/
private cleanup(): void {
this.clearEditHandles();
this.removeEventListeners();
this.highlightDrawing(false);
this.isEditing = false;
this.currentDrawing = null;
this.originalPositions = [];
}
/**
*
*/
private clearEditHandles(): void {
this.editHandles.forEach(handle => {
this.viewer.entities.remove(handle.entity);
});
this.editHandles = [];
}
/**
*
*/
private removeEventListeners(): void {
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP);
// 移除ESC键监听
document.removeEventListener('keydown', this.escapeHandler);
}
/**
* ESC键处理函数
*/
private escapeHandler = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
this.cancelEditing();
}
};
/**
*
*/
getEditingState(): { isEditing: boolean; currentDrawing: any } {
return {
isEditing: this.isEditing,
currentDrawing: this.currentDrawing
};
}
/**
*
*/
destroy(): void {
this.cleanup();
this.handler.destroy();
}
}

View File

@ -50,7 +50,10 @@ export interface DrawingResult {
info: DrawingInfo; // 新增信息字段 info: DrawingInfo; // 新增信息字段
} }
import { AirspaceEditor } from './AirspaceEditor';
export class DrawingTool { export class DrawingTool {
private airspaceEditor: AirspaceEditor;
private viewer: Cesium.Viewer; private viewer: Cesium.Viewer;
private handler: Cesium.ScreenSpaceEventHandler; private handler: Cesium.ScreenSpaceEventHandler;
private entities: Cesium.EntityCollection; private entities: Cesium.EntityCollection;
@ -83,6 +86,7 @@ export class DrawingTool {
this.viewer = viewer; this.viewer = viewer;
this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
this.entities = viewer.entities; this.entities = viewer.entities;
this.airspaceEditor = new AirspaceEditor(viewer);
// 初始化点击事件监听 // 初始化点击事件监听
this.initClickHandler(); this.initClickHandler();
@ -262,6 +266,55 @@ export class DrawingTool {
return perimeter; return perimeter;
} }
/**
*
*/
startEditing(drawingId: string): void {
console.log('开始编辑空域:', drawingId);
const drawing = this.drawingEntities.get(drawingId);
if (!drawing) {
console.error('未找到空域:', drawingId);
return;
}
this.airspaceEditor.startEditing(drawing);
}
/**
*
*/
finishEditing(): void {
this.airspaceEditor.finishEditing();
}
/**
*
*/
cancelEditing(): void {
this.airspaceEditor.cancelEditing();
}
/**
*
*/
getEditingState(): { isEditing: boolean; currentDrawing: any } {
return this.airspaceEditor.getEditingState();
}
/**
*
*/
isEditing(): boolean {
return this.airspaceEditor.getEditingState().isEditing;
}
/**
*
*/
getCurrentEditingDrawing(): any {
return this.airspaceEditor.getEditingState().currentDrawing;
}

View File

@ -8,6 +8,63 @@ export function useDrawingManager(drawingTool: any) { // 修改参数类型为 a
const drawings = reactive(new Map<string, DrawingResult>()); const drawings = reactive(new Map<string, DrawingResult>());
const selectedDrawing = ref<string | null>(null); const selectedDrawing = ref<string | null>(null);
const drawingInfo = ref<DrawingInfo | null>(null); const drawingInfo = ref<DrawingInfo | null>(null);
const isEditing = ref(false);
const editingDrawing = ref<any>(null);
/**
*
*/
const startEditing = (drawingId: string): void => {
console.log('开始编辑:', drawingId);
const tool = getTool();
if (!tool) {
console.error('绘图工具未初始化');
return;
}
tool.startEditing(drawingId);
// 更新状态
const editingState = tool.getEditingState();
isEditing.value = editingState.isEditing;
editingDrawing.value = editingState.currentDrawing;
};
/**
*
*/
const finishEditing = (): void => {
const tool = getTool();
if (tool) {
tool.finishEditing();
isEditing.value = false;
editingDrawing.value = null;
}
};
/**
*
*/
const cancelEditing = (): void => {
const tool = getTool();
if (tool) {
tool.cancelEditing();
isEditing.value = false;
editingDrawing.value = null;
}
};
/**
*
*/
const getEditingState = () => {
const tool = getTool();
if (tool) {
return tool.getEditingState();
}
return { isEditing: false, currentDrawing: null };
};
// 绘图选项 // 绘图选项
const drawingOptions = reactive<{ const drawingOptions = reactive<{
@ -571,6 +628,12 @@ export function useDrawingManager(drawingTool: any) { // 修改参数类型为 a
importAirspaceData, importAirspaceData,
importFromGeoJSON, importFromGeoJSON,
importFromFile, importFromFile,
getImportStatistics getImportStatistics,
isEditing,
editingDrawing,
startEditing,
finishEditing,
cancelEditing,
getEditingState
}; };
} }