cesium地图空域的导入导出及定位

This commit is contained in:
zhulongchuan 2025-10-17 16:50:43 +08:00
parent 838d0878aa
commit e8b8d12623
5 changed files with 1094 additions and 7 deletions

1
auto-imports.d.ts vendored
View File

@ -2,7 +2,6 @@
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const ElMessage: typeof import('element-plus/es')['ElMessage']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const customRef: typeof import('vue')['customRef']

View File

@ -74,6 +74,17 @@
@print-drawing-info="handlePrintDrawingInfo"
@export-drawing-info="handleExportDrawingInfo"
/>
<!-- 导入工具面板 -->
<ImportToolPanel
v-if="isInitialized"
:import-from-file="importFromFile"
:import-airspace-data="importAirspaceData"
:get-import-statistics="getImportStatistics"
@import-complete="handleImportComplete"
/>
</div>
</template>
@ -88,6 +99,7 @@ import { useDrawingManager } from './components/useDrawingManager';
import ModelControlPanel from './ModelControlPanel.vue';
import CoordinatePickerPanel from './CoordinatePickerPanel.vue';
import DrawingToolPanel from './DrawingToolPanel.vue';
import ImportToolPanel from './ImportToolPanel.vue';
const cesiumContainer = ref<HTMLElement>();
@ -161,7 +173,11 @@ const {
printSelectedDrawingInfo,
printAllDrawingsInfo,
printDrawingInfo,
exportSelectedDrawingAsText
exportSelectedDrawingAsText,
importAirspaceData,
importFromFile,
importFromGeoJSON,
getImportStatistics
} = useDrawingManager(drawingTool);
@ -267,6 +283,22 @@ const flyToSelectedDrawing = () => {
// };
//
const handleImportComplete = (result: any) => {
console.log('导入完成:', result);
//
if (result.success) {
showMessage(`成功导入 ${result.importedIds.length} 个空域`, 'success');
} else {
showMessage('导入失败', 'error');
}
};
//
const showMessage = (message: string, type: 'success' | 'error' | 'info' = 'info') => {
// ...
};
onMounted(() => {
//
setTimeout(() => {

View File

@ -0,0 +1,532 @@
<!-- src/components/ImportToolPanel.vue -->
<template>
<div class="import-tool-panel">
<div class="panel-header">
<h3>📥 空域导入工具</h3>
</div>
<div class="panel-section">
<h4>文件导入</h4>
<div class="file-import">
<input
type="file"
ref="fileInput"
@change="handleFileSelect"
accept=".json,.geojson"
style="display: none"
/>
<button @click="triggerFileInput" class="import-btn file-btn">
📁 选择文件导入
</button>
<div class="file-info" v-if="selectedFile">
<span>已选择: {{ selectedFile.name }}</span>
<button @click="clearFile" class="clear-file-btn">×</button>
</div>
</div>
<div class="import-options">
<label class="option-checkbox">
<input type="checkbox" v-model="importOptions.autoZoom" />
导入后自动缩放
</label>
<label class="option-checkbox">
<input type="checkbox" v-model="importOptions.mergeExisting" />
合并现有空域
</label>
</div>
<button
@click="executeFileImport"
class="import-btn execute-btn"
:disabled="!selectedFile || isImporting"
>
{{ isImporting ? '⏳ 导入中...' : '🚀 执行导入' }}
</button>
</div>
<div class="panel-section">
<h4>数据导入</h4>
<div class="data-import">
<textarea
v-model="jsonInput"
placeholder="在此粘贴JSON或GeoJSON数据..."
class="json-input"
rows="8"
></textarea>
<button
@click="executeJsonImport"
class="import-btn json-btn"
:disabled="!jsonInput.trim() || isImporting"
>
{{ isImporting ? '⏳ 导入中...' : '📋 导入JSON数据' }}
</button>
</div>
</div>
<div class="panel-section" v-if="importResult">
<h4>导入结果</h4>
<div class="import-result" :class="importResult.success ? 'success' : 'error'">
<div class="result-icon">
{{ importResult.success ? '✅' : '❌' }}
</div>
<div class="result-content">
<div class="result-message">{{ importResult.message }}</div>
<div v-if="importResult.importedIds" class="result-details">
导入ID: {{ importResult.importedIds.join(', ') }}
</div>
<div v-if="importResult.statistics" class="result-statistics">
圆形: {{ importResult.statistics.circles }},
多边形: {{ importResult.statistics.polygons }},
总计: {{ importResult.statistics.total }}
</div>
</div>
</div>
</div>
<div class="panel-section">
<h4>示例数据</h4>
<div class="sample-data">
<button @click="loadSampleData" class="sample-btn">
🎯 加载示例数据
</button>
<div class="sample-description">
加载示例圆形和多边形空域数据用于测试
</div>
</div>
</div>
<div class="panel-section help-section">
<h4>支持格式</h4>
<ul class="format-list">
<li> <strong>JSON数组</strong>: 包含空域对象的数组</li>
<li> <strong>GeoJSON</strong>: 标准的GeoJSON格式</li>
<li> <strong>文件类型</strong>: .json, .geojson</li>
</ul>
<h4>数据格式示例</h4>
<pre class="format-example">{{ formatExample }}</pre>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue';
const props = defineProps<{
importFromFile: (file: File, options: any) => Promise<string[]>;
importAirspaceData: (data: any[], options: any) => string[];
getImportStatistics: () => { total: number; circles: number; polygons: number };
}>();
const emit = defineEmits<{
'import-complete': [result: any];
}>();
const fileInput = ref<HTMLInputElement>();
const selectedFile = ref<File | null>(null);
const jsonInput = ref('');
const isImporting = ref(false);
const importResult = ref<any>(null);
const importOptions = ref({
autoZoom: true,
mergeExisting: false
});
//
const triggerFileInput = () => {
fileInput.value?.click();
};
//
const handleFileSelect = (event: Event) => {
const target = event.target as HTMLInputElement;
if (target.files && target.files[0]) {
selectedFile.value = target.files[0];
}
};
//
const clearFile = () => {
selectedFile.value = null;
if (fileInput.value) {
fileInput.value.value = '';
}
};
//
const executeFileImport = async () => {
if (!selectedFile.value) return;
isImporting.value = true;
importResult.value = null;
try {
const importedIds = await props.importFromFile(selectedFile.value, importOptions.value);
const statistics = props.getImportStatistics();
importResult.value = {
success: true,
message: `成功导入 ${importedIds.length} 个空域`,
importedIds,
statistics
};
emit('import-complete', importResult.value);
} catch (error) {
importResult.value = {
success: false,
message: `导入失败: ${error}`
};
} finally {
isImporting.value = false;
}
};
// JSON
const executeJsonImport = () => {
if (!jsonInput.value.trim()) return;
isImporting.value = true;
importResult.value = null;
try {
const data = JSON.parse(jsonInput.value);
const importedIds = props.importAirspaceData(data, importOptions.value);
const statistics = props.getImportStatistics();
importResult.value = {
success: true,
message: `成功导入 ${importedIds.length} 个空域`,
importedIds,
statistics
};
emit('import-complete', importResult.value);
} catch (error) {
importResult.value = {
success: false,
message: `JSON解析失败: ${error}`
};
} finally {
isImporting.value = false;
}
};
//
const loadSampleData = () => {
const sampleData = [
{
id: 'sample_circle_1',
type: 'circle',
coordinates: {
center: {
longitude: 106.5516,
latitude: 29.5630,
height: 500
},
radius: 2000
},
properties: {
name: '示例圆形空域1',
color: '#FF6B6B',
outlineColor: '#C44D4D'
}
},
{
id: 'sample_circle_2',
type: 'circle',
coordinates: {
center: {
longitude: 106.5716,
latitude: 29.5730,
height: 500
},
radius: 1500
},
properties: {
name: '示例圆形空域2',
color: '#4ECDC4',
outlineColor: '#3AA39C'
}
},
{
id: 'sample_polygon_1',
type: 'polygon',
coordinates: [
{ longitude: 106.5400, latitude: 29.5500, height: 300 },
{ longitude: 106.5600, latitude: 29.5500, height: 300 },
{ longitude: 106.5600, latitude: 29.5700, height: 300 },
{ longitude: 106.5400, latitude: 29.5700, height: 300 }
],
properties: {
name: '示例多边形空域1',
color: '#45B7D1',
outlineColor: '#368EA6'
}
}
];
jsonInput.value = JSON.stringify(sampleData, null, 2);
};
//
const formatExample = computed(() => {
return `{
"id": "airspace_001",
"type": "circle",
"coordinates": {
"center": {
"longitude": 106.5516,
"latitude": 29.5630,
"height": 500
},
"radius": 2000
},
"properties": {
"name": "禁飞区",
"color": "#FF0000"
}
}`;
});
</script>
<style scoped>
.import-tool-panel {
position: absolute;
top: 20px;
right: 220px;
background: rgba(42, 42, 42, 0.95);
color: white;
padding: 15px;
border-radius: 10px;
min-width: 320px;
max-height: 80vh;
overflow-y: auto;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.panel-header h3 {
margin: 0 0 15px 0;
font-size: 16px;
color: #fff;
}
.panel-section {
margin-bottom: 20px;
}
.panel-section h4 {
margin: 0 0 12px 0;
font-size: 14px;
color: #ccc;
}
.file-import {
display: flex;
flex-direction: column;
gap: 10px;
}
.import-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.3s ease;
}
.import-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.import-btn:not(:disabled):hover {
transform: translateY(-1px);
}
.file-btn {
background: rgba(76, 175, 80, 0.3);
}
.file-btn:hover:not(:disabled) {
background: rgba(76, 175, 80, 0.5);
}
.json-btn {
background: rgba(156, 39, 176, 0.3);
}
.json-btn:hover:not(:disabled) {
background: rgba(156, 39, 176, 0.5);
}
.execute-btn {
background: rgba(255, 152, 0, 0.3);
}
.execute-btn:hover:not(:disabled) {
background: rgba(255, 152, 0, 0.5);
}
.file-info {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 12px;
background: rgba(255, 255, 255, 0.05);
border-radius: 4px;
font-size: 12px;
}
.clear-file-btn {
background: none;
border: none;
color: #ff4d4f;
cursor: pointer;
font-size: 16px;
padding: 0 4px;
}
.import-options {
display: flex;
flex-direction: column;
gap: 8px;
margin: 10px 0;
}
.option-checkbox {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: #ccc;
cursor: pointer;
}
.option-checkbox input {
margin: 0;
}
.data-import {
display: flex;
flex-direction: column;
gap: 10px;
}
.json-input {
padding: 10px;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 6px;
color: white;
font-family: 'Courier New', monospace;
font-size: 11px;
resize: vertical;
}
.json-input::placeholder {
color: #888;
}
.import-result {
display: flex;
align-items: flex-start;
gap: 10px;
padding: 12px;
border-radius: 6px;
font-size: 12px;
}
.import-result.success {
background: rgba(76, 175, 80, 0.2);
border: 1px solid rgba(76, 175, 80, 0.4);
}
.import-result.error {
background: rgba(244, 67, 54, 0.2);
border: 1px solid rgba(244, 67, 54, 0.4);
}
.result-icon {
font-size: 16px;
}
.result-content {
flex: 1;
}
.result-message {
font-weight: bold;
margin-bottom: 4px;
}
.result-details,
.result-statistics {
font-size: 11px;
color: #ccc;
margin-top: 2px;
}
.sample-data {
display: flex;
flex-direction: column;
gap: 8px;
}
.sample-btn {
padding: 8px 12px;
background: rgba(33, 150, 243, 0.3);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 6px;
color: white;
cursor: pointer;
font-size: 12px;
}
.sample-btn:hover {
background: rgba(33, 150, 243, 0.5);
}
.sample-description {
font-size: 11px;
color: #ccc;
line-height: 1.4;
}
.help-section {
border-top: 1px solid rgba(255, 255, 255, 0.1);
padding-top: 15px;
}
.format-list {
list-style: none;
padding: 0;
margin: 0 0 15px 0;
}
.format-list li {
font-size: 11px;
margin-bottom: 6px;
color: #ccc;
line-height: 1.4;
}
.format-list strong {
color: #fff;
}
.format-example {
background: rgba(0, 0, 0, 0.3);
padding: 10px;
border-radius: 4px;
font-size: 10px;
color: #fff;
overflow-x: auto;
white-space: pre-wrap;
word-wrap: break-word;
}
</style>

View File

@ -19,7 +19,11 @@ export interface PolygonOptions extends DrawingOptions {
closePath?: boolean;
}
export interface ImportOptions {
autoZoom?: boolean;
mergeExisting?: boolean;
coordinateSystem?: 'wgs84' | 'gcj02' | 'bd09';
}
export interface DrawingInfo {
id: string;
@ -64,7 +68,7 @@ export class DrawingTool {
fill: true,
classificationType: Cesium.ClassificationType.BOTH,
height: 0,
extrudedHeight: 1000
extrudedHeight: 0
};
private drawingCallbacks: {
@ -668,6 +672,467 @@ export class DrawingTool {
// }
/**
*
*/
importAirspaceData(data: any[], options: ImportOptions = {}): string[] {
console.log('=== 开始导入空域数据 ===');
console.log('导入数据:', data);
console.log('导入选项:', options);
const defaultOptions: ImportOptions = {
autoZoom: true,
mergeExisting: false,
coordinateSystem: 'wgs84'
};
const mergedOptions = { ...defaultOptions, ...options };
const importedIds: string[] = [];
try {
// 如果不合并现有数据,先清除所有
if (!mergedOptions.mergeExisting) {
this.clearAllDrawings();
}
// 处理每个空域数据
data.forEach((item, index) => {
try {
const entity = this.importSingleAirspace(item, mergedOptions);
if (entity) {
importedIds.push(item.id || `imported_${Date.now()}_${index}`);
}
} catch (error) {
console.error(`导入第 ${index + 1} 个空域时发生错误:`, error);
}
});
console.log(`✅ 成功导入 ${importedIds.length} 个空域`);
// 自动缩放显示所有导入的空域
if (mergedOptions.autoZoom && importedIds.length > 0) {
setTimeout(() => {
this.zoomToImportedAirspaces(importedIds);
}, 500);
}
return importedIds;
} catch (error) {
console.error('❌ 导入空域数据时发生错误:', error);
return [];
}
}
/**
*
*/
private importSingleAirspace(data: any, options: ImportOptions): Cesium.Entity | null {
try {
// 验证数据
if (!this.validateAirspaceData(data)) {
console.error('空域数据验证失败:', data);
return null;
}
const { type, coordinates, properties = {} } = data;
const id = data.id || `imported_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
console.log(`导入空域 ${id}, 类型: ${type}`);
let positions: Cesium.Cartesian3[];
let entity: Cesium.Entity;
if (type === 'circle') {
entity = this.importCircleAirspace(id, coordinates, properties, options);
} else if (type === 'polygon') {
entity = this.importPolygonAirspace(id, coordinates, properties, options);
} else {
console.error('不支持的空域类型:', type);
return null;
}
if (entity) {
// 生成绘图信息
const drawingInfo = this.generateDrawingInfo({
id,
type: type as 'circle' | 'polygon',
positions,
entity,
properties: {
...properties,
options: properties.options || this.defaultOptions,
area: properties.area || 0
}
} as DrawingResult);
// 保存到绘图实体集合
const drawingResult: DrawingResult = {
id,
type: type as 'circle' | 'polygon',
positions,
entity,
properties: {
...properties,
imported: true, // 标记为导入的空域
importTime: new Date().toISOString()
},
info: {
...drawingInfo,
area: properties.area || this.calculateArea(positions, type as 'circle' | 'polygon')
}
};
this.drawingEntities.set(id, drawingResult);
console.log(`✅ 成功导入空域: ${id}`);
}
return entity;
} catch (error) {
console.error('导入单个空域时发生错误:', error);
return null;
}
}
/**
*
*/
private importCircleAirspace(
id: string,
coordinates: any,
properties: any,
options: ImportOptions
): Cesium.Entity {
const { center, radius } = coordinates;
// 坐标转换
const convertedCenter = this.convertCoordinates(
center.longitude,
center.latitude,
center.height || 0,
options.coordinateSystem
);
const centerCartesian = Cesium.Cartesian3.fromDegrees(
convertedCenter.longitude,
convertedCenter.latitude,
convertedCenter.height
);
const positions = [centerCartesian];
if (radius > 0) {
const edgePoint = this.calculateCircleEdgePoint(convertedCenter, radius);
positions.push(edgePoint);
}
const entityOptions = {
color: properties.color ? Cesium.Color.fromCssColorString(properties.color) : this.defaultOptions.color,
outlineColor: properties.outlineColor ? Cesium.Color.fromCssColorString(properties.outlineColor) : this.defaultOptions.outlineColor,
outlineWidth: properties.outlineWidth || this.defaultOptions.outlineWidth,
height: properties.height || this.defaultOptions.height,
extrudedHeight: properties.extrudedHeight || this.defaultOptions.extrudedHeight
};
return this.createCircleEntity(id, positions, entityOptions);
}
/**
*
*/
private importPolygonAirspace(
id: string,
coordinates: any,
properties: any,
options: ImportOptions
): Cesium.Entity {
const positions = coordinates.map((coord: any) => {
const convertedCoord = this.convertCoordinates(
coord.longitude,
coord.latitude,
coord.height || 0,
options.coordinateSystem
);
return Cesium.Cartesian3.fromDegrees(
convertedCoord.longitude,
convertedCoord.latitude,
convertedCoord.height
);
});
const entityOptions = {
color: properties.color ? Cesium.Color.fromCssColorString(properties.color) : this.defaultOptions.color,
outlineColor: properties.outlineColor ? Cesium.Color.fromCssColorString(properties.outlineColor) : this.defaultOptions.outlineColor,
outlineWidth: properties.outlineWidth || this.defaultOptions.outlineWidth,
height: properties.height || this.defaultOptions.height,
extrudedHeight: properties.extrudedHeight || this.defaultOptions.extrudedHeight
};
return this.createPolygonEntity(id, positions, entityOptions);
}
/**
*
*/
private validateAirspaceData(data: any): boolean {
if (!data) {
console.error('空域数据为空');
return false;
}
if (!data.type) {
console.error('空域类型未定义');
return false;
}
if (!data.coordinates) {
console.error('空域坐标未定义');
return false;
}
if (data.type === 'circle') {
if (!data.coordinates.center || !data.coordinates.radius) {
console.error('圆形空域缺少中心点或半径');
return false;
}
} else if (data.type === 'polygon') {
if (!Array.isArray(data.coordinates) || data.coordinates.length < 3) {
console.error('多边形空域坐标无效');
return false;
}
} else {
console.error('不支持的空域类型:', data.type);
return false;
}
return true;
}
/**
*
*/
private convertCoordinates(
longitude: number,
latitude: number,
height: number,
coordinateSystem: string = 'wgs84'
): { longitude: number; latitude: number; height: number } {
// 这里可以添加坐标转换逻辑
// 目前只支持WGS84可以扩展支持GCJ02、BD09等
switch (coordinateSystem) {
case 'wgs84':
return { longitude, latitude, height };
case 'gcj02':
// 这里可以添加GCJ02到WGS84的转换
console.warn('GCJ02坐标转换暂未实现使用原始坐标');
return { longitude, latitude, height };
case 'bd09':
// 这里可以添加BD09到WGS84的转换
console.warn('BD09坐标转换暂未实现使用原始坐标');
return { longitude, latitude, height };
default:
console.warn(`不支持的坐标系: ${coordinateSystem}使用WGS84`);
return { longitude, latitude, height };
}
}
/**
*
*/
private calculateCircleEdgePoint(center: any, radius: number): Cesium.Cartesian3 {
const earthRadius = 6371000; // 地球半径(米)
const angularDistance = radius / earthRadius;
// 在正北方向计算边缘点
const edgeLat = center.latitude + (angularDistance * 180 / Math.PI);
return Cesium.Cartesian3.fromDegrees(
center.longitude,
edgeLat,
center.height
);
}
/**
*
*/
private zoomToImportedAirspaces(importedIds: string[]): void {
try {
const entities: Cesium.Entity[] = [];
importedIds.forEach(id => {
const drawing = this.drawingEntities.get(id);
if (drawing) {
entities.push(drawing.entity);
}
});
if (entities.length > 0) {
this.viewer.zoomTo(entities, new Cesium.HeadingPitchRange(0, -Math.PI/4, 0));
console.log('✅ 已缩放显示导入的空域');
}
} catch (error) {
console.error('缩放显示导入空域时发生错误:', error);
}
}
/**
* GeoJSON导入空域
*/
importFromGeoJSON(geoJSON: any, options: ImportOptions = {}): string[] {
console.log('=== 从GeoJSON导入空域 ===');
try {
if (!geoJSON || !geoJSON.features) {
console.error('无效的GeoJSON数据');
return [];
}
const airspaceData: any[] = [];
geoJSON.features.forEach((feature: any, index: number) => {
try {
const airspace = this.convertGeoJSONToAirspace(feature, index);
if (airspace) {
airspaceData.push(airspace);
}
} catch (error) {
console.error(`转换GeoJSON要素 ${index} 时发生错误:`, error);
}
});
return this.importAirspaceData(airspaceData, options);
} catch (error) {
console.error('导入GeoJSON时发生错误:', error);
return [];
}
}
/**
* GeoJSON要素转换为空域数据
*/
private convertGeoJSONToAirspace(feature: any, index: number): any {
const { geometry, properties } = feature;
if (!geometry || !geometry.coordinates) {
console.error('GeoJSON要素缺少几何数据');
return null;
}
const airspace: any = {
id: feature.id || `geojson_${Date.now()}_${index}`,
type: '',
coordinates: null,
properties: properties || {}
};
switch (geometry.type) {
case 'Polygon':
airspace.type = 'polygon';
// GeoJSON多边形坐标是三维数组取第一个环外环
airspace.coordinates = geometry.coordinates[0].map((coord: number[]) => ({
longitude: coord[0],
latitude: coord[1],
height: coord[2] || 0
}));
break;
case 'Point':
airspace.type = 'circle';
// 将点转换为圆形默认半径1000米
airspace.coordinates = {
center: {
longitude: geometry.coordinates[0],
latitude: geometry.coordinates[1],
height: geometry.coordinates[2] || 0
},
radius: properties?.radius || 1000
};
break;
default:
console.warn(`不支持的GeoJSON几何类型: ${geometry.type}`);
return null;
}
return airspace;
}
/**
*
*/
async importFromFile(file: File, options: ImportOptions = {}): Promise<string[]> {
return new Promise((resolve) => {
console.log('=== 从文件导入空域 ===');
console.log('文件:', file);
const reader = new FileReader();
reader.onload = (e) => {
try {
const content = e.target?.result as string;
let data;
// 根据文件类型解析
if (file.name.endsWith('.json')) {
data = JSON.parse(content);
} else if (file.name.endsWith('.geojson')) {
data = JSON.parse(content);
resolve(this.importFromGeoJSON(data, options));
return;
} else {
console.error('不支持的文件格式:', file.name);
resolve([]);
return;
}
// 判断数据格式
if (Array.isArray(data)) {
resolve(this.importAirspaceData(data, options));
} else if (data.features) {
resolve(this.importFromGeoJSON(data, options));
} else {
console.error('无法识别的数据格式');
resolve([]);
}
} catch (error) {
console.error('解析文件时发生错误:', error);
resolve([]);
}
};
reader.onerror = () => {
console.error('读取文件时发生错误');
resolve([]);
};
reader.readAsText(file);
});
}
/**
*
*/
getImportStatistics(): { total: number; circles: number; polygons: number } {
let circles = 0;
let polygons = 0;
this.drawingEntities.forEach((drawing) => {
if (drawing.properties.imported) {
if (drawing.type === 'circle') {
circles++;
} else {
polygons++;
}
}
});
return {
total: circles + polygons,
circles,
polygons
};
}
/**
*
*/

View File

@ -20,7 +20,7 @@ export function useDrawingManager(drawingTool: any) { // 修改参数类型为 a
outlineWidth: 2,
fill: true,
height: 0,
extrudedHeight: 1000
extrudedHeight: 0
},
polygon: {
color: Cesium.Color.CYAN.withAlpha(0.3),
@ -28,7 +28,7 @@ export function useDrawingManager(drawingTool: any) { // 修改参数类型为 a
outlineWidth: 2,
fill: true,
height: 0,
extrudedHeight: 1000,
extrudedHeight: 0,
closePath: true
}
});
@ -302,6 +302,61 @@ export function useDrawingManager(drawingTool: any) { // 修改参数类型为 a
return text;
};
/**
*
*/
const importAirspaceData = (data: any[], options: ImportOptions = {}): string[] => {
const tool = getTool();
if (!tool) {
console.error('❌ 绘图工具未初始化');
return [];
}
console.log('开始导入空域数据,数量:', data.length);
return tool.importAirspaceData(data, options);
};
/**
* GeoJSON导入空域
*/
const importFromGeoJSON = (geoJSON: any, options: ImportOptions = {}): string[] => {
const tool = getTool();
if (!tool) {
console.error('❌ 绘图工具未初始化');
return [];
}
return tool.importFromGeoJSON(geoJSON, options);
};
/**
*
*/
const importFromFile = async (file: File, options: ImportOptions = {}): Promise<string[]> => {
const tool = getTool();
if (!tool) {
console.error('❌ 绘图工具未初始化');
return [];
}
return await tool.importFromFile(file, options);
};
/**
*
*/
const getImportStatistics = (): { total: number; circles: number; polygons: number } => {
const tool = getTool();
if (!tool) {
return { total: 0, circles: 0, polygons: 0 };
}
return tool.getImportStatistics();
};
// 更新绘图选项
const updateDrawingOptions = (type: 'circle' | 'polygon', options: Partial<DrawingOptions>): void => {
drawingOptions[type] = { ...drawingOptions[type], ...options };
@ -512,6 +567,10 @@ export function useDrawingManager(drawingTool: any) { // 修改参数类型为 a
getSelectedDrawingJSON,
getAllDrawingsJSON,
exportSelectedDrawingAsText,
flyToSelectedDrawing
flyToSelectedDrawing,
importAirspaceData,
importFromGeoJSON,
importFromFile,
getImportStatistics
};
}