From 4a67166430835e26b8993f92b7370b69372a0ca6 Mon Sep 17 00:00:00 2001 From: zhaipx Date: Thu, 13 Mar 2025 13:41:32 +0800 Subject: [PATCH] =?UTF-8?q?feature:=20=E5=AE=9E=E7=8E=B0=E4=B8=8EQT?= =?UTF-8?q?=E7=AB=AFwebsocket=E7=9A=84=E4=BA=A4=E4=BA=92=EF=BC=8C=E5=88=9D?= =?UTF-8?q?=E6=AD=A5=E5=AE=9E=E7=8E=B0=E4=B8=89=E7=BB=B4=E4=BC=B4=E9=A3=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/js/cesium-map/measureDistance.js | 2 +- src/assets/js/websocketProtocol.ts | 24 +++++++++++- src/components/SpatialAnalysis.vue | 29 ++++++++++++--- src/components/toolbar.vue | 23 ++++-------- src/store/staticOptions.js | 2 +- src/utils/map/SpatialAnalysis.ts | 41 ++++++++++++++++++--- 6 files changed, 91 insertions(+), 30 deletions(-) diff --git a/src/assets/js/cesium-map/measureDistance.js b/src/assets/js/cesium-map/measureDistance.js index 0f99364..12ede66 100644 --- a/src/assets/js/cesium-map/measureDistance.js +++ b/src/assets/js/cesium-map/measureDistance.js @@ -67,6 +67,7 @@ export default class MeasureDistance { clampToGround: true, }, }) + this.analyseGraphs.push(line) } //通视分析仅支持选择两个点 if(useStaticStore().analysisVars.analysisType===2&&profilePts.length===2){ @@ -97,7 +98,6 @@ export default class MeasureDistance { let endEntity = this._createPointEntity(position, count.toString()) this.viewer.entities.add(endEntity) this.analyseGraphs.push(endEntity) - this.analyseGraphs.push(line) this.unRegisterEvents() useStaticStore().analysisVars.profilePts = profilePts }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); diff --git a/src/assets/js/websocketProtocol.ts b/src/assets/js/websocketProtocol.ts index 1fc8b3e..b7a374f 100644 --- a/src/assets/js/websocketProtocol.ts +++ b/src/assets/js/websocketProtocol.ts @@ -1,7 +1,7 @@ import {Airline, AirlinePoint, UavDynamicInfo} from "@/types/entityoptions.ts"; /** - * 处理来自websocket的数据,返回所需数据 + * 处理来自中心指控websocket的数据,返回所需数据 * @param websocketDataCC * @return UavDynamicInfo */ @@ -30,6 +30,26 @@ function dataProcess(websocketDataCC:any): UavDynamicInfo|null { return data.lon==0? null: data } +/** + * 处理来自QT端 websocket的数据,返回所需数据 + * @param websocketDataQT + * @return UavDynamicInfo + */ +function dataProcess_fromQT(websocketDataQT:any): UavDynamicInfo|null { + let data:UavDynamicInfo = { + alt: 0, groundSpeed: 0, heading: 0, lat: 0, lon: 0, uavId: "", uavType: "" + } + data.uavId = websocketDataQT.uavId + data.uavType = websocketDataQT.uavType + data.heading = websocketDataQT.HeadAngle + data.lon = websocketDataQT.lon + data.lat = websocketDataQT.lat + data.alt = websocketDataQT.height + data.groundSpeed = websocketDataQT.groundSpeed //km/h + + return data.lon==0? null: data +} + function getAirline(data: any): Airline | null { let line: Airline = {totalDistance: 0, PtNum: 0, name: "", isClose: false, points: []} line.PtNum = data.PtNum @@ -53,4 +73,4 @@ function getUavTypeStr(type: number) : string{ default: return 'test' } } -export {dataProcess,getAirline} \ No newline at end of file +export {dataProcess_fromQT,getAirline} \ No newline at end of file diff --git a/src/components/SpatialAnalysis.vue b/src/components/SpatialAnalysis.vue index a329258..af8aeed 100644 --- a/src/components/SpatialAnalysis.vue +++ b/src/components/SpatialAnalysis.vue @@ -8,7 +8,7 @@ import {nextTick, ref, watch} from "vue"; import { drawEchartsProfileAnalyse, drawEchartsVisibility, elevationProfile, - profileAnalyse + profileAnalyse, visibilityAnalyse2 } from "@/utils/map/SpatialAnalysis.ts"; import {useStaticStore} from "@/store/staticOptions"; import {useMessage} from "naive-ui"; @@ -23,8 +23,9 @@ let formParams = ref({ interval: 100, startClearance: 40, //起点离地高度 endClearance: 10, //起点离地高度 + curve: true }) - +let isVisible = ref(false) // 关闭地形分析结果窗口德回调 const handleCloseProfile = ()=>{ //移除图形元素 @@ -53,12 +54,15 @@ function executeTopographicAnalyse(polyline:Cartesian3[]) { let res = profileAnalyse(window.viewer, polyline,formParams.value.interval) // 计算视线起始点距离和高度 let eyeRes = elevationProfile(window.viewer,polyline[0],polyline[1],-1) - eyeRes.elevationArray[0] += Number(formParams.value.startClearance) - eyeRes.elevationArray[1] += Number(formParams.value.endClearance) + // 弹出图表窗口 showResultModal.value = true nextTick(()=>{ - drawEchartsVisibility(res.distanceArray, res.elevationArray, eyeRes.elevationArray[0],eyeRes.elevationArray[1]) + drawEchartsVisibility(res.distanceArray, res.elevationArray, + eyeRes.elevationArray[0]+Number(formParams.value.startClearance), + eyeRes.elevationArray[1]+Number(formParams.value.endClearance)) + + isVisible.value = visibilityAnalyse2(res,true, Number(formParams.value.startClearance),Number(formParams.value.endClearance)) }) } @@ -121,6 +125,11 @@ const afterCoordInput = ()=> { preset="card" draggable :mask-closable="false" :on-after-leave="handleCloseProfile" :title="store.analysisVars.analysisType==2? '通视分析结果':'剖面分析结果'"> @@ -154,6 +163,10 @@ const afterCoordInput = ()=> { + + + + @@ -193,4 +206,10 @@ const afterCoordInput = ()=> { position: relative; margin-top: -2rem; } +.ResGreen{ + color: #26c926; +} +.ResRed{ + color: #FF0000; +} diff --git a/src/components/toolbar.vue b/src/components/toolbar.vue index c26b0ff..0761401 100644 --- a/src/components/toolbar.vue +++ b/src/components/toolbar.vue @@ -11,8 +11,8 @@ import {DrawPolygon} from '@vicons/fa' import {useMessage} from 'naive-ui' import {ref} from "vue"; import {useStaticStore} from "@/store/staticOptions.js"; -import {login, requestAirline} from "@/assets/js/request.js"; -import {dataProcess, getAirline} from "@/assets/js/websocketProtocol.ts"; +import {requestAirline} from "@/assets/js/request.js"; +import {dataProcess_fromQT, getAirline} from "@/assets/js/websocketProtocol.ts"; import SpatialAnalysis from "@/components/SpatialAnalysis.vue"; import LayerManager from "@/components/map/LayerManager.vue"; @@ -143,22 +143,15 @@ function measureArea() { * @returns {Promise} */ async function connectWebSocket() { - await login(store.temp.userName, store.temp.password).then(rsp => { - let resData = JSON.parse(rsp.data.data) - console.log(resData) - sessionStorage.setItem('token',resData.jwtToken) - }).catch(err => { - console.log(err) - sessionStorage.setItem('token','err') - - }) - if(sessionStorage.getItem('token') === 'err') return + 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 ..."); + store.webskt.ws.send("hello QT!") + } - store.webskt.ws = new WebSocket('ws://123.57.54.1:8048/htfp/websocket/uavGlobal/sysUser003', sessionStorage.getItem('token')) - // store.server.ws = new WebSocket('ws://'+store.server.ws_config.address+':'+store.server.ws_config.port); store.webskt.ws.onmessage = (event) => { //收到消息后的处理流程.... - let data = dataProcess(JSON.parse(event.data)) + let data = dataProcess_fromQT(JSON.parse(event.data)) console.log(data); // 添加飞机三维图标 if (!hasPlane.value && data != null) { diff --git a/src/store/staticOptions.js b/src/store/staticOptions.js index ed032e7..2f50462 100644 --- a/src/store/staticOptions.js +++ b/src/store/staticOptions.js @@ -46,7 +46,7 @@ export const useStaticStore = defineStore('staticOptions',{ isOpen: false, ws_config: { address: '127.0.0.1', - port: 8000, + port: 9090, }, }, models: { diff --git a/src/utils/map/SpatialAnalysis.ts b/src/utils/map/SpatialAnalysis.ts index 400a53f..9070274 100644 --- a/src/utils/map/SpatialAnalysis.ts +++ b/src/utils/map/SpatialAnalysis.ts @@ -106,7 +106,9 @@ export function visibilityAnalyse(viewer: Viewer, viewpoint:Cartesian3, target:C for (let i = 1; i <= breakNum; i++) { let breakP = Cartesian3.lerp(viewpoint, target, i/breakNum, new Cartesian3()) let breakPH = getElevation(viewer, breakP) //断点海拔 - let breakPDis = getDistance(viewpoint,breakP)*1000 //断点与视点的距离 + if(breakPH == -9999.2024) return false + + let breakPDis = Math.floor(getDistance(viewpoint,breakP)*1000) //断点与视点的距离 // 计算断点与视点的斜率 let breakPK = (breakPH-viewpointH)/breakPDis if(breakPK>visibleK){ @@ -121,6 +123,37 @@ export function visibilityAnalyse(viewer: Viewer, viewpoint:Cartesian3, target:C return true } +/** + * 两点间通视分析(基于最大斜率的算法)
+ * 返回值:通视为true,不通视为false + * @param profile 剖面分析的结果 + * @param curvature 是否考虑地球曲率 + * @param startExtraH 视点地面挂高 m + * @param endExtraH 目标点地面挂高 m + */ +export function visibilityAnalyse2(profile: ProfileResult, curvature:boolean, startExtraH:number,endExtraH:number) +{ + // 计算起点、终点的高度(海拔+挂高)m + let startH = profile.elevationArray[0] + startExtraH + let endH = profile.elevationArray.at(-1) + endExtraH + // 计算首尾点斜率 + let visibleK = (endH - startH)/profile.distanceArray.at(-1) + // 逐个计算断点与视点的斜率 + for (let i = 1; i < profile.elevationArray.length ; i++) { + let breakPK = (profile.elevationArray[i] - startH) / profile.distanceArray[i] + if(breakPK > visibleK) + return false + } + + if(curvature){ + let coefficient: number = 3.57 //考虑大气折射 4.12, 公司文件给出 2.898 + let Rmax = coefficient * (Math.sqrt(startExtraH) + Math.sqrt(endExtraH)) + if (Rmax < profile.distanceArray.at(-1)/1000.0) + return false + } + return true +} + /** * 绘制地形剖面折线图 * @param xData x数组 @@ -319,11 +352,7 @@ export const drawEchartsAirlineDetect = (xData:number[],yData:number[],yData2:nu * @param endHeight 视线终点高度(包含地面挂高) */ export const drawEchartsVisibility = (xData:number[], yData:number[],startHeight:number, endHeight:number) => { - console.group() - console.log(0, startHeight) - console.log(xData.at(-1), endHeight) - console.groupEnd() - console.log(xData) + let myChart = echarts.init(document.getElementById('profileEChart')) //Echarts-UnitTest // 绘制图表 myChart.setOption({