空域页面修改及工具集成
This commit is contained in:
parent
7cb20acd98
commit
9763668130
1
auto-imports.d.ts
vendored
1
auto-imports.d.ts
vendored
@ -2,6 +2,7 @@
|
||||
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']
|
||||
|
||||
@ -1,13 +1,7 @@
|
||||
<!-- src/App.vue -->
|
||||
<template>
|
||||
<div id="app">
|
||||
<!-- <header class="app-header">
|
||||
<h1>🌉 重庆三维地图系统</h1>
|
||||
<p>基于 Vue 3 + Cesium 的三维地理信息系统</p>
|
||||
</header> -->
|
||||
<main class="app-main">
|
||||
<CesiumViewer />
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
339
src/views/cesiums/CesiumViewers.vue
Normal file
339
src/views/cesiums/CesiumViewers.vue
Normal file
@ -0,0 +1,339 @@
|
||||
<!-- src/components/CesiumViewer.vue -->
|
||||
<template>
|
||||
<div class="cesium-container">
|
||||
<!-- Cesium 容器 -->
|
||||
<div id="cesiumContainer" ref="cesiumContainer"></div>
|
||||
|
||||
<!-- 绘图工具面板 -->
|
||||
<!-- <DrawingToolPanel
|
||||
v-if="isInitialized"
|
||||
:is-drawing="isDrawing"
|
||||
:current-drawing-type="currentDrawingType"
|
||||
:drawings="drawings"
|
||||
:selected-drawing="selectedDrawing"
|
||||
:drawing-info="drawingInfo"
|
||||
:drawing-options="drawingOptions"
|
||||
:get-drawing-status="getDrawingStatus"
|
||||
:get-drawing-info-text="getDrawingInfoText"
|
||||
@start-circle-drawing="startCircleDrawing"
|
||||
@start-polygon-drawing="startPolygonDrawing"
|
||||
@cancel-drawing="cancelDrawing"
|
||||
@select-drawing="selectDrawing"
|
||||
@deselect-drawing="deselectDrawing"
|
||||
@remove-drawing="removeDrawing"
|
||||
@clear-drawings="clearAllDrawings"
|
||||
@fly-to-drawing="flyToDrawing"
|
||||
@update-circle-option="updateCircleOption"
|
||||
@update-polygon-option="updatePolygonOption"
|
||||
@copy-drawing-info="copyDrawingInfo"
|
||||
@fly-to-selected-drawing="flyToSelectedDrawing"
|
||||
@print-selected-drawing-info="handlePrintSelectedDrawingInfo"
|
||||
@print-all-drawings-info="handlePrintAllDrawingsInfo"
|
||||
@print-drawing-info="handlePrintDrawingInfo"
|
||||
@export-drawing-info="handleExportDrawingInfo"
|
||||
/> -->
|
||||
|
||||
|
||||
<!-- 空域列表 -->
|
||||
<routeList v-if="showType=='routeList'" @setShowType="setShowType" :id="planId" />
|
||||
<!-- 空域新增 -->
|
||||
<routeAdd v-if="showType=='routeAdd'" @setShowType="setShowType" :id="planId" :hxid="hxId" />
|
||||
<!-- 空域查看 -->
|
||||
<!-- <routeGet v-if="showType=='routeGet'" @setShowType="setShowType" :id="planId" :hxid="hxId" /> -->
|
||||
|
||||
<RouteGet
|
||||
v-if="showType=='routeGet'"
|
||||
@setShowType="setShowType" :id="planId" :hxid="hxId"
|
||||
:import-from-file="importFromFile"
|
||||
:import-airspace-data="importAirspaceData"
|
||||
:get-import-statistics="getImportStatistics"
|
||||
@import-complete="handleImportComplete"
|
||||
/>
|
||||
|
||||
|
||||
<!-- 导入工具面板 -->
|
||||
<!-- <ImportToolPanel
|
||||
v-if="false"
|
||||
:import-from-file="importFromFile"
|
||||
:import-airspace-data="importAirspaceData"
|
||||
:get-import-statistics="getImportStatistics"
|
||||
@import-complete="handleImportComplete"
|
||||
/> -->
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import { useCesium } from './components/useCesium';
|
||||
import { useCesiumTools } from './components/useCesiumTools';
|
||||
// import CesiumToolPanel from './CesiumToolPanel.vue';
|
||||
import { useCoordinatePicker } from './components/useCoordinatePicker';
|
||||
import { useModelManager } from './components/useModelManager';
|
||||
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';
|
||||
|
||||
import routeList from "./components/routeList.vue";
|
||||
import routeAdd from "./components/routeAdd.vue";
|
||||
// import routeGet from "./components/routeGets.vue";
|
||||
import RouteGet from "./RouteGet.vue";
|
||||
|
||||
|
||||
// 项目ID
|
||||
const planId = ref('')
|
||||
// 项目ID
|
||||
const hxId = ref('')
|
||||
// 设置显示页面
|
||||
const showType = ref('routeList');
|
||||
|
||||
const setShowType = (val, id, hx) => {
|
||||
showType.value = val
|
||||
if (id) {
|
||||
planId.value = id
|
||||
}
|
||||
if (hxId) {
|
||||
hxId.value = hx
|
||||
} else {
|
||||
hxId.value = ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const cesiumContainer = ref<HTMLElement>();
|
||||
|
||||
|
||||
// 初始化 Cesium
|
||||
const { viewer, viewTool, markerTool, modelTool, coordinatePicker, drawingTool, isInitialized } = useCesium('cesiumContainer');
|
||||
|
||||
// 初始化工具
|
||||
const {
|
||||
currentView,
|
||||
cameraInfo,
|
||||
viewOptions,
|
||||
landmarkOptions,
|
||||
setView,
|
||||
addLandmarks,
|
||||
clearLandmarks,
|
||||
startCameraTracking
|
||||
} = useCesiumTools(viewTool, markerTool);
|
||||
|
||||
// 初始化模型管理
|
||||
const {
|
||||
models,
|
||||
selectedModel,
|
||||
isModelLoading,
|
||||
predefinedModels,
|
||||
loadChongqingLandmarks,
|
||||
loadPredefinedModel,
|
||||
selectModel,
|
||||
deselectModel,
|
||||
updateModelScale,
|
||||
updateModelPosition,
|
||||
removeModel,
|
||||
clearAllModels,
|
||||
flyToModel
|
||||
} = useModelManager(modelTool);
|
||||
|
||||
// 初始化坐标拾取
|
||||
const {
|
||||
isPickerEnabled,
|
||||
pickHistory,
|
||||
lastPickResult,
|
||||
enablePicker,
|
||||
disablePicker,
|
||||
togglePicker,
|
||||
clearHistory,
|
||||
copyToClipboard,
|
||||
formatCoordinate
|
||||
} = useCoordinatePicker(coordinatePicker);
|
||||
|
||||
// 初始化绘图管理
|
||||
const {
|
||||
isDrawing,
|
||||
currentDrawingType,
|
||||
drawings,
|
||||
selectedDrawing,
|
||||
drawingInfo,
|
||||
drawingOptions,
|
||||
startCircleDrawing,
|
||||
startPolygonDrawing,
|
||||
cancelDrawing,
|
||||
selectDrawing,
|
||||
deselectDrawing,
|
||||
removeDrawing,
|
||||
clearAllDrawings,
|
||||
flyToDrawing,
|
||||
updateDrawingOptions,
|
||||
getDrawingStatus,
|
||||
getDrawingInfoText,
|
||||
printSelectedDrawingInfo,
|
||||
printAllDrawingsInfo,
|
||||
printDrawingInfo,
|
||||
exportSelectedDrawingAsText,
|
||||
importAirspaceData,
|
||||
importFromFile,
|
||||
importFromGeoJSON,
|
||||
getImportStatistics,
|
||||
isEditing,
|
||||
editingDrawing,
|
||||
startEditing,
|
||||
finishEditing,
|
||||
cancelEditing,
|
||||
} = useDrawingManager(drawingTool);
|
||||
|
||||
|
||||
// 打印方法
|
||||
const handlePrintSelectedDrawingInfo = () => {
|
||||
console.log('执行打印选中空域');
|
||||
printSelectedDrawingInfo();
|
||||
};
|
||||
|
||||
const handlePrintAllDrawingsInfo = () => {
|
||||
console.log('执行打印所有空域');
|
||||
printAllDrawingsInfo();
|
||||
};
|
||||
|
||||
const handlePrintDrawingInfo = (id: string) => {
|
||||
console.log('执行打印指定空域:', id);
|
||||
printDrawingInfo(id);
|
||||
};
|
||||
|
||||
const handleExportDrawingInfo = () => {
|
||||
const text = exportSelectedDrawingAsText();
|
||||
if (text) {
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
console.log('空域信息已复制到剪贴板');
|
||||
// 可以添加提示消息
|
||||
}).catch(err => {
|
||||
console.error('复制失败:', err);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 添加预定义模型
|
||||
const addPredefinedModel = async (modelType: string, position: any) => {
|
||||
const modelId = `model_${Date.now()}`;
|
||||
await loadPredefinedModel(modelId, modelType as any, position);
|
||||
};
|
||||
|
||||
// 复制坐标
|
||||
const copyCoordinate = (result: any) => {
|
||||
copyToClipboard(result);
|
||||
// 可以在这里添加复制成功的提示
|
||||
console.log('坐标已复制:', formatCoordinate(result));
|
||||
};
|
||||
|
||||
// 飞向坐标
|
||||
const flyToCoordinate = (result: any) => {
|
||||
if (viewTool.value) {
|
||||
viewTool.value.flyTo(
|
||||
result.longitude,
|
||||
result.latitude,
|
||||
result.height + 100, // 在坐标上方100米查看
|
||||
1.5
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// 更新圆形选项
|
||||
const updateCircleOption = (key: string, value: any) => {
|
||||
updateDrawingOptions('circle', { [key]: value });
|
||||
};
|
||||
|
||||
// 更新多边形选项
|
||||
const updatePolygonOption = (key: string, value: any) => {
|
||||
updateDrawingOptions('polygon', { [key]: value });
|
||||
};
|
||||
|
||||
// 复制绘图信息
|
||||
const copyDrawingInfo = () => {
|
||||
if (drawingInfo.value) {
|
||||
const text = getDrawingInfoText();
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
console.log('绘图信息已复制到剪贴板');
|
||||
}).catch(err => {
|
||||
console.error('复制失败:', err);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 飞向选中的绘图
|
||||
const flyToSelectedDrawing = () => {
|
||||
if (selectedDrawing.value && drawingTool.value) {
|
||||
drawingTool.value.flyToDrawing(selectedDrawing.value);
|
||||
}
|
||||
};
|
||||
|
||||
// const copyDrawingInfo = () => {
|
||||
// if (drawingInfo.value) {
|
||||
// const text = getDrawingInfoText();
|
||||
// navigator.clipboard.writeText(text).then(() => {
|
||||
// console.log('绘图信息已复制到剪贴板');
|
||||
// }).catch(err => {
|
||||
// console.error('复制失败:', err);
|
||||
// });
|
||||
// }
|
||||
// };
|
||||
|
||||
// // 飞向选中的绘图
|
||||
// const flyToSelectedDrawing = () => {
|
||||
// if (selectedDrawing.value && drawingTool.value) {
|
||||
// drawingTool.value.flyToDrawing(selectedDrawing.value);
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
// 处理导入完成
|
||||
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(() => {
|
||||
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === 'Escape') {
|
||||
if (isEditing.value) {
|
||||
cancelEditing();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', handleKeyDown);
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('keydown', handleKeyDown);
|
||||
});
|
||||
// 开始跟踪相机信息
|
||||
setTimeout(() => {
|
||||
startCameraTracking();
|
||||
}, 2000);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.cesium-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
#cesiumContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@ -328,19 +328,6 @@ import { ref } from 'vue';
|
||||
import * as Cesium from 'cesium';
|
||||
import type { DrawingResult } from './components/DrawingTool';
|
||||
|
||||
// const props = defineProps<{
|
||||
// isDrawing: boolean;
|
||||
// currentDrawingType: string | null;
|
||||
// drawings: Map<string, DrawingResult>;
|
||||
// selectedDrawing: string | null;
|
||||
// drawingInfo: any;
|
||||
// drawingOptions: any;
|
||||
// getDrawingStatus: () => string;
|
||||
// getDrawingInfoText: () => string;
|
||||
// printSelectedDrawingInfo: () => void;
|
||||
// printAllDrawingsInfo: () => void;
|
||||
// exportSelectedDrawingAsText: () => string;
|
||||
// }>();
|
||||
|
||||
// 定义props
|
||||
const props = defineProps<{
|
||||
|
||||
@ -124,7 +124,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import { API_GET_list, API_GET_byId, API_DELETE_delPlotting, API_POST_addPlotting, API_PUT_updatePlotting,} from "../../api/uav/plotting";
|
||||
import { id } from 'element-plus/es/locale/index.js';
|
||||
|
||||
const props = defineProps<{
|
||||
importFromFile: (file: File, options: any) => Promise<string[]>;
|
||||
@ -204,6 +203,7 @@ const executeJsonImport = () => {
|
||||
importResult.value = null;
|
||||
|
||||
try {
|
||||
console.log("jsonInput.value:",jsonInput.value)
|
||||
const data = JSON.parse(jsonInput.value);
|
||||
console.log("data:",data)
|
||||
const importedIds = props.importAirspaceData(data, importOptions.value);
|
||||
@ -235,6 +235,34 @@ const loadData= () => {
|
||||
const jsonData = item.plottingJson
|
||||
console.log("此间数据如下111:"+jsonData)
|
||||
jsonInput.value = jsonData;
|
||||
if (!jsonInput.value.trim()) return;
|
||||
|
||||
isImporting.value = true;
|
||||
importResult.value = null;
|
||||
|
||||
try {
|
||||
console.log("jsonInput.value:",jsonInput.value)
|
||||
const data = JSON.parse(jsonInput.value);
|
||||
console.log("data:",data)
|
||||
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;
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
|
||||
782
src/views/cesiums/RouteGet.vue
Normal file
782
src/views/cesiums/RouteGet.vue
Normal file
@ -0,0 +1,782 @@
|
||||
<!-- src/components/ImportToolPanel.vue -->
|
||||
<template>
|
||||
<div class="el-container flexD dark">
|
||||
<div class="el-header">
|
||||
<div style="display: flex;align-items: center;">
|
||||
<h2 class="title" style="display: inline-block;margin-left: 8px;">创建空域</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="el-main">
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-position="top">
|
||||
<el-form-item label="空域名称" prop="name">
|
||||
<el-input v-model.trim="form.name" placeholder="请输入空域名称(建议:分局名称+时间+编号)" maxlength="15"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="所属战区" prop="militaryAreaName">
|
||||
<el-select v-model="form.militaryAreaName" placeholder="请选择所属战区" style="width: 100%;">
|
||||
<el-option v-for="item in slectmilitaryAreaList" :key="item.value" :label="item.name"
|
||||
:value="item.value">{{ item.name }}</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="空域类型" prop="airspaceType">
|
||||
<el-select v-model="form.airspaceType" placeholder="请选择空域类型" style="width: 100%;" >
|
||||
<el-option v-for="item in slectAirspaceTypeList" :key="item.value" :label="item.name"
|
||||
:value="item.value">{{ item.name }}</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="空域性制" prop="airspaceProp">
|
||||
<el-select v-model="form.airspaceProp" placeholder="请选择空域性制" style="width: 100%;">
|
||||
<el-option v-for="item in slectAirspacePropList" :key="item.value" :label="item.name"
|
||||
:value="item.value">{{ item.name }}</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="最大高度" prop="hightMax">
|
||||
<el-input v-model.trim="form.hightMax" maxlength="15"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="planBeg">
|
||||
<el-date-picker
|
||||
v-model="form.planBeg"
|
||||
type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
value-format="YYYY-MM-DD hh:mm:ss"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="截止时间" prop="planEnd">
|
||||
<el-date-picker v-model="form.planEnd" type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
value-format="YYYY-MM-DD hh:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="el-footer">
|
||||
<el-button type="primary" @click="submitForm" style="width: 100%;">返回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted,reactive } from 'vue';
|
||||
import { API_GET_list, API_GET_byId, API_DELETE_delPlotting, API_POST_addPlotting, API_PUT_updatePlotting,} from "../../api/uav/plotting";
|
||||
import "./components/ele.dark.style.css";
|
||||
import "@/assets/styles/c_style.scss"
|
||||
import { eidtAirLine_c, getLineListDetial_c,getPlottingByUuid } from "./api.js";
|
||||
import type { DrawingResult } from './components/DrawingTool';
|
||||
|
||||
const props = defineProps<{
|
||||
importFromFile: (file: File, options: any) => Promise<string[]>;
|
||||
importAirspaceData: (data: any[], options: any) => string[];
|
||||
getImportStatistics: () => { total: number; circles: number; polygons: number };
|
||||
id:string;
|
||||
hxid:string;
|
||||
isDrawing: boolean;
|
||||
currentDrawingType: string | null;
|
||||
drawings: Map<string, DrawingResult>;
|
||||
selectedDrawing: string | null;
|
||||
drawingInfo: any;
|
||||
drawingOptions: any;
|
||||
getDrawingStatus: () => 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;
|
||||
}>();
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
console.log("props:",props)
|
||||
if (props.hxid) {
|
||||
getDetial(props.hxid)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const emit = defineEmits<{
|
||||
'start-circle-drawing': [];
|
||||
'start-polygon-drawing': [];
|
||||
'cancel-drawing': [];
|
||||
'select-drawing': [id: string];
|
||||
'deselect-drawing': [];
|
||||
'remove-drawing': [id: string];
|
||||
'clear-drawings': [];
|
||||
'fly-to-drawing': [id: string];
|
||||
'update-circle-option': [key: string, value: any];
|
||||
'update-polygon-option': [key: string, value: any];
|
||||
'copy-drawing-info': [];
|
||||
'fly-to-selected-drawing': [id: string];
|
||||
'print-selected-drawing-info': [];
|
||||
'print-all-drawings-info': [];
|
||||
'print-drawing-info': [id: string];
|
||||
'export-drawing-info': [id: string];
|
||||
'export-drawing': [id: string];
|
||||
'start-editing': [id: string];
|
||||
'finish-editing': [];
|
||||
'cancel-editing': [];
|
||||
'setShowType':[id: string];
|
||||
}>();
|
||||
|
||||
// const emit = defineEmits(["setShowType"])
|
||||
//表单数据
|
||||
const formRef = ref(null)
|
||||
const form = reactive({
|
||||
// airlineName: '',
|
||||
airlineType: 0,
|
||||
waypointCount: '',
|
||||
length: '',
|
||||
expectedTime: '',
|
||||
flyToWaylineMode: 'safely',
|
||||
alt: 0,
|
||||
heightType: 'relativeToStartPoint',
|
||||
waypointHeadingMode: 'followWayline',
|
||||
gimbalPitchMode: 'manual',
|
||||
waypointTurnMode: 'coordinateTurn',
|
||||
executionType: 'goHome',
|
||||
uavType: '',
|
||||
uavPTZ: '',
|
||||
storageType: ['wide', 'zoom', 'ir'],
|
||||
hightMax: '',
|
||||
hightMin: '',
|
||||
lat: '',
|
||||
lng: '',
|
||||
militaryAreaName: '',
|
||||
militaryAreaId: null,
|
||||
name: '',
|
||||
flightRule: '',
|
||||
airspaceType: '',
|
||||
airspaceProp: '',
|
||||
radLength: '',
|
||||
startTime: null,
|
||||
endTime: null,
|
||||
planBeg: null,
|
||||
planEnd: null,
|
||||
uuid: null
|
||||
})
|
||||
|
||||
|
||||
// 表单校验
|
||||
const rules = reactive({
|
||||
name: [{ required: true, message: '请输入名称' },],
|
||||
militaryAreaName: [{ required: true, message: '请选择所属战区' },],
|
||||
airspaceType: [{ required: true, message: '请选择空域类型' },],
|
||||
airspaceProp: [{ required: true, message: '请选择空域性质' },],
|
||||
flightRule: [{ required: true, message: '请选择飞行规则' },],
|
||||
})
|
||||
//表单提交方法
|
||||
const submitForm = () => {
|
||||
toList()
|
||||
}
|
||||
|
||||
// 返回列表
|
||||
const toList = () => {
|
||||
console.log("重置地图")
|
||||
emit('setShowType', 'routeList', props.id)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 获取详情
|
||||
const getDetial = (id) => {
|
||||
getLineListDetial_c(id).then((res) => {
|
||||
if (res.code === 200) {
|
||||
Object.assign(form, res.data)
|
||||
console.log("返回的经纬度",res.data.lat)
|
||||
console.log("返回的UUID",res.data.uuid)
|
||||
getPlotting(res.data.uuid)
|
||||
}
|
||||
});
|
||||
}
|
||||
const getPlotting = (id) => {
|
||||
getPlottingByUuid(id).then((res) => {
|
||||
if (res.code == 200) {
|
||||
console.log("返回的数据0:",res)
|
||||
console.log("返回的数据1:",res.data[0].data)
|
||||
|
||||
const jsonData = res.data[0].data
|
||||
console.log("此间数据如下111:"+jsonData)
|
||||
jsonInput.value = jsonData;
|
||||
if (!jsonInput.value.trim()) return;
|
||||
|
||||
isImporting.value = true;
|
||||
importResult.value = null;
|
||||
|
||||
try {
|
||||
console.log("jsonInput.value:",jsonInput.value)
|
||||
const data = JSON.parse(jsonInput.value);
|
||||
console.log("data:",data)
|
||||
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;
|
||||
}
|
||||
|
||||
console.log("返回的数据:",res.data)
|
||||
} else {
|
||||
// proxy.$message.error(res.msg);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// 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}`
|
||||
};
|
||||
isImporting.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 执行JSON导入
|
||||
const executeJsonImport = () => {
|
||||
if (!jsonInput.value.trim()) return;
|
||||
|
||||
isImporting.value = true;
|
||||
importResult.value = null;
|
||||
|
||||
try {
|
||||
console.log("jsonInput.value:",jsonInput.value)
|
||||
const data = JSON.parse(jsonInput.value);
|
||||
console.log("data:",data)
|
||||
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 loadData= () => {
|
||||
API_GET_list().then((response) => {
|
||||
if (response.code === 200) {
|
||||
// message.success("图上标绘加载成功");
|
||||
response.rows.forEach((item) => {
|
||||
const jsonData = item.plottingJson
|
||||
console.log("此间数据如下111:"+jsonData)
|
||||
jsonInput.value = jsonData;
|
||||
if (!jsonInput.value.trim()) return;
|
||||
|
||||
isImporting.value = true;
|
||||
importResult.value = null;
|
||||
|
||||
try {
|
||||
console.log("jsonInput.value:",jsonInput.value)
|
||||
const data = JSON.parse(jsonInput.value);
|
||||
console.log("data:",data)
|
||||
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;
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
// message.error(response.msg);
|
||||
}
|
||||
}, error => {
|
||||
// message.success("图上标绘加载失败");
|
||||
});
|
||||
|
||||
executeJsonImport();
|
||||
}
|
||||
|
||||
// 加载示例数据
|
||||
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 lang="scss" 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;
|
||||
}
|
||||
|
||||
.el-container {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: auto;
|
||||
bottom: 70px;
|
||||
z-index: 1001;
|
||||
width: 420px;
|
||||
height: auto;
|
||||
background: rgba(29, 37, 50, 0.85);
|
||||
|
||||
.el-header,
|
||||
.el-footer {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.addBtn {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.editBtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
background: #414243;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.displayFlex {
|
||||
border-bottom: 1px solid #414243;
|
||||
|
||||
.contentDom {
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
|
||||
.contentDom {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
.contentDom {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
161
src/views/cesiums/api.js
Normal file
161
src/views/cesiums/api.js
Normal file
@ -0,0 +1,161 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} options
|
||||
* 航线规划添加项目
|
||||
*/
|
||||
export function addPlaning (options) {
|
||||
return request({
|
||||
url: `/item`,
|
||||
method: 'post',
|
||||
data: options,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} options
|
||||
* 获取应用列表
|
||||
*/
|
||||
export function getApplicationList (data) {
|
||||
return request({
|
||||
url: `/app/management/findApplicationList`,
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {*} options
|
||||
* 获取项目列表
|
||||
*/
|
||||
export function getPlaningList_c (data) {
|
||||
return request({
|
||||
url: `/item/list`,
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 新增航线
|
||||
*/
|
||||
|
||||
// export function addAirLine_c (data) {
|
||||
// return request({
|
||||
// url: `/airline`,
|
||||
// method: 'post',
|
||||
// data: data
|
||||
// })
|
||||
// }
|
||||
export function addAirLine_c (data) {
|
||||
return request({
|
||||
url: `/airspace`,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改航线
|
||||
*/
|
||||
// export function eidtAirLine_c (data) {
|
||||
// return request({
|
||||
// url: `/airline`,
|
||||
// method: 'put',
|
||||
// data: data
|
||||
// })
|
||||
// }
|
||||
export function eidtAirLine_c (data) {
|
||||
return request({
|
||||
url: `/airspace`,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 获取航线详情
|
||||
*/
|
||||
|
||||
// export function getLineListDetial_c (data) {
|
||||
// return request({
|
||||
// url: `/airline/` + data,
|
||||
// method: 'GET',
|
||||
// })
|
||||
// }
|
||||
export function getLineListDetial_c (data) {
|
||||
return request({
|
||||
url: `/airspace/` + data,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
export function getPlottingByUuid (data) {
|
||||
return request({
|
||||
url: '/plot/selectPlotByUuid/'+ data,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取无人机类型
|
||||
*/
|
||||
|
||||
export function getSelectUavTypeList_c () {
|
||||
return request({
|
||||
url: '/type/selectUavTypeList',
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取航线列表
|
||||
*/
|
||||
|
||||
// export function getLineList_c (data) {
|
||||
// return request({
|
||||
// url: `/airline/list`,
|
||||
// method: 'GET',
|
||||
// params: data
|
||||
// })
|
||||
// }
|
||||
export function getLineList_c (data) {
|
||||
return request({
|
||||
url: `/airspace/list`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
export function API_PUT_archiveAirline (id) {
|
||||
return request({
|
||||
url: '/airline/archive/' + id,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
export function API_PUT_removeAirline (id) {
|
||||
return request({
|
||||
// url: '/airline/remove/' + id,
|
||||
url: '/airspace/' + id,
|
||||
method: 'DELETE'
|
||||
})
|
||||
}
|
||||
export function API_PUT_removeAspace (id) {
|
||||
return request({
|
||||
url: '/airspace/' + id,
|
||||
method: 'DElETE'
|
||||
})
|
||||
}
|
||||
//查询分组
|
||||
export function getGroupList () {
|
||||
return request({
|
||||
url: `/airline/groups/groups`,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
80
src/views/cesiums/c_airspace.vue
Normal file
80
src/views/cesiums/c_airspace.vue
Normal file
@ -0,0 +1,80 @@
|
||||
<!-- src/App.vue -->
|
||||
<template>
|
||||
<div id="app">
|
||||
<CesiumViewers />
|
||||
<div >
|
||||
<!-- 空域列表 -->
|
||||
<!-- <routeList v-if="showType=='routeList'" @setShowType="setShowType" :id="planId" /> -->
|
||||
<!-- 空域新增 -->
|
||||
<!-- <routeAdd v-if="showType=='routeAdd'" @setShowType="setShowType" :id="planId" :hxid="hxId" /> -->
|
||||
<!-- 空域查看 -->
|
||||
<!-- <routeGet v-if="showType=='routeGet'" @setShowType="setShowType" :id="planId" :hxid="hxId" /> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import CesiumViewers from './CesiumViewers.vue';
|
||||
import routeList from "./components/routeList.vue";
|
||||
import routeAdd from "./components/routeAdd.vue";
|
||||
import routeGet from "./components/routeGet.vue";
|
||||
import { ref } 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 };
|
||||
}>();
|
||||
|
||||
// 项目ID
|
||||
const planId = ref('')
|
||||
// 项目ID
|
||||
const hxId = ref('')
|
||||
// 设置显示页面
|
||||
const showType = ref('routeList');
|
||||
|
||||
const setShowType = (val, id, hx) => {
|
||||
showType.value = val
|
||||
if (id) {
|
||||
planId.value = id
|
||||
}
|
||||
if (hxId) {
|
||||
hxId.value = hx
|
||||
} else {
|
||||
hxId.value = ""
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#app {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
.app-header {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.app-header h1 {
|
||||
margin-bottom: 8px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.app-header p {
|
||||
opacity: 0.9;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.app-main {
|
||||
height: calc(100vh - 80px);
|
||||
}
|
||||
</style>
|
||||
92
src/views/cesiums/components/ele.dark.style.css
Normal file
92
src/views/cesiums/components/ele.dark.style.css
Normal file
@ -0,0 +1,92 @@
|
||||
.dark {
|
||||
color-scheme: dark;
|
||||
--el-color-primary: #409eff;
|
||||
--el-color-primary-light-3: #3375b9;
|
||||
--el-color-primary-light-5: #2a598a;
|
||||
--el-color-primary-light-7: #213d5b;
|
||||
--el-color-primary-light-8: #1d3043;
|
||||
--el-color-primary-light-9: #18222c;
|
||||
--el-color-primary-dark-2: #66b1ff;
|
||||
--el-color-success: #67c23a;
|
||||
--el-color-success-light-3: #4e8e2f;
|
||||
--el-color-success-light-5: #3e6b27;
|
||||
--el-color-success-light-7: #2d481f;
|
||||
--el-color-success-light-8: #25371c;
|
||||
--el-color-success-light-9: #1c2518;
|
||||
--el-color-success-dark-2: #85ce61;
|
||||
--el-color-warning: #e6a23c;
|
||||
--el-color-warning-light-3: #a77730;
|
||||
--el-color-warning-light-5: #7d5b28;
|
||||
--el-color-warning-light-7: #533f20;
|
||||
--el-color-warning-light-8: #3e301c;
|
||||
--el-color-warning-light-9: #292218;
|
||||
--el-color-warning-dark-2: #ebb563;
|
||||
--el-color-danger: #f56c6c;
|
||||
--el-color-danger-light-3: #b25252;
|
||||
--el-color-danger-light-5: #854040;
|
||||
--el-color-danger-light-7: #582e2e;
|
||||
--el-color-danger-light-8: #412626;
|
||||
--el-color-danger-light-9: #2b1d1d;
|
||||
--el-color-danger-dark-2: #f78989;
|
||||
--el-color-error: #f56c6c;
|
||||
--el-color-error-light-3: #b25252;
|
||||
--el-color-error-light-5: #854040;
|
||||
--el-color-error-light-7: #582e2e;
|
||||
--el-color-error-light-8: #412626;
|
||||
--el-color-error-light-9: #2b1d1d;
|
||||
--el-color-error-dark-2: #f78989;
|
||||
--el-color-info: #909399;
|
||||
--el-color-info-light-3: #6b6d71;
|
||||
--el-color-info-light-5: #525457;
|
||||
--el-color-info-light-7: #393a3c;
|
||||
--el-color-info-light-8: #2d2d2f;
|
||||
--el-color-info-light-9: #202121;
|
||||
--el-color-info-dark-2: #a6a9ad;
|
||||
--el-box-shadow: 0px 12px 32px 4px rgba(0, 0, 0, 0.36),
|
||||
0px 8px 20px rgba(0, 0, 0, 0.72);
|
||||
--el-box-shadow-light: 0px 0px 12px rgba(0, 0, 0, 0.72);
|
||||
--el-box-shadow-lighter: 0px 0px 6px rgba(0, 0, 0, 0.72);
|
||||
--el-box-shadow-dark: 0px 16px 48px 16px rgba(0, 0, 0, 0.72),
|
||||
0px 12px 32px #000000, 0px 8px 16px -8px #000000;
|
||||
--el-bg-color-page: #0a0a0a;
|
||||
--el-bg-color: #141414;
|
||||
--el-bg-color-overlay: #1d1e1f;
|
||||
--el-text-color-primary: #e5eaf3;
|
||||
--el-text-color-regular: #cfd3dc;
|
||||
--el-text-color-secondary: #a3a6ad;
|
||||
--el-text-color-placeholder: #8d9095;
|
||||
--el-text-color-disabled: #6c6e72;
|
||||
--el-border-color-darker: #636466;
|
||||
--el-border-color-dark: #58585b;
|
||||
--el-border-color: #d9d9d9;
|
||||
--el-border-color-light: #414243;
|
||||
--el-border-color-lighter: #363637;
|
||||
--el-border-color-extra-light: #2b2b2c;
|
||||
--el-fill-color-darker: #424243;
|
||||
--el-fill-color-dark: #39393a;
|
||||
--el-fill-color: #303030;
|
||||
--el-fill-color-light: #262727;
|
||||
--el-fill-color-lighter: #1d1d1d;
|
||||
--el-fill-color-extra-light: #191919;
|
||||
--el-fill-color-blank: transparent;
|
||||
--el-mask-color: rgba(0, 0, 0, 0.8);
|
||||
--el-mask-color-extra-light: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.dark .el-button {
|
||||
--el-button-disabled-text-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.dark .el-card {
|
||||
--el-card-bg-color: var(--el-bg-color-overlay);
|
||||
}
|
||||
.dark .el-empty {
|
||||
--el-empty-fill-color-0: var(--el-color-black);
|
||||
--el-empty-fill-color-1: #4b4b52;
|
||||
--el-empty-fill-color-2: #36383d;
|
||||
--el-empty-fill-color-3: #1e1e20;
|
||||
--el-empty-fill-color-4: #262629;
|
||||
--el-empty-fill-color-5: #202124;
|
||||
--el-empty-fill-color-6: #212224;
|
||||
--el-empty-fill-color-7: #1b1c1f;
|
||||
--el-empty-fill-color-8: #1c1d1f;
|
||||
--el-empty-fill-color-9: #18181a;
|
||||
}
|
||||
564
src/views/cesiums/components/routeAdd.vue
Normal file
564
src/views/cesiums/components/routeAdd.vue
Normal file
@ -0,0 +1,564 @@
|
||||
<!--
|
||||
航线规划-航线列表
|
||||
crate by churl
|
||||
2023-3-6
|
||||
-->
|
||||
<template>
|
||||
<div class="el-container flexD dark">
|
||||
<div class="el-header">
|
||||
<div style="display: flex;align-items: center;">
|
||||
<!-- <el-popconfirm title="返回后内容不会保存;确定返回吗?" @confirm="toList()">
|
||||
<template #reference>
|
||||
<el-icon size="24px" class="addBtn">
|
||||
<ArrowLeftBold />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-popconfirm> -->
|
||||
<h2 class="title" style="display: inline-block;margin-left: 8px;">创建空域</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="el-main">
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-position="top">
|
||||
<el-form-item label="空域名称" prop="name">
|
||||
<el-input v-model.trim="form.name" placeholder="请输入空域名称(建议:分局名称+时间+编号)"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="所属战区" prop="militaryAreaName">
|
||||
<el-select v-model="form.militaryAreaName" placeholder="请选择所属战区" style="width: 100%;">
|
||||
<el-option v-for="item in slectmilitaryAreaList" :key="item.value" :label="item.name"
|
||||
:value="item.value">{{ item.name }}</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="空域性制" prop="airspaceProp">
|
||||
<el-select v-model="form.airspaceProp" placeholder="请选择空域性制" style="width: 100%;">
|
||||
<el-option v-for="item in slectAirspacePropList" :key="item.value" :label="item.name"
|
||||
:value="item.value">{{ item.name }}</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="飞行规则" prop="flightRule">
|
||||
<el-select v-model="form.flightRule" placeholder="请选择飞行规则" style="width: 100%;">
|
||||
<el-option v-for="item in slectFlightRuleList" :key="item.value" :label="item.name"
|
||||
:value="item.value">{{ item.name }}</el-option>
|
||||
</el-select>
|
||||
</el-form-item> -->
|
||||
<!--
|
||||
|
||||
<div class="marginBottom18">
|
||||
<div class="labelBtnDom">
|
||||
<span class="label">申请空域起点设置 (AGL)</span>
|
||||
<el-button v-if="mapWork.qfdPosition.value?.lng" size="small" type="danger"
|
||||
@click="mapWork.deleteQFD">删除起点</el-button>
|
||||
<el-button v-else size="small" type="success"
|
||||
@click="() => { pointList_show_handel(false), mapWork.setQFD() }">设置起点</el-button>
|
||||
</div>
|
||||
<div class="lnglataltDom" v-if="mapWork.qfdPosition.value?.lng">
|
||||
<div style="margin-bottom: 8px;">
|
||||
<CLngLat :lngValue="mapWork.qfdPosition.value.lng"
|
||||
:latValue="mapWork.qfdPosition.value.lat"
|
||||
:rules="[{ required: true, message: '请输入经度和纬度', trigger: 'change' }]"
|
||||
@change="setPosition" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="marginBottom18" v-if="form.airspaceType==2">
|
||||
<div class="labelBtnDom">
|
||||
<span class="label">边界点</span>
|
||||
<div v-if="mapWork.qfdPosition.value">
|
||||
<el-button size="small" v-if="pointList_show" type="info"
|
||||
@click="pointList_show_handel(false)">关闭</el-button>
|
||||
<el-button size="small" v-else type="warning"
|
||||
@click="pointList_show_handel(true)">设置</el-button>
|
||||
</div>
|
||||
<div v-else>请先设置申请空域起点</div>
|
||||
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
|
||||
|
||||
|
||||
<div>
|
||||
<el-form-item label="空域类型" prop="airspaceType">
|
||||
<el-select v-model="form.airspaceType" placeholder="请选择空域类型" style="width: 40%;" >
|
||||
<el-option v-for="item in slectAirspaceTypeList" :key="item.value" :label="item.name"
|
||||
:value="item.value">{{ item.name }}</el-option>
|
||||
</el-select>
|
||||
<div style="margin-left: 10px;"></div>
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
content="圆"
|
||||
placement="top-start"
|
||||
>
|
||||
<el-button class="vertical-button" v-if="form.airspaceType==1" type="primary" @click="mapWork.drawEllipse(false)">
|
||||
绘制空域:
|
||||
<svg-icon icon-class="circle"/>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
content="多边形"
|
||||
placement="top-start"
|
||||
>
|
||||
<el-button class="vertical-button" v-if="form.airspaceType==2" type="primary" @click="mapWork.drawPolygon(false)">
|
||||
绘制空域:
|
||||
<svg-icon icon-class="polygon"/>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-button type="primary" v-if="form.airspaceType==1 || form.airspaceType==2 " @click="clear">清除空域</el-button>
|
||||
<!-- <el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
content="取消绘制"
|
||||
placement="top-start"
|
||||
>
|
||||
<el-button class="vertical-button" type="primary" @click="mapWork.endDraw()">
|
||||
<el-icon>
|
||||
<Close />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip> -->
|
||||
</el-form-item>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- <el-form-item label="半径长度" prop="radLength" v-if="form.airspaceType==1">
|
||||
<el-input v-model.trim="form.radLength" placeholder="请输入半径长度 单位(米)" maxlength="15"></el-input>
|
||||
</el-form-item> -->
|
||||
<!-- <el-form-item label="最小高度" prop="hightMin">
|
||||
<el-input v-model.trim="form.hightMin" maxlength="15"></el-input>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="最大高度" prop="hightMax">
|
||||
<el-input v-model.trim="form.hightMax" maxlength="15"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="planBeg">
|
||||
<el-date-picker
|
||||
v-model="form.planBeg"
|
||||
type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
value-format="YYYY-MM-DD hh:mm:ss"
|
||||
>
|
||||
</el-date-picker>
|
||||
<!-- <el-input v-model.trim="form.hightMin" maxlength="15"></el-input> -->
|
||||
<!-- <el-date-picker v-model="form.planBeg" value-format="YYYY-MM-DD HH:mm:SS" type="date" style="width: 100%" size="default"
|
||||
@change="getLineList" /> -->
|
||||
</el-form-item>
|
||||
<el-form-item label="截止时间" prop="planEnd">
|
||||
<!-- <el-input v-model.trim="form.hightMin" maxlength="15"></el-input> -->
|
||||
<el-date-picker v-model="form.planEnd" type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
value-format="YYYY-MM-DD hh:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="el-footer">
|
||||
<!-- <el-popconfirm title="提交后会覆盖之前内容;确定提交吗?" @confirm=" editForm()" v-if="props.hxid">
|
||||
<template #reference>
|
||||
<div>
|
||||
<el-tooltip :content="form.isOriginal === 0 ? '该副本不支持修改后保存' : ''" placement="top">
|
||||
<el-button :type="form.isOriginal === 0 ? 'info' : 'primary'" :disabled="form.isOriginal === 0">
|
||||
提交
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</el-popconfirm> -->
|
||||
<el-button type="primary" @click="submitForms">返回</el-button>
|
||||
<el-button type="primary" v-if="props.hxid" @click="editForm">提交</el-button>
|
||||
<el-button type="primary" v-else @click="submitForm">提交</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 途径点列表 -->
|
||||
<!-- <pointList ref="pointListRef" :storageTypeList="storageTypeList" :storageType="form.storageType" v-if="pointList_show"
|
||||
@close="pointList_show_handel" /> -->
|
||||
</template>
|
||||
<script setup>
|
||||
|
||||
import "./ele.dark.style.css";
|
||||
import "@/assets/styles/c_style.scss"
|
||||
// import * as mapWork from "../map.js";
|
||||
import { ref, reactive, onMounted, getCurrentInstance, computed } from 'vue';
|
||||
import { addAirLine_c, eidtAirLine_c, getLineListDetial_c,getPlottingByUuid } from "../api";
|
||||
// import pointList from "./pointList.vue";
|
||||
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const props = defineProps(["id", 'hxid'])
|
||||
const emit = defineEmits(["setShowType"])
|
||||
//表单数据
|
||||
const formRef = ref(null)
|
||||
const form = reactive({
|
||||
// airlineName: '',
|
||||
airlineType: 0,
|
||||
waypointCount: '',
|
||||
length: '',
|
||||
expectedTime: '',
|
||||
flyToWaylineMode: 'safely',
|
||||
alt: 0,
|
||||
heightType: 'relativeToStartPoint',
|
||||
// height: 0,
|
||||
// speed: 1,
|
||||
waypointHeadingMode: 'followWayline',
|
||||
gimbalPitchMode: 'manual',
|
||||
waypointTurnMode: 'coordinateTurn',
|
||||
executionType: 'goHome',
|
||||
uavType: '',
|
||||
uavPTZ: '',
|
||||
storageType: ['wide', 'zoom', 'ir'],
|
||||
hightMax: '',
|
||||
hightMin: '',
|
||||
lat: '',
|
||||
lng: '',
|
||||
militaryAreaName: '',
|
||||
militaryAreaId: null,
|
||||
name: '',
|
||||
flightRule: '',
|
||||
airspaceType: '',
|
||||
airspaceProp: '',
|
||||
radLength: '',
|
||||
startTime: null,
|
||||
endTime: null,
|
||||
planBeg: null,
|
||||
planEnd: null,
|
||||
uuid: null
|
||||
})
|
||||
//
|
||||
// 表单校验
|
||||
const rules = reactive({
|
||||
name: [{ required: true, message: '请输入名称' },],
|
||||
militaryAreaName: [{ required: true, message: '请选择所属战区' },],
|
||||
airspaceType: [{ required: true, message: '请选择空域类型' },],
|
||||
airspaceProp: [{ required: true, message: '请选择空域性质' },],
|
||||
flightRule: [{ required: true, message: '请选择飞行规则' },],
|
||||
})
|
||||
//表单提交方法
|
||||
const submitForm = () => {
|
||||
formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
form.itemId = props.id
|
||||
// form.uuid =mapWork.kyuuid
|
||||
// console.log("form.uuID",form.uuid)
|
||||
addAirLine_c(form).then((res) => {
|
||||
if (res.code === 200) {
|
||||
// proxy.$message.success("添加成功");
|
||||
toList()
|
||||
} else {
|
||||
// proxy.$message.error(res.message);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
const submitForms = () => {
|
||||
toList()
|
||||
}
|
||||
|
||||
// 修改保存
|
||||
const editForm = () => {
|
||||
formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
if (form.isOriginal == 0) {
|
||||
return proxy.$message.error("该副本不支持修改后保存");
|
||||
}
|
||||
// form.uuid =mapWork.kyuuid
|
||||
// console.log("form.uuID",form.uuid)
|
||||
eidtAirLine_c(form).then((res) => {
|
||||
if (res.code === 200) {
|
||||
// proxy.$message.success("修改成功");
|
||||
toList()
|
||||
} else {
|
||||
// proxy.$message.error(res.message);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 设置位置
|
||||
const setPosition = (val) => {
|
||||
if (val.lng && val.lat) {
|
||||
mapWork.setQFDposition(val)
|
||||
}
|
||||
if (typeof val === 'number') {
|
||||
mapWork.setQFDposition({ alt: val })
|
||||
}
|
||||
|
||||
}
|
||||
// 设置公共高度
|
||||
const changeHeight = (val) => {
|
||||
|
||||
form.height = val
|
||||
// form.ellipsoidHeight = val.egmAlt
|
||||
mapWork.commonData.height = val
|
||||
}
|
||||
|
||||
const clear = () => {
|
||||
mapWork.resethangxian()
|
||||
console.log("清除地图")
|
||||
}
|
||||
|
||||
|
||||
// 返回列表
|
||||
const toList = () => {
|
||||
// mapWork.resethangxian()
|
||||
console.log("重置地图")
|
||||
emit('setShowType', 'routeList', props.id)
|
||||
}
|
||||
|
||||
// 无人机下拉列表
|
||||
const slectUavTypeList = [{ name: 'M30 系列', value: '67' }, { name: 'Mavic 3 行业系列', value: '77' }]
|
||||
const slectmilitaryAreaList = [{ name: '东部战区', value: '1' }, { name: '南部战区', value: '2' }, { name: '西部战区', value: '3' }, { name: '北部战区', value: '4' }, { name: '中部战区', value: '5' }]
|
||||
const slectAirspaceTypeList = [{ name: '圆形空域', value: '1' }, { name: '多边形空域', value: '2' }]
|
||||
const slectFlightRuleList = [{ name: 'VFR', value: '1' }, { name: 'IFR', value: '2' }]
|
||||
const slectAirspacePropList = [{ name: '固定空域', value: '1' }, { name: '临时空域', value: '2' }]
|
||||
// const getSelectUavTypeList = (val) => {
|
||||
// getSelectUavTypeList_c().then((res) => {
|
||||
// slectUavTypeList.value = res.data
|
||||
// });
|
||||
// }
|
||||
// 云台列表
|
||||
const payloadTypeList = computed(() => {
|
||||
let arr = []
|
||||
if (form.uavType == '77') {
|
||||
arr = [{ name: 'Mavic 3E 相机', value: '66' }, { name: 'Mavic 3T 相机', value: '67' }]
|
||||
} else if (form.uavType == '67') {
|
||||
arr = [{ name: 'M30 相机', value: '52' }, { name: 'M30T 相机', value: '53' }]
|
||||
} else {
|
||||
arr = [{ name: '请选择无人机后选择云台', value: '' }]
|
||||
}
|
||||
return arr
|
||||
})
|
||||
// 存储类型
|
||||
const storageTypeList = computed(() => {
|
||||
let arr = []
|
||||
const arrMap = [
|
||||
[() => form.uavType == '77' && form.payloadType == '66', () => arr = []],
|
||||
[() => form.uavType == '77' && form.payloadType == '67', () => arr = []],
|
||||
[() => form.uavType == '67' && form.payloadType == '52', () => arr = [{ value: 'wide', name: '广角照片(W)', jc: 'W' }, { value: 'zoom', name: '变焦照片(Z)', jc: 'Z' },]],
|
||||
[() => form.uavType == '67' && form.payloadType == '53', () => arr = [{ value: 'wide', name: '广角照片(W)', jc: 'W' }, { value: 'zoom', name: '变焦照片(Z)', jc: 'Z' }, { value: 'ir', name: '红外照片(IR)', jc: 'IR' },]],
|
||||
|
||||
]
|
||||
const target = arrMap.find((m) => m[0]())
|
||||
if (target) {
|
||||
target[1]()
|
||||
}
|
||||
|
||||
|
||||
|
||||
return arr
|
||||
})
|
||||
|
||||
watch(() => payloadTypeList.value, (val) => {
|
||||
//form.payloadType = ''
|
||||
|
||||
}, { deep: true })
|
||||
|
||||
watch(() => storageTypeList.value, (val) => {
|
||||
if (val && val.length) {
|
||||
form.storageType = val.map(obj => obj.value)
|
||||
} else {
|
||||
form.storageType = []
|
||||
}
|
||||
|
||||
}, { deep: true })
|
||||
|
||||
const pointList_show = ref(false)
|
||||
const pointList_show_handel = (val) => {
|
||||
console.log("这个val的值为",val)
|
||||
pointList_show.value = val
|
||||
if (!val) {
|
||||
mapWork?.pointEndDraw()
|
||||
}
|
||||
}
|
||||
|
||||
// 获取详情
|
||||
const getDetial = (id) => {
|
||||
// mapWork.loadingDomShow(true)
|
||||
// console.log("这个是地图",mapWork)
|
||||
getLineListDetial_c(id).then((res) => {
|
||||
if (res.code === 200) {
|
||||
Object.assign(form, res.data)
|
||||
console.log("返回的经纬度",res.data.lat)
|
||||
console.log("返回的UUID",res.data.uuid)
|
||||
getPlotting(res.data.uuid)
|
||||
} else {
|
||||
proxy.$message.error(res.message);
|
||||
}
|
||||
});
|
||||
// mapWork.loadingDomShow(false)
|
||||
}
|
||||
const getPlotting = (id) => {
|
||||
getPlottingByUuid(id).then((res) => {
|
||||
if (res.code == 200) {
|
||||
mapWork.groupLayerTreeArr.value = []
|
||||
mapWork.graphicLayer;
|
||||
console.log("mapWork.graphicLayer:",mapWork.graphicLayer)
|
||||
mapWork.graphicLayer.getGraphicById(id)
|
||||
console.log("mapWork.graphicLayer根据id获取:",mapWork.graphicLayer.getGraphicById(id))
|
||||
console.log("返回的数据:",res.data)
|
||||
let dirList = res.data;
|
||||
let plot = [];
|
||||
dirList.forEach((item, index) => {
|
||||
plot = plot.concat(item.plottings)
|
||||
// item.plottings.forEach((m,n) =>{
|
||||
// plot.push(m)
|
||||
// })
|
||||
// if(item.init === 1 && item.source === 2){
|
||||
// item.name = 'DroneFly共享目录'
|
||||
// item.plottings.forEach((plot,inde) =>{
|
||||
// plot.isShare = true
|
||||
// })
|
||||
// }
|
||||
// if(item.init === 1 && item.source === 1){
|
||||
// item.name = '默认目录'
|
||||
// }
|
||||
mapWork.groupLayerTreeArr.value
|
||||
.push({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
type: item.type,
|
||||
appId: item.appId,
|
||||
orgId: item.orgId,
|
||||
// parentId: item.parentId,
|
||||
// folderId: item.parentId,
|
||||
// lockStatus: item.lockStatus,
|
||||
// shareStatus: item.shareStatus,
|
||||
showStatusWeb: item.showStatusWeb,
|
||||
// source: item.source,
|
||||
// init: item.init,
|
||||
// couldDel: item.couldDel,
|
||||
plottingStatus:item.plottingStatus,
|
||||
children: item.plottings,
|
||||
});
|
||||
});
|
||||
// mapWork.groupLayerTreeArr.value
|
||||
// .push({
|
||||
// id: res.data.id,
|
||||
// name: res.data.name,
|
||||
// type: res.data.type,
|
||||
// appId: res.data.appId,
|
||||
// orgId: res.data.orgId,
|
||||
// // parentId: item.parentId,
|
||||
// // folderId: item.parentId,
|
||||
// // lockStatus: item.lockStatus,
|
||||
// // shareStatus: item.shareStatus,
|
||||
// showStatusWeb: res.data.showStatusWeb,
|
||||
// // source: item.source,
|
||||
// // init: item.init,
|
||||
// // couldDel: item.couldDel,
|
||||
// plottingStatus:item.plottingStatus,
|
||||
// children: item.plottings,
|
||||
// });
|
||||
|
||||
mapWork.geoJsonLayerList(res.data);
|
||||
|
||||
// handleLocal(res.data)
|
||||
// 在数据加载完毕后,使用 nextTick 确保 el-tree 渲染完毕再设置选中
|
||||
// nextTick(() => {
|
||||
// setTreeNodeSelected({ id: 9 });
|
||||
// });
|
||||
} else {
|
||||
proxy.$message.error(res.msg);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 关闭途径点标绘
|
||||
const closedTJD = () => {
|
||||
if (proxy.$refs['pointListRef']) {
|
||||
console.log("🚀 ~ file: routeAdd.vue:377 ~ closedTJD ~ proxy.$refs['pointListRef']:", proxy.$refs['pointListRef'])
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
if (props.hxid) {
|
||||
getDetial(props.hxid)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.el-container {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: auto;
|
||||
bottom: 70px;
|
||||
z-index: 1001;
|
||||
width: 420px;
|
||||
height: auto;
|
||||
background: rgba(29, 37, 50, 0.85);
|
||||
|
||||
.el-header,
|
||||
.el-footer {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.addBtn {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.editBtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
background: #414243;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.displayFlex {
|
||||
border-bottom: 1px solid #414243;
|
||||
|
||||
.contentDom {
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
|
||||
.contentDom {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
.contentDom {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
388
src/views/cesiums/components/routeGet.vue
Normal file
388
src/views/cesiums/components/routeGet.vue
Normal file
@ -0,0 +1,388 @@
|
||||
<!--
|
||||
航线规划-航线列表
|
||||
crate by churl
|
||||
2023-3-6
|
||||
-->
|
||||
<template>
|
||||
<div class="el-container flexD dark">
|
||||
<div class="el-header">
|
||||
<div style="display: flex;align-items: center;">
|
||||
<h2 class="title" style="display: inline-block;margin-left: 8px;">创建空域</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="el-main">
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-position="top">
|
||||
<el-form-item label="空域名称" prop="name">
|
||||
<el-input v-model.trim="form.name" placeholder="请输入空域名称(建议:分局名称+时间+编号)" maxlength="15"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="所属战区" prop="militaryAreaName">
|
||||
<el-select v-model="form.militaryAreaName" placeholder="请选择所属战区" style="width: 100%;">
|
||||
<el-option v-for="item in slectmilitaryAreaList" :key="item.value" :label="item.name"
|
||||
:value="item.value">{{ item.name }}</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="空域类型" prop="airspaceType">
|
||||
<el-select v-model="form.airspaceType" placeholder="请选择空域类型" style="width: 100%;" >
|
||||
<el-option v-for="item in slectAirspaceTypeList" :key="item.value" :label="item.name"
|
||||
:value="item.value">{{ item.name }}</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="空域性制" prop="airspaceProp">
|
||||
<el-select v-model="form.airspaceProp" placeholder="请选择空域性制" style="width: 100%;">
|
||||
<el-option v-for="item in slectAirspacePropList" :key="item.value" :label="item.name"
|
||||
:value="item.value">{{ item.name }}</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="最大高度" prop="hightMax">
|
||||
<el-input v-model.trim="form.hightMax" maxlength="15"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="planBeg">
|
||||
<el-date-picker
|
||||
v-model="form.planBeg"
|
||||
type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
value-format="YYYY-MM-DD hh:mm:ss"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="截止时间" prop="planEnd">
|
||||
<el-date-picker v-model="form.planEnd" type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
value-format="YYYY-MM-DD hh:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="el-footer">
|
||||
<el-button type="primary" @click="submitForm" style="width: 100%;">返回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import "./ele.dark.style.css";
|
||||
import "@/assets/styles/c_style.scss"
|
||||
import { ref, reactive, onMounted, getCurrentInstance, computed } from 'vue';
|
||||
import { eidtAirLine_c, getLineListDetial_c,getPlottingByUuid } from "../api.js";
|
||||
|
||||
|
||||
import { useCesium } from './useCesium.js';
|
||||
import { useCesiumTools } from './useCesiumTools.js';
|
||||
import { useDrawingManager } from './useDrawingManager.js';
|
||||
const cesiumContainer = ref<HTMLElement>();
|
||||
// 初始化 Cesium
|
||||
const { viewer, viewTool, markerTool, modelTool, coordinatePicker, drawingTool, isInitialized } = useCesium('cesiumContainer');
|
||||
|
||||
// import { useDrawingManager } from './useDrawingManager'; // 调整路径
|
||||
|
||||
const drawingManager = useDrawingManager();
|
||||
|
||||
|
||||
// 初始化绘图管理
|
||||
const {
|
||||
isDrawing,
|
||||
currentDrawingType,
|
||||
drawings,
|
||||
selectedDrawing,
|
||||
drawingInfo,
|
||||
drawingOptions,
|
||||
startCircleDrawing,
|
||||
startPolygonDrawing,
|
||||
cancelDrawing,
|
||||
selectDrawing,
|
||||
deselectDrawing,
|
||||
removeDrawing,
|
||||
clearAllDrawings,
|
||||
flyToDrawing,
|
||||
updateDrawingOptions,
|
||||
getDrawingStatus,
|
||||
getDrawingInfoText,
|
||||
printSelectedDrawingInfo,
|
||||
printAllDrawingsInfo,
|
||||
printDrawingInfo,
|
||||
exportSelectedDrawingAsText,
|
||||
importAirspaceData,
|
||||
importFromFile,
|
||||
importFromGeoJSON,
|
||||
getImportStatistics,
|
||||
isEditing,
|
||||
editingDrawing,
|
||||
startEditing,
|
||||
finishEditing,
|
||||
cancelEditing,
|
||||
} = useDrawingManager(drawingTool);
|
||||
|
||||
|
||||
// const { proxy } = getCurrentInstance();
|
||||
const props = defineProps<{
|
||||
importFromFile: (file: File, options: any) => Promise<string[]>;
|
||||
importAirspaceData: (data: any[], options: any) => string[];
|
||||
getImportStatistics: () => { total: number; circles: number; polygons: number };
|
||||
id:string;
|
||||
hxid:string;
|
||||
}>();
|
||||
|
||||
// const props = defineProps(["id", 'hxid'])
|
||||
const emit = defineEmits(["setShowType"])
|
||||
//表单数据
|
||||
const formRef = ref(null)
|
||||
const form = reactive({
|
||||
// airlineName: '',
|
||||
airlineType: 0,
|
||||
waypointCount: '',
|
||||
length: '',
|
||||
expectedTime: '',
|
||||
flyToWaylineMode: 'safely',
|
||||
alt: 0,
|
||||
heightType: 'relativeToStartPoint',
|
||||
waypointHeadingMode: 'followWayline',
|
||||
gimbalPitchMode: 'manual',
|
||||
waypointTurnMode: 'coordinateTurn',
|
||||
executionType: 'goHome',
|
||||
uavType: '',
|
||||
uavPTZ: '',
|
||||
storageType: ['wide', 'zoom', 'ir'],
|
||||
hightMax: '',
|
||||
hightMin: '',
|
||||
lat: '',
|
||||
lng: '',
|
||||
militaryAreaName: '',
|
||||
militaryAreaId: null,
|
||||
name: '',
|
||||
flightRule: '',
|
||||
airspaceType: '',
|
||||
airspaceProp: '',
|
||||
radLength: '',
|
||||
startTime: null,
|
||||
endTime: null,
|
||||
planBeg: null,
|
||||
planEnd: null,
|
||||
uuid: null
|
||||
})
|
||||
|
||||
|
||||
// 表单校验
|
||||
const rules = reactive({
|
||||
name: [{ required: true, message: '请输入名称' },],
|
||||
militaryAreaName: [{ required: true, message: '请选择所属战区' },],
|
||||
airspaceType: [{ required: true, message: '请选择空域类型' },],
|
||||
airspaceProp: [{ required: true, message: '请选择空域性质' },],
|
||||
flightRule: [{ required: true, message: '请选择飞行规则' },],
|
||||
})
|
||||
//表单提交方法
|
||||
//表单提交方法
|
||||
const submitForm = () => {
|
||||
toList()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 返回列表
|
||||
const toList = () => {
|
||||
// mapWork.resethangxian()
|
||||
// window.location.reload()
|
||||
console.log("重置地图")
|
||||
// mapWork.endDraw()
|
||||
// mapWork.handleResetPlot()
|
||||
// mapWork.destroyMap()
|
||||
emit('setShowType', 'routeList', props.id)
|
||||
}
|
||||
|
||||
// 无人机下拉列表
|
||||
const slectUavTypeList = [{ name: 'M30 系列', value: '67' }, { name: 'Mavic 3 行业系列', value: '77' }]
|
||||
const slectmilitaryAreaList = [{ name: '东部战区', value: '1' }, { name: '南部战区', value: '2' }, { name: '西部战区', value: '3' }, { name: '北部战区', value: '4' }, { name: '中部战区', value: '5' }]
|
||||
const slectAirspaceTypeList = [{ name: '圆形空域', value: '1' }, { name: '多边形空域', value: '2' }]
|
||||
const slectFlightRuleList = [{ name: 'VFR', value: '1' }, { name: 'IFR', value: '2' }]
|
||||
const slectAirspacePropList = [{ name: '固定空域', value: '1' }, { name: '临时空域', value: '2' }]
|
||||
|
||||
|
||||
const pointList_show = ref(false)
|
||||
const pointList_show_handel = (val) => {
|
||||
console.log("这个val的值为",val)
|
||||
pointList_show.value = val
|
||||
if (!val) {
|
||||
// mapWork?.pointEndDraw()
|
||||
}
|
||||
}
|
||||
|
||||
// 获取详情
|
||||
const getDetial = (id) => {
|
||||
// mapWork.loadingDomShow(true)
|
||||
// console.log("这个是地图",mapWork)
|
||||
getLineListDetial_c(id).then((res) => {
|
||||
if (res.code === 200) {
|
||||
Object.assign(form, res.data)
|
||||
console.log("返回的经纬度",res.data.lat)
|
||||
console.log("返回的UUID",res.data.uuid)
|
||||
getPlotting(res.data.uuid)
|
||||
} else {
|
||||
message.error(res.message);
|
||||
}
|
||||
});
|
||||
// mapWork.loadingDomShow(false)
|
||||
}
|
||||
const getPlotting = (id) => {
|
||||
getPlottingByUuid(id).then((res) => {
|
||||
if (res.code == 200) {
|
||||
console.log("返回的数据0:",res)
|
||||
console.log("返回的数据1:",res.data[0].data)
|
||||
const data = JSON.parse(res.data[0].data);
|
||||
console.log("isInitialized:",isInitialized)
|
||||
const importedIds = props.importAirspaceData(data, null);
|
||||
importAirspaceData(data, null);
|
||||
console.log("返回的数据:",res.data)
|
||||
// mapWork.groupLayerTreeArr.value = []
|
||||
console.log("返回的数据:",res.data)
|
||||
let dirList = res.data;
|
||||
let plot = [];
|
||||
dirList.forEach((item, index) => {
|
||||
plot = plot.concat(item.plottings)
|
||||
// item.plottings.forEach((m,n) =>{
|
||||
// plot.push(m)
|
||||
// })
|
||||
// if(item.init === 1 && item.source === 2){
|
||||
// item.name = 'DroneFly共享目录'
|
||||
// item.plottings.forEach((plot,inde) =>{
|
||||
// plot.isShare = true
|
||||
// })
|
||||
// }
|
||||
// if(item.init === 1 && item.source === 1){
|
||||
// item.name = '默认目录'
|
||||
// }
|
||||
// mapWork.groupLayerTreeArr.value
|
||||
// .push({
|
||||
// id: item.id,
|
||||
// name: item.name,
|
||||
// type: item.type,
|
||||
// appId: item.appId,
|
||||
// orgId: item.orgId,
|
||||
// showStatusWeb: item.showStatusWeb,
|
||||
// plottingStatus:item.plottingStatus,
|
||||
// children: item.plottings,
|
||||
// });
|
||||
});
|
||||
// mapWork.groupLayerTreeArr.value
|
||||
// .push({
|
||||
// id: res.data.id,
|
||||
// name: res.data.name,
|
||||
// type: res.data.type,
|
||||
// appId: res.data.appId,
|
||||
// orgId: res.data.orgId,
|
||||
// // parentId: item.parentId,
|
||||
// // folderId: item.parentId,
|
||||
// // lockStatus: item.lockStatus,
|
||||
// // shareStatus: item.shareStatus,
|
||||
// showStatusWeb: res.data.showStatusWeb,
|
||||
// // source: item.source,
|
||||
// // init: item.init,
|
||||
// // couldDel: item.couldDel,
|
||||
// plottingStatus:item.plottingStatus,
|
||||
// children: item.plottings,
|
||||
// });
|
||||
|
||||
// mapWork.geoJsonLayerList(res.data);
|
||||
|
||||
handleLocal(res.data)
|
||||
// 在数据加载完毕后,使用 nextTick 确保 el-tree 渲染完毕再设置选中
|
||||
// nextTick(() => {
|
||||
// setTreeNodeSelected({ id: 9 });
|
||||
// });
|
||||
} else {
|
||||
// proxy.$message.error(res.msg);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
const handleLocal = (data) => {
|
||||
console.log("走到非地图这儿了吗!",data)
|
||||
// mapWork.geoCurrentGeoJsonLayers(data)
|
||||
// let vectorObj = JSON.parse(data);
|
||||
// console.log("vectorObj:",vectorObj)
|
||||
// let layer = mapWork.graphicLayer.getGraphicById(data.uuid) || mapWork.currentGeoJsonLayer.getGraphicById(data.uuid)
|
||||
// 定位到矢量要素所在位置
|
||||
// layer.flyTo();
|
||||
};
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
console.log("props:",props)
|
||||
if (props.hxid) {
|
||||
getDetial(props.hxid)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.el-container {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: auto;
|
||||
bottom: 70px;
|
||||
z-index: 1001;
|
||||
width: 420px;
|
||||
height: auto;
|
||||
background: rgba(29, 37, 50, 0.85);
|
||||
|
||||
.el-header,
|
||||
.el-footer {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.addBtn {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.editBtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
background: #414243;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.displayFlex {
|
||||
border-bottom: 1px solid #414243;
|
||||
|
||||
.contentDom {
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
|
||||
.contentDom {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
.contentDom {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
299
src/views/cesiums/components/routeList.vue
Normal file
299
src/views/cesiums/components/routeList.vue
Normal file
@ -0,0 +1,299 @@
|
||||
<!--
|
||||
空域规划-空域列表
|
||||
crate by churl
|
||||
2023-3-6
|
||||
-->
|
||||
<template>
|
||||
<div class="el-container flexD dark">
|
||||
<div class="el-header">
|
||||
<div style="display: flex;align-items: center;">
|
||||
<h2 class="title" style="display: inline-block;margin-left: 8px;">空域列表</h2>
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
<el-tooltip class="box-item" effect="dark" content="新增空域" placement="bottom-end">
|
||||
<el-icon size="24px" class="addBtn" @click="emit('setShowType','routeAdd', props.id)">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="el-header">
|
||||
<div>
|
||||
<div>
|
||||
<el-input style="width: 100%;" placeholder="请输入名称" v-model="queryParams.taskName" clearable @change="getLineList" />
|
||||
</div>
|
||||
<div style="margin-top:10px">
|
||||
<el-date-picker v-model="queryParams.taskTime" value-format="YYYY-MM-DD" type="daterange" style="width: 100%" range-separator="-" start-placeholder="开始时间" end-placeholder="结束时间" size="default"
|
||||
@change="getLineList" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="el-main" v-loading="tableData.loading" element-loading-background="rgba(0, 0, 0, 0.3)" element-loading-text="Loading...">
|
||||
<template v-for="item in tableData.list" :key="item.id">
|
||||
<div class="displayFlex">
|
||||
<ul class="contentDom">
|
||||
<li style="margin:5px 0;color: hsla(0deg, 0%, 100%, 0.45);">
|
||||
<span>空域名称:{{item.name?item.name:'--'}}</span>
|
||||
</li>
|
||||
<!-- <li style="margin:5px 0;color: hsla(0deg, 0%, 100%, 0.45);"> <span>所属战区:{{item.militaryAreaName?item.militaryAreaName:'--'}}</span></li> -->
|
||||
<li style="margin:5px 0;color: hsla(0deg, 0%, 100%, 0.45);"> <span>高度范围:{{0+"m~"+item.hightMax}}m</span></li>
|
||||
<li style="margin:5px 0;color: hsla(0deg, 0%, 100%, 0.45);">
|
||||
<span>开始时间 {{item.planBeg}} </span>
|
||||
</li>
|
||||
<li style="margin:5px 0;color: hsla(0deg, 0%, 100%, 0.45);">
|
||||
<span>截止时间 {{item.planEnd}} </span>
|
||||
</li>
|
||||
<li style="margin:5px 0;color: hsla(0deg, 0%, 100%, 0.45);">创建时间:{{item.createTime}}</li>
|
||||
<!-- <li style="margin:5px 0;color: hsla(0deg, 0%, 100%, 0.45);" v-if="item.archiveFlag === '1' ">已归档</li> -->
|
||||
<!-- <li>
|
||||
<el-icon size="20px" color="hsla(0,0%,100%,.45)" style="float:left">
|
||||
<UserFilled />
|
||||
</el-icon>
|
||||
<span style="margin-left:8px"> 1511796</span>
|
||||
</li> -->
|
||||
</ul>
|
||||
<!-- <div class="editBtn" @click="getDetial(item.id)" style="padding-left: 10px">-->
|
||||
<!-- <el-icon size="20px" color="#ffffff" class="enter-style">-->
|
||||
<!-- <Operation />-->
|
||||
<!-- </el-icon>-->
|
||||
<!-- </div>-->
|
||||
<div class="bottom">
|
||||
|
||||
<div class="btn-group">
|
||||
<el-button type="primary" style="margin-top: 5px;" @click="getDetials(item.id)" >查看</el-button>
|
||||
<el-button type="primary" style="margin-top: 5px;" @click="getDetial(item.id)">编辑</el-button>
|
||||
<el-button type="primary" style="margin-top: 5px;" @click="handleDel(item)" >删除</el-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="el-footer" v-if="tableData.total>0">
|
||||
<el-pagination background :small="true" layout="total, prev, pager, next" :page-sizes="[10, 30, 50, 100]" :total="tableData.total" v-model:page-size="queryParams.pageSize"
|
||||
v-model:currentPage="queryParams.pageNum" @size-change="getLineList" @current-change="getLineList"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
// import { useRouter } from "vue-router/dist/vue-router";
|
||||
import "./ele.dark.style.css";
|
||||
import "@/assets/styles/c_style.scss"
|
||||
import { ref,reactive, onMounted, getCurrentInstance } from 'vue';
|
||||
import { API_PUT_archiveAirline, getLineList_c,API_PUT_removeAirline } from "../api";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const props = defineProps(["id"])
|
||||
const emit = defineEmits(["setShowType"])
|
||||
|
||||
|
||||
// 判断是否为列表页面
|
||||
// 筛选条件
|
||||
const queryParams = reactive({
|
||||
taskName: '',
|
||||
taskTime: [],
|
||||
pageSize: 10,
|
||||
pageNum: 1
|
||||
})
|
||||
// 数据
|
||||
const tableData = reactive({
|
||||
loading: true,
|
||||
list: [],
|
||||
total: 0,
|
||||
})
|
||||
// 获取数据
|
||||
const getLineList = () => {
|
||||
let fromData = {
|
||||
// itemId: props.id,
|
||||
pageSize: queryParams.pageSize,
|
||||
pageNum: queryParams.pageNum,
|
||||
name: queryParams.taskName,
|
||||
startTime: queryParams.taskTime[0] ? queryParams.taskTime[0] : '',
|
||||
endTime: queryParams.taskTime[1] ? queryParams.taskTime[1] : '',
|
||||
}
|
||||
console.log("fromData: " , fromData);
|
||||
getLineList_c(fromData).then((res) => {
|
||||
tableData.loading = false
|
||||
if (res.code === 200) {
|
||||
tableData.list = res.rows;
|
||||
tableData.total = res.total;
|
||||
} else {
|
||||
proxy.$message.error(res.message);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
// 返回列表
|
||||
const toList = () => {
|
||||
emit('setShowType', 'planList')
|
||||
}
|
||||
// 编辑
|
||||
const getDetial = (id) => {
|
||||
emit('setShowType', 'routeAdd', props.id, id)
|
||||
}
|
||||
// 获取详情
|
||||
const getDetials = (id) => {
|
||||
emit('setShowType', 'routeGet', props.id, id)
|
||||
}
|
||||
|
||||
// 归档
|
||||
const handleTask = async (row) => { //归档事件
|
||||
const id = row.id;
|
||||
const idName = row.airlineName
|
||||
proxy.$confirm('是否确认归档空域"' + idName + '"', "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(function () {
|
||||
return API_PUT_archiveAirline(id);
|
||||
}).then(() => {
|
||||
getLineList()
|
||||
proxy.$message.success(`归档成功`)
|
||||
}).catch(function () { return false });
|
||||
}
|
||||
// 删除
|
||||
const handleDel = async (row) => { //删除事件
|
||||
const id = row.id;
|
||||
const idName = row.name
|
||||
proxy.$confirm('是否确认删除空域"' + idName + '"', "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(function () {
|
||||
return API_PUT_removeAirline(id);
|
||||
}).then(() => {
|
||||
getLineList()
|
||||
proxy.$message.success(`删除成功`)
|
||||
}).catch(function () { return false });
|
||||
}
|
||||
|
||||
const router = useRouter()
|
||||
onMounted(() => {
|
||||
// 是否页面跳转校验
|
||||
if (router.currentRoute.value.query.id) {
|
||||
let id = router.currentRoute.value.query.id
|
||||
emit('setShowType', 'routeAdd', props.id, id)
|
||||
router.currentRoute.value.query.id = null
|
||||
}else {
|
||||
getLineList()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.singleton-tooltip {
|
||||
transition: transform 0.3s var(--el-transition-function-fast-bezier);
|
||||
}
|
||||
.center {
|
||||
color: #0a0a0a;
|
||||
cursor: pointer;
|
||||
padding: 8px 11px;
|
||||
font-size: 15px;
|
||||
|
||||
.el-popper.is-customized {
|
||||
padding: 6px 12px;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgb(159, 229, 151),
|
||||
rgb(204, 229, 129)
|
||||
);
|
||||
}
|
||||
|
||||
.el-popper.is-customized .el-popper__arrow::before {
|
||||
background: linear-gradient(45deg, #b2e68d, #bce689);
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
.btn-group button {
|
||||
display: block; /* 使按钮出现在彼此下方 */
|
||||
margin-left: 20px;
|
||||
}
|
||||
.el-container {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: auto;
|
||||
bottom: 10px;
|
||||
z-index: 1001;
|
||||
width: 420px;
|
||||
height: auto;
|
||||
background: rgba(29, 37, 50, 0.85);
|
||||
|
||||
.el-header {
|
||||
background: transparent;
|
||||
}
|
||||
.customer-header {
|
||||
background: transparent;
|
||||
display: block !important; /* 使用 display: block 覆盖 flex */
|
||||
}
|
||||
.el-footer {
|
||||
background: transparent;
|
||||
display: block !important; /* 使用 display: block 覆盖 flex */
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: white; }
|
||||
|
||||
.addBtn {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.editBtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 15px;
|
||||
margin: 26px 0;
|
||||
background: #414243;
|
||||
}
|
||||
}
|
||||
.exx {
|
||||
color: #ecf5ff;
|
||||
}
|
||||
.exx:hover {
|
||||
background-color: #0a4b8e;
|
||||
color: #ecf5ff;
|
||||
}
|
||||
|
||||
.displayFlex {
|
||||
border-bottom: 1px solid #414243;
|
||||
.contentDom {
|
||||
padding: 15px 0;
|
||||
}
|
||||
li {
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
.close-button {
|
||||
margin-left: 800px; /* 调整右侧间距,根据需要进行调整 */
|
||||
}
|
||||
.ImportAirlinesButton {
|
||||
text-align: left; /* 将文本左对齐 */
|
||||
margin-left: -160px; /* 调整左侧间距,根据第一个字段的宽度进行调整 */
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
display: flex;
|
||||
justify-content: center; // 水平居中
|
||||
align-items: center; // 垂直居中
|
||||
flex-direction: column; // 确保内容是垂直的
|
||||
height: 100%; // 使用100%的高度确保内容在对话框中居中
|
||||
}
|
||||
.table-container {
|
||||
max-height: 550px; /* You can adjust this value based on your requirements */
|
||||
overflow-y: auto; /* Enable vertical scrolling when the content overflows */
|
||||
width: 100%; /* Ensure the container takes full width */
|
||||
}
|
||||
.el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: #409eff;
|
||||
}
|
||||
.el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
@ -366,12 +366,29 @@ export function useDrawingManager(drawingTool: any) { // 修改参数类型为 a
|
||||
* 导入空域数据
|
||||
*/
|
||||
const importAirspaceData = (data: any[], options: ImportOptions = {}): string[] => {
|
||||
console.log("drawingTool:",drawingTool)
|
||||
watch(() => drawingTool?.value, (newTool) => {
|
||||
if (newTool) {
|
||||
newTool.setCallbacks({
|
||||
onClick: (result: DrawingResult, info: DrawingInfo) => {
|
||||
handleDrawingClick(result, info);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, { immediate: true });
|
||||
const getTool = () => {
|
||||
console.log("drawingTool1:",drawingTool)
|
||||
console.log("drawingTool2:",drawingTool?.value)
|
||||
return drawingTool?.value;
|
||||
};
|
||||
const tool = getTool();
|
||||
console.log("tool:",tool)
|
||||
if (!tool) {
|
||||
console.error('❌ 绘图工具未初始化');
|
||||
return [];
|
||||
}
|
||||
|
||||
console.log('开始导入空域数据:', data);
|
||||
console.log('开始导入空域数据,数量:', data.length);
|
||||
return tool.importAirspaceData(data, options);
|
||||
};
|
||||
|
||||
49
src/views/cesiums/sandtable.vue
Normal file
49
src/views/cesiums/sandtable.vue
Normal file
@ -0,0 +1,49 @@
|
||||
<!-- src/App.vue -->
|
||||
<template>
|
||||
<div id="app">
|
||||
<!-- <header class="app-header">
|
||||
<h1>🌉 重庆三维地图系统</h1>
|
||||
<p>基于 Vue 3 + Cesium 的三维地理信息系统</p>
|
||||
</header> -->
|
||||
<!-- <main class="app-main"> -->
|
||||
<CesiumViewer />
|
||||
<!-- </main> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import CesiumViewer from './CesiumViewer.vue';
|
||||
</script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#app {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
.app-header {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.app-header h1 {
|
||||
margin-bottom: 8px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.app-header p {
|
||||
opacity: 0.9;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.app-main {
|
||||
height: calc(100vh - 80px);
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user