|  |  |  | @ -4,38 +4,35 @@ | 
		
	
		
			
				|  |  |  |  |   创建人:Zhaipeixiu | 
		
	
		
			
				|  |  |  |  | --> | 
		
	
		
			
				|  |  |  |  | <script setup> | 
		
	
		
			
				|  |  |  |  | import {ChevronBack,ChevronForward, CreateOutline, DuplicateSharp, EyeSharp, Layers, Settings} from '@vicons/ionicons5' | 
		
	
		
			
				|  |  |  |  | import {ChevronBack, CreateOutline, DuplicateSharp, EyeSharp, Layers, Settings} from '@vicons/ionicons5' | 
		
	
		
			
				|  |  |  |  | import {RulerAlt} from '@vicons/carbon' | 
		
	
		
			
				|  |  |  |  | import {TerrainSharp} from '@vicons/material' | 
		
	
		
			
				|  |  |  |  | import {DrawPolygon} from '@vicons/fa' | 
		
	
		
			
				|  |  |  |  | import {useMessage} from 'naive-ui' | 
		
	
		
			
				|  |  |  |  | import {ref, defineEmits} from "vue"; | 
		
	
		
			
				|  |  |  |  | import {nextTick, ref} from "vue"; | 
		
	
		
			
				|  |  |  |  | import {useStaticStore} from "@/store/staticOptions.js"; | 
		
	
		
			
				|  |  |  |  | import {dataProcess_fromQT, dataProcess_fromQT_route} from "@/assets/js/websocketProtocol.ts"; | 
		
	
		
			
				|  |  |  |  | import SpatialAnalysis from "@/components/SpatialAnalysis.vue"; | 
		
	
		
			
				|  |  |  |  | import LayerManager from "@/components/map/LayerManager.vue"; | 
		
	
		
			
				|  |  |  |  | import CollisionDetection from "./CollisionDetection.vue" | 
		
	
		
			
				|  |  |  |  | import CollisionDetection from "@/components/CollisionDetection.vue"; | 
		
	
		
			
				|  |  |  |  | import {useLayerStore} from "@/store/layerManagerStore.ts"; | 
		
	
		
			
				|  |  |  |  | import {Cartesian3} from "cesium"; | 
		
	
		
			
				|  |  |  |  | import {ByDirectionAndLen, getDistance, getElevation} from "@/utils/map/geocomputation.ts"; | 
		
	
		
			
				|  |  |  |  | import * as echarts from "echarts"; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | const emit = defineEmits(['resizeMap']) | 
		
	
		
			
				|  |  |  |  | const message = useMessage(); | 
		
	
		
			
				|  |  |  |  | let SceneValue; | 
		
	
		
			
				|  |  |  |  | let showModal = ref(false); | 
		
	
		
			
				|  |  |  |  | let hasPlane = ref(false); | 
		
	
		
			
				|  |  |  |  | let showDetection = ref(false); | 
		
	
		
			
				|  |  |  |  | let hasPlane = ref(false); | 
		
	
		
			
				|  |  |  |  | let store = useStaticStore(); | 
		
	
		
			
				|  |  |  |  | let lStore = useLayerStore(); | 
		
	
		
			
				|  |  |  |  | let groundHeight = ref(-1) | 
		
	
		
			
				|  |  |  |  | let detectDivHeight = ref(25) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | const spatialAnalyse = ref(null) | 
		
	
		
			
				|  |  |  |  | const layerManager = ref(null) | 
		
	
		
			
				|  |  |  |  | const collisionDetection = ref(null) | 
		
	
		
			
				|  |  |  |  | SceneValue = ref('untrace'); | 
		
	
		
			
				|  |  |  |  | let frameCount = 0 | 
		
	
		
			
				|  |  |  |  | let lastPos = undefined;  //飞机上一时点的坐标 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | function handleSceneSelect(key){ | 
		
	
		
			
				|  |  |  |  |   if(!hasPlane.value)   return; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -47,19 +44,9 @@ function handleSceneSelect(key){ | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | let layerValue = ref('layer1'); | 
		
	
		
			
				|  |  |  |  | let barIsOpen = ref(true); | 
		
	
		
			
				|  |  |  |  | function openCloseBar() { | 
		
	
		
			
				|  |  |  |  |   // 获取元素 | 
		
	
		
			
				|  |  |  |  |   let toolbar = document.querySelector('.panel-toolbar989834y34'); | 
		
	
		
			
				|  |  |  |  |   if(toolbar?.classList.contains('open')){  //关闭 | 
		
	
		
			
				|  |  |  |  |     toolbar?.classList.remove('open'); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   else {         // 打开 | 
		
	
		
			
				|  |  |  |  |     toolbar?.classList.add('open'); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   barIsOpen.value = !barIsOpen.value | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | function handleEditSelect(key) { | 
		
	
		
			
				|  |  |  |  |   if(key === 'createLine') { | 
		
	
		
			
				|  |  |  |  |   if(key === 'requestLine') { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   else{ | 
		
	
	
		
			
				
					|  |  |  | @ -165,7 +152,7 @@ function measureArea() { | 
		
	
		
			
				|  |  |  |  | async function connectWebSocket() { | 
		
	
		
			
				|  |  |  |  |   store.webskt.ws = new WebSocket('ws://'+store.webskt.ws_config.address+':'+store.webskt.ws_config.port); | 
		
	
		
			
				|  |  |  |  |   store.webskt.ws.onopen = function(event){ | 
		
	
		
			
				|  |  |  |  |     console.log("Connection open ...") | 
		
	
		
			
				|  |  |  |  |     console.log("Connection open ..."); | 
		
	
		
			
				|  |  |  |  |     store.webskt.ws.send("hello QT!") | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -179,72 +166,49 @@ async function connectWebSocket() { | 
		
	
		
			
				|  |  |  |  |       if (ycData != null) { | 
		
	
		
			
				|  |  |  |  |         // 更新遥测数据(飞机位置) | 
		
	
		
			
				|  |  |  |  |         window.measureViewer.updateDynamicData(ycData) | 
		
	
		
			
				|  |  |  |  |         lStore.validYCData = true | 
		
	
		
			
				|  |  |  |  |         // 添加飞机三维图标 | 
		
	
		
			
				|  |  |  |  |         if(!hasPlane.value){ | 
		
	
		
			
				|  |  |  |  |           window.measureViewer.addAirplaneEntity(store.models.fp98, ycData.uavId + ycData.uavType) | 
		
	
		
			
				|  |  |  |  |           window.measureViewer.addAirplaneEntity(store.models.defaultAirPlane, ycData.uavId + ycData.uavType) | 
		
	
		
			
				|  |  |  |  |           SceneValue.value = 'fallow' | 
		
	
		
			
				|  |  |  |  |           hasPlane.value = true; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         // 加载和更新碰撞检测图(50帧更新一次) | 
		
	
		
			
				|  |  |  |  |         if(frameCount>50 && lStore.openDetect){ | 
		
	
		
			
				|  |  |  |  |           emit('resizeMap', detectDivHeight.value) | 
		
	
		
			
				|  |  |  |  |           showDetection.value = true | 
		
	
		
			
				|  |  |  |  |         /************************测试代码(以下)******************/ | 
		
	
		
			
				|  |  |  |  |         // if(frameCount>50) {   //(50帧更新一次) | 
		
	
		
			
				|  |  |  |  |         //   frameCount = 0 | 
		
	
		
			
				|  |  |  |  |         //   //TODO: 调用子组件函数、测试 | 
		
	
		
			
				|  |  |  |  |         //   let cartesianTarget = Cartesian3.fromDegrees(114.6, 37.8) | 
		
	
		
			
				|  |  |  |  |         //   let cartesianCurr = Cartesian3.fromDegrees(ycData.lon, ycData.lat, ycData.alt) | 
		
	
		
			
				|  |  |  |  |         //   collisionDetection.value?.drawDetection(ycData.alt, cartesianCurr, cartesianTarget) | 
		
	
		
			
				|  |  |  |  |         // } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         /************************测试代码(以上)******************/ | 
		
	
		
			
				|  |  |  |  |         // 加载和更新碰撞检测图(20帧更新一次) | 
		
	
		
			
				|  |  |  |  |         if(lStore.navi.airlines.length>0 && frameCount>50){ | 
		
	
		
			
				|  |  |  |  |           frameCount = 0 | 
		
	
		
			
				|  |  |  |  |           let currentPos = Cartesian3.fromDegrees(ycData.lon, ycData.lat,ycData.alt) | 
		
	
		
			
				|  |  |  |  |           // 显示飞机当前位置的地表投影点海拔高度 和 飞机高度(折线图) | 
		
	
		
			
				|  |  |  |  |           new Promise(resolve => { | 
		
	
		
			
				|  |  |  |  |             // 计算对地高度 m | 
		
	
		
			
				|  |  |  |  |             groundHeight.value = ycData.alt - getElevation(window.viewer, currentPos) | 
		
	
		
			
				|  |  |  |  |             // 计算当前点与上一点的距离 米 | 
		
	
		
			
				|  |  |  |  |             if(lastPos===undefined){ | 
		
	
		
			
				|  |  |  |  |               lastPos = currentPos; | 
		
	
		
			
				|  |  |  |  |           lStore.navi.airlines.forEach(airline => { | 
		
	
		
			
				|  |  |  |  |             if(airline.code === lStore.navi.currentRouteID){ | 
		
	
		
			
				|  |  |  |  |               let targetPos = airline.points[lStore.navi.nextPoint] | 
		
	
		
			
				|  |  |  |  |               //TODO: 调用子组件函数、测试 | 
		
	
		
			
				|  |  |  |  |               let cartesianTarget = Cartesian3.fromDegrees(targetPos.lon, targetPos.lat,targetPos.alt) | 
		
	
		
			
				|  |  |  |  |               let cartesianCurr = Cartesian3.fromDegrees(ycData.lon, ycData.lat,ycData.alt) | 
		
	
		
			
				|  |  |  |  |               collisionDetection.value?.drawDetection(ycData.alt, cartesianCurr, cartesianTarget) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             let dis = getDistance(currentPos, lastPos) * 1000 | 
		
	
		
			
				|  |  |  |  |             lastPos = currentPos | 
		
	
		
			
				|  |  |  |  |             resolve(dis) | 
		
	
		
			
				|  |  |  |  |           }).then(res=>{ | 
		
	
		
			
				|  |  |  |  |             collisionDetection.value.drawDetection(ycData.alt, res, ycData.alt-groundHeight.value) | 
		
	
		
			
				|  |  |  |  |           }) | 
		
	
		
			
				|  |  |  |  |           // 当前飞机高度(折线图) 和飞机前方10公里处的地形高度(以飞机当前航向推算) | 
		
	
		
			
				|  |  |  |  |           let max_dis = 5000 | 
		
	
		
			
				|  |  |  |  |           new Promise(resolve => { | 
		
	
		
			
				|  |  |  |  |             // 计算前方5公里处的坐标点 | 
		
	
		
			
				|  |  |  |  |             let detectPos = ByDirectionAndLen(currentPos, ycData.heading, max_dis) | 
		
	
		
			
				|  |  |  |  |             // 计算地形剖面 | 
		
	
		
			
				|  |  |  |  |             collisionDetection.value.drawTerrain(ycData.alt, currentPos, detectPos, max_dis) | 
		
	
		
			
				|  |  |  |  |             resolve(detectPos) | 
		
	
		
			
				|  |  |  |  |           }) | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       else{ //遥测解析错误或无数据 | 
		
	
		
			
				|  |  |  |  |         lStore.validYCData = false | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     if(sktData.type === 1){ | 
		
	
		
			
				|  |  |  |  |       let routeData = dataProcess_fromQT_route(sktData) | 
		
	
		
			
				|  |  |  |  |       lStore.navi.airlines.push(routeData) | 
		
	
		
			
				|  |  |  |  |       console.log(routeData) | 
		
	
		
			
				|  |  |  |  |       if(routeData != null){ | 
		
	
		
			
				|  |  |  |  |         lStore.navi.airlines.push(routeData) | 
		
	
		
			
				|  |  |  |  |         lStore.navi.currentRouteID = routeData.code | 
		
	
		
			
				|  |  |  |  |         console.log(routeData) | 
		
	
		
			
				|  |  |  |  |         window.measureViewer.showAirLine(routeData) | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | //关闭动态碰撞检测功能 | 
		
	
		
			
				|  |  |  |  | function shutDownDetec() { | 
		
	
		
			
				|  |  |  |  |   if(lStore.openDetect){ | 
		
	
		
			
				|  |  |  |  |     emit('resizeMap', -1) | 
		
	
		
			
				|  |  |  |  |   }else{ | 
		
	
		
			
				|  |  |  |  |     emit('resizeMap', detectDivHeight.value) | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   showDetection.value = !showDetection.value; | 
		
	
		
			
				|  |  |  |  |   lStore.openDetect = !lStore.openDetect | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | /** | 
		
	
		
			
				|  |  |  |  |  * 关闭websocket连接 | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
	
		
			
				
					|  |  |  | @ -261,7 +225,7 @@ function manageLayer(){ | 
		
	
		
			
				|  |  |  |  | </script> | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | <template> | 
		
	
		
			
				|  |  |  |  |   <n-space class="panel-toolbar989834y34"> | 
		
	
		
			
				|  |  |  |  |   <n-space id="panel"> | 
		
	
		
			
				|  |  |  |  |     <n-row justify-content="space-between"> | 
		
	
		
			
				|  |  |  |  |     <n-tooltip placement="bottom" trigger="hover" > | 
		
	
		
			
				|  |  |  |  |       <template #trigger> | 
		
	
	
		
			
				
					|  |  |  | @ -292,7 +256,6 @@ function manageLayer(){ | 
		
	
		
			
				|  |  |  |  |     </n-dropdown> | 
		
	
		
			
				|  |  |  |  |     <n-dropdown :options="store.menuOptions.EditOptions" @select="handleEditSelect"> | 
		
	
		
			
				|  |  |  |  |     <n-button tertiary circle type="warning"> | 
		
	
		
			
				|  |  |  |  |     <!--航线绘制--> | 
		
	
		
			
				|  |  |  |  |       <template #icon> | 
		
	
		
			
				|  |  |  |  |         <n-icon><CreateOutline/></n-icon> | 
		
	
		
			
				|  |  |  |  |       </template> | 
		
	
	
		
			
				
					|  |  |  | @ -324,32 +287,25 @@ function manageLayer(){ | 
		
	
		
			
				|  |  |  |  |     </n-tooltip> | 
		
	
		
			
				|  |  |  |  |     <n-popselect v-model:value="SceneValue" :options="store.menuOptions.sceneOptions" | 
		
	
		
			
				|  |  |  |  |                  @update:value="handleSceneSelect" size="medium"> | 
		
	
		
			
				|  |  |  |  | <!--                 :disabled="!hasPlane" --> | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       <n-button tertiary circle type="warning"> | 
		
	
		
			
				|  |  |  |  |         <template #icon> | 
		
	
		
			
				|  |  |  |  |           <n-icon><EyeSharp/></n-icon> | 
		
	
		
			
				|  |  |  |  |         </template> | 
		
	
		
			
				|  |  |  |  |       </n-button> | 
		
	
		
			
				|  |  |  |  |     </n-popselect> | 
		
	
		
			
				|  |  |  |  |     <n-button tertiary circle type="warning" @click="openCloseBar"> | 
		
	
		
			
				|  |  |  |  |     <n-button tertiary circle type="warning"> | 
		
	
		
			
				|  |  |  |  |       <template #icon> | 
		
	
		
			
				|  |  |  |  |         <n-icon v-if="barIsOpen"><ChevronBack/></n-icon> | 
		
	
		
			
				|  |  |  |  |         <n-icon v-else><ChevronForward/></n-icon> | 
		
	
		
			
				|  |  |  |  | <!--        ChevronBack,ChevronForward,--> | 
		
	
		
			
				|  |  |  |  |         <n-icon><ChevronBack/></n-icon> | 
		
	
		
			
				|  |  |  |  |       </template> | 
		
	
		
			
				|  |  |  |  |     </n-button> | 
		
	
		
			
				|  |  |  |  |     </n-row> | 
		
	
		
			
				|  |  |  |  |   </n-space> | 
		
	
		
			
				|  |  |  |  |   <n-button id="bt_switch" size="small" :type="showDetection? 'error': 'success'" v-if="lStore.validYCData" | 
		
	
		
			
				|  |  |  |  |             @click="shutDownDetec" :style="{bottom:'0vh'}"> | 
		
	
		
			
				|  |  |  |  |     {{showDetection? '关闭图表': '显示图表'}} | 
		
	
		
			
				|  |  |  |  |   </n-button> | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   <n-collapse-transition v-show="showDetection"> | 
		
	
		
			
				|  |  |  |  |     <n-flex id="detectionGraph" justify="center" | 
		
	
		
			
				|  |  |  |  |             :style="{height: detectDivHeight +'vh'}"> | 
		
	
		
			
				|  |  |  |  |       <CollisionDetection ref="collisionDetection" ></CollisionDetection> | 
		
	
		
			
				|  |  |  |  |     </n-flex> | 
		
	
		
			
				|  |  |  |  |   </n-collapse-transition> | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   <n-space id="detectionGraph" v-show="showDetection"> | 
		
	
		
			
				|  |  |  |  |     <CollisionDetection ref="collisionDetection"></CollisionDetection> | 
		
	
		
			
				|  |  |  |  |   </n-space> | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   <n-modal v-model:show="showModal" | 
		
	
		
			
				|  |  |  |  |         style="width: 30%" | 
		
	
	
		
			
				
					|  |  |  | @ -385,31 +341,21 @@ function manageLayer(){ | 
		
	
		
			
				|  |  |  |  |   <LayerManager ref="layerManager"></LayerManager> | 
		
	
		
			
				|  |  |  |  | </template> | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | <style> | 
		
	
		
			
				|  |  |  |  | .panel-toolbar989834y34{ | 
		
	
		
			
				|  |  |  |  | <style scoped> | 
		
	
		
			
				|  |  |  |  | #panel{ | 
		
	
		
			
				|  |  |  |  |   position: absolute; | 
		
	
		
			
				|  |  |  |  |   top: 10px; | 
		
	
		
			
				|  |  |  |  |   left: 2px; | 
		
	
		
			
				|  |  |  |  |   border-radius: 7px; | 
		
	
		
			
				|  |  |  |  |   background: rgba(21, 21, 21, 0.94); | 
		
	
		
			
				|  |  |  |  |   transition: left 0.3s; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | .panel-toolbar989834y34.open{ | 
		
	
		
			
				|  |  |  |  |   position: absolute; | 
		
	
		
			
				|  |  |  |  |   left: -20rem; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #bt_switch{ | 
		
	
		
			
				|  |  |  |  |   position: absolute; | 
		
	
		
			
				|  |  |  |  |   z-index: 2; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | #detectionGraph{ | 
		
	
		
			
				|  |  |  |  |   position: absolute; | 
		
	
		
			
				|  |  |  |  |   bottom: -25vh; | 
		
	
		
			
				|  |  |  |  |   width: 100vW; | 
		
	
		
			
				|  |  |  |  |   bottom: 2rem; | 
		
	
		
			
				|  |  |  |  |   width: 100rem; | 
		
	
		
			
				|  |  |  |  |   height: 15rem; | 
		
	
		
			
				|  |  |  |  |   border-radius: 7px; | 
		
	
		
			
				|  |  |  |  |   background: rgba(255, 255, 255, 0.8); | 
		
	
		
			
				|  |  |  |  |   background: rgba(21, 21, 21, 0.94); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | </style> | 
		
	
	
		
			
				
					|  |  |  | 
 |