diff --git a/src/pages/Satellite/Cesium/cesium-helper/00.cesium-init.VIEWER_OPTIONS.ts b/src/pages/Satellite/Cesium/cesium-helper/00.cesium-init.VIEWER_OPTIONS.ts index f67d760..ab9a348 100644 --- a/src/pages/Satellite/Cesium/cesium-helper/00.cesium-init.VIEWER_OPTIONS.ts +++ b/src/pages/Satellite/Cesium/cesium-helper/00.cesium-init.VIEWER_OPTIONS.ts @@ -7,9 +7,9 @@ export const VIEWER_OPTIONS: Viewer.ConstructorOptions = { baseLayer: Cesium.ImageryLayer.fromProviderAsync( Cesium.TileMapServiceImageryProvider.fromUrl(Cesium.buildModuleUrl('Assets/Textures/NaturalEarthII')), ), - baseLayerPicker: !true, + baseLayerPicker: false, fullscreenButton: !true, // 全屏按钮 - geocoder: !true, // = IonGeocodeProviderType.DEFAULT] - 在使用Geocoder小部件进行搜索时使用的地理编码服务或服务。如果设置为false,则不会创建Geocoder小部件。 + geocoder: false, // = IonGeocodeProviderType.DEFAULT] - 在使用Geocoder小部件进行搜索时使用的地理编码服务或服务。如果设置为false,则不会创建Geocoder小部件。 // globe: false, // 地球 homeButton: true, // Home按钮 diff --git a/src/pages/Satellite/Cesium/cesium-helper/00.cesium-init.ts b/src/pages/Satellite/Cesium/cesium-helper/00.cesium-init.ts index 0ac272b..fb6f407 100644 --- a/src/pages/Satellite/Cesium/cesium-helper/00.cesium-init.ts +++ b/src/pages/Satellite/Cesium/cesium-helper/00.cesium-init.ts @@ -4,6 +4,8 @@ import { VIEWER_OPTIONS } from './00.cesium-init.VIEWER_OPTIONS'; import 'cesium/Build/Cesium/Widgets/widgets.css'; +Cesium.Ion.defaultAccessToken = import.meta.env.VITE_CESIUM_ION_TOKEN; // 用了离线地图的情况是不需要的。 + Object.assign(window, { Cesium }); _configureCesium(); @@ -13,6 +15,8 @@ export function cesium_init(container: Element) { viewer.scene.debugShowFramesPerSecond = true; + initTimeLine(viewer); + return viewer; } @@ -60,3 +64,15 @@ function _configureCesium() { 60, // 北纬 ); } + +function initTimeLine(viewer: Cesium.Viewer, totalSeconds = /* 默认场景的时间跨度 */ 24 * 60 * 60) { + const start = Cesium.JulianDate.fromIso8601(new Date().toISOString()); + const stop = Cesium.JulianDate.addSeconds(start, totalSeconds, new Cesium.JulianDate()); + viewer.clock.startTime = start.clone(); + viewer.clock.stopTime = stop.clone(); + viewer.clock.currentTime = start.clone(); + viewer.timeline.zoomTo(start, stop); + viewer.clock.multiplier = 1; + viewer.clock.shouldAnimate = true; + viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; +} diff --git a/src/pages/Satellite/Cesium/cesium-helper/SatelliteEntity.ts b/src/pages/Satellite/Cesium/cesium-helper/SatelliteEntity.ts new file mode 100644 index 0000000..c43a6d9 --- /dev/null +++ b/src/pages/Satellite/Cesium/cesium-helper/SatelliteEntity.ts @@ -0,0 +1,108 @@ +import type { Cartesian3 } from 'cesium'; + +import * as Cesium from 'cesium'; +import { propagate, twoline2satrec } from 'satellite.js'; + +class SatelliteEntity { + private leadTime!: number; + private name!: string; + private satrec: any; + private stepSeconds!: number; + private tleLine1!: string; + private tleLine2!: string; + private totalSeconds!: number; + private trailTime!: number; + + constructor(tle = '' /* , options = {} */) { + const [name, tleLine1, tleLine2] = this._checkTle(tle); + const circle = Number(tleLine2.slice(52, 64)); + + this.name = name.trim(); + this.tleLine1 = tleLine1.trim(); + this.tleLine2 = tleLine2.trim(); + this.satrec = twoline2satrec(this.tleLine1, this.tleLine2); + + this.totalSeconds = 86_400; // 24小时 + this.stepSeconds = 100; + this.leadTime = Math.round((24 * 3600) / circle); + this.trailTime = 0; + } + + _checkTle(tle: string) { + const elements = tle.split('\n'); + if (elements.length !== 3) throw new Error('tle data error'); + return elements as [string, string, string]; + } + + // 创建PositionProperty + _getPositionProperty() { + const start = Cesium.JulianDate.fromIso8601(new Date().toISOString()); + const positionProperty = new Cesium.SampledPositionProperty(Cesium.ReferenceFrame.INERTIAL); + + const now = Date.now(); + for (let i = 0; i < this.totalSeconds / this.stepSeconds; i++) { + const sateTime = new Date(now + i * this.stepSeconds * 1000); + const sateCoord = this.getPositionEci(sateTime); + if (!sateCoord) continue; + const cesiumTime = Cesium.JulianDate.addSeconds(start, i * this.stepSeconds, new Cesium.JulianDate()); + const cesiumPosition = { + x: sateCoord.x * 1000, + y: sateCoord.y * 1000, + z: sateCoord.z * 1000, + } as Cartesian3; + positionProperty.addSample(cesiumTime, cesiumPosition); + } + return positionProperty; + } + + // 创建卫星实例 + createSatelliteEntity() { + const start = Cesium.JulianDate.fromIso8601(new Date().toISOString()); + const stop = Cesium.JulianDate.addSeconds(start, this.totalSeconds, new Cesium.JulianDate()); + const color = Cesium.Color.fromRandom({ alpha: 1 }); + const satelliteEntity = { + availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start, stop })]), + description: this.name, + label: { + backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.5), + backgroundPadding: new Cesium.Cartesian2(4, 4), + fillColor: Cesium.Color.WHITE, + font: '12px sans-serif', + horizontalOrigin: Cesium.HorizontalOrigin.LEFT, + outlineWidth: 1, + pixelOffset: new Cesium.Cartesian2(0, 5), + showBackground: true, + text: this.name, + verticalOrigin: Cesium.VerticalOrigin.TOP, + // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(10.0, 50000000), + }, + name: this.name, + path: new Cesium.PathGraphics({ + leadTime: this.leadTime, + material: color, + show: true, + trailTime: this.trailTime, + width: 0.5, + }), + point: { + color, + pixelSize: 8, + // scaleByDistance: new Cesium.NearFarScalar(1.5e3, 1, 8.0e8, 0.5), + }, + position: this._getPositionProperty(), + }; + return satelliteEntity; + } + + // 获取地心惯性坐标系坐标 + getPositionEci(date: Date) { + const result = propagate(this.satrec, date); + // 检查position是否为对象且不是true + if (typeof result.position !== 'object' || result.position === null) { + return null; + } + return result.position; + } +} + +export default SatelliteEntity; diff --git a/src/pages/Satellite/Cesium/cesium-helper/_TLE_DATA.ts b/src/pages/Satellite/Cesium/cesium-helper/_TLE_DATA.ts new file mode 100644 index 0000000..79a4294 --- /dev/null +++ b/src/pages/Satellite/Cesium/cesium-helper/_TLE_DATA.ts @@ -0,0 +1,8 @@ +export const TLE_LIST = [ + `2025-045A +1 63157U 25045A 25069.35219743 .00000545 -65692-6 00000+0 0 9992 +2 63157 19.0062 64.6364 7327661 179.7218 141.4162 2.26206155 28`, + `STARLINK-11371 [DTC] +1 62879U 25024A 25062.93300820 .00003305 00000+0 21841-4 0 9995 +2 62879 42.9977 257.3937 0001725 269.2925 90.7748 15.77864921 5143`, +]; diff --git a/src/pages/Satellite/Cesium/cesium-helper/demo_02_Track.ts b/src/pages/Satellite/Cesium/cesium-helper/demo_02_Track.ts index 61543f8..a66cb81 100644 --- a/src/pages/Satellite/Cesium/cesium-helper/demo_02_Track.ts +++ b/src/pages/Satellite/Cesium/cesium-helper/demo_02_Track.ts @@ -45,8 +45,6 @@ export async function demo_02_Track(viewer: Viewer) { outlineWidth: 2, pixelSize: 10, }, - // viewFrom: new Cartesian3(0, -1.5e7, 2.5e7), - // https://www.google.com/search?q=cesium%C2%A0viewFrom%C2%A0+trackedEntity }); // 计算并绘制卫星轨迹 diff --git a/src/pages/Satellite/Cesium/index.page.vue b/src/pages/Satellite/Cesium/index.page.vue index 37c4813..afb3e27 100644 --- a/src/pages/Satellite/Cesium/index.page.vue +++ b/src/pages/Satellite/Cesium/index.page.vue @@ -2,17 +2,28 @@ import type { Viewer } from 'cesium'; import { cesium_init } from './cesium-helper/00.cesium-init'; +import { TLE_LIST } from './cesium-helper/_TLE_DATA'; import { demo_01_OrbitGeneration } from './cesium-helper/demo_01_OrbitGeneration'; import { demo_02_Track } from './cesium-helper/demo_02_Track'; +import SatelliteEntity from './cesium-helper/SatelliteEntity'; let viewer: Viewer; onMounted(async () => { - viewer = cesium_init(document.getElementById('cesiumContainer')!); + viewer = cesium_init(document.querySelector('#cesiumContainer')!); Object.assign(globalThis, { viewer }); (({ run }) => (run ? demo_01_OrbitGeneration(viewer) : null))({ run: false }); - (({ run }) => (run ? demo_02_Track(viewer) : null))({ run: true }); + (({ run }) => (run ? demo_02_Track(viewer) : null))({ run: false }); + + // demo_01_OrbitGeneration(viewer); + // demo_02_Track(viewer); + + TLE_LIST.forEach((tle) => { + const satellite = new SatelliteEntity(tle); + const cesiumSateEntity = satellite.createSatelliteEntity(); + /* let result = */ viewer.entities.add(cesiumSateEntity); + }); }); diff --git a/src/pages/UI-components/AntdV/index.page.vue b/src/pages/UI-components/AntdV/index.page.vue index 3555d87..98f0df7 100644 --- a/src/pages/UI-components/AntdV/index.page.vue +++ b/src/pages/UI-components/AntdV/index.page.vue @@ -34,4 +34,3 @@ async function handleConfirmAsync(e: MouseEvent) { -./HAPopconfirm.vue