109 lines
3.6 KiB
TypeScript
109 lines
3.6 KiB
TypeScript
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;
|