feat: /cesium
This commit is contained in:
@ -51,11 +51,7 @@ export async function demo_02_Track(viewer: Viewer) {
|
|||||||
const totalSeconds = 60 * 60 * 2; // 2小时的轨迹
|
const totalSeconds = 60 * 60 * 2; // 2小时的轨迹
|
||||||
const timeStepInSeconds = 30; // 每30秒一个点
|
const timeStepInSeconds = 30; // 每30秒一个点
|
||||||
const startTime = Cesium.JulianDate.fromDate(new Date());
|
const startTime = Cesium.JulianDate.fromDate(new Date());
|
||||||
const endTime = Cesium.JulianDate.addSeconds(
|
const endTime = Cesium.JulianDate.addSeconds(startTime, totalSeconds, new Cesium.JulianDate());
|
||||||
startTime,
|
|
||||||
totalSeconds,
|
|
||||||
new Cesium.JulianDate(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// 设置时钟范围
|
// 设置时钟范围
|
||||||
viewer.clock.startTime = startTime.clone();
|
viewer.clock.startTime = startTime.clone();
|
||||||
@ -73,13 +69,12 @@ export async function demo_02_Track(viewer: Viewer) {
|
|||||||
// 用于存储轨道点的数组(用于显示完整轨道)
|
// 用于存储轨道点的数组(用于显示完整轨道)
|
||||||
const orbitPositions: Cesium.Cartesian3[] = [];
|
const orbitPositions: Cesium.Cartesian3[] = [];
|
||||||
|
|
||||||
|
// 保存卫星高度数据,用于覆盖范围计算
|
||||||
|
// const satelliteAltitude = 550_000; // 默认高度为550公里
|
||||||
|
|
||||||
// 计算轨道上的点
|
// 计算轨道上的点
|
||||||
for (let i = 0; i <= totalSeconds; i += timeStepInSeconds) {
|
for (let i = 0; i <= totalSeconds; i += timeStepInSeconds) {
|
||||||
const time = Cesium.JulianDate.addSeconds(
|
const time = Cesium.JulianDate.addSeconds(startTime, i, new Cesium.JulianDate());
|
||||||
startTime,
|
|
||||||
i,
|
|
||||||
new Cesium.JulianDate(),
|
|
||||||
);
|
|
||||||
const jsDate = Cesium.JulianDate.toDate(time);
|
const jsDate = Cesium.JulianDate.toDate(time);
|
||||||
|
|
||||||
// 计算卫星位置
|
// 计算卫星位置
|
||||||
@ -91,11 +86,11 @@ export async function demo_02_Track(viewer: Viewer) {
|
|||||||
const position = eciToEcf(positionAndVelocity.position, gmst);
|
const position = eciToEcf(positionAndVelocity.position, gmst);
|
||||||
|
|
||||||
// 转换为Cesium坐标(单位:米)
|
// 转换为Cesium坐标(单位:米)
|
||||||
const cesiumPosition = new Cesium.Cartesian3(
|
const cesiumPosition = new Cesium.Cartesian3(position.x * 1000, position.y * 1000, position.z * 1000);
|
||||||
position.x * 1000,
|
|
||||||
position.y * 1000,
|
// 计算卫星高度
|
||||||
position.z * 1000,
|
// const cartographic = Cesium.Cartographic.fromCartesian(cesiumPosition);
|
||||||
);
|
// satelliteAltitude = cartographic.height;
|
||||||
|
|
||||||
// 保存位置用于绘制完整轨道
|
// 保存位置用于绘制完整轨道
|
||||||
orbitPositions.push(cesiumPosition);
|
orbitPositions.push(cesiumPosition);
|
||||||
@ -122,16 +117,52 @@ export async function demo_02_Track(viewer: Viewer) {
|
|||||||
|
|
||||||
// 设置卫星的位置
|
// 设置卫星的位置
|
||||||
satelliteEntity.position = positionProperty;
|
satelliteEntity.position = positionProperty;
|
||||||
satelliteEntity.orientation = new Cesium.VelocityOrientationProperty(
|
satelliteEntity.orientation = new Cesium.VelocityOrientationProperty(positionProperty);
|
||||||
positionProperty,
|
|
||||||
);
|
|
||||||
|
|
||||||
// 添加卫星覆盖范围
|
// 添加卫星覆盖范围
|
||||||
// Starlink 卫星通常覆盖范围以锥形方式向地面投射
|
// Starlink 卫星通常覆盖范围以锥形方式向地面投射
|
||||||
// 创建一个椭球体来表示卫星的覆盖范围
|
// 创建一个椭球体来表示卫星的覆盖范围
|
||||||
const coverageAngle = 45; // 覆盖角度(度)
|
const coverageAngle = 45; // 覆盖角度(度)
|
||||||
|
|
||||||
|
// satelliteAltitude * Math.tan(Cesium.Math.toRadians(coverageAngle));
|
||||||
|
|
||||||
// 创建覆盖范围实体
|
// 创建覆盖范围实体
|
||||||
|
viewer.entities.add({
|
||||||
|
ellipsoid: {
|
||||||
|
material: Cesium.Color.BLUE.withAlpha(0.2),
|
||||||
|
outline: true,
|
||||||
|
outlineColor: Cesium.Color.BLUE.withAlpha(0.8),
|
||||||
|
radii: new Cesium.CallbackProperty(() => {
|
||||||
|
const position = satelliteEntity.position?.getValue(viewer.clock.currentTime);
|
||||||
|
if (!position) return new Cesium.Cartesian3(10_000, 10_000, 10_000);
|
||||||
|
|
||||||
|
// 获取当前卫星高度
|
||||||
|
const cartographic = Cesium.Cartographic.fromCartesian(position);
|
||||||
|
const height = cartographic.height;
|
||||||
|
|
||||||
|
// 计算覆盖范围半径 (基于锥角)
|
||||||
|
const coverageRadius = height * Math.tan(Cesium.Math.toRadians(coverageAngle));
|
||||||
|
|
||||||
|
// 椭球体形状: xy平面为圆形基底,z轴方向为高度
|
||||||
|
return new Cesium.Cartesian3(coverageRadius, coverageRadius, height / 2);
|
||||||
|
}, false),
|
||||||
|
slicePartitions: 24,
|
||||||
|
stackPartitions: 16,
|
||||||
|
},
|
||||||
|
id: 'STARLINK-11371-coverage',
|
||||||
|
name: 'STARLINK-11371 Coverage',
|
||||||
|
orientation: new Cesium.CallbackProperty(() => {
|
||||||
|
// 确保椭球体始终指向地球中心
|
||||||
|
const position = satelliteEntity.position?.getValue(viewer.clock.currentTime);
|
||||||
|
if (!position) return Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3());
|
||||||
|
|
||||||
|
// 计算从卫星到地球中心的方向
|
||||||
|
Cesium.Cartesian3.normalize(Cesium.Cartesian3.negate(position, new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
|
||||||
|
return Cesium.Transforms.headingPitchRollQuaternion(position, new Cesium.HeadingPitchRoll(0, Math.PI, 0));
|
||||||
|
}, false),
|
||||||
|
position: positionProperty,
|
||||||
|
});
|
||||||
|
|
||||||
// 添加地面覆盖范围投影
|
// 添加地面覆盖范围投影
|
||||||
viewer.entities.add({
|
viewer.entities.add({
|
||||||
@ -143,51 +174,39 @@ export async function demo_02_Track(viewer: Viewer) {
|
|||||||
outlineColor: Cesium.Color.BLUE.withAlpha(0.8),
|
outlineColor: Cesium.Color.BLUE.withAlpha(0.8),
|
||||||
outlineWidth: 2,
|
outlineWidth: 2,
|
||||||
semiMajorAxis: new Cesium.CallbackProperty(() => {
|
semiMajorAxis: new Cesium.CallbackProperty(() => {
|
||||||
const satPosition = satelliteEntity.position?.getValue(
|
const satPosition = satelliteEntity.position?.getValue(viewer.clock.currentTime);
|
||||||
viewer.clock.currentTime,
|
|
||||||
);
|
|
||||||
if (!satPosition) return 10_000;
|
if (!satPosition) return 10_000;
|
||||||
|
|
||||||
// 计算卫星高度
|
// 计算卫星高度
|
||||||
const cartographic = Cesium.Cartographic.fromCartesian(satPosition);
|
const cartographic = Cesium.Cartographic.fromCartesian(satPosition);
|
||||||
// 根据高度和覆盖角度计算地面覆盖半径
|
// 根据高度和覆盖角度计算地面覆盖半径
|
||||||
return (
|
return cartographic.height * Math.tan(Cesium.Math.toRadians(coverageAngle));
|
||||||
cartographic.height * Math.tan(Cesium.Math.toRadians(coverageAngle))
|
|
||||||
);
|
|
||||||
}, false),
|
}, false),
|
||||||
semiMinorAxis: new Cesium.CallbackProperty(() => {
|
semiMinorAxis: new Cesium.CallbackProperty(() => {
|
||||||
const satPosition = satelliteEntity.position?.getValue(
|
const satPosition = satelliteEntity.position?.getValue(viewer.clock.currentTime);
|
||||||
viewer.clock.currentTime,
|
|
||||||
);
|
|
||||||
if (!satPosition) return 10_000;
|
if (!satPosition) return 10_000;
|
||||||
|
|
||||||
// 计算卫星高度
|
// 计算卫星高度
|
||||||
const cartographic = Cesium.Cartographic.fromCartesian(satPosition);
|
const cartographic = Cesium.Cartographic.fromCartesian(satPosition);
|
||||||
// 根据高度和覆盖角度计算地面覆盖半径
|
// 根据高度和覆盖角度计算地面覆盖半径
|
||||||
return (
|
return cartographic.height * Math.tan(Cesium.Math.toRadians(coverageAngle));
|
||||||
cartographic.height * Math.tan(Cesium.Math.toRadians(coverageAngle))
|
|
||||||
);
|
|
||||||
}, false),
|
}, false),
|
||||||
},
|
},
|
||||||
id: 'STARLINK-11371-ground-coverage',
|
id: 'STARLINK-11371-ground-coverage',
|
||||||
name: 'STARLINK-11371 Ground Coverage',
|
name: 'STARLINK-11371 Ground Coverage',
|
||||||
position: new Cesium.CallbackPositionProperty(() => {
|
position: new Cesium.CallbackPositionProperty(() => {
|
||||||
const satPosition = satelliteEntity.position?.getValue(
|
const satPosition = satelliteEntity.position?.getValue(viewer.clock.currentTime);
|
||||||
viewer.clock.currentTime,
|
|
||||||
);
|
|
||||||
if (!satPosition) return new Cesium.Cartesian3();
|
if (!satPosition) return new Cesium.Cartesian3();
|
||||||
|
|
||||||
// 计算卫星在地表的投影点
|
// 计算卫星在地表的投影点
|
||||||
const cartographic = Cesium.Cartographic.fromCartesian(satPosition);
|
const cartographic = Cesium.Cartographic.fromCartesian(satPosition);
|
||||||
return Cesium.Cartesian3.fromRadians(
|
return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0);
|
||||||
cartographic.longitude,
|
|
||||||
cartographic.latitude,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
}, false),
|
}, false),
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://github.com/CesiumGS/cesium/issues/8350
|
// - https://community.cesium.com/t/entity-viewfrom-property-example/2299/3
|
||||||
|
// - https://github.com/CesiumGS/cesium/issues/8900#issuecomment-638114149
|
||||||
|
// - which is normal from a bird's eye view. But after setting it as the trackedEntity, it behaves abnormally.
|
||||||
// 设置相机自动跟踪卫星
|
// 设置相机自动跟踪卫星
|
||||||
viewer.trackedEntity = satelliteEntity;
|
viewer.trackedEntity = satelliteEntity;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user