三维伴飞测试

devzpx
zhaipx 3 months ago
parent 4a67166430
commit c5b665157c

@ -304,15 +304,14 @@ export default class MeasureDistance {
showAirLine(line){ showAirLine(line){
let degreesArr = [] let degreesArr = []
for (let i = 0; i < line.points.length; i++) { for (let i = 0; i < line.points.length; i++) {
degreesArr.push(line.points[i].lon) let coord = new Cartesian3.fromDegrees(line.points[i].lon,line.points[i].lat,line.points[i].alt)
degreesArr.push(line.points[i].lat) degreesArr.push(coord)
degreesArr.push(line.points[i].alt)
} }
let airlineEntity = new Cesium.Entity({ let airlineEntity = new Cesium.Entity({
name: line.name, name: line.name,
id: line.name+line.totalDistance, id: line.name+line.totalDistance,
polyline: { polyline: {
positions:Cesium.Cartesian3.fromDegreesArray(degreesArr), positions: degreesArr,
width: 2, width: 2,
material: Cesium.Color.ORANGE, material: Cesium.Color.ORANGE,
clampToGround: true, clampToGround: true,
@ -322,9 +321,11 @@ export default class MeasureDistance {
} }
addAirplaneEntity(modelPath,StrUavTypeID){ addAirplaneEntity(modelPath,StrUavTypeID){
this.viewer.scene.globe.depthTestAgainstTerrain = true;
store.uav.ModelIDinMap = "ID: " + StrUavTypeID
let entity = this.viewer.entities.add({ let entity = this.viewer.entities.add({
name: StrUavTypeID, name: StrUavTypeID,
id: "ID: "+StrUavTypeID, id: "ID: " + StrUavTypeID,
position: new Cesium.CallbackProperty(() => { position: new Cesium.CallbackProperty(() => {
return new Cesium.Cartesian3.fromDegrees(this.dynamicData.lon, this.dynamicData.lat, this.dynamicData.alt) return new Cesium.Cartesian3.fromDegrees(this.dynamicData.lon, this.dynamicData.lat, this.dynamicData.alt)
}, false), }, false),
@ -347,7 +348,8 @@ export default class MeasureDistance {
clampAnimations: true, clampAnimations: true,
color: Cesium.Color.fromAlpha(Cesium.Color.RED, parseFloat(1.0)), color: Cesium.Color.fromAlpha(Cesium.Color.RED, parseFloat(1.0)),
colorBlendMode: Cesium.ColorBlendMode['MIX'], colorBlendMode: Cesium.ColorBlendMode['MIX'],
colorBlendAmount: 0 colorBlendAmount: 0,
clampToGround: true,
} }
}); });
this.viewer.trackedEntity = entity; this.viewer.trackedEntity = entity;

@ -1,4 +1,5 @@
import {Airline, AirlinePoint, UavDynamicInfo} from "@/types/entityoptions.ts"; import {Airline, AirlinePoint, UavDynamicInfo} from "@/types/entityoptions.ts";
import {useLayerStore} from "@/store/layerManagerStore.ts";
/** /**
* websocket * websocket
@ -39,32 +40,49 @@ function dataProcess_fromQT(websocketDataQT:any): UavDynamicInfo|null {
let data:UavDynamicInfo = { let data:UavDynamicInfo = {
alt: 0, groundSpeed: 0, heading: 0, lat: 0, lon: 0, uavId: "", uavType: "" alt: 0, groundSpeed: 0, heading: 0, lat: 0, lon: 0, uavId: "", uavType: ""
} }
data.uavId = websocketDataQT.uavId data.uavId = websocketDataQT.pos.uavId
data.uavType = websocketDataQT.uavType data.uavType = websocketDataQT.pos.uavType
data.heading = websocketDataQT.HeadAngle data.heading = websocketDataQT.pos.HeadAngle
data.lon = websocketDataQT.lon data.lon = websocketDataQT.pos.lon
data.lat = websocketDataQT.lat data.lat = websocketDataQT.pos.lat
data.alt = websocketDataQT.height data.alt = websocketDataQT.pos.height
data.groundSpeed = websocketDataQT.groundSpeed //km/h data.groundSpeed = websocketDataQT.pos.groundSpeed //km/h
useLayerStore().navi.currentRouteID = websocketDataQT.navi.currentRouteID
useLayerStore().navi.nextRouteID = websocketDataQT.navi.nextRouteID
useLayerStore().navi.nextPoint = websocketDataQT.navi.nextPoint
useLayerStore().navi.distonext = websocketDataQT.navi.distonext
console.log(data.lon,data.lat, data.alt)
return data.lon==0? null: data return data.lon==0? null: data
} }
function getAirline(data: any): Airline | null { function dataProcess_fromQT_route(websocketDataQT:any): Airline|null {
let line: Airline = {totalDistance: 0, PtNum: 0, name: "", isClose: false, points: []} let data: Airline = {
line.PtNum = data.PtNum code: 0, PtNum: 0, isClose: false, name: "", points: [], totalDistance: 0
line.name = data.Name
line.isClose = data.isClose
line.totalDistance = data.totalDistance
for (let i = 0; i < data.ListPoints.length; i++) {
let point: AirlinePoint = {
alt: 0, lat: 0, lon: 0
}
line.points.push(point)
} }
return line if(!websocketDataQT.route) return null
} data.PtNum = websocketDataQT.route.length
for (let i = 1; i < websocketDataQT.route.length; i++) {
let aPt: AirlinePoint = {alt: 0, ch1: 0, ch2: 0, lat: 0, lon: 0, nPt: 0, speed: 0}
aPt.lon = websocketDataQT.route[i].lon
aPt.lat = websocketDataQT.route[i].lat
aPt.alt = websocketDataQT.route[i].height
aPt.ch1 = websocketDataQT.route[i].ch1
aPt.ch2 = websocketDataQT.route[i].ch2
aPt.nPt = websocketDataQT.route[i].nPt
aPt.speed = websocketDataQT.route[i].nV
data.code = websocketDataQT.route[i].nL
data.points.push(aPt)
}
if(data.points[data.PtNum-2].ch1 ==2)
data.isClose = true
data.name = "lineID-" + data.code.toString()
console.log(data)
return data.PtNum==0? null: data
}
function getUavTypeStr(type: number) : string{ function getUavTypeStr(type: number) : string{
switch (type) { switch (type) {
@ -73,4 +91,4 @@ function getUavTypeStr(type: number) : string{
default: return 'test' default: return 'test'
} }
} }
export {dataProcess_fromQT,getAirline} export {dataProcess_fromQT,dataProcess_fromQT_route}

@ -0,0 +1,50 @@
<script setup lang="ts">
import {
drawEcharts_CollisionDetection,
profileAnalyse
} from "@/utils/map/SpatialAnalysis.ts";
import {Cartesian3} from "cesium";
import {nextTick, onMounted} from "vue";
import * as echarts from "echarts";
import {EChartsType} from "echarts";
let myChart: EChartsType = undefined
onMounted(()=>{
myChart = echarts.init(document.getElementById('detection-chart'))
// nextTick(()=>{
//
// })
})
/**
* 绘制地形碰撞检测折线图
* @param height 飞机高度作为检测线
* @param currentPos 当前飞机经纬度作为原点
* @param nextPos 下一航点经纬度作为目标点
*/
const drawDetection = (height: number, currentPos:Cartesian3, nextPos: Cartesian3) => {
//
let res = profileAnalyse(window.viewer, [currentPos, nextPos], 10)
//
nextTick(()=>{
drawEcharts_CollisionDetection(myChart, res.distanceArray, res.elevationArray, height)
})
}
defineExpose({
drawDetection,
})
</script>
<template>
<div id="detection-chart"></div>
</template>
<style scoped>
#detection-chart{
width: 50rem;
height: 15rem;
position: relative;
}
</style>

@ -9,22 +9,29 @@ import {RulerAlt} from '@vicons/carbon'
import {TerrainSharp} from '@vicons/material' import {TerrainSharp} from '@vicons/material'
import {DrawPolygon} from '@vicons/fa' import {DrawPolygon} from '@vicons/fa'
import {useMessage} from 'naive-ui' import {useMessage} from 'naive-ui'
import {ref} from "vue"; import {nextTick, ref} from "vue";
import {useStaticStore} from "@/store/staticOptions.js"; import {useStaticStore} from "@/store/staticOptions.js";
import {requestAirline} from "@/assets/js/request.js"; import {dataProcess_fromQT, dataProcess_fromQT_route} from "@/assets/js/websocketProtocol.ts";
import {dataProcess_fromQT, getAirline} from "@/assets/js/websocketProtocol.ts";
import SpatialAnalysis from "@/components/SpatialAnalysis.vue"; import SpatialAnalysis from "@/components/SpatialAnalysis.vue";
import LayerManager from "@/components/map/LayerManager.vue"; import LayerManager from "@/components/map/LayerManager.vue";
import CollisionDetection from "@/components/CollisionDetection.vue";
import {useLayerStore} from "@/store/layerManagerStore.ts";
import {Cartesian3} from "cesium";
import * as echarts from "echarts";
const message = useMessage(); const message = useMessage();
let SceneValue; let SceneValue;
let showModal = ref(false); let showModal = ref(false);
let showDetection = ref(false);
let hasPlane = ref(false); let hasPlane = ref(false);
let store = useStaticStore(); let store = useStaticStore();
let lStore = useLayerStore();
const spatialAnalyse= ref(null) const spatialAnalyse = ref(null)
const layerManager= ref(null) const layerManager = ref(null)
const collisionDetection = ref(null)
SceneValue = ref('untrace'); SceneValue = ref('untrace');
let frameCount = 0
function handleSceneSelect(key){ function handleSceneSelect(key){
if(!hasPlane.value) return; if(!hasPlane.value) return;
@ -32,7 +39,7 @@ function handleSceneSelect(key){
if(key === 'untrace') { if(key === 'untrace') {
window.measureViewer.setNoTrack() window.measureViewer.setNoTrack()
}else if(key === 'fallow') { }else if(key === 'fallow') {
window.viewer.trackedEntity = window.viewer.entities.getById('websocket-flying-plane'); window.viewer.trackedEntity = window.viewer.entities.getById(store.uav.ModelIDinMap);
} }
} }
let layerValue = ref('layer1'); let layerValue = ref('layer1');
@ -40,7 +47,7 @@ let barIsOpen = ref(true);
function handleEditSelect(key) { function handleEditSelect(key) {
if(key === 'requestLine') { if(key === 'requestLine') {
getUavAirline()
} }
else{ else{
// 线 // 线
@ -151,16 +158,53 @@ async function connectWebSocket() {
store.webskt.ws.onmessage = (event) => { store.webskt.ws.onmessage = (event) => {
//.... //....
let data = dataProcess_fromQT(JSON.parse(event.data)) let sktData = JSON.parse(event.data)
console.log(data); // console.log(sktData);
// frameCount++
if (!hasPlane.value && data != null) { if(sktData.type === 0){
window.measureViewer.addAirplaneEntity(store.models.defaultAirPlane, data.uavId + data.uavType) let ycData = dataProcess_fromQT(sktData)
SceneValue.value = 'fallow' if (ycData != null) {
hasPlane.value = true; //
window.measureViewer.updateDynamicData(ycData)
//
if(!hasPlane.value){
window.measureViewer.addAirplaneEntity(store.models.defaultAirPlane, ycData.uavId + ycData.uavType)
SceneValue.value = 'fallow'
hasPlane.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
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)
}
})
}
}
} }
if (data != null) { if(sktData.type === 1){
window.measureViewer.updateDynamicData(data) let routeData = dataProcess_fromQT_route(sktData)
lStore.navi.airlines.push(routeData)
console.log(routeData)
if(routeData != null){
window.measureViewer.showAirLine(routeData)
}
} }
}; };
} }
@ -174,20 +218,6 @@ function closeWS(){
} }
} }
/**
* 请求航线接口
*/
function getUavAirline() {
if(sessionStorage.getItem('uavId')){
requestAirline(sessionStorage.getItem('uavId')).then(rsp => {
console.log(rsp.data)
window.measureViewer.showAirLine(getAirline(rsp.data))
})
}else {
message.warning('当前未连接飞机')
}
}
function manageLayer(){ function manageLayer(){
layerManager.value?.open_closeSidebar() layerManager.value?.open_closeSidebar()
} }
@ -273,6 +303,9 @@ function manageLayer(){
</n-button> </n-button>
</n-row> </n-row>
</n-space> </n-space>
<n-space id="detectionGraph" v-show="showDetection">
<CollisionDetection ref="collisionDetection"></CollisionDetection>
</n-space>
<n-modal v-model:show="showModal" <n-modal v-model:show="showModal"
style="width: 30%" style="width: 30%"
@ -316,4 +349,13 @@ function manageLayer(){
border-radius: 7px; border-radius: 7px;
background: rgba(21, 21, 21, 0.94); background: rgba(21, 21, 21, 0.94);
} }
#detectionGraph{
position: absolute;
bottom: 2rem;
width: 100rem;
height: 15rem;
border-radius: 7px;
background: rgba(21, 21, 21, 0.94);
}
</style> </style>

@ -1,4 +1,5 @@
import {defineStore} from "pinia"; import {defineStore} from "pinia";
import {Airline} from "@/types/entityoptions.ts";
type layer = { type layer = {
lName: string lName: string
lId: string lId: string
@ -10,7 +11,14 @@ type layer = {
export const useLayerStore = defineStore('LayerStore', { export const useLayerStore = defineStore('LayerStore', {
state: ()=>{ state: ()=>{
return { return {
Layers: [] as layer[] Layers: [] as layer[],
navi: {
airlines: [] as Airline[],
currentRouteID: undefined, //当前航线号
nextRouteID: undefined, //下一航线号
nextPoint: undefined, //下一航点号
distonext: undefined, //待飞距离
},
} }
}, },
actions: { actions: {

@ -53,6 +53,10 @@ export const useStaticStore = defineStore('staticOptions',{
defaultAirPlane: cesiumAirPlane, defaultAirPlane: cesiumAirPlane,
}, },
hasPlane: false, hasPlane: false,
uav: {
ModelIDinMap: '', //地图中的飞机entity ID
},
analysisVars: { analysisVars: {
//当前的空间分析类型剖面1 通视2 //当前的空间分析类型剖面1 通视2
analysisType: -1, analysisType: -1,

@ -39,10 +39,15 @@ export type AirlinePoint = {
lon:number, lon:number,
lat:number, lat:number,
alt:number, alt:number,
ch2:number,
ch1:number, //任务特征字, 2为闭合航线 0为开航线
speed:number, //航点特征字
nPt:number, //航点号
} }
export type Airline = { export type Airline = {
name: string, name: string,
code: number, //航线编号
PtNum: number, PtNum: number,
isClose: boolean, isClose: boolean,
totalDistance: number, totalDistance: number,

@ -7,6 +7,7 @@
import {getDistance, getElevation} from "@/utils/map/geocomputation.ts"; import {getDistance, getElevation} from "@/utils/map/geocomputation.ts";
import {Cartesian3, Viewer} from "cesium"; import {Cartesian3, Viewer} from "cesium";
import * as echarts from "echarts"; import * as echarts from "echarts";
import {EChartsType} from "echarts";
type ProfileResult = { type ProfileResult = {
distanceArray:number[], distanceArray:number[],
elevationArray:number[], elevationArray:number[],
@ -245,30 +246,37 @@ export function drawEchartsProfileAnalyse(xData:number[], yData:number[]) {
/** /**
* 线线 *
* @param myChart ECharts
* @param xData x * @param xData x
* @param yData y线 * @param yData y线
* @param yData2 y线 * @param height 线
*/ */
export const drawEchartsAirlineDetect = (xData:number[],yData:number[],yData2:number[]) => { export function drawEcharts_CollisionDetection(myChart: EChartsType, xData:number[], yData:number[], height:number) {
let myChart = echarts.init(document.getElementById('profileEChart'))
// 绘制图表 // 绘制图表
myChart.setOption({ myChart.setOption({
legend:{ legend: {
show: true, show: true,
type: 'plain', type: 'plain',
top: '7%', top: '5%',
data:[ data:[
{ {
name: 'groundLine', name: '地形',
itemStyle: 'inherit', itemStyle: 'inherit',
lineStyle: 'inherit', lineStyle: 'inherit',
}, },
{ { //视线图例
name: 'airLine', name: '飞机高度',
itemStyle: 'inherit', lineStyle: {
lineStyle: 'inherit', type: 'dotted',
}] width: 3,
color: '#f8364d'
},
itemStyle: {
fontSize: 18
}
}
]
}, },
tooltip: { tooltip: {
show: true, show: true,
@ -276,11 +284,11 @@ export const drawEchartsAirlineDetect = (xData:number[],yData:number[],yData2:nu
axisPointer: { axisPointer: {
type: 'cross' type: 'cross'
}, },
formatter:'地表高度: {c0}<br>航线高度: {c1}' formatter:'地表高度: {c0}'
}, },
xAxis: { xAxis: {
data: xData, data: xData,
name: '距离', name: '距离/米',
nameTextStyle: { nameTextStyle: {
fontWeight:'bolder', fontWeight:'bolder',
fontSize: 14 fontSize: 14
@ -293,7 +301,7 @@ export const drawEchartsAirlineDetect = (xData:number[],yData:number[],yData2:nu
symbolSize: [7, 10] symbolSize: [7, 10]
}, },
axisLabel: { axisLabel: {
formatter: '{value} m', formatter: '{value}',
margin: 5, margin: 5,
}, },
axisTick: { axisTick: {
@ -308,7 +316,7 @@ export const drawEchartsAirlineDetect = (xData:number[],yData:number[],yData2:nu
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
name: '高度', name: '高度/米',
nameTextStyle: { nameTextStyle: {
fontWeight:'bolder', fontWeight:'bolder',
fontSize: 14 fontSize: 14
@ -316,7 +324,7 @@ export const drawEchartsAirlineDetect = (xData:number[],yData:number[],yData2:nu
nameLocation: 'end', nameLocation: 'end',
position: 'left', position: 'left',
axisLabel: { axisLabel: {
formatter: '{value} m' formatter: '{value}'
}, },
axisLine: { axisLine: {
show: true, show: true,
@ -324,23 +332,66 @@ export const drawEchartsAirlineDetect = (xData:number[],yData:number[],yData2:nu
symbolSize: [7, 10] 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: [ series: [
{ {
name:'groundLine', name:'地形',
type: 'line', type: 'line',
data: yData, data: yData,
areaStyle: { areaStyle: {
color: '#37a5fb', color: '#37a5fb',
opacity: 0.5 opacity: 0.5
} },
markLine: {
name: "飞机高度",
data: [
{
yAxis: height,
itemStyle: {
normal: { color: '#c60c30' }
}
}
],
symbol:['circle', 'arrow'],
label:{
formatter: "飞机高度",
show: true,
position: 'middle',
fontSize: 15,
fontWeight: 'bold',
color: '#e73d3d',
},
lineStyle: { //标注线样式
type: 'dashed',
color: 'red',
with: 10
}
},
}, },
{ {
name:'airLine',
type: 'line', type: 'line',
data: yData2, symbol: 'none',
name: '飞机高度',
color: 'transparent'
} }
] ]
}); }, false);
} }

Loading…
Cancel
Save