diff --git a/src/assets/js/cesium-map/measureDistance.js b/src/assets/js/measureDistance.js similarity index 98% rename from src/assets/js/cesium-map/measureDistance.js rename to src/assets/js/measureDistance.js index 8625797..7344228 100644 --- a/src/assets/js/cesium-map/measureDistance.js +++ b/src/assets/js/measureDistance.js @@ -119,6 +119,23 @@ export default class MeasureDistance { this.viewer.scene.requestRender() } + addPointEntity(position){ + let pEntity = this.viewer.entities.add({ + position: position, + type: "routeDetectPoint", + point: { + show: true, + pixelSize: 10, + color: Cesium.Color.ORANGERED, + outlineColor: Cesium.Color.WHITE, + outlineWidth: 2, + clampToGround: true, + heightReference:Cesium.HeightReference.CLAMP_TO_GROUND, + disableDepthTestDistance:99000000, + }, + }); + this.vertexEntities.push(pEntity) + } addKml(kml_file){ let kmlDataPromise = Cesium.KmlDataSource.load(kml_file, { camera: this.viewer.scene.camera, @@ -377,6 +394,7 @@ export default class MeasureDistance { window.viewer.trackedEntity = null; window.viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); } + stopAreaMeasure(){ if (!this.measAreaStatus) return; this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); diff --git a/src/assets/js/websocketProtocol.ts b/src/assets/js/websocketProtocol.ts index 5c29074..05b20f7 100644 --- a/src/assets/js/websocketProtocol.ts +++ b/src/assets/js/websocketProtocol.ts @@ -8,7 +8,7 @@ import {useLayerStore} from "@/store/layerManagerStore.ts"; */ function dataProcess(websocketDataCC:any): UavDynamicInfo|null { let data:UavDynamicInfo = { - alt: 0, groundSpeed: 0, heading: 0, lat: 0, lon: 0, uavId: "", uavType: "" + alt: 0, groundSpeed: 0, heading: 0, pitch: 0,lat: 0, lon: 0, uavId: "", uavType: "" } if(websocketDataCC.infoType===1) { let aUavInfo:any = websocketDataCC.info[0] //目前只取第一个uav @@ -38,11 +38,12 @@ function dataProcess(websocketDataCC:any): UavDynamicInfo|null { */ function dataProcess_fromQT(websocketDataQT:any): UavDynamicInfo|null { let data:UavDynamicInfo = { - alt: 0, groundSpeed: 0, heading: 0, lat: 0, lon: 0, uavId: "", uavType: "" + alt: 0, groundSpeed: 0, heading: 0, pitch: 0, lat: 0, lon: 0, uavId: "", uavType: "" } data.uavId = websocketDataQT.pos.uavId data.uavType = websocketDataQT.pos.uavType data.heading = websocketDataQT.pos.HeadAngle + data.pitch = websocketDataQT.pos.FyAngle data.lon = websocketDataQT.pos.lon data.lat = websocketDataQT.pos.lat data.alt = Number(websocketDataQT.pos.height) + useLayerStore().navi.hFactor diff --git a/src/components/CollisionDetection.vue b/src/components/CollisionDetection.vue index f0747aa..6c050d2 100644 --- a/src/components/CollisionDetection.vue +++ b/src/components/CollisionDetection.vue @@ -11,26 +11,28 @@ import {EChartsType} from "echarts"; import {useLayerStore} from "@/store/layerManagerStore.ts"; let l_store = useLayerStore() let myChart: EChartsType = undefined +let myChart1: EChartsType = undefined let uavDisArr: number[] = [] let uavHeightArr: number[] = [] let terrainArr: number[] = [] onMounted(()=>{ myChart = echarts.init(document.getElementById('detection-chart')) + myChart1 = echarts.init(document.getElementById('terrain-chart')) }) const props = defineProps(['groundHeight']) /** - * 绘制地形碰撞检测折线图 + * 绘制地形碰撞检测折线图,差值间隔为1km * @param height 飞机高度,作为检测线 * @param currentPos 当前飞机经纬度,作为原点 * @param nextPos 下一航点经纬度,作为目标点 + * @param max_dis 预先探测距离 m */ -const drawDetection = (height: number, currentPos:Cartesian3, nextPos: Cartesian3) => { +const drawTerrain = (height: number, currentPos:Cartesian3, nextPos: Cartesian3, max_dis: number) => { // 计算地形剖面 - let res = profileAnalyse(window.viewer, [currentPos, nextPos], 10) + let res = profileAnalyse(window.viewer, [currentPos, nextPos], max_dis/1000) // 弹出图表窗口 - drawEcharts_CollisionDetection(myChart, res.distanceArray, res.elevationArray, height) - + drawEcharts_CollisionDetection(myChart1, res.distanceArray, res.elevationArray, height, max_dis) } /** @@ -39,7 +41,7 @@ const drawDetection = (height: number, currentPos:Cartesian3, nextPos: Cartesian * @param uavDis 飞机当前位置与上一位置的距离 米 * @param terrainH 飞机当前地面投影点的地形高度 */ -const drawDetection2 = (uavH: number, uavDis:number, terrainH: number) => { +const drawDetection = (uavH: number, uavDis:number, terrainH: number) => { if(uavDisArr.length == 0){ uavDisArr.push(Math.round(uavDis)) } @@ -57,24 +59,28 @@ const drawDetection2 = (uavH: number, uavDis:number, terrainH: number) => { defineExpose({ drawDetection, - drawDetection2, + drawTerrain, }) \ No newline at end of file diff --git a/src/components/map/SceneViewer.vue b/src/components/map/SceneViewer.vue index 5c0c439..f00d807 100644 --- a/src/components/map/SceneViewer.vue +++ b/src/components/map/SceneViewer.vue @@ -21,7 +21,7 @@ import { } from '@/utils/map/TDTProvider' import { initViewer, perfViewer, showNavigator } from '@/utils/map/sceneViewer' import { flyToChina } from '@/utils/map/camera' -import MeasureDistance from "@/assets/js/cesium-map/measureDistance"; +import MeasureDistance from "@/assets/js/measureDistance.js"; const viewerDivRef = ref() let viewer: Viewer diff --git a/src/components/toolbar.vue b/src/components/toolbar.vue index a77654f..9441678 100644 --- a/src/components/toolbar.vue +++ b/src/components/toolbar.vue @@ -17,7 +17,7 @@ import LayerManager from "@/components/map/LayerManager.vue"; import CollisionDetection from "@/components/CollisionDetection.vue"; import {useLayerStore} from "@/store/layerManagerStore.ts"; import {Cartesian3} from "cesium"; -import {getDistance, getElevation} from "@/utils/map/geocomputation.ts"; +import {ByDirectionAndLen, getDistance, getElevation} from "@/utils/map/geocomputation.ts"; const message = useMessage(); let SceneValue; @@ -172,12 +172,12 @@ async function connectWebSocket() { SceneValue.value = 'fallow' hasPlane.value = true; } - console.log(frameCount) // 加载和更新碰撞检测图(50帧更新一次) if(frameCount>50){ showDetection.value = true frameCount = 0 let currentPos = Cartesian3.fromDegrees(ycData.lon, ycData.lat,ycData.alt) + // 显示飞机当前位置的地表投影点海拔高度 和 飞机高度(折线图) new Promise(resolve => { // 计算对地高度 m groundHeight.value = ycData.alt - getElevation(window.viewer, currentPos) @@ -189,7 +189,18 @@ async function connectWebSocket() { lastPos = currentPos resolve(dis) }).then(res=>{ - collisionDetection.value.drawDetection2(ycData.alt, res, ycData.alt-groundHeight.value) + collisionDetection.value.drawDetection(ycData.alt, res, ycData.alt-groundHeight.value) + }) + // 当前飞机高度(折线图) 和飞机前方10公里处的地形高度(以飞机当前航向推算) + let max_dis = 5000 + new Promise(resolve => { + // 计算前方10公里处的坐标点 + let detectPos = ByDirectionAndLen(currentPos, ycData.heading, max_dis) + // 计算地形剖面 + collisionDetection.value.drawTerrain(ycData.alt, currentPos, detectPos, max_dis) + resolve(detectPos) + }).then(res=>{ + window.measureViewer.addPointEntity(res) }) } } @@ -200,20 +211,7 @@ async function connectWebSocket() { lStore.navi.airlines.push(routeData) lStore.navi.currentRouteID = routeData.code console.log(routeData) - window.measureViewer.showAirLine(routeData) - - //计算航线的地形剖面,并存储到store中 - // FIXME: 当前逻辑有待更新 - /* - profileAnalyse_promise(window.viewer, routeData,100).then((result) => { - let routeTerr = {} - routeTerr.routeID = routeData.code - routeTerr.distanceArray = result.distanceArray - routeTerr.elevationArray = result.elevationArray - lStore.routesTerrain.push(routeTerr) - }) - */ } } @@ -314,9 +312,9 @@ function manageLayer(){ - + - + diff --git a/src/types/entityoptions.ts b/src/types/entityoptions.ts index 65d65d1..26ce27e 100644 --- a/src/types/entityoptions.ts +++ b/src/types/entityoptions.ts @@ -30,6 +30,7 @@ export type UavDynamicInfo = { uavType: string, uavFlightControlSn?: string, heading:number, + pitch:number, lon:number, lat:number, alt:number, diff --git a/src/utils/map/SpatialAnalysis.ts b/src/utils/map/SpatialAnalysis.ts index 3137555..257da0e 100644 --- a/src/utils/map/SpatialAnalysis.ts +++ b/src/utils/map/SpatialAnalysis.ts @@ -283,8 +283,9 @@ export function drawEchartsProfileAnalyse(xData:number[], yData:number[]) { * @param xData x数组 * @param yData y数组,以面积线绘制 * @param height 水平辅助线的高度 + * @param max_distance 预先探测距离 */ -export function drawEcharts_CollisionDetection(myChart: EChartsType, xData:number[], yData:number[], height:number) { +export function drawEcharts_CollisionDetection(myChart: EChartsType, xData:number[], yData:number[], height:number,max_distance:number) { // 绘制图表 myChart.setOption({ legend: { @@ -319,13 +320,14 @@ export function drawEcharts_CollisionDetection(myChart: EChartsType, xData:numbe formatter:'地表高度: {c0}' }, xAxis: { + max: max_distance, data: xData, - name: '距离/米', nameTextStyle: { fontWeight:'bolder', - fontSize: 14 + fontSize: 14, + padding:[0,0,-520,0] }, - nameLocation: 'end', + nameLocation: 'bottom', axisLine:{ onZero: false, show: true, // 是否显示坐标轴轴线 @@ -333,7 +335,7 @@ export function drawEcharts_CollisionDetection(myChart: EChartsType, xData:numbe symbolSize: [7, 10] }, axisLabel: { - formatter: '{value}', + formatter: '{value} m', margin: 5, }, axisTick: { @@ -349,6 +351,12 @@ export function drawEcharts_CollisionDetection(myChart: EChartsType, xData:numbe yAxis: { type: 'value', name: '高度/米', + max: (value:any)=>{ + return Math.floor(Math.max(value.max,height) * 1.01) + }, + min: (value:any)=>{ + return Math.floor(value.min * 0.99) + }, nameTextStyle: { fontWeight:'bolder', fontSize: 14 @@ -364,23 +372,6 @@ export function drawEcharts_CollisionDetection(myChart: EChartsType, xData:numbe symbolSize: [7, 10] } }, - visualMap: { - type: 'piecewise', - show: false, - dimension: 1, - // seriesIndex: [0, 1], // 虽然可以指定多个series,但是线的颜色只能设置一条 - seriesIndex: [0, 1], - pieces: [{ - gt: height, - color: 'red' - }, { - lt: 0, - color: 'blue' - }], - outOfRange: { // 在选中范围外 的视觉元素,这里设置在正常范围内的图形颜色 - color: 'blue', - }, - }, series: [ { name:'地形', @@ -394,7 +385,7 @@ export function drawEcharts_CollisionDetection(myChart: EChartsType, xData:numbe name: "飞机高度", data: [ { - yAxis: height, + yAxis: height.toString(), itemStyle: { normal: { color: '#c60c30' } } @@ -448,14 +439,7 @@ export function drawEcharts_CollisionDetection2(myChart: EChartsType, xData:numb }, { name: '飞机高度', - lineStyle: { - type: 'dotted', - width: 3, - color: '#f8364d' - }, - itemStyle: { - fontSize: 18 - } + lineStyle: 'inherit', } ] }, @@ -469,7 +453,7 @@ export function drawEcharts_CollisionDetection2(myChart: EChartsType, xData:numb }, xAxis: { data: xData, - name: '距离/米', + // name: '距离/米', nameTextStyle: { fontWeight:'bolder', fontSize: 14 diff --git a/src/utils/map/geocomputation.ts b/src/utils/map/geocomputation.ts index 8887bd5..d84e5f5 100644 --- a/src/utils/map/geocomputation.ts +++ b/src/utils/map/geocomputation.ts @@ -5,7 +5,15 @@ * @LastEditTime: 2024-04-01 14:05:43 * @Description: 地理计算 */ -import {Cartesian3, Cartographic, EllipsoidGeodesic, Math as Cesium_Math, Matrix4, Transforms, Viewer} from 'cesium' +import { + Cartesian3, + Cartographic, + EllipsoidGeodesic, + Math as Cesium_Math, Matrix3, + Matrix4, + Transforms, + Viewer +} from 'cesium' import {Angle} from "@/utils/map/angle.ts"; /** @@ -161,5 +169,19 @@ export function getElevation(viewer: Viewer, pos: Cartographic|Cartesian3|number } } - +/** + * 根据起始点、方位角、距离,计算下一点 + * @param position 起始点 + * @param angle 方位角 度(顺时针,正北为0,正东为90) + * @param distance 距离 米 + * @constructor + */ +export function ByDirectionAndLen(position: Cartesian3, angle:number, distance:number){ + let matrix = Transforms.eastNorthUpToFixedFrame(position); + let mz = Matrix3.fromRotationZ(2*Cesium_Math.PI - Cesium_Math.toRadians(angle || 0)) + let rotationZ = Matrix4.fromRotationTranslation(mz); + Matrix4.multiply(matrix, rotationZ, matrix); + return Matrix4.multiplyByPoint(matrix, new Cartesian3(0, distance, 0), + new Cartesian3()); +} export { getClosestPoint, isOnLineSegment, getDistance, getAzimuth, getPolygonArea }