feat: 添加卫星覆盖范围计算功能
This commit is contained in:
4
src/components/h-cesium-viewer/README.md
Normal file
4
src/components/h-cesium-viewer/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
- 卫星覆盖范围: 当前实现是基于卫星高度的一个简化估算(altitude * 0.8),代码注释也指明了这一点。这种方法不够精确,仅能提供一个大致的视觉参考。精确的覆盖范围计算需要考虑卫星的视场角 (FOV) 或波束宽度等具体参数。
|
||||
- TLE 数据 → 轨道 → 位置 & 速度
|
||||
- 大小 → 需要外部规格数据
|
||||
- 精确姿态 → 需要专门的 ADCS 数据 (TLE 不提供)
|
@ -29,7 +29,14 @@ export class HCesiumViewerCls {
|
||||
// 用于存储当前地面站实体的 Map
|
||||
currentStationEntities: Map<string, Cesium.Entity> = new Map();
|
||||
// 用于存储当前卫星实体的 Map (包括轨道实体)
|
||||
currentSatelliteEntities: Map<string, { entity: Cesium.Entity; orbitEntity?: Cesium.Entity }> = new Map();
|
||||
currentSatelliteEntities: Map<
|
||||
string,
|
||||
{
|
||||
coverageEntity?: Cesium.Entity;
|
||||
entity: Cesium.Entity;
|
||||
orbitEntity?: Cesium.Entity;
|
||||
}
|
||||
> = new Map();
|
||||
|
||||
/**
|
||||
* 初始化 Cesium Viewer
|
||||
@ -250,6 +257,67 @@ export class HCesiumViewerCls {
|
||||
satelliteEntity.position = positionProperty;
|
||||
satelliteEntity.orientation = new Cesium.VelocityOrientationProperty(positionProperty);
|
||||
|
||||
// --- 添加卫星地面覆盖范围 ---
|
||||
// 使用 CallbackProperty 动态计算星下点位置
|
||||
const subsatellitePosition = new Cesium.CallbackPositionProperty(
|
||||
(time, result) => {
|
||||
// 从 satelliteEntity 获取当前时间的精确位置
|
||||
const satelliteCartesian = positionProperty.getValue(time, result);
|
||||
if (!satelliteCartesian) {
|
||||
return; // 如果位置无效,则不返回任何内容
|
||||
}
|
||||
// 转换为地理坐标(包含高度)
|
||||
const satelliteCartographic = Cesium.Cartographic.fromCartesian(satelliteCartesian);
|
||||
if (!satelliteCartographic) {
|
||||
return; // 如果转换失败,则不返回任何内容
|
||||
}
|
||||
// 创建星下点地理坐标(高度设为0)
|
||||
const subsatelliteCartographic = new Cesium.Cartographic(
|
||||
satelliteCartographic.longitude,
|
||||
satelliteCartographic.latitude,
|
||||
0,
|
||||
);
|
||||
// 转换回笛卡尔坐标
|
||||
return Cesium.Cartographic.toCartesian(subsatelliteCartographic, Cesium.Ellipsoid.WGS84, result);
|
||||
},
|
||||
false,
|
||||
Cesium.ReferenceFrame.FIXED,
|
||||
); // isConstant: false, referenceFrame: FIXED
|
||||
|
||||
// 使用 CallbackProperty 动态计算覆盖半径 (基于高度的简单估算)
|
||||
const coverageRadius = new Cesium.CallbackProperty((time) => {
|
||||
const satelliteCartesian = positionProperty.getValue(time);
|
||||
if (!satelliteCartesian) {
|
||||
return 100_000; // 默认半径 100km
|
||||
}
|
||||
const satelliteCartographic = Cesium.Cartographic.fromCartesian(satelliteCartesian);
|
||||
if (!satelliteCartographic) {
|
||||
return 100_000;
|
||||
}
|
||||
const altitude = satelliteCartographic.height;
|
||||
// 简化的估算:半径约为高度的 0.8 倍,最小 50km
|
||||
// 实际应用中应基于卫星的视场角 (FOV) 或波束宽度计算
|
||||
const calculatedRadius = altitude * 0.8;
|
||||
return Math.max(calculatedRadius, 50_000); // 最小半径 50km
|
||||
}, false); // isConstant 设置为 false
|
||||
|
||||
const coverageEntity = this.viewer.entities.add({
|
||||
id: `${id}-coverage`,
|
||||
name: `${name} 覆盖范围`,
|
||||
position: subsatellitePosition,
|
||||
ellipse: {
|
||||
semiMajorAxis: coverageRadius,
|
||||
semiMinorAxis: coverageRadius, // 假设圆形覆盖
|
||||
material: Cesium.Color.RED.withAlpha(0.3), // 半透明红色
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, // 贴合地形
|
||||
outline: true,
|
||||
outlineColor: Cesium.Color.BLACK.withAlpha(0.5),
|
||||
outlineWidth: 1,
|
||||
// fill: true, // 默认填充
|
||||
},
|
||||
});
|
||||
// --- 覆盖范围结束 ---
|
||||
|
||||
let orbitEntity: Cesium.Entity | undefined;
|
||||
// 添加完整轨道线(如果需要)
|
||||
if (showOrbit && orbitPositions.length > 1) {
|
||||
@ -269,7 +337,7 @@ export class HCesiumViewerCls {
|
||||
}
|
||||
|
||||
// 存储实体引用
|
||||
this.currentSatelliteEntities.set(id, { entity: satelliteEntity, orbitEntity });
|
||||
this.currentSatelliteEntities.set(id, { entity: satelliteEntity, orbitEntity, coverageEntity });
|
||||
|
||||
return satelliteEntity;
|
||||
}
|
||||
@ -288,6 +356,7 @@ export class HCesiumViewerCls {
|
||||
if (satelliteData) {
|
||||
let removedMain = true;
|
||||
let removedOrbit = true;
|
||||
let removedCoverage = true; // 新增:覆盖范围移除状态
|
||||
|
||||
// 移除卫星主体
|
||||
if (satelliteData.entity) {
|
||||
@ -305,8 +374,17 @@ export class HCesiumViewerCls {
|
||||
}
|
||||
}
|
||||
|
||||
// 移除覆盖范围
|
||||
if (satelliteData.coverageEntity) {
|
||||
removedCoverage = this.viewer.entities.remove(satelliteData.coverageEntity);
|
||||
if (!removedCoverage) {
|
||||
console.warn(`尝试从 Cesium 移除卫星覆盖范围 ID 为 "${satelliteData.coverageEntity.id}" 的实体失败。`);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果主体和轨道(如果存在)都移除成功或不存在,则从 Map 中删除
|
||||
if (removedMain && removedOrbit) {
|
||||
// 如果主体、轨道(如果存在)和覆盖范围(如果存在)都移除成功或不存在,则从 Map 中删除
|
||||
if (removedMain && removedOrbit && removedCoverage) {
|
||||
this.currentSatelliteEntities.delete(entityId);
|
||||
return true;
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user