perf: 碰撞检测功能逻辑细化和UI优化

devzpx
zhaipx 2 months ago
parent e81f71b1d3
commit 6572ef649d

@ -37,6 +37,7 @@ function dataProcess(websocketDataCC:any): UavDynamicInfo|null {
* @return UavDynamicInfo
*/
function dataProcess_fromQT(websocketDataQT:any): UavDynamicInfo|null {
let data:UavDynamicInfo = {
alt: 0, groundSpeed: 0, heading: 0, pitch: 0, lat: 0, lon: 0, uavId: "", uavType: ""
}

@ -5,7 +5,7 @@ import {
profileAnalyse
} from "@/utils/map/SpatialAnalysis.ts";
import {Cartesian3} from "cesium";
import {onMounted} from "vue";
import {defineEmits, onMounted} from "vue";
import * as echarts from "echarts";
import {EChartsType} from "echarts";
import {useLayerStore} from "@/store/layerManagerStore.ts";
@ -15,11 +15,15 @@ let myChart1: EChartsType = undefined
let uavDisArr: number[] = []
let uavHeightArr: number[] = []
let terrainArr: number[] = []
defineEmits(['shutdown']);
onMounted(()=>{
myChart = echarts.init(document.getElementById('detection-chart'))
myChart1 = echarts.init(document.getElementById('terrain-chart'))
})
window.addEventListener('resize',function(){
myChart.resize()
myChart1.resize()
})
const props = defineProps(['groundHeight'])
/**
* 绘制地形碰撞检测折线图差值间隔为1km
@ -29,8 +33,8 @@ const props = defineProps(['groundHeight'])
* @param max_dis 预先探测距离 m
*/
const drawTerrain = (height: number, currentPos:Cartesian3, nextPos: Cartesian3, max_dis: number) => {
//
let res = profileAnalyse(window.viewer, [currentPos, nextPos], max_dis/1000)
// 1km
let res = profileAnalyse(window.viewer, [currentPos, nextPos],1000)
//
drawEcharts_CollisionDetection(myChart1, res.distanceArray, res.elevationArray, height, max_dis)
}
@ -67,20 +71,12 @@ defineExpose({
<template>
<div class="chart" id="detection-chart"></div>
<div class="chart" id="terrain-chart"></div>
<!-- <n-grid x-gap="12" :cols="2">-->
<!-- <n-gi class="chart">-->
<!-- <div id="detection-chart"></div>-->
<!-- </n-gi>-->
<!-- <n-gi class="chart">-->
<!-- <div id="terrain-chart"></div>-->
<!-- </n-gi>-->
<!-- </n-grid>-->
</template>
<style scoped>
.chart{
height: 15rem;
height: 25vh;
width: 33rem;
margin: 1rem 0 -4rem 0;
margin: 0 0 0 0;
}
</style>

@ -3,33 +3,59 @@ import {defineComponent} from 'vue'
import SceneViewer from "@/components/map/SceneViewer.vue";
import BottomBar from "@/components/map/BottomBar.vue";
import Toolbar from "@/components/toolbar.vue";
import CollisionDetection from "@/components/CollisionDetection.vue";
import {useMessage} from 'naive-ui'
export default defineComponent({
name: "HomePage",
components: {Toolbar, BottomBar, SceneViewer}
components: {CollisionDetection, Toolbar, BottomBar, SceneViewer},
data(){
return {
showDetection: false,
graphHeight: 0,
message: useMessage()
}
},
computed: {
setPageStyle: function () {
return this.showDetection? 100 - this.graphHeight : 100
}
},
methods: {
// resize
resizeMap(height: number) {
if(height<0)
this.showDetection = false
else{
this.graphHeight = height
this.showDetection = true
}
},
}
})
</script>
<template>
<div id="map">
<div id="map" :style="{height: setPageStyle+'vh'}">
<SceneViewer id="scene-viewer"></SceneViewer>
<BottomBar></BottomBar>
<toolbar></toolbar>
<toolbar ref="ToolBar" @resizeMap="resizeMap"></toolbar>
</div>
</template>
<style>
@import '../styles/cesium-compass.css';
#map {
width: 100vw;
height: 100vh;
position: relative;
/* overflow: hidden; */
}
#scene-viewer {
width: 100vw;
height: 100vh;
height: 100%;
position: absolute;
overflow: hidden;
}
</style>

@ -4,29 +4,32 @@
创建人Zhaipeixiu
-->
<script setup>
import {ChevronBack, CreateOutline, DuplicateSharp, EyeSharp, Layers, Settings} from '@vicons/ionicons5'
import {ChevronBack,ChevronForward, 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} from "vue";
import {ref, defineEmits} 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 "@/components/CollisionDetection.vue";
import CollisionDetection from "./CollisionDetection.vue"
import {useLayerStore} from "@/store/layerManagerStore.ts";
import {Cartesian3} from "cesium";
import {ByDirectionAndLen, getDistance, getElevation} from "@/utils/map/geocomputation.ts";
const emit = defineEmits(['resizeMap'])
const message = useMessage();
let SceneValue;
let showModal = ref(false);
let showDetection = ref(false);
let hasPlane = ref(false);
let showDetection = 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)
@ -44,9 +47,19 @@ 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 === 'requestLine') {
if(key === 'createLine') {
}
else{
@ -152,7 +165,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!")
}
@ -166,6 +179,7 @@ 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)
@ -173,7 +187,8 @@ async function connectWebSocket() {
hasPlane.value = true;
}
// (50)
if(frameCount>50){
if(frameCount>50 && lStore.openDetect){
emit('resizeMap', detectDivHeight.value)
showDetection.value = true
frameCount = 0
let currentPos = Cartesian3.fromDegrees(ycData.lon, ycData.lat,ycData.alt)
@ -194,16 +209,17 @@ async function connectWebSocket() {
// 线 10
let max_dis = 5000
new Promise(resolve => {
// 10
// 5
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)
})
}
}
else{ //
lStore.validYCData = false
}
}
if(sktData.type === 1){
let routeData = dataProcess_fromQT_route(sktData)
@ -218,6 +234,17 @@ async function connectWebSocket() {
};
}
//
function shutDownDetec() {
if(lStore.openDetect){
emit('resizeMap', -1)
}else{
emit('resizeMap', detectDivHeight.value)
}
showDetection.value = !showDetection.value;
lStore.openDetect = !lStore.openDetect
}
/**
* 关闭websocket连接
*/
@ -234,7 +261,7 @@ function manageLayer(){
</script>
<template>
<n-space id="panel">
<n-space class="panel-toolbar989834y34">
<n-row justify-content="space-between">
<n-tooltip placement="bottom" trigger="hover" >
<template #trigger>
@ -265,6 +292,7 @@ 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>
@ -296,25 +324,32 @@ 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">
<n-button tertiary circle type="warning" @click="openCloseBar">
<template #icon>
<!-- ChevronBack,ChevronForward,-->
<n-icon><ChevronBack/></n-icon>
<n-icon v-if="barIsOpen"><ChevronBack/></n-icon>
<n-icon v-else><ChevronForward/></n-icon>
</template>
</n-button>
</n-row>
</n-space>
<n-flex id="detectionGraph" justify="center" v-show="showDetection">
<CollisionDetection ref="collisionDetection" :groundHeight="groundHeight"></CollisionDetection>
<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-modal v-model:show="showModal"
style="width: 30%"
@ -350,21 +385,31 @@ function manageLayer(){
<LayerManager ref="layerManager"></LayerManager>
</template>
<style scoped>
#panel{
<style>
.panel-toolbar989834y34{
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: 2rem;
width: 100%;
height: 15rem;
bottom: -25vh;
width: 100vW;
border-radius: 7px;
background: rgba(255, 255, 255, 0.8);
}
</style>

@ -12,6 +12,8 @@ export const useLayerStore = defineStore('LayerStore', {
state: ()=>{
return {
Layers: [] as layer[],
openDetect: true,
validYCData: false,
navi: {
airlines: [] as Airline[],
currentRouteID: -1, //当前航线号

@ -13,7 +13,7 @@ export const useStaticStore = defineStore('staticOptions',{
},
menuOptions:{
EditOptions: [
{label: '查询航线', key: 'requestLine'},
{label: '绘制航线', key: 'createLine'},
{label: '航线管理', key: 'manage'}
],
sceneOptions:[

@ -49,7 +49,7 @@ screen and (max-height: 420px) {
.navigation-controls {
position: absolute;
right: 1.8rem;
top: 65vh;
top: 55vh;
width: 2rem;
border: 1px solid rgba(255, 255, 255, 0.8);
border-radius: .3rem .3rem .3rem .3rem;
@ -107,7 +107,7 @@ screen and (max-height: 420px) {
pointer-events: auto;
position: absolute;
right: 0;
top: 50vh;
top: 41vh;
width: 6rem;
height: 6rem;
overflow: hidden;

@ -8,7 +8,7 @@ import {getDistance, getElevation} from "@/utils/map/geocomputation.ts";
import {Cartesian3, Viewer} from "cesium";
import * as echarts from "echarts";
import {EChartsType} from "echarts";
import {Airline, AirlinePoint} from "@/types/entityoptions.ts";
import {Airline} from "@/types/entityoptions.ts";
type ProfileResult = {
distanceArray:number[],
elevationArray:number[],
@ -84,7 +84,7 @@ export function profileAnalyse(viewer: Viewer, polyline:Cartesian3[], interval:
* @return 线线
*/
export function profileAnalyse_promise(viewer: Viewer, route: Airline, interval: number){
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
let result: ProfileResult = { distanceArray:[], elevationArray:[] }
let polyline = []
//航线转为坐标点数组
@ -288,6 +288,13 @@ export function drawEchartsProfileAnalyse(xData:number[], yData:number[]) {
export function drawEcharts_CollisionDetection(myChart: EChartsType, xData:number[], yData:number[], height:number,max_distance:number) {
// 绘制图表
myChart.setOption({
/** 配置图标离容器上下左右的距离 */
grid: {
top: "20%",
right: "5%",
left:"10%",
bottom: "12%",
},
legend: {
show: true,
type: 'plain',
@ -320,12 +327,11 @@ export function drawEcharts_CollisionDetection(myChart: EChartsType, xData:numbe
formatter:'地表高度: {c0}'
},
xAxis: {
max: max_distance,
max: Math.ceil(max_distance).toString(),
data: xData,
nameTextStyle: {
fontWeight:'bolder',
fontSize: 14,
padding:[0,0,-520,0]
},
nameLocation: 'bottom',
axisLine:{
@ -427,6 +433,13 @@ export function drawEcharts_CollisionDetection(myChart: EChartsType, xData:numbe
export function drawEcharts_CollisionDetection2(myChart: EChartsType, xData:number[], yData:number[], yData2: number[]) {
// 绘制图表
myChart.setOption({
/** 配置图标离容器上下左右的距离 */
grid: {
top: "20%",
right: "5%",
left:"10%",
bottom: "12%",
},
legend: {
show: true,
type: 'plain',

Loading…
Cancel
Save