From 2d7b7d3cae733d95032b76e5b286ce7cb83e66f3 Mon Sep 17 00:00:00 2001 From: jiangteng <1348746268@qq.com> Date: Fri, 3 Feb 2023 17:16:20 +0800 Subject: [PATCH] =?UTF-8?q?'=E5=A2=9E=E5=8A=A0=E5=8D=AB=E6=98=9F=E6=98=9F?= =?UTF-8?q?=E5=BA=A7=E9=80=89=E6=8B=A9'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 31 +- src/http/index.js | 26 +- src/js/SatelliteEntity.js | 5 +- src/views/satellite-track/SatelliteTrack.scss | 27 ++ src/views/satellite-track/SatelliteTrack.vue | 183 +++++------ src/views/satellite-track/satelliteType.js | 306 ++++++++++++++++++ 6 files changed, 452 insertions(+), 126 deletions(-) create mode 100644 src/views/satellite-track/satelliteType.js diff --git a/README.md b/README.md index 6791002..8a0c657 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,30 @@ # satellite-track -satellite-track使用TLE数据追踪卫星,使用cesium、vue、satelliteJS开发。 +**README.en.md** -## [预览](https://jiangteng2019.github.io/satellite-track/) +### satellite-track uses TLE data to track satellites and is developed using cesium, vue and satelliteJS. -###说明 -1、为了节约性能,卫星轨道数据选择显示,而不全量显示; -2、数据来源于celestrak \ No newline at end of file +### [preview](https://jiangteng2019.github.io/satellite-track/) + + +1. In order to save performance, the satellite orbit data is displayed by clicking. +1. Data from celestrak. +1. The access speed of github pages is slow, and the TLE data and cesium data are large. Please wait patiently for the resources to load. + +------------------------------------------- + +**README.md** + +### satellite-track使用TLE数据追踪卫星,使用cesium、vue、satelliteJS开发。 + +### [预览](https://jiangteng2019.github.io/satellite-track/) + + +1. 为了节约性能,卫星轨道数据点击显示,而非全量显示; +1. 数据来源于celestrak; +1. github pages 访问速度慢,TLE数据与cesium数据较大,请耐心等待资源加载; + + +[![satellite-track](https://images.cnblogs.com/cnblogs_com/engeng/2270012/o_230203011203_1.jpg "satellite-track")](https://images.cnblogs.com/cnblogs_com/engeng/2270012/o_230203011203_1.jpg "satellite-track") + +[![satellite-track](https://images.cnblogs.com/cnblogs_com/engeng/2270012/o_230203011139_2.jpg "satellite-track")](https://images.cnblogs.com/cnblogs_com/engeng/2270012/o_230203011139_2.jpg "satellite-track") \ No newline at end of file diff --git a/src/http/index.js b/src/http/index.js index bfb96f3..7192a0b 100644 --- a/src/http/index.js +++ b/src/http/index.js @@ -1,21 +1,21 @@ import axios from "axios"; -const BASE_URL = "https://celestrak.org" +const BASE_URL = "https://celestrak.org"; -function getTleData(path = "") { - let uri = BASE_URL + path; +function getTleDataFromExternal(path = "") { + let uri = `${BASE_URL}/NORAD/elements/gp.php?GROUP=${path}&FORMAT=tle`; return axios.get(uri).then(res => { - res.status === 200 ? ElMessage.success('获取TLE成功') : ElMessage.error('获取TLE失败'); - return res.status === 200 ? Promise.resolve(res.data) : Promise.reject(res.statusText); + if (res.status === 200) { + ElMessage.success('获取TLE成功'); + localStorage.setItem(path, res.data); // 缓存TLE数据,减轻数据服务压力 + return Promise.resolve(res.data); + } else { + ElMessage.error('获取TLE失败'); + return Promise.reject(res.statusText); + } }); } -/** - * @description 获取最近30天的发射卫星的TLE数据 - * @returns Promise - */ -function getTleWithLastThirtyDays(path = "/NORAD/elements/gp.php?GROUP=last-30-days&FORMAT=tle") { - return getTleData(path); -} -export { getTleWithLastThirtyDays }; \ No newline at end of file + +export { getTleDataFromExternal }; \ No newline at end of file diff --git a/src/js/SatelliteEntity.js b/src/js/SatelliteEntity.js index deadd13..b6b04e7 100644 --- a/src/js/SatelliteEntity.js +++ b/src/js/SatelliteEntity.js @@ -12,7 +12,7 @@ class SatelliteEntity { this.tleLine2 = tleLine2.trim(); this.satrec = twoline2satrec(this.tleLine1, this.tleLine2); - this.totalSeconds = 864000;// 864000 + this.totalSeconds = 86400;// 24小时 this.stepSeconds = 100; this.leadTime = parseInt(24 * 3600 / circle); this.trailTime = 0; @@ -56,7 +56,7 @@ class SatelliteEntity { description: this.name, availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start: start, stop: stop })]), position: this._getPositionProperty(), - point: { pixelSize: 10, color: Cesium.Color.fromRandom({ alpha: 1.0 }) }, + point: { pixelSize: 8, color: Cesium.Color.fromRandom({ alpha: 1.0 }) }, path: new Cesium.PathGraphics({ width: 1, show: false, @@ -67,7 +67,6 @@ class SatelliteEntity { label: { text: this.name, font: '12px sans-serif', - scale: 0.8, showBackground: true, backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.5), backgroundPadding: new Cesium.Cartesian2(4, 4), diff --git a/src/views/satellite-track/SatelliteTrack.scss b/src/views/satellite-track/SatelliteTrack.scss index e1b3747..4dc363a 100644 --- a/src/views/satellite-track/SatelliteTrack.scss +++ b/src/views/satellite-track/SatelliteTrack.scss @@ -28,6 +28,7 @@ fill: #edffff; cursor: pointer; } + .menu_button:hover { color: #fff; fill: #fff; @@ -40,11 +41,37 @@ .el-drawer { background-color: rgba($color: #303336, $alpha: 0.9); color: #fff; + + .satellite_type { + color: #95D475; + font-weight: bold; + font-size: 14px; + padding: 10px; + padding-left: 0; + } + .el-drawer__header { background-color: #303336; color: inherit; + margin: 0 } + .el-checkbox { color: inherit; } +} + +::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +::-webkit-scrollbar-track { + border-radius: 10px; +} + +::-webkit-scrollbar-thumb { + background-color: #ccc; + border-radius: 10px; + transition: all .2s ease-in-out; } \ No newline at end of file diff --git a/src/views/satellite-track/SatelliteTrack.vue b/src/views/satellite-track/SatelliteTrack.vue index bcc21d8..3a055d8 100644 --- a/src/views/satellite-track/SatelliteTrack.vue +++ b/src/views/satellite-track/SatelliteTrack.vue @@ -7,18 +7,11 @@ - - 卫星 - - - {{ item.label }} - - - - 气象和地球资源卫星 - - - {{ item.label }} + + @@ -29,97 +22,33 @@ import * as Cesium from 'cesium'; import "cesium/Build/Cesium/Widgets/widgets.css"; -import { onMounted, onBeforeMount, ref } from 'vue'; +import { onMounted, ref, watch } from 'vue'; import "./SatelliteTrack.scss" -import { getTleWithLastThirtyDays } from '@/http/index' +import { getTleDataFromExternal } from '@/http/index' import SatelliteEntity from '@/js/SatelliteEntity'; +import { specialSatellite, weatherSatellite, communicationSatellite, navigationSatellite, scientificSatellite, miscellaneousSatellite } from "./satelliteType" +import { add } from 'lodash'; + +let allSatellite = [...specialSatellite, ...weatherSatellite, ...communicationSatellite, ...navigationSatellite, ...scientificSatellite, ...miscellaneousSatellite]; + window.CESIUM_BASE_URL = import.meta.env.MODE === 'development' ? '/cesium' : '/satellite-track/cesium'; let viewer; -const totalSeconds = 864000; +const totalSeconds = 86400; +// 保存所有的卫星实例 const satelliteMap = new Map(); // 响应式数据 const drawer = ref(false); -const checked = ref([]); -const options = ref([ - { - label: "Last 30 Days' Launches", - value: 1 - }, - { - label: 'Space Stations', - value: 2 - }, - { - label: '100 (or so) Brightest', - value: 3 - }, - { - label: 'Active Satellites', - value: 4 - }, - { - label: 'Analyst Satellites ', - value: 5 - }, - { - label: 'IRIDIUM 33 Debris', - value: 6 - }, - { - label: 'COSMOS 2251 Debris', - value: 7 - } -]) -const weatherSatellite = ref([ -{ - label: 'Weather', - value: 1 - }, - { - label: 'NOAA', - value: 2 - }, - { - label: 'GOES', - value: 3 - }, - { - label: 'Earth Resources', - value: 4 - }, - { - label: 'Search & Rescue (SARSAT) ', - value: 5 - }, - { - label: 'Disaster Monitoring', - value: 6 - }, - { - label: 'TDRSS', - value: 7 - }, - { - label: 'ARGOS Data Collection System', - value: 8 - }, - { - label: 'Planet', - value: 9 - }, - { - label: 'Spire', - value: 10 - } -]) +const checked = ref([]); + +const clickedSatelliteArray = []; Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiYjZmMWM4Ny01YzQ4LTQ3MzUtYTI5Mi1hNTgyNjdhMmFiMmMiLCJpZCI6NjIwMjgsImlhdCI6MTYyNjY3MTMxNX0.5SelYUyzXWRoMyjjFvmFIAoPtWlJPQMjsVl2e_jQe-c'; @@ -194,48 +123,92 @@ function parseTle(data = "") { } function addCesiumEventListener() { - let callback = viewer.screenSpaceEventHandler.getInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);// 还原点击聚焦方块的效果。 + let callback = viewer.screenSpaceEventHandler.getInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) { callback(movement); const pickedFeature = viewer.scene.pick(movement.position); console.log(pickedFeature); if (!Cesium.defined(pickedFeature)) { - satelliteMap.forEach(item => { - item.path.show = false; + clickedSatelliteArray.forEach(item => { + item.id.path.show = false; }) return; } if (pickedFeature) { pickedFeature.id.path.show = new Cesium.ConstantProperty(true); pickedFeature.id.label.distanceDisplayCondition = undefined; + clickedSatelliteArray.push(pickedFeature); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); } // 事件 -function handleSpacialInterestChange(e) { - console.log(e); +function handleSatelliteChange(e) { + } -function handleWeatherSatelliteChange(e) { - console.log(e); + +// 获取tle数据,从缓存中获取,若无请求数据 + +async function getTleData(path) { + let data = localStorage.getItem(path); + if (data) { + console.log(`%c 命中缓存,key值为${path}`, 'color:#0f0;'); + return data; + } else { + console.warn("未命中缓存,开始下载TLE数据"); + return await getTleDataFromExternal(path); + } } +// 创建satellite entity 实例 +async function addSatellite(path) { + // 判断map中是否已经包含对应的路径实例 + if (satelliteMap.has(path)) { + let satelliteList = satelliteMap.get(path); + satelliteList.forEach(item => viewer.entities.add(item)); + } else { + let result = await getTleData(path); + let parsedResult = parseTle(result); + let satelliteSet = new Set(); + + parsedResult.forEach(tle => { + let satellite = new SatelliteEntity(tle); + let cesiumSateEntity = satellite.createSatelliteEntity(); + let result = viewer.entities.add(cesiumSateEntity); + satelliteSet.add(result); + }); + satelliteMap.set(path, satelliteSet); + } +} + +function removeSatellite(path) { + if (satelliteMap.has(path)) { + let satelliteList = satelliteMap.get(path); + satelliteList.forEach(item => viewer.entities.remove(item)); + } +} + +// 侦听器 +watch(checked, (newValue, oldValue) => { + let filterValue = newValue.concat(oldValue).filter((item, index, arr) => arr.indexOf(item) === arr.lastIndexOf(item)); + let satelliteClassify = allSatellite.find(item => item.value === filterValue[0]); + // 勾选了卫星 + if (newValue.length > oldValue.length) { + addSatellite(satelliteClassify.group); + } else { + //取消了勾选 + removeSatellite(satelliteClassify.group); + } +}) + + +// 生命周期 onMounted(async () => { initCesium(); initTimeLine(); addCesiumEventListener(); - - let result = await getTleWithLastThirtyDays(); - let parsedResult = parseTle(result); - - parsedResult.forEach(tle => { - let satellite = new SatelliteEntity(tle); - let cesiumSateEntity = satellite.createSatelliteEntity(); - let result = viewer.entities.add(cesiumSateEntity); - satelliteMap.set(satellite.name, result); - }); }) diff --git a/src/views/satellite-track/satelliteType.js b/src/views/satellite-track/satelliteType.js new file mode 100644 index 0000000..3e6b2aa --- /dev/null +++ b/src/views/satellite-track/satelliteType.js @@ -0,0 +1,306 @@ +let specialSatellite = [ + { + label: "特殊卫星", + value: null, + group: null, + type: "title" + }, + { + label: "Last 30 Days' Launches", + value: 1, + group: 'last-30-days' + }, + { + label: 'Space Stations', + value: 2, + group: 'stations' + }, + { + label: '100 (or so) Brightest', + value: 3, + group: 'visual' + }, + { + label: 'Active Satellites', + value: 4, + group: 'active' + }, + { + label: 'Analyst Satellites ', + value: 5, + group: 'analyst' + } +]; + +let weatherSatellite = [ + { + label: "气象和地球资源卫星", + value: null, + group: null, + type: "title" + }, + { + label: 'Weather', + value: 6, + group: 'weather' + }, + { + label: 'NOAA', + value: 7, + group: 'noaa' + }, + { + label: 'GOES', + value: 8, + group: 'goes' + }, + { + label: 'Earth Resources', + value: 9, + group: 'resource' + }, + { + label: 'Search & Rescue (SARSAT) ', + value: 10, + group: 'sarsat' + }, + { + label: 'Disaster Monitoring', + value: 11, + group: 'dmc' + }, + { + label: 'TDRSS', + value: 12, + group: 'tdrss' + }, + { + label: 'ARGOS Data Collection System', + value: 13, + group: 'argos' + }, + { + label: 'Planet', + value: 14, + group: 'planet' + }, + { + label: 'Spire', + value: 15, + group: 'spire' + } +]; + +let communicationSatellite = [ + { + label: "通讯卫星", + value: null, + group: null, + type: "title" + }, + { + label: 'Active Geosynchronous', + value: 16, + group: 'geo' + }, + { + label: 'GEO Protected Zone', + value: 17, + group: 'gpz' + }, + { + label: 'GEO Protected Zone Plus', + value: 18, + group: 'gpz-plus' + }, + { + label: 'Intelsat', + value: 19, + group: 'intelsat' + }, + { + label: 'SES', + value: 20, + group: 'ses' + }, + { + label: 'Iridium', + value: 21, + group: 'iridium' + }, + { + label: 'Iridium NEXT', + value: 22, + group: 'iridium-NEXT' + }, + { + label: 'Starlink', + value: 23, + group: 'starlink' + }, + { + label: 'OneWeb', + value: 24, + group: 'oneweb' + }, + { + label: 'Orbcomm', + value: 25, + group: 'orbcomm' + }, + { + label: 'Globalstar', + value: 26, + group: 'globalstar' + }, + { + label: 'Swarm', + value: 27, + group: 'swarm' + }, + { + label: 'Amateur Radio', + value: 28, + group: 'amateur' + }, + { + label: 'Experimental Comm', + value: 29, + group: 'x-comm' + }, + { + label: 'Other Comm', + value: 30, + group: 'other-comm' + }, + { + label: 'SatNOGS', + value: 31, + group: 'satnogs' + }, + { + label: 'Gorizont', + value: 32, + group: 'gorizont' + }, + { + label: 'Raduga', + value: 33, + group: 'raduga' + }, + { + label: 'Molniya', + value: 34, + group: 'molniya' + }, +]; + +let navigationSatellite = [ + { + label: "导航卫星", + value: null, + group: null, + type: "title" + }, + { + label: 'GNSS', + value: 35, + group: 'gnss' + }, + { + label: 'GPS Operational', + value: 36, + group: 'gps-ops' + }, + { + label: 'GLONASS Operational', + value: 37, + group: 'glo-ops' + }, + { + label: 'Galileo', + value: 38, + group: 'galileo' + }, + { + label: 'Beidou', + value: 39, + group: 'beidou' + }, + { + label: 'Satellite-Based Augmentation System', + value: 40, + group: 'sbas' + }, + { + label: 'Navy Navigation Satellite System (NNSS)', + value: 41, + group: 'nnss' + }, + { + label: 'Russian LEO Navigation', + value: 42, + group: 'musson' + }, +]; + +let scientificSatellite = [ + { + label: "科学卫星", + value: null, + group: null, + type: "title" + }, + { + label: 'Space & Earth Science', + value: 43, + group: 'science' + }, + { + label: 'Geodetic', + value: 44, + group: 'geodetic' + }, + { + label: 'Engineering', + value: 45, + group: 'engineering' + }, + { + label: 'Education', + value: 46, + group: 'education' + } +]; + +let miscellaneousSatellite = [ + { + label: "其他卫星", + value: null, + group: null, + type: "title" + }, + { + label: 'Miscellaneous Military', + value: 47, + group: 'military' + }, + { + label: 'Radar Calibration', + value: 48, + group: 'radar' + }, + { + label: 'CubeSats', + value: 49, + group: 'cubesat' + }, + { + label: 'Other Satellites', + value: 50, + group: 'other' + } +] + +export { specialSatellite, weatherSatellite, communicationSatellite, navigationSatellite, scientificSatellite, miscellaneousSatellite }; +