添加星座图和载噪比视图

master
叶志超 2021-11-15 12:12:15 +08:00
parent 46769106b5
commit b6c21343f3
9 changed files with 358 additions and 0 deletions

13
planisphere.html Normal file
View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html class="w-h-full">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body class="w-h-full">
<div id="app" class="w-h-full text-white"></div>
<script type="module" src="/src/render/planisphere.ts"></script>
</body>
</html>

13
snr.html Normal file
View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html class="w-h-full">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body class="w-h-full">
<div id="app" class="w-h-full text-white"></div>
<script type="module" src="/src/render/snr.ts"></script>
</body>
</html>

View File

@ -0,0 +1,26 @@
<template>
<full-screen-container>
<TheHeader />
<div class="main-content flex-1 grid grid-cols-2 grid-rows-2">
<div class="">
<PlanisphereView title="北斗" />
</div>
<div class="">
<PlanisphereView title="GPS" />
</div>
<div class="">
<PlanisphereView title="格洛纳斯" />
</div>
<div class="">
<PlanisphereView title="伽利略" />
</div>
</div>
</full-screen-container>
</template>
<script lang="ts" setup>
import FullScreenContainer from './components/Layout/FullScreenContainer.vue'
import TheHeader from './components/Layout/TheHeader.vue'
import PlanisphereView from './components/PlanisphereView.vue'
</script>

26
src/render/SNRPage.vue Normal file
View File

@ -0,0 +1,26 @@
<template>
<full-screen-container>
<TheHeader />
<div class="main-content flex flex-wrap flex-1">
<div class="w-1/2 h/1/2">
<PlanisphereView />
</div>
<div class="w-1/2 h/1/2">
<PlanisphereView />
</div>
<div class="w-1/2 h/1/2">
<PlanisphereView />
</div>
<div class="w-1/2 h/1/2">
<PlanisphereView />
</div>
</div>
</full-screen-container>
</template>
<script lang="ts" setup>
import FullScreenContainer from './components/Layout/FullScreenContainer.vue'
import TheHeader from './components/Layout/TheHeader.vue'
import SNRView from './components/SNRView.vue'
</script>

View File

@ -25,3 +25,12 @@ export function getPolylineLength(points) {
return mulAdd(lengths) return mulAdd(lengths)
} }
export function get_in_positioning_id(GSAArr) {
let in_positioning_id = []
GSAArr.forEach(({ satellites }) => {
in_positioning_id.push(...satellites)
});
return in_positioning_id
}

View File

@ -0,0 +1,135 @@
<template>
<VChart :option="option" />
</template>
<script lang="ts" setup>
import { reactive } from "vue";
import { use } from "echarts/core";
import { CanvasRenderer } from "echarts/renderers";
import { ScatterChart } from "echarts/charts";
import {
TitleComponent,
PolarComponent
} from "echarts/components";
import VChart from "vue-echarts";
import { get_in_positioning_id } from '../api/util'
use([
CanvasRenderer,
ScatterChart,
TitleComponent,
PolarComponent
]);
const props = defineProps({
title: String
})
const option = reactive({
title: {
text: props.title,
left: 'center'
// textAlign: 'center'
},
polar: {
radius: '75%'
},
angleAxis: {
min: 0,
max: 360,
interval: 45,
axisTick: {
show: false
},
axisLabel: {
fontSize: 24,
formatter: function (value: number) {
switch (value)
{
case 0 : return '北';
case 90 : return '东';
case 180 : return '南';
case 270 : return '西';
}
},
}
},
radiusAxis: {
min: -90,
max: 0,
interval: 30,
axisLabel: {
rotate: -25,
showMinLabel: false,
showMaxLabel: false,
verticalAlign: 'bottom',
formatter: function(value: number){
return Math.abs(value)
},
}
},
series: [{
nmea: 'un-positioning',
coordinateSystem: 'polar',
type: 'scatter',
symbolSize: 32,
label: {
show: true,
formatter: '{@[2]}'
},
itemStyle: {
color: '#9ca3af'
}
}, {
nmea: 'in-positioning',
coordinateSystem: 'polar',
type: 'scatter',
symbolSize: 32,
label: {
show: true,
formatter: '{@[2]}'
},
itemStyle: {
color: '#e5323e'
}
}]
})
const update = (GSVArr: Array<any>, GSAArr: Array<any>) => {
const planisphereOption: any = getPlanisphereOption(GSVArr, GSAArr)
if (!planisphereOption) return
Object.assign(option, planisphereOption)
}
const getPlanisphereOption = (GSVArr: Array<any>, GSAArr: Array<any>) => {
try {
let in_positioning_data: Array<any> = [],
un_positioning_data: Array<any> = []
const in_positioning_id = utils.get_in_positioning_id(GSAArr)
GSVArr.forEach(({ satellites }) => {
satellites.forEach(({ id, elevationDeg, azimuthTrue }) => {
if (in_positioning_id.indexOf(parseInt(id)) < 0) {
un_positioning_data.push([parseInt(elevationDeg) * -1, azimuthTrue, id])
} else {
in_positioning_data.push([parseInt(elevationDeg) * -1, azimuthTrue, id])
}
});
});
const planisphereOption = {
series: [{
data: un_positioning_data
}, {
data: in_positioning_data
}]
}
return planisphereOption
} catch (error) {
console.error(error);
}
}
defineExpose({ update })
</script>

View File

@ -0,0 +1,124 @@
<template>
<div class="w-h-full">
<v-chart :option="option" />
</div>
</template>
<script lang="ts" setup>
import { reactive } from "vue"
import { use, graphic } from "echarts/core";
import { CanvasRenderer } from "echarts/renderers";
import { BarChart } from "echarts/charts";
import { GridComponent } from "echarts/components";
import VChart from "vue-echarts";
import utils from '../api/utils'
use([
CanvasRenderer,
BarChart,
GridComponent
]);
const BAR_COUNT = 16
const UN_POSITIONING_COLOR = '#9ca3af'
const IN_POSITIONING_COLOR = new graphic.LinearGradient(
0, 1, 0, 0,
[
{offset: 0.3, color: '#83bff6'},
{offset: 1, color: '#188df0'}
]
)
const option = reactive({
grid: {
containLabel: true
},
xAxis: {
type: 'category',
axisTick: {show: false},
axisLine: {show: false},
axisLabel: {
color: 'black'
}
},
yAxis: {
max: 60,
axisLabel: {
textStyle: {
fontSize: 24
}
}
},
series: [{
type: 'bar',
barCategoryGap: '50%',
label: {
show: true,
position: 'top',
formatter: function ({ value }) {
return !value || value[1] === 0 ? '' : value[1];
}
},
itemStyle: {
color: ({ value }) => {
return value[2] ? IN_POSITIONING_COLOR : UN_POSITIONING_COLOR
}
}
}]
})
const update = (GSVArr: Array<any>, GSAArr: Array<any>) => {
const SNROption: any = getSNROption(GSVArr, GSAArr)
if (!SNROption) return
if (SNROption.xAxis.data.length !== SNROption.series[0].data.length) {
return
}
const length = SNROption.xAxis.data.length
if (length < BAR_COUNT) {
const fill_num = BAR_COUNT - length
SNROption.xAxis.data = SNROption.xAxis.data.concat(new Array(fill_num).fill(''))
SNROption.series[0].data = SNROption.series[0].data.concat(new Array(fill_num).fill(0))
}
Object.assign(option, SNROption)
}
const getSNROption = (GSVArr: Array<any>, GSAArr: Array<any>) => {
try {
let xAxis_data : Array<any> = []
let series_data : Array<any> = []
const in_positioning_id = utils.get_in_positioning_id(GSAArr)
GSAArr.forEach(({ satellites }) => {
in_positioning_id.push(...satellites)
});
GSVArr.forEach(({ satellites }) => {
satellites.forEach(({ id, SNRdB }) => {
xAxis_data.push(id)
if (in_positioning_id.indexOf(parseInt(id)) < 0) {
series_data.push([id, SNRdB, false])
} else {
series_data.push([id, SNRdB, true])
}
});
});
const SNROption = {
xAxis: {
data: xAxis_data
},
series: [{
data: series_data
}]
}
return SNROption
} catch (error) {
console.error(error);
}
}
defineExpose({ update })
</script>

View File

@ -0,0 +1,6 @@
import { createApp } from 'vue'
import App from './PlanispherePage.vue'
import './assets/css/main.css'
createApp(App).mount('#app')

6
src/render/snr.ts Normal file
View File

@ -0,0 +1,6 @@
import { createApp } from 'vue'
import App from './SNRPage.vue'
import './assets/css/main.css'
createApp(App).mount('#app')