119 lines
3.4 KiB
TypeScript
119 lines
3.4 KiB
TypeScript
import type { Viewer } from 'cesium';
|
|
import * as Cesium from 'cesium';
|
|
import { twoline2satrec, propagate, gstime, eciToEcf } from 'satellite.js';
|
|
|
|
export async function demoOrbitGeneration(viewer: Viewer) {
|
|
const tle = `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`;
|
|
|
|
// 解析TLE数据
|
|
const lines = tle.split('\n');
|
|
const satelliteName = lines[0].trim();
|
|
const tleLine1 = lines[1];
|
|
const tleLine2 = lines[2];
|
|
|
|
// 创建卫星记录
|
|
const satrec = twoline2satrec(tleLine1, tleLine2);
|
|
|
|
// 创建轨道点
|
|
const pointsArray = [];
|
|
const totalMinutes = 1440; // 一天的分钟数
|
|
const timeStepInMinutes = 10;
|
|
|
|
// 当前时间
|
|
const now = new Date();
|
|
|
|
// 计算一条完整的轨道
|
|
for (let i = 0; i < totalMinutes; i += timeStepInMinutes) {
|
|
// 创建时间点
|
|
const time = new Date(now.getTime() + i * 60000);
|
|
|
|
// 获取卫星位置
|
|
const positionAndVelocity = propagate(satrec, time);
|
|
|
|
// 有时可能返回false
|
|
const position = positionAndVelocity.position;
|
|
if (typeof position === 'boolean') {
|
|
console.error('Error calculating satellite position');
|
|
return;
|
|
}
|
|
// 转换为千米
|
|
const gmst = gstime(time);
|
|
const p = eciToEcf(position, gmst);
|
|
|
|
// 添加到点数组
|
|
pointsArray.push(
|
|
Cesium.Cartesian3.fromDegrees(
|
|
Cesium.Math.toDegrees(Math.atan2(p.y, p.x)),
|
|
Cesium.Math.toDegrees(Math.atan2(p.z, Math.sqrt(p.x * p.x + p.y * p.y))),
|
|
Math.sqrt(p.x * p.x + p.y * p.y + p.z * p.z) * 1000, // 转换为米
|
|
),
|
|
);
|
|
}
|
|
|
|
// 获取当前位置用于放置卫星模型
|
|
const time = new Date();
|
|
const positionAndVelocity = propagate(satrec, time);
|
|
const position = positionAndVelocity.position;
|
|
const gmst = gstime(time);
|
|
if (typeof position === 'boolean') {
|
|
console.error('Error calculating satellite position');
|
|
return;
|
|
}
|
|
const p = eciToEcf(position, gmst);
|
|
|
|
const currentPosition = Cesium.Cartesian3.fromDegrees(
|
|
Cesium.Math.toDegrees(Math.atan2(p.y, p.x)),
|
|
Cesium.Math.toDegrees(Math.atan2(p.z, Math.sqrt(p.x * p.x + p.y * p.y))),
|
|
Math.sqrt(p.x * p.x + p.y * p.y + p.z * p.z) * 1000, // 转换为米
|
|
);
|
|
|
|
// 创建轨道线
|
|
const orbitPath = viewer.entities.add({
|
|
name: `${satelliteName} Orbit`,
|
|
polyline: {
|
|
positions: pointsArray,
|
|
width: 2,
|
|
material: new Cesium.PolylineGlowMaterialProperty({
|
|
glowPower: 0.2,
|
|
color: Cesium.Color.BLUE,
|
|
}),
|
|
},
|
|
});
|
|
|
|
// 添加卫星实体
|
|
const satellite = viewer.entities.add({
|
|
name: satelliteName,
|
|
position: currentPosition,
|
|
point: {
|
|
pixelSize: 10,
|
|
color: Cesium.Color.YELLOW,
|
|
outlineColor: Cesium.Color.WHITE,
|
|
outlineWidth: 2,
|
|
},
|
|
label: {
|
|
text: satelliteName,
|
|
font: '14pt sans-serif',
|
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
|
fillColor: Cesium.Color.WHITE,
|
|
outlineColor: Cesium.Color.BLACK,
|
|
outlineWidth: 2,
|
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
|
pixelOffset: new Cesium.Cartesian2(0, -10),
|
|
},
|
|
// billboard: {
|
|
// image: '/assets/satellite.png', // 您需要添加一个卫星图标
|
|
// scale: 0.5,
|
|
// },
|
|
});
|
|
|
|
// 将相机定位到卫星
|
|
viewer.flyTo(satellite, { duration: 3 });
|
|
|
|
return {
|
|
orbitPath,
|
|
satellite,
|
|
};
|
|
}
|