使用TLE计算轨道并使用Cesium绘制

使用TLE计算轨道并使用Cesium绘制

依赖库

  • satellite.js

npm install satellite.js

实现思路

  1. 利用satellite.js获取一个轨道周期内的全部轨迹点坐标
  2. 使用Cesium的primitive绘制轨迹线

完整代码

import { twoline2satrec, propagate, gstime, eciToEcf } from "satellite.js";

const tle1 = `1 00005U 58002B   24282.07474862  .00001783  00000-0  22061-2 0  9998  `
const tle2 = `2 00005  34.2560  58.9866 1843712 236.2153 104.9193 10.85699439376194  `


const satrec = twoline2satrec(item.tleLine1, item.tleLine2); 


/**
 * 计算卫星每圈所需的时间
 * 
 * @param {Object} satrec - 卫星轨道数据
 * @param {number} satrec.no - 卫星每分钟的平均角速度,单位为弧度/分钟
 * @returns {number} 卫星运行一圈所需的时间,单位为分钟
 */
function calCircleBySatrec(satrec) {
  return (2 * Math.PI) / satrec.no;
}

/**
 * 根据卫星的 TLE 数据和指定时间计算卫星在地心惯性坐标系中的位置。
 *
 * @param {Object} satrec - 卫星轨道数据对象,包含轨道信息。
 * @param {number} [time=Date.now()] - 可选参数,计算位置的时间(时间戳,默认为当前时间)。
 * @param {string} type - 坐标系类型,支持 "ECI"(地心惯性坐标系)和 "ECF"(地心固定坐标系)。
 * @returns {Cesium.Cartesian3|undefined} - 卫星在指定坐标系中的位置/undefined。
 */
function getPositionFromTle(satrec, time = Date.now(), type = "ECI") {
  const curTimeDate = new Date(time);
  const { position } = propagate(satrec, curTimeDate) || {};

  if (!position) return;

  const conversionFactor = 1000; 
  if (type === "ECI") {
    return new Cesium.Cartesian3(
      position.x * conversionFactor,
      position.y * conversionFactor,
      position.z * conversionFactor
    );
  }

  if (type === "ECF") {
    const gmst = gstime(curTimeDate);
    const positionEcf = eciToEcf(position, gmst);
    if (!positionEcf) return;

    return new Cesium.Cartesian3(
      positionEcf.x * conversionFactor,
      positionEcf.y * conversionFactor,
      positionEcf.z * conversionFactor
    );
  }

  return;
}


const timeStamp = Date.now(); 
const minsPerInterval = calCircleBySatrec(satrec); //轨道周期
const positionsArr = []; // 轨迹点数组

for (let i = 0; i <= minsPerInterval; i++) {
  const curPosition = getPositionFromTle(satrec, timeStamp + i * 60 * 1000);
  if (curPosition) {
    positionsArr.push(curPosition);
  }
}

 const viewer = new Cesium.Viewer('cesiumContainer', {
 })


 const satPolylineCollection = viewer.scene.primitives.add(
    new Cesium.PolylineCollection()
 );

 const trackPrimitive = satPolylineCollection.add({
    id: 1,
    positions: positionsArr,
    width: 2,
    material: Cesium.Material.fromType("Color", {
      glowPower: 0.1,
      color: new Cesium.Color(0, 0.9, 0.8, 0.3),
      // color: new Cesium.Color(...getRandomColor()),
    }),
  });



posted @ 2024-11-04 17:44  泽111  阅读(952)  评论(0)    收藏  举报