四大卫星运行状态监控系统

This commit is contained in:
2026-03-18 16:39:48 +08:00
parent 0cdfee2f2e
commit ca8c24c058
43 changed files with 2609 additions and 544 deletions

View File

@@ -1,4 +1,4 @@
require('ts-node').register({
project:'./tsconfig.electron.json'
});
require('./src/main/app.ts')
require('./src/main/app.ts');

56
oneShow.html Normal file
View File

@@ -0,0 +1,56 @@
<!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" />
<style>
/* 当屏幕宽度大于或等于3840px时 */
@media (min-width: 3840px) {
html {
font-size: 40px;
}
}
/* 当屏幕宽度在2560px到3839px之间时 */
@media (min-width: 2560px) and (max-width: 3839px) {
html {
font-size: 26px;
}
}
/* 当屏幕宽度在1920px到2559px之间时 */
@media (min-width: 1920px) and (max-width: 2559px) {
html {
font-size: 20px;
}
}
/* 当屏幕宽度在750px到1919px之间时 */
@media (min-width: 750px) and (max-width: 1919px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度在600px到749px之间时 */
@media (min-width: 600px) and (max-width: 749px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度小于600px时 */
@media (max-width: 599px) {
html {
font-size: 12px;
}
}
</style>
<title>卫星数据监控平台</title>
</head>
<body class="w-h-full">
<div id="app" class="w-h-full text-white"></div>
<script type="module" src="/src/render/oneShow.ts"></script>
</body>
</html>

56
oneShowAll.html Normal file
View File

@@ -0,0 +1,56 @@
<!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" />
<style>
/* 当屏幕宽度大于或等于3840px时 */
@media (min-width: 3840px) {
html {
font-size: 40px;
}
}
/* 当屏幕宽度在2560px到3839px之间时 */
@media (min-width: 2560px) and (max-width: 3839px) {
html {
font-size: 26px;
}
}
/* 当屏幕宽度在1920px到2559px之间时 */
@media (min-width: 1920px) and (max-width: 2559px) {
html {
font-size: 20px;
}
}
/* 当屏幕宽度在750px到1919px之间时 */
@media (min-width: 750px) and (max-width: 1919px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度在600px到749px之间时 */
@media (min-width: 600px) and (max-width: 749px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度小于600px时 */
@media (max-width: 599px) {
html {
font-size: 12px;
}
}
</style>
<title>卫星数据监控平台</title>
</head>
<body class="w-h-full">
<div id="app" class="w-h-full text-white"></div>
<script type="module" src="/src/render/oneShowAll.ts"></script>
</body>
</html>

56
oneShowSwitch.html Normal file
View File

@@ -0,0 +1,56 @@
<!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" />
<style>
/* 当屏幕宽度大于或等于3840px时 */
@media (min-width: 3840px) {
html {
font-size: 40px;
}
}
/* 当屏幕宽度在2560px到3839px之间时 */
@media (min-width: 2560px) and (max-width: 3839px) {
html {
font-size: 26px;
}
}
/* 当屏幕宽度在1920px到2559px之间时 */
@media (min-width: 1920px) and (max-width: 2559px) {
html {
font-size: 20px;
}
}
/* 当屏幕宽度在750px到1919px之间时 */
@media (min-width: 750px) and (max-width: 1919px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度在600px到749px之间时 */
@media (min-width: 600px) and (max-width: 749px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度小于600px时 */
@media (max-width: 599px) {
html {
font-size: 12px;
}
}
</style>
<title>卫星数据监控平台</title>
</head>
<body class="w-h-full">
<div id="app" class="w-h-full text-white"></div>
<script type="module" src="/src/render/oneShowSwitch.ts"></script>
</body>
</html>

View File

@@ -4,6 +4,49 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
/* 当屏幕宽度大于或等于3840px时 */
@media (min-width: 3840px) {
html {
font-size: 40px;
}
}
/* 当屏幕宽度在2560px到3839px之间时 */
@media (min-width: 2560px) and (max-width: 3839px) {
html {
font-size: 26px;
}
}
/* 当屏幕宽度在1920px到2559px之间时 */
@media (min-width: 1920px) and (max-width: 2559px) {
html {
font-size: 20px;
}
}
/* 当屏幕宽度在750px到1919px之间时 */
@media (min-width: 750px) and (max-width: 1919px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度在600px到749px之间时 */
@media (min-width: 600px) and (max-width: 749px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度小于600px时 */
@media (max-width: 599px) {
html {
font-size: 12px;
}
}
</style>
<title>卫星数据监控平台</title>
</head>
<body class="w-h-full">

View File

@@ -4,6 +4,49 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
/* 当屏幕宽度大于或等于3840px时 */
@media (min-width: 3840px) {
html {
font-size: 40px;
}
}
/* 当屏幕宽度在2560px到3839px之间时 */
@media (min-width: 2560px) and (max-width: 3839px) {
html {
font-size: 26px;
}
}
/* 当屏幕宽度在1920px到2559px之间时 */
@media (min-width: 1920px) and (max-width: 2559px) {
html {
font-size: 20px;
}
}
/* 当屏幕宽度在750px到1919px之间时 */
@media (min-width: 750px) and (max-width: 1919px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度在600px到749px之间时 */
@media (min-width: 600px) and (max-width: 749px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度小于600px时 */
@media (max-width: 599px) {
html {
font-size: 12px;
}
}
</style>
<title>卫星信息监控平台</title>
</head>
<body class="w-h-full">

View File

@@ -4,6 +4,49 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
/* 当屏幕宽度大于或等于3840px时 */
@media (min-width: 3840px) {
html {
font-size: 40px;
}
}
/* 当屏幕宽度在2560px到3839px之间时 */
@media (min-width: 2560px) and (max-width: 3839px) {
html {
font-size: 26px;
}
}
/* 当屏幕宽度在1920px到2559px之间时 */
@media (min-width: 1920px) and (max-width: 2559px) {
html {
font-size: 20px;
}
}
/* 当屏幕宽度在750px到1919px之间时 */
@media (min-width: 750px) and (max-width: 1919px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度在600px到749px之间时 */
@media (min-width: 600px) and (max-width: 749px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度小于600px时 */
@media (max-width: 599px) {
html {
font-size: 12px;
}
}
</style>
<title>卫星信号监控平台</title>
</head>
<body class="w-h-full">

View File

@@ -4,6 +4,49 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
/* 当屏幕宽度大于或等于3840px时 */
@media (min-width: 3840px) {
html {
font-size: 40px;
}
}
/* 当屏幕宽度在2560px到3839px之间时 */
@media (min-width: 2560px) and (max-width: 3839px) {
html {
font-size: 26px;
}
}
/* 当屏幕宽度在1920px到2559px之间时 */
@media (min-width: 1920px) and (max-width: 2559px) {
html {
font-size: 20px;
}
}
/* 当屏幕宽度在750px到1919px之间时 */
@media (min-width: 750px) and (max-width: 1919px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度在600px到749px之间时 */
@media (min-width: 600px) and (max-width: 749px) {
html {
font-size: 14px;
}
}
/* 当屏幕宽度小于600px时 */
@media (max-width: 599px) {
html {
font-size: 12px;
}
}
</style>
<title>卫星状态监控平台</title>
</head>
<body class="w-h-full">

View File

@@ -1,3 +1,3 @@
// 加密关键字
const keyword = 'GNSS'
export { keyword }
const keyword = 'BD';
export { keyword };

View File

@@ -1,39 +1,39 @@
import nmea from 'nmea'
import nmea from 'nmea';
let events = {}
let events = {};
const on = (eventName, callback) => {
if (!(eventName in events)) {
events[eventName] = []
events[eventName] = [];
}
events[eventName].push(callback)
}
events[eventName].push(callback);
};
const emit = (eventName, ...args) => {
if (!(eventName in events)) {
return
return;
}
const cbs = events[eventName]
const cbs = events[eventName];
cbs.forEach(cb => {
cb.call(this, ...args)
cb.call(this, ...args);
});
}
};
const includes = (arr1, arr2) => {
return arr2.every(val => arr1.includes(val));
}
};
const handle = (value) => {
if (value.length <= 0) return
if (value.length <= 0) return;
emit('received', value)
emit('received', value);
const strArr = value.split('\r\n')
const strArr = value.split('\r\n');
for (let i = 0; i < strArr.length; i++) {
const element = strArr[i];
doHandle(element)
doHandle(element);
}
nmeaObj.GSA.forEach(element => {
@@ -42,7 +42,9 @@ const handle = (value) => {
GP:{talker_id:'GP',satellites:[]},
GL:{talker_id:'GL',satellites:[]},
GA:{talker_id:'GA',satellites:[]},
GQ:{talker_id:'GQ',satellites:[]}
GQ:{talker_id:'GQ',satellites:[]},
GI:{talker_id:'GI',satellites:[]},
GN:{talker_id:'GN',satellites:[]}
};
nmeaObj.GSV.forEach(item => {
if(item.talker_id == nmeaCache[item.talker_id].talker_id){
@@ -60,16 +62,16 @@ const handle = (value) => {
nmeaCache = null;
});
emit('handled', nmeaObj)
nmeaObj = resetNMEAObj()
}
emit('handled', nmeaObj);
nmeaObj = resetNMEAObj();
};
const doHandle = (value) => {
if (!verify(value)) {
return
return;
}
const result = nmea.parse(value)
const result = nmea.parse(value);
switch (result.sentence) {
case 'RMC':
nmeaObj.RMC = result
@@ -84,22 +86,22 @@ const doHandle = (value) => {
nmeaObj.GSV.push(result)
break;
}
}
};
const verify = (value) => {
if (!value) {
return false
return false;
}
const dollar_index = value.indexOf('$')
const star_index = value.indexOf('*')
const dollar_index = value.indexOf('$');
const star_index = value.indexOf('*');
if (value.indexOf('$') !== 0 || star_index <= dollar_index) {
return false
return false;
}
const [sentence, checksum, ] = value.split('*')
return nmea.Helpers.verifyChecksum(sentence, checksum)
}
const [sentence, checksum, ] = value.split('*');
return nmea.Helpers.verifyChecksum(sentence, checksum);
};
const resetNMEAObj = () => {
return {
@@ -107,9 +109,9 @@ const resetNMEAObj = () => {
'GGA': null,
'GSA': [],
'GSV': []
}
}
};
};
let nmeaObj = resetNMEAObj()
let nmeaObj = resetNMEAObj();
module.exports = { on, handle }
module.exports = { on, handle };

View File

@@ -1,80 +1,80 @@
import { ipcMain, app, screen, globalShortcut, BrowserWindow, dialog, crashReporter } from 'electron'
import { ipcMain, app, screen, globalShortcut, BrowserWindow, dialog, crashReporter } from 'electron';
import { join } from "path";
const config = require('./config')
import './load-serialport'
import { keyword } from './KeyWord'
const config = require('./config');
import './load-serialport';
import { keyword } from './KeyWord';
const child_process = require('child_process')
const crypto = require('crypto')
const fs = require('fs')
const child_process = require('child_process');
const crypto = require('crypto');
const fs = require('fs');
function queryPass(passPath: string, passValue: string) {
return new Promise(function (resolve, reject) {
try {
child_process.exec(`reg query ${passPath} /v ${passValue}`, (error: Error, stdout: string, stderr: string) => {
if (error) {
reject(error)
return
reject(error);
return;
}
resolve({stdout, stderr})
resolve({stdout, stderr});
});
} catch (error) {
reject(error)
reject(error);
}
})
}
};
function queryKey(keyPath: string, keyValue: string) {
return new Promise(function (resolve, reject) {
try {
child_process.exec(`reg query ${keyPath} /v ${keyValue}`, (error: Error, stdout: string, stderr: string) => {
if (error) {
reject(error)
return
reject(error);
return;
}
resolve({stdout, stderr})
resolve({stdout, stderr});
})
} catch (error) {
reject(error)
reject(error);
}
})
}
};
function cryptMD5(GUID: string) {
let md5 = crypto.createHash('md5')
let ciphertext = md5.update(GUID).digest('hex')
return ciphertext.slice(0,8)+'-'+ciphertext.slice(8,12)+'-'+ciphertext.slice(12,16)+'-'+ciphertext.slice(16,20)+'-'+ciphertext.slice(20,32)
}
let md5 = crypto.createHash('md5');
let ciphertext = md5.update(GUID).digest('hex');
return ciphertext.slice(0,8)+'-'+ciphertext.slice(8,12)+'-'+ciphertext.slice(12,16)+'-'+ciphertext.slice(16,20)+'-'+ciphertext.slice(20,32);
};
const passPath = 'HKEY_CURRENT_USER\\SOFTWARE\\HwaSmart'
const passValue = 'BDAuthorization'
const keyPath = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography'
const keyValue = 'MachineGuid'
const passPath = 'HKEY_CURRENT_USER\\SOFTWARE\\HwaSmart';
const passValue = 'BDAuthorization';
const keyPath = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography';
const keyValue = 'MachineGuid';
async function checkLaunchEnv() {
try {
const passResult: any = await queryPass(passPath, passValue)
const keyResult: any = await queryKey(keyPath, keyValue)
const passResult: any = await queryPass(passPath, passValue);
const keyResult: any = await queryKey(keyPath, keyValue);
if(cryptMD5(keyResult.stdout.slice(83,119) + keyword) == passResult.stdout.slice(72,108)){
return true
return true;
}else{
return false
return false;
}
// 成功
// 查询到 有这个app启动项
} catch (error) {
// 没有查询到该app启动项目
return false
}
return false;
}
};
// 记录崩溃信息
function recordCrash() {
return new Promise<void>(resolve => {
// 崩溃日志请求成功....
resolve();
})
}
});
};
function abnormalLog(txtName: string, txtLog: string) {
fs.writeFile(txtName, txtLog, (ero:any) => {
@@ -83,7 +83,7 @@ function abnormalLog(txtName: string, txtLog: string) {
}
console.log(`创建成功!`);
});
}
};
var windows:Array<BrowserWindow> = [];
@@ -98,24 +98,24 @@ function createWindow(page: string, display: any) {
preload: join(__dirname, 'preload.js'),
webgl: true
}
})
});
ipcMain.on("APP_MOUNTED", (event) => {
const { sender } = event
if (page == 'satellite-data-monitor-platform') {
let depth = config.get('depth')
let secondary = config.get('secondary')
sender.send('deep', [depth, secondary])
const { sender } = event;
if (page == 'satellite-data-monitor-platform' || page == 'oneShow' || page == 'oneShowAll' || page == 'oneShowSwitch') {
const depth = config.get('depth');
const secondary = config.get('secondary');
sender.send('deep', [depth, secondary]);
}
})
});
ipcMain.on("webglcontextlost", (event) => {
abnormalLog(`./resources/webglcontextlost${new Date().getTime()}.txt`, `webglcontextlost: ${new Date()}`);
})
});
ipcMain.on("refresh", (event) => {
abnormalLog(`./resources/refresh${new Date().getTime()}.txt`, `refresh: ${new Date()}`);
})
});
// 监听到软件奔溃时执行
win.webContents.on('crashed', () => {
@@ -146,51 +146,76 @@ function createWindow(page: string, display: any) {
console.log('err', e);
abnormalLog(`./resources/crash${new Date().getTime()}.txt`, `crash: ${new Date()}, err: ${e}`);
});
})
});
if (process.env.NODE_ENV === 'development') {
win.loadURL(`http://localhost:3000/${page}.html`)
win.webContents.openDevTools()
win.loadURL(`http://localhost:3000/${page}.html`);
// win.webContents.openDevTools();
} else {
win.loadFile(`dist/render/${page}.html`)
// win.webContents.openDevTools()
win.loadFile(`dist/render/${page}.html`);
// win.webContents.openDevTools();
}
windows.push(win);
return win;
}
};
const sleep = (timeout:number) => {
return new Promise((resolve?:any)=>{
setTimeout(()=>{
resolve();
}, timeout)
})
}
}, timeout);
});
};
async function launch() {
const displays = screen.getAllDisplays()
const showMode = config.get('showMode');
const displays = screen.getAllDisplays();
if (displays.length !== 4) {
createWindow('satellite-data-monitor-platform', displays[0])
await sleep(100);
createWindow('satellite-info-monitor-platform', displays[0])
switch (showMode) {
case "oneShow":
createWindow('oneShow', displays[0]);
break;
case "oneShowSwitch":
createWindow('oneShowSwitch', displays[0]);
break;
case "oneShowAll":
createWindow('oneShowAll', displays[0]);
break;
case "twoShow":
if (displays.length == 2) {
createWindow('oneShowSwitch', displays[0]);
await sleep(200);
createWindow('satellite-signal-monitor-platform', displays[0])
await sleep(300);
createWindow('satellite-state-monitor-platform', displays[0])
createWindow('oneShowAll', displays[1]);
} else {
createWindow('satellite-data-monitor-platform', displays[0])
createWindow('oneShowSwitch', displays[0]);
await sleep(200);
createWindow('satellite-info-monitor-platform', displays[1])
createWindow('oneShowAll', displays[0]);
}
break;
case "fourShow":
createWindow('satellite-data-monitor-platform', displays[0]);
await sleep(200);
createWindow('satellite-info-monitor-platform', displays[0]);
await sleep(400);
createWindow('satellite-signal-monitor-platform', displays[2])
createWindow('satellite-signal-monitor-platform', displays[0]);
await sleep(600);
createWindow('satellite-state-monitor-platform', displays[3])
createWindow('satellite-state-monitor-platform', displays[0]);
break;
}
} else {
createWindow('satellite-data-monitor-platform', displays[0]);
await sleep(200);
createWindow('satellite-info-monitor-platform', displays[1]);
await sleep(400);
createWindow('satellite-signal-monitor-platform', displays[2]);
await sleep(600);
createWindow('satellite-state-monitor-platform', displays[3]);
}
// 屏蔽 F11 进入/退出全屏功能
globalShortcut.register('F11', () => { return })
}
globalShortcut.register('F11', () => { return });
};
ipcMain.on('CLOSE', (event) => {
const res = dialog.showMessageBox({
@@ -210,48 +235,48 @@ ipcMain.on('CLOSE', (event) => {
});
windows = [];
}else{
console.log('not close software')
console.log('not close software');
}
})
})
});
async function main() {
// 异步代码
const checkReault: any = await checkLaunchEnv()
console.log('env right:', checkReault)
const checkReault: any = await checkLaunchEnv();
console.log('env right:', checkReault);
// 异步代码执行完毕后执行的代码
if (checkReault) {
launch()
launch();
// 模拟软件崩溃
// setTimeout(() => {
// process.crash();
// }, 10000);
} else {
dialog.showErrorBox('系统提示', '软件启动出错,请联系售后技术支持人员')
process.exit(1)
}
dialog.showErrorBox('系统提示', '软件启动出错,请联系售后技术支持人员');
process.exit(1);
}
};
crashReporter.start({uploadToServer: false})
crashReporter.start({uploadToServer: false});
app.commandLine.appendSwitch('ignore-gpu-blacklist')
app.commandLine.appendSwitch('ignore-gpu-blacklist');
app.disableDomainBlockingFor3DAPIs()
app.disableDomainBlockingFor3DAPIs();
// 禁用GPU加速,此模式下何时刷新canvas不能通过判断webgl上下文丢失实现
// app.disableHardwareAcceleration()
app.whenReady().then(main)
app.whenReady().then(main);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
app.quit();
}
})
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
launch()
launch();
}
})
});

View File

@@ -1,8 +1,8 @@
const Store = require('electron-store')
const Store = require('electron-store');
const store = new Store()
const set = (key, val) => store.set(key, val)
const store = new Store();
const set = (key, val) => store.set(key, val);
const get = (key) => store.get(key)
const get = (key) => store.get(key);
module.exports = { set, get }
module.exports = { set, get };

View File

@@ -1,72 +1,72 @@
const { ipcMain } = require('electron')
const { SerialPort } = require("serialport")
const { InterByteTimeoutParser } = require('@serialport/parser-inter-byte-timeout')
const config = require('./config')
const { ipcMain } = require('electron');
const { SerialPort } = require("serialport");
const { InterByteTimeoutParser } = require('@serialport/parser-inter-byte-timeout');
const config = require('./config');
const NMEAHandler = require('./api/NMEAHandler')
const NMEAHandler = require('./api/NMEAHandler');
const DEFAULT_BAUDRATE = 115200
const DEFAULT_BAUDRATE = 115200;
const getSerialPortConstructorArguments = (ports) => {
let serialport = config.get('serialport')
const path = ( serialport && serialport.path ) ? serialport.path : ports[0].path
const baudRate = ( serialport && serialport.baudRate ) ? serialport.baudRate : DEFAULT_BAUDRATE
return { path, baudRate }
}
let serialport = config.get('serialport');
const path = ( serialport && serialport.path ) ? serialport.path : ports[0].path;
const baudRate = ( serialport && serialport.baudRate ) ? serialport.baudRate : DEFAULT_BAUDRATE;
return { path, baudRate };
};
const senders = []
const senders = [];
ipcMain.on("APP_MOUNTED", (event) => {
const { sender } = event
senders.push(sender)
const { sender } = event;
senders.push(sender);
sender.once('destroyed', () => {
const index = senders.indexOf(sender)
if (index >= 0) senders.splice(index, 1)
const index = senders.indexOf(sender);
if (index >= 0) senders.splice(index, 1);
})
})
const sendMsg = (channel, msg) => {
if (senders.length <= 0) return
if (senders.length <= 0) return;
try {
senders.forEach((sender) => {
sender.send(channel, msg)
sender.send(channel, msg);
})
} catch (error) {
console.error(error)
console.error(error);
}
}
SerialPort.list().then((ports, err) => {
if (err) {
console.log(err)
return
console.log(err);
return;
}
// 过滤掉COM1口,很多电脑自带COM1接口
ports = ports.filter((port) => port.path != 'COM1')
ports = ports.filter((port) => port.path != 'COM1');
if (ports.length == 0) {
console.error('设备未连接')
return
console.error('设备未连接');
return;
}
try {
const { path, baudRate } = getSerialPortConstructorArguments(ports)
console.log(path, baudRate, '=====================')
const serialPort = new SerialPort({ path, baudRate })
const { path, baudRate } = getSerialPortConstructorArguments(ports);
console.log(path, baudRate, '=====================');
const serialPort = new SerialPort({ path, baudRate });
const parser = serialPort.pipe(new InterByteTimeoutParser({interval: 30}))
const parser = serialPort.pipe(new InterByteTimeoutParser({interval: 30}));
NMEAHandler.on('received' , (nmeaStr) => {
sendMsg('NMEA_RECEIVED', nmeaStr)
})
sendMsg('NMEA_RECEIVED', nmeaStr);
});
NMEAHandler.on('handled' , (nmeaObj) => {
sendMsg('nmea', JSON.stringify(nmeaObj))
})
sendMsg('nmea', JSON.stringify(nmeaObj));
});
parser.on('data', (data) => NMEAHandler.handle(data.toString()))
parser.on('data', (data) => NMEAHandler.handle(data.toString()));
} catch (error) {
console.error(error);
}
})
});

View File

@@ -1,21 +1,21 @@
const {ipcRenderer, contextBridge} = require('electron')
const {ipcRenderer, contextBridge} = require('electron');
contextBridge.exposeInMainWorld('ipcRenderer', {
send: (channel, data) => {
// whitelist channels
let validChannels = ['toMain']
let validChannels = ['toMain'];
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data)
ipcRenderer.send(channel, data);
}
ipcRenderer.send(channel, data)
ipcRenderer.send(channel, data);
},
receive: (channel, func) => {
console.log(func())
let validChannels = ['fromMain']
console.log(func());
let validChannels = ['fromMain'];
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`
ipcRenderer.on(channel, (event, ...args) => func(...args))
ipcRenderer.on(channel, (event, ...args) => func(...args));
}
ipcRenderer.on(channel, (event, ...args) => func(...args))
ipcRenderer.on(channel, (event, ...args) => func(...args));
}
})
});

View File

@@ -1,65 +1,65 @@
export function filterNonNumber (array) {
return array.filter(n => typeof n === 'number')
}
return array.filter(n => typeof n === 'number');
};
export function mulAdd (nums) {
nums = filterNonNumber(nums)
nums = filterNonNumber(nums);
return nums.reduce((all, num) => all + num, 0)
}
return nums.reduce((all, num) => all + num, 0);
};
export function getTwoPointDistance (pointOne, pointTwo) {
const minusX = Math.abs(pointOne[0] - pointTwo[0])
const minusX = Math.abs(pointOne[0] - pointTwo[0]);
const minusY = Math.abs(pointOne[1] - pointTwo[1])
const minusY = Math.abs(pointOne[1] - pointTwo[1]);
return Math.sqrt(minusX * minusX + minusY * minusY)
}
return Math.sqrt(minusX * minusX + minusY * minusY);
};
export function getPolylineLength(points) {
const lineSegments = new Array(points.length - 1)
.fill(0)
.map((foo, i) => [points[i], points[i + 1]])
.map((foo, i) => [points[i], points[i + 1]]);
const lengths = lineSegments.map(item => getTwoPointDistance(...item))
const lengths = lineSegments.map(item => getTwoPointDistance(...item));
return mulAdd(lengths)
}
return mulAdd(lengths);
};
export function get_in_positioning_id(GSAArr) {
let in_positioning_id = []
let in_positioning_id = [];
GSAArr.forEach(({ satellites }) => {
in_positioning_id.push(...satellites)
in_positioning_id.push(...satellites);
});
return in_positioning_id
}
return in_positioning_id;
};
export function getNMEAObj(nmeaStr) {
if (!nmeaStr) return
if (!nmeaStr) return;
return JSON.parse(nmeaStr)
}
return JSON.parse(nmeaStr);
};
export function getGSV (nmeaStr) {
const nmeaObj = getNMEAObj(nmeaStr)
// console.log(nmeaObj, '================')
if (!nmeaObj || !nmeaObj.GSV) return null
const nmeaObj = getNMEAObj(nmeaStr);
// console.log(nmeaObj, '================');
if (!nmeaObj || !nmeaObj.GSV) return null;
const { GSV } = nmeaObj
const { GSV } = nmeaObj;
const bd = {
// GSVArr: GSV.filter((gsv) => gsv.talker_id === 'BD')
GSVArr: GSV.filter((gsv) => gsv.talker_id === 'GB')
}
};
const gp = {
GSVArr: GSV.filter((gsv) => gsv.talker_id === 'GP')
}
};
const gl = {
GSVArr: GSV.filter((gsv) => gsv.talker_id === 'GL')
}
};
const ga = {
GSVArr: GSV.filter((gsv) => gsv.talker_id === 'GA')
}
};
return { bd, gp, gl, ga }
}
return { bd, gp, gl, ga };
};

View File

@@ -1,14 +1,15 @@
<template>
<div class="center-cmp">
<div class="cc-header">
<Decoration1 style="width:200px;height:50px;" />
<div>监测到卫星总数</div>
<Decoration1 style="width:200px;height:50px;" />
<div class="cc-header" :style="styleMode == 'small' ? 'height: 3rem;font-size: 1.6rem;' : ''">
<Decoration1 :style="styleMode == 'small' ? 'width:7rem;height:2.5rem;' : 'width:200px;height:50px;'" />
<div :style="styleMode == 'small' ? 'font-size: 1rem;' : 'font-size: 2rem;'">监测到卫星总数</div>
<Decoration1 :style="styleMode == 'small' ? 'width:7rem;height:2.5rem;' : 'width:200px;height:50px;'" />
</div>
<div class="cc-details">
<div class="cc-details" :style="styleMode == 'small' ? 'height: 3rem;font-size: 1.6rem;' : ''">
<div
class="card"
:style="styleMode == 'small' ? 'height: 2.5rem;width: 2.5rem;font-size: 1.5rem;line-height: 2.5rem;' : ''"
v-for="(s, i) in count_str_arr"
:key="`count-${i}`">
{{ s }}
@@ -18,23 +19,23 @@
<div class="cc-main-container">
<div class="ccmc-left">
<div class="station-info">
<span id="fontBd" style="text-shadow:0 0 0.5em #ff3232;"> 北 斗 {{ bd_satellite_count }}</span>
<span id="fontBd" :style="styleMode == 'small' ? 'text-shadow:0 0 0.5em #ff3232;font-size: 0.8rem;' : 'text-shadow:0 0 0.5em #ff3232;'"> 北 斗 {{ bd_satellite_count }}</span>
</div>
<div class="station-info">
<span id="fontGl" style="text-shadow:0 0 0.5em #6600ff;">GLONASS {{ gl_satellite_count }}</span>
<span id="fontGl" :style="styleMode == 'small' ? 'text-shadow:0 0 0.5em #6600ff;font-size: 0.8rem;' : 'text-shadow:0 0 0.5em #6600ff;'">GLONASS {{ gl_satellite_count }}</span>
</div>
</div>
<div class="ccmc-middle">
<Ring ref="ring" @changeColor="changeColor"/>
<Ring ref="ring" @changeColor="changeColor" :styleMode="styleMode" />
</div>
<div class="ccmc-right">
<div class="station-info">
<span id="fontGp" style="text-shadow:0 0 0.5em #00ffff;">{{ gp_satellite_count }} G P S</span>
<span id="fontGp" :style="styleMode == 'small' ? 'text-shadow:0 0 0.5em #00ffff;font-size: 0.8rem;' : 'text-shadow:0 0 0.5em #00ffff;'">{{ gp_satellite_count }} G P S</span>
</div>
<div class="station-info">
<span id="fontGa" style="text-shadow:0 0 0.5em #00ff66;">{{ ga_satellite_count }} Galileo</span>
<span id="fontGa" :style="styleMode == 'small' ? 'text-shadow:0 0 0.5em #00ff66;font-size: 0.8rem;' : 'text-shadow:0 0 0.5em #00ff66;'">{{ ga_satellite_count }} Galileo</span>
</div>
</div>
</div>
@@ -42,40 +43,37 @@
</template>
<script lang="ts" setup>
import Ring from './Ring.vue'
import Decoration1 from './Layout/Decoration1.vue'
import Ring from './Ring.vue';
import Decoration1 from './Layout/Decoration1.vue';
import { ref, computed, onMounted } from 'vue'
import { ref, computed, onMounted } from 'vue';
const bd_satellite_count = ref(0)
const gp_satellite_count = ref(0)
const gl_satellite_count = ref(0)
const ga_satellite_count = ref(0)
const bd_satellite_count = ref(0);
const gp_satellite_count = ref(0);
const gl_satellite_count = ref(0);
const ga_satellite_count = ref(0);
defineProps({
styleMode: String
});
const count_str_arr = computed(() => {
return (bd_satellite_count.value + gp_satellite_count.value + gl_satellite_count.value + ga_satellite_count.value).toString().split('')
})
return (bd_satellite_count.value + gp_satellite_count.value + gl_satellite_count.value + ga_satellite_count.value).toString().split('');
});
const ring = ref(null);
const ring = ref(null)
const update = (bd_satellite_length: number, gp_satellite_length: number, gl_satellite_length: number, ga_satellite_length: number) => {
bd_satellite_count.value = bd_satellite_length
gp_satellite_count.value = gp_satellite_length
gl_satellite_count.value = gl_satellite_length
ga_satellite_count.value = ga_satellite_length
bd_satellite_count.value = bd_satellite_length;
gp_satellite_count.value = gp_satellite_length;
gl_satellite_count.value = gl_satellite_length;
ga_satellite_count.value = ga_satellite_length;
ring.value.update(bd_satellite_length, gp_satellite_length, gl_satellite_length, ga_satellite_length)
ring.value.update(bd_satellite_length, gp_satellite_length, gl_satellite_length, ga_satellite_length);
}
let bdText, glText, gpText, gaText;
onMounted(() => {
bdText = document.getElementById("fontBd");
gpText = document.getElementById("fontGp");
glText = document.getElementById("fontGl");
gaText = document.getElementById("fontGa");
});
const changeColor = (change, id) => {
let idPie = [bdText, gpText, glText, gaText];
let colorPie = ['#ff3232', '#00ffff', '#6600ff', '#00ff66'];
@@ -86,9 +84,16 @@ const changeColor = (change, id) => {
element.style.color = "#ffffff";
});
}
}
} ;
defineExpose({ update })
defineExpose({ update });
onMounted(() => {
bdText = document.getElementById("fontBd");
gpText = document.getElementById("fontGp");
glText = document.getElementById("fontGl");
gaText = document.getElementById("fontGa");
});
</script>
@@ -103,31 +108,29 @@ defineExpose({ update })
}
.cc-header {
height: 125px;
height: 6rem;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 30px;
}
.cc-details {
height: 120px;
height: 6rem;
display: flex;
justify-content: center;
font-size: 32px;
align-items: center;
}
.cc-details .card {
background-color: rgba(4,49,128,.6);
color: #08e5ff;
height: 100px;
width: 100px;
font-size: 65px;
height: 5rem;
width: 5rem;
font-size: 3rem;
line-height: 5rem;
font-weight: bold;
line-height: 100px;
text-align: center;
margin: 10px;
margin: 0.5rem;
}
.cc-main-container {
@@ -141,7 +144,7 @@ defineExpose({ update })
}
.active-ring-name {
font-size: 20px !important;
font-size: 1rem !important;
}
.ccmc-left, .ccmc-right {
@@ -149,16 +152,16 @@ defineExpose({ update })
display: flex;
flex-direction: column;
justify-content: center;
font-size: 24px;
font-size: 1.2rem;
}
.ccmc-left span, .ccmc-right span {
font-size: 30px;
font-size: 1.5rem;
font-weight: bold;
}
.ccmc-left .station-info, .ccmc-right .station-info {
height: 80px;
height: 4rem;
display: flex;
align-items: center;
}
@@ -168,7 +171,7 @@ defineExpose({ update })
}
.ccmc-left span {
margin-left: 10px;
margin-left: 0.5rem;
}
.ccmc-right {
@@ -176,14 +179,14 @@ defineExpose({ update })
}
.ccmc-right span {
margin-right: 10px;
margin-right: 0.5rem;
}
.label-tag {
position: absolute;
width: 500px;
height: 30px;
bottom: 10px;
width: 25rem;
height: 1.5rem;
bottom: 0.5rem;
left: 50%;
transform: translateX(-50%);
}

View File

@@ -11,11 +11,11 @@ import { GaugeChart } from "echarts/charts";
import VChart from "vue-echarts";
import { reactive, onMounted } from "vue";
use([
CanvasRenderer,
TitleComponent,
GaugeChart
]);
use([ CanvasRenderer, TitleComponent, GaugeChart ]);
const props = defineProps({
styleMode: String
});
onMounted(() => {
var mychart = document.getElementById("myClock");
@@ -69,8 +69,8 @@ const option = reactive({
},
axisLabel: {
color: '#fff',
fontSize: 12,
distance: 15,
fontSize: props.styleMode == "small" ? 12 : 12,
distance: props.styleMode == "small" ? 5 : 15,
formatter: function (value) {
if (value === 0) {
return '';

View File

@@ -11,11 +11,11 @@ import { GaugeChart } from "echarts/charts";
import VChart from "vue-echarts";
import { reactive, onMounted } from "vue";
use([
CanvasRenderer,
TitleComponent,
GaugeChart
]);
use([ CanvasRenderer, TitleComponent, GaugeChart ]);
const props = defineProps({
styleMode: String
});
onMounted(() => {
var mychart = document.getElementById("myCompass");
@@ -54,8 +54,8 @@ const option = reactive({
},
axisLabel:{
color: 'white',
distance: -40,
fontSize: 18,
distance: props.styleMode == "small" ? -35 : -40,
fontSize: props.styleMode == "small" ? 12 : 18,
formatter: function(v: Number){
switch(v){
case 0 : return '北';

View File

@@ -4,8 +4,8 @@
v-for="item in digitalFlopData"
:key="item.key"
>
<div class="digital-flop-title text-2xl mb-5">{{ item.title }}</div>
<div class="digital-flop flex">
<div class="text-2xl mb-5" :style="styleMode == 'small' ? 'font-size: 1rem;margin-bottom: 0;' : ''">{{ item.title }}</div>
<div class="flex" :style="styleMode == 'small' ? 'font-size: 1rem;' : ''">
<DigitalFlop
:value="item.value"
:style="item.style"
@@ -17,36 +17,40 @@
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
import DigitalFlop from './DigitalFlop.vue'
import { reactive } from 'vue';
import DigitalFlop from './DigitalFlop.vue';
const props = defineProps({
styleMode: String
});
const digitalFlopData = reactive([
{
title: '日  期',
value: '',
style: 'color: #4d99fc'
style: props.styleMode == "small" ? 'font-size: 1rem; color: #4d99fc' : 'color: #4d99fc'
}, {
title: '时  间',
value: '',
style: 'color: #f46827'
style: props.styleMode == "small" ? 'font-size: 1rem; color: #f46827' : 'color: #f46827'
}, {
title: '经  度',
value: '',
style: 'color: #40faee'
style: props.styleMode == "small" ? 'font-size: 1rem; color: #40faee' : 'color: #40faee'
}, {
title: '纬  度',
value: '',
style: 'color: #4d99fc'
style: props.styleMode == "small" ? 'font-size: 1rem; color: #4d99fc' : 'color: #4d99fc'
}, {
title: '海  拔',
value: '',
style: 'color: #f46827'
style: props.styleMode == "small" ? 'font-size: 1rem; color: #f46827' : 'color: #f46827'
}, {
title: '定位卫星数目',
value: '',
style: 'color: #40faee'
style: props.styleMode == "small" ? 'font-size: 1rem; color: #40faee' : 'color: #40faee'
}
])
]);
const update = (
dateTime: Date,
@@ -55,20 +59,20 @@ const update = (
alt: number,
numSat: number) => {
// 日期
digitalFlopData[0].value = dateTime.toLocaleDateString()
digitalFlopData[0].value = dateTime.toLocaleDateString();
// 时间
digitalFlopData[1].value = dateTime.toLocaleTimeString()
digitalFlopData[1].value = dateTime.toLocaleTimeString();
// 经度
digitalFlopData[2].value = `${longitude} ${longitude >= 0 ? 'E' : 'W'}`
digitalFlopData[2].value = `${Number(longitude).toFixed(6)} ${longitude >= 0 ? 'E' : 'W'}`;
// 纬度
digitalFlopData[3].value = `${latitude} ${latitude >= 0 ? 'N' : 'S'}`
digitalFlopData[3].value = `${Number(latitude).toFixed(6)} ${latitude >= 0 ? 'N' : 'S'}`;
// 海拔
digitalFlopData[4].value = `${alt} 米`
digitalFlopData[4].value = `${alt} 米`;
// 定位卫星数目
digitalFlopData[5].value = numSat.toString()
}
digitalFlopData[5].value = numSat.toString();
};
defineExpose({ update })
defineExpose({ update });
</script>
<style scoped>

View File

@@ -77,6 +77,6 @@ onMounted(() => {
position: relative;
width: 100%;
height: 100%;
padding: 25px;
padding: 1.3rem;
}
</style>

View File

@@ -0,0 +1,24 @@
<template>
<div class="the-header flex justify-between flex-shrink-0 relative left-0 top-0">
<Decoration8 class="w-1/4 h-8" />
<Decoration5 class="w-2/5 h-8 mt-8" />
<Decoration8 class="w-1/4 h-8" :reverse="true" />
<div v-if="title == '卫星数据监控平台'" @dblclick="close" class="absolute left-1/2 transform -translate-x-2/4 text-xl font-bold top-2 text-white">{{ title }}</div>
<div v-if="title == '卫星信息监控平台'" @dblclick="close" class="absolute left-1/2 transform -translate-x-2/4 text-xl font-bold top-2 text-white">{{ title }}</div>
<div v-if="title == '卫星信号监控平台'" @dblclick="close" class="absolute left-1/2 transform -translate-x-2/4 text-xl font-bold top-2 text-white">{{ title }}</div>
<div v-if="title == '卫星状态监控平台'" @dblclick="close" class="absolute left-1/2 transform -translate-x-2/4 text-xl font-bold top-2 text-white">{{ title }}</div>
</div>
</template>
<script lang="ts" setup>
import Decoration5 from './Decoration5.vue'
import Decoration8 from './Decoration8.vue'
const close = () => {
window.ipcRenderer.send('CLOSE')
}
defineProps({
title: String
})
</script>

View File

@@ -14,6 +14,10 @@ import { intersect, findMap } from "../assets/geojson/geo.js";
use([ CanvasRenderer, MapChart, ScatterChart ]);
const props = defineProps({
styleMode: String
});
onMounted(() => {
var mychart = document.getElementById("myMap");
mychart.firstChild.style.margin = "auto";
@@ -28,7 +32,7 @@ const option = reactive({
label: {
show: true,
color: 'white',
fontSize: 18
fontSize: props.styleMode == "small" ? 12 : 18
},
itemStyle: {
normal: {
@@ -46,7 +50,7 @@ const option = reactive({
label: {
show: true,
color: 'white',
fontSize: 18
fontSize: props.styleMode == "small" ? 12 : 18
},
itemStyle: {
normal: {

View File

@@ -1,6 +1,6 @@
<template>
<div id="animationList" class="animationText mb-2"></div>
<div id="newnmeaList" class="animationText"></div>
<div id="animationList" class="animationText mb-2" :style="styleMode == 'small' ? 'font-size: 0.2rem;line-height: 0.4rem;' : ''"></div>
<div id="newnmeaList" class="animationText" :style="styleMode == 'small' ? 'font-size: 0.2rem;line-height: 0.4rem;' : ''"></div>
</template>
<script setup>
@@ -9,6 +9,10 @@ import { ref, onMounted } from "vue";
const animationValue = ref("");
const colorId = ref(0);
defineProps({
styleMode: String
});
var nmeaList;
var newList;
@@ -76,7 +80,7 @@ onMounted(() => {
<style scoped>
.animationText {
font-size: 0.5rem;
line-height: 1rem;
font-size: 0.4rem;
line-height: 0.8rem;
}
</style>

View File

@@ -37,6 +37,7 @@ const props = defineProps({
title: String,
color: String,
baseUrl: String,
styleMode: String
});
const option = reactive({
@@ -45,7 +46,7 @@ const option = reactive({
left: "center",
textStyle: {
color: "white",
fontSize: 28,
fontSize: props.styleMode == "small" ? 14 : 28,
textBorderColor: props.color,
textBorderWidth: 2,
textShadowColor: props.color,
@@ -64,7 +65,7 @@ const option = reactive({
show: false,
},
axisLabel: {
fontSize: 24,
fontSize: props.styleMode == "small" ? 12 : 24,
formatter: function (value: number) {
switch (value) {
case 0:
@@ -98,13 +99,13 @@ const option = reactive({
nmea: "un-positioning",
coordinateSystem: "polar",
type: "scatter",
symbolSize: 32,
symbolSize: props.styleMode == "small" ? 16 : 32,
symbol: "image://" + baseImg[props.baseUrl],
label: {
show: true,
color: "white",
fontSize: 14,
offset: [0,30],
fontSize: props.styleMode == "small" ? 7 : 14,
offset: props.styleMode == "small" ? [0,15] : [0,30],
textBorderColor: props.color,
textBorderWidth: 2,
formatter: "{@[2]}",
@@ -121,13 +122,13 @@ const option = reactive({
nmea: "un-positioning-un",
coordinateSystem: "polar",
type: "scatter",
symbolSize: 32,
symbolSize: props.styleMode == "small" ? 16: 32,
symbol: "image://" + baseImg["un" + props.baseUrl],
label: {
show: true,
color: "white",
fontSize: 14,
offset: [0,30],
fontSize: props.styleMode == "small" ? 7 : 14,
offset: props.styleMode == "small" ? [0,15] : [0,30],
textBorderColor: "#ccc",
textBorderWidth: 2,
formatter: "{@[2]}",
@@ -144,13 +145,13 @@ const option = reactive({
nmea: "in-positioning",
coordinateSystem: "polar",
type: "scatter",
symbolSize: 32,
symbolSize: props.styleMode == "small" ? 16 : 32,
symbol: "image://" + baseImg[props.baseUrl],
label: {
show: true,
color: "white",
fontSize: 14,
offset: [0,30],
fontSize: props.styleMode == "small" ? 7 : 14,
offset: props.styleMode == "small" ? [0,15] : [0,30],
textBorderColor: props.color,
textBorderWidth: 2,
formatter: "{@[2]}",
@@ -167,13 +168,13 @@ const option = reactive({
nmea: "in-positioning-un",
coordinateSystem: "polar",
type: "scatter",
symbolSize: 32,
symbolSize: props.styleMode == "small" ? 16 : 32,
symbol: "image://" + baseImg["un" + props.baseUrl],
label: {
show: true,
color: "white",
fontSize: 14,
offset: [0,30],
fontSize: props.styleMode == "small" ? 7 : 14,
offset: props.styleMode == "small" ? [0,15] : [0,30],
textBorderColor: "#ccc",
textBorderWidth: 2,
formatter: "{@[2]}",

View File

@@ -14,6 +14,10 @@ import { ref, reactive, onMounted } from "vue";
use([CanvasRenderer, LegendComponent, PieChart]);
const props = defineProps({
styleMode: String
});
const emit = defineEmits(['changeColor']);
const ring = ref(null);
@@ -109,12 +113,12 @@ const option = reactive({
bottom: '10%',
left: 'center',
selectedMode: false,
itemGap: 12,
itemWidth: 35,
itemHeight: 20,
itemGap: props.styleMode == "small" ? 6 : 12,
itemWidth: props.styleMode == "small" ? 18 : 36,
itemHeight: props.styleMode == "small" ? 10 : 20,
textStyle: {
color: 'auto',
fontSize: 16
fontSize: props.styleMode == "small" ? 10 : 16
}
},
xAxis3D: {
@@ -264,7 +268,7 @@ const option = reactive({
label: {
show: true,
color: 'white',
fontSize: '28',
fontSize: props.styleMode == "small" ? '14' : '28',
fontWeight: 'bold',
formatter: '{c}\n\n{b}',
textBorderWidth: 1,
@@ -313,6 +317,7 @@ const getPie3D = (sumValue, pieValue, internalDiameterRatio, height, size) => {
let highlightIndex = 0;
let reset = false;
const highlight = () => {
let colorPie = ['#ff3232', '#00ffff', '#6600ff', '#00ff66'];
reset = !reset;

View File

@@ -18,7 +18,8 @@ use([CanvasRenderer, BarChart, TitleComponent, GridComponent, DataZoomComponent]
const props = defineProps({
title: String,
color: String,
myid: String
myid: String,
styleMode: String
});
onMounted(() => {
@@ -68,7 +69,7 @@ const option = reactive({
top: 36,
textStyle: {
color: "white",
fontSize: 36,
fontSize: props.styleMode == "small" ? 18 : 36,
textBorderColor: props.color,
textBorderWidth: 2,
textShadowColor: props.color,
@@ -83,7 +84,7 @@ const option = reactive({
show: true,
textStyle: {
color: "white",
fontSize: 12,
fontSize: props.styleMode == "small" ? 10 : 12,
textBorderColor: props.color,
textBorderWidth: 1,
textShadowColor: props.color,

View File

@@ -1,10 +1,26 @@
<template>
<div class="satellite-table h-full flex flex-col">
<div class="shadow text-center text-3xl my-2">{{ title }}</div>
<div class="table-title shadow text-center text-3xl my-2"
:style="styleMode == 'small' ?
title == '北  斗' ? 'color: #ff3232;text-shadow:0 0 1em #ff3232;font-size: 1rem;'
: title == 'G P S' ? 'color: #00ffff;text-shadow:0 0 1em #00ffff;font-size: 1rem;'
: title == 'GLONASS' ? 'color: #6600ff;text-shadow:0 0 1em #6600ff;font-size: 1rem;'
: title == 'Galileo' ? 'color: #00ff66;text-shadow:0 0 1em #00ff66;font-size: 1rem;'
: ''
:
title == '北  斗' ? 'color: #ff3232;text-shadow:0 0 1em #ff3232;margin-bottom: 0.5rem;'
: title == 'G P S' ? 'color: #00ffff;text-shadow:0 0 1em #00ffff;margin-bottom: 0.5rem;'
: title == 'GLONASS' ? 'color: #6600ff;text-shadow:0 0 1em #6600ff;margin-bottom: 0.5rem;'
: title == 'Galileo' ? 'color: #00ff66;text-shadow:0 0 1em #00ff66;margin-bottom: 0.5rem;'
: ''
">
{{ title }}
</div>
<div class="table-header flex">
<div class="table-header flex" :style="styleMode == 'small' ? 'font-size: 0.5rem;' : ''">
<div
class="table-header-item leading-10 flex-1"
:style="styleMode == 'small' ? 'height: 1rem;line-height: 1rem;' : ''"
v-for="(headerItem, i) in header"
:key="`${headerItem}${i}`"
v-html="headerItem"
@@ -16,11 +32,16 @@
class="row-item flex"
v-for="(row, ri) in data.satellites"
:key="`${row.toString()}`"
:style="`
background-color: ${ri % 2 === 0 ? evenRowBGC : oddRowBGC};
:style="styleMode == 'small' ?
`background-color: ${ri % 2 === 0 ? evenRowBGC : oddRowBGC};
--itemY: -${data.itemY}px;
--itemS: ${data.itemS}s;
`"
font-size: 0.5rem;
height: 1rem;
line-height: 1rem;`:
`background-color: ${ri % 2 === 0 ? evenRowBGC : oddRowBGC};
--itemY: -${data.itemY}px;
--itemS: ${data.itemS}s;`"
>
<div
class="ceil flex-1 cell"
@@ -34,17 +55,25 @@
</template>
<script lang="ts" setup>
import { ref, reactive, getCurrentInstance } from 'vue'
import { ref, reactive, getCurrentInstance } from 'vue';;
defineProps({
title: String
})
const props = defineProps({
title: String,
styleMode: String
});
const instance = getCurrentInstance()
const oddRowBGC = '#003B51'
const evenRowBGC = '#0A2732'
const titleColor = {
"北  斗": 'color: #ff3232',
"G P S": 'color: #00ffff',
"GLONASS": 'color: #6600ff',
"Galileo": 'color: #00ff66',
};
const header = ['卫星编号', '仰角', '方位角', '载噪比']
const instance = getCurrentInstance();
const oddRowBGC = '#003B51';
const evenRowBGC = '#0A2732';
const header = ['卫星编号', '仰角', '方位角', '载噪比'];
const data = reactive({
satellites: [
// {id: 0, svid: 1, cn: 2, sd: 3},
@@ -60,51 +89,57 @@ const data = reactive({
],
itemY: 0,
itemS: 0
})
const warehouse = ref([])
const count = ref(0)
});
const warehouse = ref([]);
const count = ref(0);
const update = (GSVArr: Array<any>) => {
if (GSVArr.length <= 0 ) return
if (GSVArr.length <= 0 ) return;
let satellites: any[] = []
let satellites: any[] = [];
GSVArr.forEach((GSV) => {
satellites = satellites.concat(GSV.satellites)
})
satellites = satellites.concat(GSV.satellites);
});
if(warehouse.value.length < 4){
warehouse.value.push(satellites)
warehouse.value.push(satellites);
}
if(warehouse.value.length == 4){
if(count.value < 5){
if(count.value == 4){
count.value = 0
count.value = 0;
}
if(warehouse.value[count.value].length == satellites.length){
data.satellites = satellites
data.itemY = (satellites.length-9<0?0:satellites.length-9)*38.02
data.itemS = (satellites.length-9<0?0:satellites.length-9)*6
data.satellites = satellites;
data.itemY = (satellites.length-9<0?0:satellites.length-9)*38.02;
data.itemS = (satellites.length-9<0?0:satellites.length-9)*6;
}else{
warehouse.value[count.value] = satellites
data.satellites = []
data.itemY = 0
data.itemS = 0
}
count.value = count.value + 1
warehouse.value[count.value] = satellites;
data.satellites = [];
data.itemY = 0;
data.itemS = 0;
}
count.value = count.value + 1;
}
}
};
defineExpose({ update })
defineExpose({ update });
</script>
<style scoped>
.table-title {
font-size: 2rem;
margin: 0;
}
.table-header {
font-size: 1rem;
background-color: rgba(25, 129, 246, .6);
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
.table-body {
height: 342px;
height: 16rem;
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
}
@@ -114,7 +149,7 @@ defineExpose({ update })
}
.table-body:hover::-webkit-scrollbar {
width: 12px;
width: 0.6rem;
}
.table-body:hover::-webkit-scrollbar-thumb {
@@ -129,7 +164,8 @@ defineExpose({ update })
}
.row-item {
line-height: 38px;
font-size: 1rem;
line-height: 2rem;
animation: rolling var(--itemS) infinite linear;
transition-property: all;
transition-duration: 4s;

View File

@@ -11,17 +11,17 @@ import 'echarts-liquidfill'
import VChart from "vue-echarts";
use([
CanvasRenderer,
TitleComponent
]);
use([ CanvasRenderer, TitleComponent ]);
const props = defineProps({
styleMode: String
});
onMounted(() => {
var mychart = document.getElementById("myWaterLevel");
mychart.firstChild.style.margin = "auto";
});
const option = reactive({
title: {
text: '海拔',
@@ -36,7 +36,7 @@ const option = reactive({
color: 'transparency'
},
label: {
fontSize : 36,
fontSize : props.styleMode == "small" ? 18 : 36,
formatter: function({ value }) {
return parseInt(value)
}

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

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

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

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

View File

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

View File

@@ -1,27 +1,25 @@
<template>
<full-screen-container>
<TheHeader title="卫星数据监控平台" />
<div class="main-content flex flex-1 flex-col">
<DigitalFlopContainer ref="digitalFlopContainer" />
<DigitalFlopContainer ref="digitalFlopContainer" styleMode="large" />
<div class="block-left-right-content flex flex-1 mt-5">
<div class="block-left-content w-1/5 flex flex-col">
<div class="clock-content mb-2 flex-1">
<Clock ref="clock" />
<Clock ref="clock" styleMode="large" />
</div>
<div class="compass-content mb-2 flex-1">
<Compass ref="compass" />
<Compass ref="compass" styleMode="large" />
</div>
<div class="water-level-content flex-1">
<WaterLevel ref="waterLevel" />
<WaterLevel ref="waterLevel" styleMode="large" />
</div>
</div>
<div class="block-right-content mx-2 flex flex-1">
<Map ref="map" />
<Map ref="map" styleMode="large" />
</div>
<div class="block-right-content w-1/5 flex flex-col py-2 px-2">
<NMEAAnimation ref="nmeaAnimate" />
<NMEAAnimation ref="nmeaAnimate" styleMode="large" />
</div>
<div class="text-white fixed bottom-0 right-0">
四大系统卫星运行状态监控系统V1.0
@@ -85,9 +83,7 @@ const getMonitoringData = (nmeaStr: string) => {
const { date, timestamp, variation, variationPole } = RMC;
// 经度,经度方向,纬度,纬度方向,海拔,用于定位的卫星数目
const { lon, lonPole, lat, latPole, alt, numSat } = GGA;
const dateTime = getDate(date, timestamp);
const longitude = Helpers.parseLongitude(lon, lonPole);
const latitude = Helpers.parseLatitude(lat, latPole);
@@ -97,7 +93,6 @@ const getMonitoringData = (nmeaStr: string) => {
const update = (nmeaStr: string) => {
const data: any = getMonitoringData(nmeaStr);
if (!data) return;
const { dateTime, longitude, latitude, alt, variation, variationPole, numSat } = data;
if (longitude != NaN && latitude != NaN && longitude != "NaN" && latitude != "NaN") {
stagingObj.dateTime = dateTime;

View File

@@ -1,27 +1,26 @@
<template>
<full-screen-container>
<TheHeader title="卫星信息监控平台" />
<div class="main-content flex flex-1">
<div class="w-1/4 px-2 flex flex-col">
<border-box-3>
<ScrollBoardTable ref="BDScrollBoardTable" title="北  斗" />
<ScrollBoardTable ref="BDScrollBoardTable" title="北  斗" styleMode="large" />
</border-box-3>
<border-box-3>
<ScrollBoardTable ref="GLScrollBoardTable" title="GLONASS" />
<ScrollBoardTable ref="GLScrollBoardTable" title="GLONASS" styleMode="large" />
</border-box-3>
</div>
<div class="w-1/2 px-2">
<border-box-3>
<CenterCmp ref="centerCmp" />
<CenterCmp ref="centerCmp" styleMode="large" />
</border-box-3>
</div>
<div class="w-1/4 flex flex-col px-2">
<border-box-3>
<ScrollBoardTable ref="GPScrollBoardTable" title="G P S" />
<ScrollBoardTable ref="GPScrollBoardTable" title="G P S" styleMode="large" />
</border-box-3>
<border-box-3>
<ScrollBoardTable ref="GAScrollBoardTable" title="Galileo" />
<ScrollBoardTable ref="GAScrollBoardTable" title="Galileo" styleMode="large" />
</border-box-3>
</div>
</div>
@@ -29,53 +28,55 @@
</template>
<script lang="ts" setup>
import FullScreenContainer from '../components/Layout/FullScreenContainer.vue'
import TheHeader from '../components/Layout/TheHeader.vue'
import BorderBox3 from '../components/Layout/BorderBox3.vue'
import CenterCmp from '../components/CenterCmp.vue'
import ScrollBoardTable from '../components/ScrollBoardTable.vue'
import FullScreenContainer from '../components/Layout/FullScreenContainer.vue';
import TheHeader from '../components/Layout/TheHeader.vue';
import BorderBox3 from '../components/Layout/BorderBox3.vue';
import CenterCmp from '../components/CenterCmp.vue';
import ScrollBoardTable from '../components/ScrollBoardTable.vue';
import { ref, onMounted } from 'vue'
import { getGSV } from '../api/util'
import { ref, onMounted } from 'vue';
import { getGSV } from '../api/util';
const BDScrollBoardTable = ref(null)
const GPScrollBoardTable = ref(null)
const GLScrollBoardTable = ref(null)
const GAScrollBoardTable = ref(null)
const centerCmp = ref(null)
const update = (nmeaStr: string) => {
const data: any = getGSV(nmeaStr)
if (!data) return
const { bd, gp, gl, ga } = data
BDScrollBoardTable.value.update(bd.GSVArr)
GPScrollBoardTable.value.update(gp.GSVArr)
GLScrollBoardTable.value.update(gl.GSVArr)
GAScrollBoardTable.value.update(ga.GSVArr)
const bd_satellite_count = getSatelliteCount(bd.GSVArr)
const gp_satellite_count = getSatelliteCount(gp.GSVArr)
const gl_satellite_count = getSatelliteCount(gl.GSVArr)
const ga_satellite_count = getSatelliteCount(ga.GSVArr)
centerCmp.value.update(bd_satellite_count, gp_satellite_count, gl_satellite_count, ga_satellite_count)
}
onMounted(() => {
if ('ipcRenderer' in window) {
ipcRenderer.receive('nmea', update)
ipcRenderer.send('APP_MOUNTED')
}
})
const BDScrollBoardTable = ref(null);
const GPScrollBoardTable = ref(null);
const GLScrollBoardTable = ref(null);
const GAScrollBoardTable = ref(null);
const centerCmp = ref(null);
const getSatelliteCount = (GSVArr: Array<any>) => {
if (!GSVArr) return
if (!GSVArr) return;
const count = GSVArr.reduce((total, gsv) => {
return total + gsv.satellites.length
}, 0)
return total + gsv.satellites.length;
}, 0);
return count
return count;
};
const update = (nmeaStr: string) => {
const data: any = getGSV(nmeaStr);
if (!data) return;
const { bd, gp, gl, ga } = data;
BDScrollBoardTable.value.update(bd.GSVArr);
GPScrollBoardTable.value.update(gp.GSVArr);
GLScrollBoardTable.value.update(gl.GSVArr);
GAScrollBoardTable.value.update(ga.GSVArr);
const bd_satellite_count = getSatelliteCount(bd.GSVArr);
const gp_satellite_count = getSatelliteCount(gp.GSVArr);
const gl_satellite_count = getSatelliteCount(gl.GSVArr);
const ga_satellite_count = getSatelliteCount(ga.GSVArr);
centerCmp.value.update(bd_satellite_count, gp_satellite_count, gl_satellite_count, ga_satellite_count);
};
onMounted(() => {
if ('ipcRenderer' in window) {
ipcRenderer.receive('nmea', update);
ipcRenderer.send('APP_MOUNTED');
}
});
</script>

View File

@@ -1,45 +1,85 @@
<template>
<full-screen-container>
<TheHeader title="卫星信号监控平台" />
<div class="main-content flex-1 grid grid-cols-2 grid-rows-2">
<div class="w-11/12 justify-self-end">
<SNRView ref="BDSNRView" color="rgb(255,50,50)" myid="bdBar" title="北斗" />
<SNRView ref="BDSNRView" color="rgb(255,50,50)" myid="bdBar" title="北斗" styleMode="large" />
</div>
<div class="w-11/12 justify-self-start">
<SNRView ref="GPSNRView" color="rgb(0,204,255)" myid="gpsBar" title="GPS" />
<SNRView ref="GPSNRView" color="rgb(0,204,255)" myid="gpsBar" title="GPS" styleMode="large" />
</div>
<div class="w-11/12 justify-self-end">
<SNRView ref="GLSNRView" color="rgb(102,0,255)" myid="glonassBar" title="GLONASS" />
<SNRView ref="GLSNRView" color="rgb(102,0,255)" myid="glonassBar" title="GLONASS" styleMode="large" />
</div>
<div class="w-11/12 justify-self-start">
<SNRView ref="GASNRView" color="rgb(0,204,102)" myid="galileoBar" title="Galileo" />
<SNRView ref="GASNRView" color="rgb(0,204,102)" myid="galileoBar" title="Galileo" styleMode="large" />
</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'
import FullScreenContainer from '../components/Layout/FullScreenContainer.vue';
import TheHeader from '../components/Layout/TheHeader.vue';
import SNRView from '../components/SNRView.vue';
import { ref, onMounted } from 'vue'
import { getNMEAObj } from '../api/util'
import { ref, onMounted } from 'vue';
import { getNMEAObj } from '../api/util';
const BDSNRView = ref(null);
const GPSNRView = ref(null);
const GLSNRView = ref(null);
const GASNRView = ref(null);
const getMonitoringData = (nmeaStr: string) => {
const nmeaObj: any = getNMEAObj(nmeaStr)
// console.log(nmeaObj, '================')
if (!nmeaObj || !nmeaObj.GSV || !nmeaObj.GSA) return null;
const { GSV, GSA } = nmeaObj;
const bd = {
// NMEA 1083 3.x $BDGSV,...*
// NMEA 1083 4.0x $GBGSV,...*
// NMEA 1083 4.1x $GBGSV,...,1* | $GBGSV,...,0*
// GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'BD'),
// GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'BD')
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'GB'),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'GB')
};
const gp = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'GP'),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'GP')
};
const gl = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'GL'),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'GL')
};
const ga = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'GA'),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'GA')
};
return { bd, gp, gl, ga };
};
const getSatelliteCount = (GSVArr: Array<any>) => {
if (!GSVArr) return;
const count = GSVArr.reduce((total, gsv) => {
return total + gsv.satellites.length;
}, 0);
return count;
};
const BDSNRView = ref(null)
const GPSNRView = ref(null)
const GLSNRView = ref(null)
const GASNRView = ref(null)
const update = (nmeaStr: string) => {
const data: any = getMonitoringData(nmeaStr)
if (!data) return
const data: any = getMonitoringData(nmeaStr);
const { bd, gp, gl, ga } = data
if (!data) return;
const bd_gp_satellite_count = getSatelliteCount(bd.GSVArr)>getSatelliteCount(gp.GSVArr)?getSatelliteCount(bd.GSVArr):getSatelliteCount(gp.GSVArr)
const gl_ga_satellite_count = getSatelliteCount(gl.GSVArr)>getSatelliteCount(ga.GSVArr)?getSatelliteCount(gl.GSVArr):getSatelliteCount(ga.GSVArr)
const lineMax=bd_gp_satellite_count>gl_ga_satellite_count?bd_gp_satellite_count:gl_ga_satellite_count
const { bd, gp, gl, ga } = data;
const bd_gp_satellite_count = getSatelliteCount(bd.GSVArr)>getSatelliteCount(gp.GSVArr)?getSatelliteCount(bd.GSVArr):getSatelliteCount(gp.GSVArr);
const gl_ga_satellite_count = getSatelliteCount(gl.GSVArr)>getSatelliteCount(ga.GSVArr)?getSatelliteCount(gl.GSVArr):getSatelliteCount(ga.GSVArr);
const lineMax=bd_gp_satellite_count>gl_ga_satellite_count?bd_gp_satellite_count:gl_ga_satellite_count;
// TODO: 找到bdgsv语句有7条的原因以及gsa语句配置talker_id为各个卫星导航系统自己的名字
@@ -50,58 +90,16 @@ const update = (nmeaStr: string) => {
// GASNRView.value.update(ga.GSVArr, ga.GSAArr, getSatelliteCount(ga.GSVArr))
// 粗细一致,x轴长度以数据最多的条目为准
BDSNRView.value.update(bd.GSVArr, bd.GSAArr, lineMax)
GPSNRView.value.update(gp.GSVArr, gp.GSAArr, lineMax)
GLSNRView.value.update(gl.GSVArr, gl.GSAArr, lineMax)
GASNRView.value.update(ga.GSVArr, ga.GSAArr, lineMax)
}
BDSNRView.value.update(bd.GSVArr, bd.GSAArr, lineMax);
GPSNRView.value.update(gp.GSVArr, gp.GSAArr, lineMax);
GLSNRView.value.update(gl.GSVArr, gl.GSAArr, lineMax);
GASNRView.value.update(ga.GSVArr, ga.GSAArr, lineMax);
};
onMounted(() => {
if ('ipcRenderer' in window) {
ipcRenderer.receive('nmea', update)
ipcRenderer.send('APP_MOUNTED')
}
})
const getSatelliteCount = (GSVArr: Array<any>) => {
if (!GSVArr) return
const count = GSVArr.reduce((total, gsv) => {
return total + gsv.satellites.length
}, 0)
return count
}
const getMonitoringData = (nmeaStr: string) => {
const nmeaObj: any = getNMEAObj(nmeaStr)
// console.log(nmeaObj, '================')
if (!nmeaObj || !nmeaObj.GSV || !nmeaObj.GSA) return null
const { GSV, GSA } = nmeaObj
const bd = {
// NMEA 1083 3.x $BDGSV,...*
// NMEA 1083 4.0x $GBGSV,...*
// NMEA 1083 4.1x $GBGSV,...,1* | $GBGSV,...,0*
// GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'BD'),
// GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'BD')
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'GB'),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'GB')
}
const gp = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'GP'),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'GP')
}
const gl = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'GL'),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'GL')
}
const ga = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'GA'),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'GA')
}
return { bd, gp, gl, ga }
ipcRenderer.receive('nmea', update);
ipcRenderer.send('APP_MOUNTED');
}
});
</script>

View File

@@ -1,63 +1,43 @@
<template>
<full-screen-container>
<TheHeader title="卫星状态监控平台" />
<div class="main-content flex-1 grid grid-cols-2 grid-rows-2">
<div class="w-5/6 justify-self-end">
<PlanisphereView ref="BDPlanisphereView" color="rgb(255,50,50)" title="北斗" baseUrl="beidou" />
<PlanisphereView ref="BDPlanisphereView" color="rgb(255,50,50)" title="北斗" baseUrl="beidou" styleMode="large" />
</div>
<div class="w-5/6 justify-self-start">
<PlanisphereView ref="GPPlanisphereView" color="rgb(0,204,255)" title="GPS" baseUrl="gps" />
<PlanisphereView ref="GPPlanisphereView" color="rgb(0,204,255)" title="GPS" baseUrl="gps" styleMode="large" />
</div>
<div class="w-5/6 justify-self-end">
<PlanisphereView ref="GLPlanisphereView" color="rgb(102,0,255)" title="GLONASS" baseUrl="glonass" />
<PlanisphereView ref="GLPlanisphereView" color="rgb(102,0,255)" title="GLONASS" baseUrl="glonass" styleMode="large" />
</div>
<div class="w-5/6 justify-self-start">
<PlanisphereView ref="GAPlanisphereView" color="rgb(0,204,102)" title="Galileo" baseUrl="galileo" />
<PlanisphereView ref="GAPlanisphereView" color="rgb(0,204,102)" title="Galileo" baseUrl="galileo" styleMode="large" />
</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'
import FullScreenContainer from '../components/Layout/FullScreenContainer.vue';
import TheHeader from '../components/Layout/TheHeader.vue';
import PlanisphereView from '../components/PlanisphereView.vue';
import { ref, onMounted } from 'vue'
import { getNMEAObj } from '../api/util'
import { ref, onMounted } from 'vue';
import { getNMEAObj } from '../api/util';
const BDPlanisphereView = ref(null)
const GPPlanisphereView = ref(null)
const GLPlanisphereView = ref(null)
const GAPlanisphereView = ref(null)
const update = (nmeaStr: string) => {
const data: any = getMonitoringData(nmeaStr)
if (!data) return
const { bd, gp, gl, ga } = data
// TODO: 找到bdgsv语句有7条的原因以及gsa语句配置talker_id为各个卫星导航系统自己的名字
BDPlanisphereView.value.update(bd.GSVArr, bd.GSAArr)
GPPlanisphereView.value.update(gp.GSVArr, gp.GSAArr)
GLPlanisphereView.value.update(gl.GSVArr, gl.GSAArr)
GAPlanisphereView.value.update(ga.GSVArr, ga.GSAArr)
}
onMounted(() => {
if ('ipcRenderer' in window) {
ipcRenderer.receive('nmea', update)
ipcRenderer.send('APP_MOUNTED')
}
})
const BDPlanisphereView = ref(null);
const GPPlanisphereView = ref(null);
const GLPlanisphereView = ref(null);
const GAPlanisphereView = ref(null);
const getMonitoringData = (nmeaStr: string) => {
const nmeaObj: any = getNMEAObj(nmeaStr)
const nmeaObj: any = getNMEAObj(nmeaStr);
// console.log(nmeaObj, '================')
if (!nmeaObj || !nmeaObj.GSV || !nmeaObj.GSA) return null
if (!nmeaObj || !nmeaObj.GSV || !nmeaObj.GSA) return null;
const { GSV, GSA } = nmeaObj;
const { GSV, GSA } = nmeaObj
const bd = {
// NMEA 1083 3.x $BDGSV,...*
// NMEA 1083 4.0x $GBGSV,...*
@@ -66,20 +46,41 @@ const getMonitoringData = (nmeaStr: string) => {
// GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'BD')
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'GB'),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'GB')
}
};
const gp = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'GP'),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'GP')
}
};
const gl = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'GL'),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'GL')
}
};
const ga = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'GA'),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'GA')
}
};
return { bd, gp, gl, ga };
};
return { bd, gp, gl, ga }
const update = (nmeaStr: string) => {
const data: any = getMonitoringData(nmeaStr);
if (!data) return;
const { bd, gp, gl, ga } = data;
// TODO: 找到bdgsv语句有7条的原因以及gsa语句配置talker_id为各个卫星导航系统自己的名字
BDPlanisphereView.value.update(bd.GSVArr, bd.GSAArr);
GPPlanisphereView.value.update(gp.GSVArr, gp.GSAArr);
GLPlanisphereView.value.update(gl.GSVArr, gl.GSAArr);
GAPlanisphereView.value.update(ga.GSVArr, ga.GSAArr);
};
onMounted(() => {
if ('ipcRenderer' in window) {
ipcRenderer.receive('nmea', update);
ipcRenderer.send('APP_MOUNTED');
}
});
</script>

759
src/render/page/oneShow.vue Normal file
View File

@@ -0,0 +1,759 @@
<template>
<select class="showModeView" v-model="showModeView">
<option v-for="(value, key) in showMode" :key="key" :value="key">
{{ value }}
</option>
</select>
<div v-if="showModeView == 'showAll'">
<full-screen-container>
<div class="w-h-full flex-1 grid grid-cols-2 grid-rows-2">
<div class="w-h-full justify-self-end border-r-4 border-r-sky-500/50">
<ShowAllHeader title="卫星数据监控平台" />
<div class="main-content w-full h-5/6 flex flex-1 flex-col">
<DigitalFlopContainer ref="digitalFlopContainerAll" styleMode="small" />
<div class="block-left-right-content flex flex-1 mt-5">
<div class="block-left-content w-1/5 flex flex-col">
<div class="clock-content mb-2 flex-1">
<Clock ref="clockAll" styleMode="small" />
</div>
<div class="compass-content mb-2 flex-1">
<Compass ref="compassAll" styleMode="small" />
</div>
<div class="water-level-content flex-1">
<WaterLevel ref="waterLevelAll" styleMode="small" />
</div>
</div>
<div class="block-right-content mx-2 flex flex-1">
<Map ref="mapAll" styleMode="small" />
</div>
<div class="block-right-content w-1/5 flex flex-col py-2 px-2">
<NMEAAnimation ref="nmeaAnimate" styleMode="small" />
</div>
</div>
</div>
</div>
<div class="w-h-full justify-self-start">
<ShowAllHeader title="卫星信息监控平台" />
<div class="main-content w-full h-5/6 flex flex-1">
<div class="w-1/4 h-1/2 px-2 flex flex-col">
<border-box-3>
<ScrollBoardTable
ref="BDScrollBoardTableAll"
title="北  斗"
styleMode="small"
/>
</border-box-3>
<border-box-3>
<ScrollBoardTable
ref="GLScrollBoardTableAll"
title="GLONASS"
styleMode="small"
/>
</border-box-3>
</div>
<div class="w-1/2 px-2">
<border-box-3>
<CenterCmp ref="centerCmpAll" styleMode="small" />
</border-box-3>
</div>
<div class="w-1/4 h-1/2 flex flex-col px-2">
<border-box-3>
<ScrollBoardTable
ref="GPScrollBoardTableAll"
title="G P S"
styleMode="small"
/>
</border-box-3>
<border-box-3>
<ScrollBoardTable
ref="GAScrollBoardTableAll"
title="Galileo"
styleMode="small"
/>
</border-box-3>
</div>
</div>
</div>
<div
class="w-h-full justify-self-end border-t-4 border-t-sky-500/50 border-r-4 border-r-sky-500/50"
>
<ShowAllHeader title="卫星信号监控平台" />
<div class="main-content w-full h-5/6 flex-1 grid grid-cols-2 grid-rows-2">
<div class="w-11/12 justify-self-end">
<SNRView
ref="BDSNRViewAll"
color="rgb(255,50,50)"
myid="bdBar"
title="北斗"
styleMode="small"
/>
</div>
<div class="w-11/12 justify-self-start">
<SNRView
ref="GPSNRViewAll"
color="rgb(0,204,255)"
myid="gpsBar"
title="GPS"
styleMode="small"
/>
</div>
<div class="w-11/12 justify-self-end">
<SNRView
ref="GLSNRViewAll"
color="rgb(102,0,255)"
myid="glonassBar"
title="GLONASS"
styleMode="small"
/>
</div>
<div class="w-11/12 justify-self-start">
<SNRView
ref="GASNRViewAll"
color="rgb(0,204,102)"
myid="galileoBar"
title="Galileo"
styleMode="small"
/>
</div>
</div>
</div>
<div class="w-h-full justify-self-start border-t-4 border-t-sky-500/50">
<ShowAllHeader title="卫星状态监控平台" />
<div class="main-content w-full h-5/6 flex-1 grid grid-cols-2 grid-rows-2">
<div class="w-5/6 justify-self-end">
<PlanisphereView
ref="BDPlanisphereViewAll"
color="rgb(255,50,50)"
title="北斗"
baseUrl="beidou"
styleMode="small"
/>
</div>
<div class="w-5/6 justify-self-start">
<PlanisphereView
ref="GPPlanisphereViewAll"
color="rgb(0,204,255)"
title="GPS"
baseUrl="gps"
styleMode="small"
/>
</div>
<div class="w-5/6 justify-self-end">
<PlanisphereView
ref="GLPlanisphereViewAll"
color="rgb(102,0,255)"
title="GLONASS"
baseUrl="glonass"
styleMode="small"
/>
</div>
<div class="w-5/6 justify-self-start">
<PlanisphereView
ref="GAPlanisphereViewAll"
color="rgb(0,204,102)"
title="Galileo"
baseUrl="galileo"
styleMode="small"
/>
</div>
</div>
</div>
</div>
<div class="text-white fixed bottom-0 right-0">
四大系统卫星运行状态监控系统V1.0
</div>
</full-screen-container>
</div>
<div v-if="showModeView == 'showSwitch'">
<select class="selectView" v-model="screenView">
<option v-for="(value, key) in view" :key="key" :value="key">
{{ value }}
</option>
</select>
<full-screen-container v-if="screenView == 'DataMonitorPage'">
<TheHeader title="卫星数据监控平台" />
<div class="main-content flex flex-1 flex-col">
<DigitalFlopContainer ref="digitalFlopContainerSwitch" styleMode="large" />
<div class="block-left-right-content flex flex-1 mt-5">
<div class="block-left-content w-1/5 flex flex-col">
<div class="clock-content mb-2 flex-1">
<Clock ref="clockSwitch" styleMode="large" />
</div>
<div class="compass-content mb-2 flex-1">
<Compass ref="compassSwitch" styleMode="large" />
</div>
<div class="water-level-content flex-1">
<WaterLevel ref="waterLevelSwitch" styleMode="large" />
</div>
</div>
<div class="block-right-content mx-2 flex flex-1">
<Map ref="mapSwitch" styleMode="large" />
</div>
<div class="block-right-content w-1/5 flex flex-col py-2 px-2">
<NMEAAnimation ref="nmeaAnimate" styleMode="large" />
</div>
<div class="text-white fixed bottom-0 right-0">
四大系统卫星运行状态监控系统V1.0
</div>
</div>
</div>
</full-screen-container>
<full-screen-container v-if="screenView == 'InfoMonitorPage'">
<TheHeader title="卫星信息监控平台" />
<div class="main-content flex flex-1">
<div class="w-1/4 px-2 flex flex-col">
<border-box-3>
<ScrollBoardTable
ref="BDScrollBoardTableSwitch"
title="北  斗"
styleMode="large"
/>
</border-box-3>
<border-box-3>
<ScrollBoardTable
ref="GLScrollBoardTableSwitch"
title="GLONASS"
styleMode="large"
/>
</border-box-3>
</div>
<div class="w-1/2 px-2">
<border-box-3>
<CenterCmp ref="centerCmpSwitch" styleMode="large" />
</border-box-3>
</div>
<div class="w-1/4 flex flex-col px-2">
<border-box-3>
<ScrollBoardTable ref="GPScrollBoardTableSwitch" title="G P S" styleMode="large" />
</border-box-3>
<border-box-3>
<ScrollBoardTable
ref="GAScrollBoardTableSwitch"
title="Galileo"
styleMode="large"
/>
</border-box-3>
</div>
</div>
</full-screen-container>
<full-screen-container v-if="screenView == 'SignalMonitorPage'">
<TheHeader title="卫星信号监控平台" />
<div class="main-content flex-1 grid grid-cols-2 grid-rows-2">
<div class="w-11/12 justify-self-end">
<SNRView
ref="BDSNRViewSwitch"
color="rgb(255,50,50)"
myid="bdBar"
title="北斗"
styleMode="large"
/>
</div>
<div class="w-11/12 justify-self-start">
<SNRView
ref="GPSNRViewSwitch"
color="rgb(0,204,255)"
myid="gpsBar"
title="GPS"
styleMode="large"
/>
</div>
<div class="w-11/12 justify-self-end">
<SNRView
ref="GLSNRViewSwitch"
color="rgb(102,0,255)"
myid="glonassBar"
title="GLONASS"
styleMode="large"
/>
</div>
<div class="w-11/12 justify-self-start">
<SNRView
ref="GASNRViewSwitch"
color="rgb(0,204,102)"
myid="galileoBar"
title="Galileo"
styleMode="large"
/>
</div>
</div>
</full-screen-container>
<full-screen-container v-if="screenView == 'StateMonitorPage'">
<TheHeader title="卫星状态监控平台" />
<div class="main-content flex-1 grid grid-cols-2 grid-rows-2">
<div class="w-5/6 justify-self-end">
<PlanisphereView
ref="BDPlanisphereViewSwitch"
color="rgb(255,50,50)"
title="北斗"
baseUrl="beidou"
styleMode="large"
/>
</div>
<div class="w-5/6 justify-self-start">
<PlanisphereView
ref="GPPlanisphereViewSwitch"
color="rgb(0,204,255)"
title="GPS"
baseUrl="gps"
styleMode="large"
/>
</div>
<div class="w-5/6 justify-self-end">
<PlanisphereView
ref="GLPlanisphereViewSwitch"
color="rgb(102,0,255)"
title="GLONASS"
baseUrl="glonass"
styleMode="large"
/>
</div>
<div class="w-5/6 justify-self-start">
<PlanisphereView
ref="GAPlanisphereViewSwitch"
color="rgb(0,204,102)"
title="Galileo"
baseUrl="galileo"
styleMode="large"
/>
</div>
</div>
</full-screen-container>
</div>
</template>
<script lang="ts" setup>
import FullScreenContainer from "../components/Layout/FullScreenContainer.vue";
import ShowAllHeader from "../components/Layout/ShowAllHeader.vue";
import TheHeader from "../components/Layout/TheHeader.vue";
import DigitalFlopContainer from "../components/DigitalFlopContainer.vue";
import Clock from "../components/Clock.vue";
import Compass from "../components/Compass.vue";
import WaterLevel from "../components/WaterLevel.vue";
import Map from "../components/Map.vue";
import NMEAAnimation from "../components/NMEAAnimation.vue";
import BorderBox3 from "../components/Layout/BorderBox3.vue";
import CenterCmp from "../components/CenterCmp.vue";
import ScrollBoardTable from "../components/ScrollBoardTable.vue";
import SNRView from "../components/SNRView.vue";
import PlanisphereView from "../components/PlanisphereView.vue";
import { ref, reactive, onMounted } from "vue";
import { Helpers } from "nmea";
import { getNMEAObj } from "../api/util";
const showModeView = ref("showAll");
const showMode = {
showAll: "多页面显示",
showSwitch: "单页面切换",
};
const screenView = ref("DataMonitorPage");
const view = {
DataMonitorPage: "卫星数据监控平台",
InfoMonitorPage: "卫星信息监控平台",
SignalMonitorPage: "卫星信号监控平台",
StateMonitorPage: "卫星状态监控平台",
};
const digitalFlopContainerAll = ref(null);
const clockAll = ref(null);
const compassAll = ref(null);
const waterLevelAll = ref(null);
const mapAll = ref(null);
const digitalFlopContainerSwitch = ref(null);
const clockSwitch = ref(null);
const compassSwitch = ref(null);
const waterLevelSwitch = ref(null);
const mapSwitch = ref(null);
const nmeaAnimate = ref(null);
const deepmsg = ref(null);
const BDScrollBoardTableAll = ref(null);
const GPScrollBoardTableAll = ref(null);
const GLScrollBoardTableAll = ref(null);
const GAScrollBoardTableAll = ref(null);
const BDScrollBoardTableSwitch = ref(null);
const GPScrollBoardTableSwitch = ref(null);
const GLScrollBoardTableSwitch = ref(null);
const GAScrollBoardTableSwitch = ref(null);
const centerCmpAll = ref(null);
const BDSNRViewAll = ref(null);
const GPSNRViewAll = ref(null);
const GLSNRViewAll = ref(null);
const GASNRViewAll = ref(null);
const centerCmpSwitch = ref(null);
const BDSNRViewSwitch = ref(null);
const GPSNRViewSwitch = ref(null);
const GLSNRViewSwitch = ref(null);
const GASNRViewSwitch = ref(null);
const BDPlanisphereViewAll = ref(null);
const GPPlanisphereViewAll = ref(null);
const GLPlanisphereViewAll = ref(null);
const GAPlanisphereViewAll = ref(null);
const BDPlanisphereViewSwitch = ref(null);
const GPPlanisphereViewSwitch = ref(null);
const GLPlanisphereViewSwitch = ref(null);
const GAPlanisphereViewSwitch = ref(null);
const stagingObjAll = reactive({
dataTime: null,
longitude: NaN,
latitude: NaN,
alt: 0,
variation: null,
variationPole: null,
numSat: 0,
});
const stagingObjSwitch = reactive({
dataTime: null,
longitude: NaN,
latitude: NaN,
alt: 0,
variation: null,
variationPole: null,
numSat: 0,
});
const getDate = (date, timestamp) => {
const year = date.substring(4);
const month = date.substring(2, 4);
const day = date.substring(0, 2);
const hours = timestamp.substring(0, 2);
const minutes = timestamp.substring(2, 4);
const seconds = timestamp.substring(4, 6);
const dateTimeStr = `20${year}-${month}-${day}T${hours}:${minutes}:${seconds}+00:00`;
const dateTime = new Date(dateTimeStr);
return dateTime;
};
const getMonitoringData = (nmeaStr: string) => {
const nmeaObj: any = getNMEAObj(nmeaStr);
// console.log(nmeaObj, "================");
if (
!nmeaObj ||
!nmeaObj.RMC ||
!nmeaObj.GGA ||
!nmeaObj ||
!nmeaObj.GSV ||
!nmeaObj.GSA
)
return null;
const { RMC, GGA, GSV, GSA } = nmeaObj;
// 日期,时间,磁偏角,磁偏角方向
const { date, timestamp, variation, variationPole } = RMC;
// 经度,经度方向,纬度,纬度方向,海拔,用于定位的卫星数目
const { lon, lonPole, lat, latPole, alt, numSat } = GGA;
const dateTime = getDate(date, timestamp);
const longitude = Helpers.parseLongitude(lon, lonPole);
const latitude = Helpers.parseLatitude(lat, latPole);
const bd = {
// NMEA 1083 3.x $BDGSV,...*
// NMEA 1083 4.0x $GBGSV,...*
// NMEA 1083 4.1x $GBGSV,...,1* | $GBGSV,...,0*
// GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'BD'),
// GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'BD')
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === "GB"),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === "GB"),
};
const gp = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === "GP"),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === "GP"),
};
const gl = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === "GL"),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === "GL"),
};
const ga = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === "GA"),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === "GA"),
};
return {
dateTime,
longitude,
latitude,
alt,
variation,
variationPole,
numSat,
bd,
gp,
gl,
ga,
};
};
const getSatelliteCount = (GSVArr: Array<any>) => {
if (!GSVArr) return;
const count = GSVArr.reduce((total, gsv) => {
return total + gsv.satellites.length;
}, 0);
return count;
};
const update = (nmeaStr: string) => {
const data: any = getMonitoringData(nmeaStr);
if (!data) return;
const {
dateTime,
longitude,
latitude,
alt,
variation,
variationPole,
numSat,
bd,
gp,
gl,
ga,
} = data;
switch (showModeView.value) {
case "showAll":
const bd_satellite_count = getSatelliteCount(bd.GSVArr);
const gp_satellite_count = getSatelliteCount(gp.GSVArr);
const gl_satellite_count = getSatelliteCount(gl.GSVArr);
const ga_satellite_count = getSatelliteCount(ga.GSVArr);
const bd_gp_satellite_count =
getSatelliteCount(bd.GSVArr) > getSatelliteCount(gp.GSVArr)
? getSatelliteCount(bd.GSVArr)
: getSatelliteCount(gp.GSVArr);
const gl_ga_satellite_count =
getSatelliteCount(gl.GSVArr) > getSatelliteCount(ga.GSVArr)
? getSatelliteCount(gl.GSVArr)
: getSatelliteCount(ga.GSVArr);
const lineMax =
bd_gp_satellite_count > gl_ga_satellite_count
? bd_gp_satellite_count
: gl_ga_satellite_count;
if (
longitude != NaN &&
latitude != NaN &&
longitude != "NaN" &&
latitude != "NaN"
) {
stagingObjAll.dateTime = dateTime;
stagingObjAll.longitude = longitude;
stagingObjAll.latitude = latitude;
stagingObjAll.alt = alt;
stagingObjAll.variation = variation;
stagingObjAll.variationPole = variationPole;
stagingObjAll.numSat = numSat;
} else {
stagingObjAll.dateTime = new Date();
}
digitalFlopContainerAll.value.update(
stagingObjAll.dateTime,
stagingObjAll.longitude,
stagingObjAll.latitude,
stagingObjAll.alt,
stagingObjAll.numSat
);
clockAll.value.update(stagingObjAll.dateTime);
compassAll.value.update(stagingObjAll.variation, stagingObjAll.variationPole);
waterLevelAll.value.update(stagingObjAll.alt);
mapAll.value.update(stagingObjAll.longitude, stagingObjAll.latitude, deepmsg.value);
centerCmpAll.value.update(
bd_satellite_count,
gp_satellite_count,
gl_satellite_count,
ga_satellite_count
);
// TODO: 找到bdgsv语句有7条的原因以及gsa语句配置talker_id为各个卫星导航系统自己的名字
// 粗细不一致,x轴长度以各数据条目自身为准
// BDSNRView.value.update(bd.GSVArr, bd.GSAArr, getSatelliteCount(bd.GSVArr))
// GPSNRView.value.update(gp.GSVArr, gp.GSAArr, getSatelliteCount(gp.GSVArr))
// GLSNRView.value.update(gl.GSVArr, gl.GSAArr, getSatelliteCount(gl.GSVArr))
// GASNRView.value.update(ga.GSVArr, ga.GSAArr, getSatelliteCount(ga.GSVArr))
BDScrollBoardTableAll.value.update(bd.GSVArr);
GPScrollBoardTableAll.value.update(gp.GSVArr);
GLScrollBoardTableAll.value.update(gl.GSVArr);
GAScrollBoardTableAll.value.update(ga.GSVArr);
// 粗细一致,x轴长度以数据最多的条目为准
BDSNRViewAll.value.update(bd.GSVArr, bd.GSAArr, lineMax);
GPSNRViewAll.value.update(gp.GSVArr, gp.GSAArr, lineMax);
GLSNRViewAll.value.update(gl.GSVArr, gl.GSAArr, lineMax);
GASNRViewAll.value.update(ga.GSVArr, ga.GSAArr, lineMax);
// TODO: 找到bdgsv语句有7条的原因以及gsa语句配置talker_id为各个卫星导航系统自己的名字
BDPlanisphereViewAll.value.update(bd.GSVArr, bd.GSAArr);
GPPlanisphereViewAll.value.update(gp.GSVArr, gp.GSAArr);
GLPlanisphereViewAll.value.update(gl.GSVArr, gl.GSAArr);
GAPlanisphereViewAll.value.update(ga.GSVArr, ga.GSAArr);
break;
case "showSwitch":
switch (screenView.value) {
case "DataMonitorPage":
if (
longitude != NaN &&
latitude != NaN &&
longitude != "NaN" &&
latitude != "NaN"
) {
stagingObjSwitch.dateTime = dateTime;
stagingObjSwitch.longitude = longitude;
stagingObjSwitch.latitude = latitude;
stagingObjSwitch.alt = alt;
stagingObjSwitch.variation = variation;
stagingObjSwitch.variationPole = variationPole;
stagingObjSwitch.numSat = numSat;
} else {
stagingObjSwitch.dateTime = new Date();
}
digitalFlopContainerSwitch.value.update(
stagingObjSwitch.dateTime,
stagingObjSwitch.longitude,
stagingObjSwitch.latitude,
stagingObjSwitch.alt,
stagingObjSwitch.numSat
);
clockSwitch.value.update(stagingObjSwitch.dateTime);
compassSwitch.value.update(stagingObjSwitch.variation, stagingObjSwitch.variationPole);
waterLevelSwitch.value.update(stagingObjSwitch.alt);
mapSwitch.value.update(stagingObjSwitch.longitude, stagingObjSwitch.latitude, deepmsg.value);
break;
case "InfoMonitorPage":
BDScrollBoardTableSwitch.value.update(bd.GSVArr);
GPScrollBoardTableSwitch.value.update(gp.GSVArr);
GLScrollBoardTableSwitch.value.update(gl.GSVArr);
GAScrollBoardTableSwitch.value.update(ga.GSVArr);
const bd_satellite_count = getSatelliteCount(bd.GSVArr);
const gp_satellite_count = getSatelliteCount(gp.GSVArr);
const gl_satellite_count = getSatelliteCount(gl.GSVArr);
const ga_satellite_count = getSatelliteCount(ga.GSVArr);
centerCmpSwitch.value.update(
bd_satellite_count,
gp_satellite_count,
gl_satellite_count,
ga_satellite_count
);
break;
case "SignalMonitorPage":
const bd_gp_satellite_count =
getSatelliteCount(bd.GSVArr) > getSatelliteCount(gp.GSVArr)
? getSatelliteCount(bd.GSVArr)
: getSatelliteCount(gp.GSVArr);
const gl_ga_satellite_count =
getSatelliteCount(gl.GSVArr) > getSatelliteCount(ga.GSVArr)
? getSatelliteCount(gl.GSVArr)
: getSatelliteCount(ga.GSVArr);
const lineMax =
bd_gp_satellite_count > gl_ga_satellite_count
? bd_gp_satellite_count
: gl_ga_satellite_count;
// TODO: 找到bdgsv语句有7条的原因以及gsa语句配置talker_id为各个卫星导航系统自己的名字
// 粗细不一致,x轴长度以各数据条目自身为准
// BDSNRView.value.update(bd.GSVArr, bd.GSAArr, getSatelliteCount(bd.GSVArr))
// GPSNRView.value.update(gp.GSVArr, gp.GSAArr, getSatelliteCount(gp.GSVArr))
// GLSNRView.value.update(gl.GSVArr, gl.GSAArr, getSatelliteCount(gl.GSVArr))
// GASNRView.value.update(ga.GSVArr, ga.GSAArr, getSatelliteCount(ga.GSVArr))
// 粗细一致,x轴长度以数据最多的条目为准
BDSNRViewSwitch.value.update(bd.GSVArr, bd.GSAArr, lineMax);
GPSNRViewSwitch.value.update(gp.GSVArr, gp.GSAArr, lineMax);
GLSNRViewSwitch.value.update(gl.GSVArr, gl.GSAArr, lineMax);
GASNRViewSwitch.value.update(ga.GSVArr, ga.GSAArr, lineMax);
break;
case "StateMonitorPage":
// TODO: 找到bdgsv语句有7条的原因以及gsa语句配置talker_id为各个卫星导航系统自己的名字
BDPlanisphereViewSwitch.value.update(bd.GSVArr, bd.GSAArr);
GPPlanisphereViewSwitch.value.update(gp.GSVArr, gp.GSAArr);
GLPlanisphereViewSwitch.value.update(gl.GSVArr, gl.GSAArr);
GAPlanisphereViewSwitch.value.update(ga.GSVArr, ga.GSAArr);
break;
}
break;
}
};
const nmeaAnmiation = async (nmeaOrigin: string) => {
nmeaAnimate.value.update(nmeaOrigin);
};
const deepset = (deepArr: Array<string | boolean>) => {
deepmsg.value = deepArr;
};
onMounted(() => {
if ("ipcRenderer" in window) {
ipcRenderer.receive("deep", deepset);
ipcRenderer.receive("nmea", update);
ipcRenderer.receive("NMEA_RECEIVED", nmeaAnmiation);
ipcRenderer.send("APP_MOUNTED");
}
});
</script>
<style scoped>
.showModeView {
font-size: 1rem;
color: #08e5ff;
width: 9rem;
height: 2rem;
line-height: 2rem;
overflow: hidden;
background-color: rgba(4, 49, 128, 1);
box-shadow: 0 0px 1rem 0px rgb(165 243 252 / 1);
position: fixed;
top: 1rem;
left: 1rem;
z-index: 99;
}
.selectView {
font-size: 1rem;
color: #08e5ff;
width: 9rem;
height: 2rem;
line-height: 2rem;
overflow: hidden;
background-color: rgba(4, 49, 128, 1);
box-shadow: 0 0px 1rem 0px rgb(165 243 252 / 1);
position: fixed;
top: 3rem;
left: 1rem;
z-index: 99;
}
.clock-content,
.compass-content,
.water-level-content,
.block-right-content {
background-color: rgba(6, 30, 93, 0.5);
}
.animationText {
font-size: 0.5rem;
line-height: 1rem;
}
</style>

View File

@@ -0,0 +1,403 @@
<template>
<full-screen-container>
<div class="w-h-full flex-1 grid grid-cols-2 grid-rows-2">
<div class="w-h-full justify-self-end border-r-4 border-r-sky-500/50">
<ShowAllHeader title="卫星数据监控平台" />
<div class="main-content w-full h-5/6 flex flex-1 flex-col">
<DigitalFlopContainer ref="digitalFlopContainer" styleMode="small" />
<div class="block-left-right-content flex flex-1 mt-5">
<div class="block-left-content w-1/5 flex flex-col">
<div class="clock-content mb-2 flex-1">
<Clock ref="clock" styleMode="small" />
</div>
<div class="compass-content mb-2 flex-1">
<Compass ref="compass" styleMode="small" />
</div>
<div class="water-level-content flex-1">
<WaterLevel ref="waterLevel" styleMode="small" />
</div>
</div>
<div class="block-right-content mx-2 flex flex-1">
<Map ref="map" styleMode="small" />
</div>
<div class="block-right-content w-1/5 flex flex-col py-2 px-2">
<NMEAAnimation ref="nmeaAnimate" styleMode="small" />
</div>
</div>
</div>
</div>
<div class="w-h-full justify-self-start">
<ShowAllHeader title="卫星信息监控平台" />
<div class="main-content w-full h-5/6 flex flex-1">
<div class="w-1/4 h-1/2 px-2 flex flex-col">
<border-box-3>
<ScrollBoardTable ref="BDScrollBoardTable" title="北  斗" styleMode="small" />
</border-box-3>
<border-box-3>
<ScrollBoardTable ref="GLScrollBoardTable" title="GLONASS" styleMode="small" />
</border-box-3>
</div>
<div class="w-1/2 px-2">
<border-box-3>
<CenterCmp ref="centerCmp" styleMode="small" />
</border-box-3>
</div>
<div class="w-1/4 h-1/2 flex flex-col px-2">
<border-box-3>
<ScrollBoardTable ref="GPScrollBoardTable" title="G P S" styleMode="small" />
</border-box-3>
<border-box-3>
<ScrollBoardTable ref="GAScrollBoardTable" title="Galileo" styleMode="small" />
</border-box-3>
</div>
</div>
</div>
<div class="w-h-full justify-self-end border-t-4 border-t-sky-500/50 border-r-4 border-r-sky-500/50">
<ShowAllHeader title="卫星信号监控平台" />
<div class="main-content w-full h-5/6 flex-1 grid grid-cols-2 grid-rows-2">
<div class="w-11/12 justify-self-end">
<SNRView
ref="BDSNRView"
color="rgb(255,50,50)"
myid="bdBar"
title="北斗"
styleMode="small"
/>
</div>
<div class="w-11/12 justify-self-start">
<SNRView
ref="GPSNRView"
color="rgb(0,204,255)"
myid="gpsBar"
title="GPS"
styleMode="small"
/>
</div>
<div class="w-11/12 justify-self-end">
<SNRView
ref="GLSNRView"
color="rgb(102,0,255)"
myid="glonassBar"
title="GLONASS"
styleMode="small"
/>
</div>
<div class="w-11/12 justify-self-start">
<SNRView
ref="GASNRView"
color="rgb(0,204,102)"
myid="galileoBar"
title="Galileo"
styleMode="small"
/>
</div>
</div>
</div>
<div class="w-h-full justify-self-start border-t-4 border-t-sky-500/50">
<ShowAllHeader title="卫星状态监控平台" />
<div class="main-content w-full h-5/6 flex-1 grid grid-cols-2 grid-rows-2">
<div class="w-5/6 justify-self-end">
<PlanisphereView
ref="BDPlanisphereView"
color="rgb(255,50,50)"
title="北斗"
baseUrl="beidou"
styleMode="small"
/>
</div>
<div class="w-5/6 justify-self-start">
<PlanisphereView
ref="GPPlanisphereView"
color="rgb(0,204,255)"
title="GPS"
baseUrl="gps"
styleMode="small"
/>
</div>
<div class="w-5/6 justify-self-end">
<PlanisphereView
ref="GLPlanisphereView"
color="rgb(102,0,255)"
title="GLONASS"
baseUrl="glonass"
styleMode="small"
/>
</div>
<div class="w-5/6 justify-self-start">
<PlanisphereView
ref="GAPlanisphereView"
color="rgb(0,204,102)"
title="Galileo"
baseUrl="galileo"
styleMode="small"
/>
</div>
</div>
</div>
</div>
<div class="text-white fixed bottom-0 right-0">
四大系统卫星运行状态监控系统V1.0
</div>
</full-screen-container>
</template>
<script lang="ts" setup>
import FullScreenContainer from "../components/Layout/FullScreenContainer.vue";
import ShowAllHeader from "../components/Layout/ShowAllHeader.vue";
import DigitalFlopContainer from "../components/DigitalFlopContainer.vue";
import Clock from "../components/Clock.vue";
import Compass from "../components/Compass.vue";
import WaterLevel from "../components/WaterLevel.vue";
import Map from "../components/Map.vue";
import NMEAAnimation from "../components/NMEAAnimation.vue";
import BorderBox3 from "../components/Layout/BorderBox3.vue";
import CenterCmp from "../components/CenterCmp.vue";
import ScrollBoardTable from "../components/ScrollBoardTable.vue";
import SNRView from "../components/SNRView.vue";
import PlanisphereView from "../components/PlanisphereView.vue";
import { ref, reactive, onMounted } from "vue";
import { Helpers } from "nmea";
import { getNMEAObj } from "../api/util";
const digitalFlopContainer = ref(null);
const clock = ref(null);
const compass = ref(null);
const waterLevel = ref(null);
const map = ref(null);
const nmeaAnimate = ref(null);
const deepmsg = ref(null);
const BDScrollBoardTable = ref(null);
const GPScrollBoardTable = ref(null);
const GLScrollBoardTable = ref(null);
const GAScrollBoardTable = ref(null);
const centerCmp = ref(null);
const BDSNRView = ref(null);
const GPSNRView = ref(null);
const GLSNRView = ref(null);
const GASNRView = ref(null);
const BDPlanisphereView = ref(null);
const GPPlanisphereView = ref(null);
const GLPlanisphereView = ref(null);
const GAPlanisphereView = ref(null);
const stagingObj = reactive({
dataTime: null,
longitude: NaN,
latitude: NaN,
alt: 0,
variation: null,
variationPole: null,
numSat: 0,
});
const getDate = (date, timestamp) => {
const year = date.substring(4);
const month = date.substring(2, 4);
const day = date.substring(0, 2);
const hours = timestamp.substring(0, 2);
const minutes = timestamp.substring(2, 4);
const seconds = timestamp.substring(4, 6);
const dateTimeStr = `20${year}-${month}-${day}T${hours}:${minutes}:${seconds}+00:00`;
const dateTime = new Date(dateTimeStr);
return dateTime;
};
const getMonitoringData = (nmeaStr: string) => {
const nmeaObj: any = getNMEAObj(nmeaStr);
// console.log(nmeaObj, "================");
if (
!nmeaObj ||
!nmeaObj.RMC ||
!nmeaObj.GGA ||
!nmeaObj ||
!nmeaObj.GSV ||
!nmeaObj.GSA
)
return null;
const { RMC, GGA, GSV, GSA } = nmeaObj;
// 日期,时间,磁偏角,磁偏角方向
const { date, timestamp, variation, variationPole } = RMC;
// 经度,经度方向,纬度,纬度方向,海拔,用于定位的卫星数目
const { lon, lonPole, lat, latPole, alt, numSat } = GGA;
const dateTime = getDate(date, timestamp);
const longitude = Helpers.parseLongitude(lon, lonPole);
const latitude = Helpers.parseLatitude(lat, latPole);
const bd = {
// NMEA 1083 3.x $BDGSV,...*
// NMEA 1083 4.0x $GBGSV,...*
// NMEA 1083 4.1x $GBGSV,...,1* | $GBGSV,...,0*
// GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'BD'),
// GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'BD')
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === "GB"),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === "GB"),
};
const gp = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === "GP"),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === "GP"),
};
const gl = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === "GL"),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === "GL"),
};
const ga = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === "GA"),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === "GA"),
};
return {
dateTime,
longitude,
latitude,
alt,
variation,
variationPole,
numSat,
bd,
gp,
gl,
ga,
};
};
const getSatelliteCount = (GSVArr: Array<any>) => {
if (!GSVArr) return;
const count = GSVArr.reduce((total, gsv) => {
return total + gsv.satellites.length;
}, 0);
return count;
};
const update = (nmeaStr: string) => {
const data: any = getMonitoringData(nmeaStr);
if (!data) return;
const {
dateTime,
longitude,
latitude,
alt,
variation,
variationPole,
numSat,
bd,
gp,
gl,
ga,
} = data;
const bd_satellite_count = getSatelliteCount(bd.GSVArr);
const gp_satellite_count = getSatelliteCount(gp.GSVArr);
const gl_satellite_count = getSatelliteCount(gl.GSVArr);
const ga_satellite_count = getSatelliteCount(ga.GSVArr);
const bd_gp_satellite_count =
getSatelliteCount(bd.GSVArr) > getSatelliteCount(gp.GSVArr)
? getSatelliteCount(bd.GSVArr)
: getSatelliteCount(gp.GSVArr);
const gl_ga_satellite_count =
getSatelliteCount(gl.GSVArr) > getSatelliteCount(ga.GSVArr)
? getSatelliteCount(gl.GSVArr)
: getSatelliteCount(ga.GSVArr);
const lineMax =
bd_gp_satellite_count > gl_ga_satellite_count
? bd_gp_satellite_count
: gl_ga_satellite_count;
if (longitude != NaN && latitude != NaN && longitude != "NaN" && latitude != "NaN") {
stagingObj.dateTime = dateTime;
stagingObj.longitude = longitude;
stagingObj.latitude = latitude;
stagingObj.alt = alt;
stagingObj.variation = variation;
stagingObj.variationPole = variationPole;
stagingObj.numSat = numSat;
} else {
stagingObj.dateTime = new Date();
}
digitalFlopContainer.value.update(
stagingObj.dateTime,
stagingObj.longitude,
stagingObj.latitude,
stagingObj.alt,
stagingObj.numSat
);
clock.value.update(stagingObj.dateTime);
compass.value.update(stagingObj.variation, stagingObj.variationPole);
waterLevel.value.update(stagingObj.alt);
map.value.update(stagingObj.longitude, stagingObj.latitude, deepmsg.value);
centerCmp.value.update(
bd_satellite_count,
gp_satellite_count,
gl_satellite_count,
ga_satellite_count
);
// TODO: 找到bdgsv语句有7条的原因以及gsa语句配置talker_id为各个卫星导航系统自己的名字
// 粗细不一致,x轴长度以各数据条目自身为准
// BDSNRView.value.update(bd.GSVArr, bd.GSAArr, getSatelliteCount(bd.GSVArr))
// GPSNRView.value.update(gp.GSVArr, gp.GSAArr, getSatelliteCount(gp.GSVArr))
// GLSNRView.value.update(gl.GSVArr, gl.GSAArr, getSatelliteCount(gl.GSVArr))
// GASNRView.value.update(ga.GSVArr, ga.GSAArr, getSatelliteCount(ga.GSVArr))
BDScrollBoardTable.value.update(bd.GSVArr);
GPScrollBoardTable.value.update(gp.GSVArr);
GLScrollBoardTable.value.update(gl.GSVArr);
GAScrollBoardTable.value.update(ga.GSVArr);
// 粗细一致,x轴长度以数据最多的条目为准
BDSNRView.value.update(bd.GSVArr, bd.GSAArr, lineMax);
GPSNRView.value.update(gp.GSVArr, gp.GSAArr, lineMax);
GLSNRView.value.update(gl.GSVArr, gl.GSAArr, lineMax);
GASNRView.value.update(ga.GSVArr, ga.GSAArr, lineMax);
// TODO: 找到bdgsv语句有7条的原因以及gsa语句配置talker_id为各个卫星导航系统自己的名字
BDPlanisphereView.value.update(bd.GSVArr, bd.GSAArr);
GPPlanisphereView.value.update(gp.GSVArr, gp.GSAArr);
GLPlanisphereView.value.update(gl.GSVArr, gl.GSAArr);
GAPlanisphereView.value.update(ga.GSVArr, ga.GSAArr);
};
const nmeaAnmiation = async (nmeaOrigin: string) => {
nmeaAnimate.value.update(nmeaOrigin);
};
const deepset = (deepArr: Array<string | boolean>) => {
deepmsg.value = deepArr;
};
onMounted(() => {
if ("ipcRenderer" in window) {
ipcRenderer.receive("deep", deepset);
ipcRenderer.receive("nmea", update);
ipcRenderer.receive("NMEA_RECEIVED", nmeaAnmiation);
ipcRenderer.send("APP_MOUNTED");
}
});
</script>
<style scoped>
.clock-content,
.compass-content,
.water-level-content,
.block-right-content {
background-color: rgba(6, 30, 93, 0.5);
}
.animationText {
font-size: 0.5rem;
line-height: 1rem;
}
</style>

View File

@@ -0,0 +1,438 @@
<template>
<select class="selectView" v-model="screenView">
<option v-for="(value, key) in view" :key="key" :value="key">
{{ value }}
</option>
</select>
<full-screen-container v-if="screenView == 'DataMonitorPage'">
<TheHeader title="卫星数据监控平台" />
<div class="main-content flex flex-1 flex-col">
<DigitalFlopContainer ref="digitalFlopContainer" styleMode="large" />
<div class="block-left-right-content flex flex-1 mt-5">
<div class="block-left-content w-1/5 flex flex-col">
<div class="clock-content mb-2 flex-1">
<Clock ref="clock" styleMode="large" />
</div>
<div class="compass-content mb-2 flex-1">
<Compass ref="compass" styleMode="large" />
</div>
<div class="water-level-content flex-1">
<WaterLevel ref="waterLevel" styleMode="large" />
</div>
</div>
<div class="block-right-content mx-2 flex flex-1">
<Map ref="map" styleMode="large" />
</div>
<div class="block-right-content w-1/5 flex flex-col py-2 px-2">
<NMEAAnimation ref="nmeaAnimate" styleMode="large" />
</div>
<div class="text-white fixed bottom-0 right-0">
四大系统卫星运行状态监控系统V1.0
</div>
</div>
</div>
</full-screen-container>
<full-screen-container v-if="screenView == 'InfoMonitorPage'">
<TheHeader title="卫星信息监控平台" />
<div class="main-content flex flex-1">
<div class="w-1/4 px-2 flex flex-col">
<border-box-3>
<ScrollBoardTable ref="BDScrollBoardTable" title="北  斗" styleMode="large" />
</border-box-3>
<border-box-3>
<ScrollBoardTable ref="GLScrollBoardTable" title="GLONASS" styleMode="large" />
</border-box-3>
</div>
<div class="w-1/2 px-2">
<border-box-3>
<CenterCmp ref="centerCmp" styleMode="large" />
</border-box-3>
</div>
<div class="w-1/4 flex flex-col px-2">
<border-box-3>
<ScrollBoardTable ref="GPScrollBoardTable" title="G P S" styleMode="large" />
</border-box-3>
<border-box-3>
<ScrollBoardTable ref="GAScrollBoardTable" title="Galileo" styleMode="large" />
</border-box-3>
</div>
</div>
</full-screen-container>
<full-screen-container v-if="screenView == 'SignalMonitorPage'">
<TheHeader title="卫星信号监控平台" />
<div class="main-content flex-1 grid grid-cols-2 grid-rows-2">
<div class="w-11/12 justify-self-end">
<SNRView ref="BDSNRView"
color="rgb(255,50,50)"
myid="bdBar"
title="北斗"
styleMode="large"
/>
</div>
<div class="w-11/12 justify-self-start">
<SNRView
ref="GPSNRView"
color="rgb(0,204,255)"
myid="gpsBar"
title="GPS"
styleMode="large" />
</div>
<div class="w-11/12 justify-self-end">
<SNRView
ref="GLSNRView"
color="rgb(102,0,255)"
myid="glonassBar"
title="GLONASS"
styleMode="large"
/>
</div>
<div class="w-11/12 justify-self-start">
<SNRView
ref="GASNRView"
color="rgb(0,204,102)"
myid="galileoBar"
title="Galileo"
styleMode="large"
/>
</div>
</div>
</full-screen-container>
<full-screen-container v-if="screenView == 'StateMonitorPage'">
<TheHeader title="卫星状态监控平台" />
<div class="main-content flex-1 grid grid-cols-2 grid-rows-2">
<div class="w-5/6 justify-self-end">
<PlanisphereView
ref="BDPlanisphereView"
color="rgb(255,50,50)"
title="北斗"
baseUrl="beidou"
styleMode="large"
/>
</div>
<div class="w-5/6 justify-self-start">
<PlanisphereView
ref="GPPlanisphereView"
color="rgb(0,204,255)"
title="GPS"
baseUrl="gps"
styleMode="large"
/>
</div>
<div class="w-5/6 justify-self-end">
<PlanisphereView
ref="GLPlanisphereView"
color="rgb(102,0,255)"
title="GLONASS"
baseUrl="glonass"
styleMode="large"
/>
</div>
<div class="w-5/6 justify-self-start">
<PlanisphereView
ref="GAPlanisphereView"
color="rgb(0,204,102)"
title="Galileo"
baseUrl="galileo"
styleMode="large"
/>
</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 DigitalFlopContainer from "../components/DigitalFlopContainer.vue";
import Clock from "../components/Clock.vue";
import Compass from "../components/Compass.vue";
import WaterLevel from "../components/WaterLevel.vue";
import Map from "../components/Map.vue";
import NMEAAnimation from "../components/NMEAAnimation.vue";
import BorderBox3 from "../components/Layout/BorderBox3.vue";
import CenterCmp from "../components/CenterCmp.vue";
import ScrollBoardTable from "../components/ScrollBoardTable.vue";
import SNRView from "../components/SNRView.vue";
import PlanisphereView from "../components/PlanisphereView.vue";
import { ref, reactive, onMounted } from "vue";
import { Helpers } from "nmea";
import { getNMEAObj } from "../api/util";
const screenView = ref("DataMonitorPage");
const view = {
DataMonitorPage: "卫星数据监控平台",
InfoMonitorPage: "卫星信息监控平台",
SignalMonitorPage: "卫星信号监控平台",
StateMonitorPage: "卫星状态监控平台",
};
const digitalFlopContainer = ref(null);
const clock = ref(null);
const compass = ref(null);
const waterLevel = ref(null);
const map = ref(null);
const nmeaAnimate = ref(null);
const deepmsg = ref(null);
const BDScrollBoardTable = ref(null);
const GPScrollBoardTable = ref(null);
const GLScrollBoardTable = ref(null);
const GAScrollBoardTable = ref(null);
const centerCmp = ref(null);
const BDSNRView = ref(null);
const GPSNRView = ref(null);
const GLSNRView = ref(null);
const GASNRView = ref(null);
const BDPlanisphereView = ref(null);
const GPPlanisphereView = ref(null);
const GLPlanisphereView = ref(null);
const GAPlanisphereView = ref(null);
const stagingObj = reactive({
dataTime: null,
longitude: NaN,
latitude: NaN,
alt: 0,
variation: null,
variationPole: null,
numSat: 0,
});
const getDate = (date, timestamp) => {
const year = date.substring(4);
const month = date.substring(2, 4);
const day = date.substring(0, 2);
const hours = timestamp.substring(0, 2);
const minutes = timestamp.substring(2, 4);
const seconds = timestamp.substring(4, 6);
const dateTimeStr = `20${year}-${month}-${day}T${hours}:${minutes}:${seconds}+00:00`;
const dateTime = new Date(dateTimeStr);
return dateTime;
};
const getMonitoringData = (nmeaStr: string) => {
const nmeaObj: any = getNMEAObj(nmeaStr);
// console.log(nmeaObj, "================");
if (
!nmeaObj ||
!nmeaObj.RMC ||
!nmeaObj.GGA ||
!nmeaObj ||
!nmeaObj.GSV ||
!nmeaObj.GSA
)
return null;
const { RMC, GGA, GSV, GSA } = nmeaObj;
// 日期,时间,磁偏角,磁偏角方向
const { date, timestamp, variation, variationPole } = RMC;
// 经度,经度方向,纬度,纬度方向,海拔,用于定位的卫星数目
const { lon, lonPole, lat, latPole, alt, numSat } = GGA;
const dateTime = getDate(date, timestamp);
const longitude = Helpers.parseLongitude(lon, lonPole);
const latitude = Helpers.parseLatitude(lat, latPole);
const bd = {
// NMEA 1083 3.x $BDGSV,...*
// NMEA 1083 4.0x $GBGSV,...*
// NMEA 1083 4.1x $GBGSV,...,1* | $GBGSV,...,0*
// GSVArr: GSV.filter((gsv: any) => gsv.talker_id === 'BD'),
// GSAArr: GSA.filter((gsa: any) => gsa.talker_id === 'BD')
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === "GB"),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === "GB"),
};
const gp = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === "GP"),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === "GP"),
};
const gl = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === "GL"),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === "GL"),
};
const ga = {
GSVArr: GSV.filter((gsv: any) => gsv.talker_id === "GA"),
GSAArr: GSA.filter((gsa: any) => gsa.talker_id === "GA"),
};
return {
dateTime,
longitude,
latitude,
alt,
variation,
variationPole,
numSat,
bd,
gp,
gl,
ga,
};
};
const getSatelliteCount = (GSVArr: Array<any>) => {
if (!GSVArr) return;
const count = GSVArr.reduce((total, gsv) => {
return total + gsv.satellites.length;
}, 0);
return count;
};
const update = (nmeaStr: string) => {
const data: any = getMonitoringData(nmeaStr);
if (!data) return;
const {
dateTime,
longitude,
latitude,
alt,
variation,
variationPole,
numSat,
bd,
gp,
gl,
ga,
} = data;
switch (screenView.value) {
case "DataMonitorPage":
if (
longitude != NaN &&
latitude != NaN &&
longitude != "NaN" &&
latitude != "NaN"
) {
stagingObj.dateTime = dateTime;
stagingObj.longitude = longitude;
stagingObj.latitude = latitude;
stagingObj.alt = alt;
stagingObj.variation = variation;
stagingObj.variationPole = variationPole;
stagingObj.numSat = numSat;
} else {
stagingObj.dateTime = new Date();
}
digitalFlopContainer.value.update(
stagingObj.dateTime,
stagingObj.longitude,
stagingObj.latitude,
stagingObj.alt,
stagingObj.numSat
);
clock.value.update(stagingObj.dateTime);
compass.value.update(stagingObj.variation, stagingObj.variationPole);
waterLevel.value.update(stagingObj.alt);
map.value.update(stagingObj.longitude, stagingObj.latitude, deepmsg.value);
break;
case "InfoMonitorPage":
BDScrollBoardTable.value.update(bd.GSVArr);
GPScrollBoardTable.value.update(gp.GSVArr);
GLScrollBoardTable.value.update(gl.GSVArr);
GAScrollBoardTable.value.update(ga.GSVArr);
const bd_satellite_count = getSatelliteCount(bd.GSVArr);
const gp_satellite_count = getSatelliteCount(gp.GSVArr);
const gl_satellite_count = getSatelliteCount(gl.GSVArr);
const ga_satellite_count = getSatelliteCount(ga.GSVArr);
centerCmp.value.update(
bd_satellite_count,
gp_satellite_count,
gl_satellite_count,
ga_satellite_count
);
break;
case "SignalMonitorPage":
const bd_gp_satellite_count =
getSatelliteCount(bd.GSVArr) > getSatelliteCount(gp.GSVArr)
? getSatelliteCount(bd.GSVArr)
: getSatelliteCount(gp.GSVArr);
const gl_ga_satellite_count =
getSatelliteCount(gl.GSVArr) > getSatelliteCount(ga.GSVArr)
? getSatelliteCount(gl.GSVArr)
: getSatelliteCount(ga.GSVArr);
const lineMax =
bd_gp_satellite_count > gl_ga_satellite_count
? bd_gp_satellite_count
: gl_ga_satellite_count;
// TODO: 找到bdgsv语句有7条的原因以及gsa语句配置talker_id为各个卫星导航系统自己的名字
// 粗细不一致,x轴长度以各数据条目自身为准
// BDSNRView.value.update(bd.GSVArr, bd.GSAArr, getSatelliteCount(bd.GSVArr))
// GPSNRView.value.update(gp.GSVArr, gp.GSAArr, getSatelliteCount(gp.GSVArr))
// GLSNRView.value.update(gl.GSVArr, gl.GSAArr, getSatelliteCount(gl.GSVArr))
// GASNRView.value.update(ga.GSVArr, ga.GSAArr, getSatelliteCount(ga.GSVArr))
// 粗细一致,x轴长度以数据最多的条目为准
BDSNRView.value.update(bd.GSVArr, bd.GSAArr, lineMax);
GPSNRView.value.update(gp.GSVArr, gp.GSAArr, lineMax);
GLSNRView.value.update(gl.GSVArr, gl.GSAArr, lineMax);
GASNRView.value.update(ga.GSVArr, ga.GSAArr, lineMax);
break;
case "StateMonitorPage":
// TODO: 找到bdgsv语句有7条的原因以及gsa语句配置talker_id为各个卫星导航系统自己的名字
BDPlanisphereView.value.update(bd.GSVArr, bd.GSAArr);
GPPlanisphereView.value.update(gp.GSVArr, gp.GSAArr);
GLPlanisphereView.value.update(gl.GSVArr, gl.GSAArr);
GAPlanisphereView.value.update(ga.GSVArr, ga.GSAArr);
break;
default:
break;
}
};
const nmeaAnmiation = async (nmeaOrigin: string) => {
nmeaAnimate.value.update(nmeaOrigin);
};
const deepset = (deepArr: Array<string | boolean>) => {
deepmsg.value = deepArr;
};
onMounted(() => {
if ("ipcRenderer" in window) {
ipcRenderer.receive("deep", deepset);
ipcRenderer.receive("nmea", update);
ipcRenderer.receive("NMEA_RECEIVED", nmeaAnmiation);
ipcRenderer.send("APP_MOUNTED");
}
});
</script>
<style scoped>
.selectView {
font-size: 1rem;
color: #08e5ff;
width: 9rem;
height: 2rem;
line-height: 2rem;
overflow: hidden;
background-color: rgba(4, 49, 128, 1);
box-shadow: 0 0px 1rem 0px rgb(165 243 252 / 1);
position: fixed;
top: 1rem;
left: 1rem;
z-index: 99;
}
.clock-content,
.compass-content,
.water-level-content,
.block-right-content {
background-color: rgba(6, 30, 93, 0.5);
}
.animationText {
font-size: 0.5rem;
line-height: 1rem;
}
</style>

View File

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

View File

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

View File

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

View File

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

View File

@@ -17,6 +17,9 @@ export default defineConfig({
emptyOutDir: true,
rollupOptions: {
input: [
'./oneShow.html',
'./oneShowAll.html',
'./oneShowSwitch.html',
'./satellite-data-monitor-platform.html',
'./satellite-info-monitor-platform.html',
'./satellite-signal-monitor-platform.html',