import type { Cartesian3 } from 'cesium'; import * as Cesium from 'cesium'; import { propagate, type SatRec, twoline2satrec } from 'satellite.js'; class SatelliteEntity { private leadTime!: number; private name!: string; private satrec: SatRec; private stepSeconds!: number; private tleLine1!: string; private tleLine2!: string; private totalSeconds!: number; private trailTime!: number; constructor(tle2LineString = '' /* , options = {} */) { const [name, tleLine1, tleLine2] = this._checkTle(tle2LineString); 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(tle2LineString: string) { const elements = tle2LineString.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 index = 0; index < this.totalSeconds / this.stepSeconds; index++) { const sateTime = new Date(now + index * this.stepSeconds * 1000); const sateCoord = this.getPositionEci(sateTime); if (!sateCoord) continue; const cesiumTime = Cesium.JulianDate.addSeconds(start, index * 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;