Files
vue-ts-example/src/pages/_cesium-demos/归档/SatelliteEntity.ts
严浩 02ce0fa9a0
Some checks failed
/ build-and-deploy-to-vercel (push) Successful in 2m45s
/ lint-build-and-check (push) Successful in 4m32s
/ playwright (push) Failing after 12m4s
/ surge (push) Successful in 2m34s
h-cesium-viewer
2025-04-02 16:39:15 +08:00

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;