From 8b702826b39937ceeda1fa7d392fa9051dfde5ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E6=B5=A9?= Date: Wed, 12 Mar 2025 19:02:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=20TLE=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=A4=84=E7=90=86=E5=92=8C=E7=A4=BA=E4=BE=8B=EF=BC=8C?= =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=8D=AB=E6=98=9F=E8=BD=A8=E9=81=93=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E8=A7=A3=E6=9E=90=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Satellite/Cesium/cesium-helper/README.md | 7 + .../Cesium/cesium-helper/_TLE_DATA.ts | 221 +++++++++++++----- 2 files changed, 166 insertions(+), 62 deletions(-) diff --git a/src/pages/Satellite/Cesium/cesium-helper/README.md b/src/pages/Satellite/Cesium/cesium-helper/README.md index 07c27b1..2505cd0 100644 --- a/src/pages/Satellite/Cesium/cesium-helper/README.md +++ b/src/pages/Satellite/Cesium/cesium-helper/README.md @@ -18,3 +18,10 @@ - https://blog.csdn.net/m0_54849806/article/details/126070809 - https://juejin.cn/post/6969838266182795278 - https://blog.csdn.net/CSDNqinzhike/article/details/139587028 + +## TLE + +- https://en.wikipedia.org/wiki/Two-line_element_set#Format +- https://grok.com/share/bGVnYWN5_f2c51def-f941-4c75-b020-e76534ba5c5e +- https://celestrak.org/NORAD/elements/gp.php?GROUP=last-30-days&FORMAT=tle +- https://celestrak.org/NORAD/elements/gp.php?GROUP=last-30-days&FORMAT=json diff --git a/src/pages/Satellite/Cesium/cesium-helper/_TLE_DATA.ts b/src/pages/Satellite/Cesium/cesium-helper/_TLE_DATA.ts index 33e802e..291bcad 100644 --- a/src/pages/Satellite/Cesium/cesium-helper/_TLE_DATA.ts +++ b/src/pages/Satellite/Cesium/cesium-helper/_TLE_DATA.ts @@ -1,109 +1,206 @@ -// eslint-disable no-unused-vars /* eslint-disable perfectionist/sort-objects */ +// eslint-disable no-unused-vars import { twoline2satrec } from 'satellite.js'; -// https://en.wikipedia.org/wiki/Two-line_element_set#Format - -// https://celestrak.org/NORAD/elements/gp.php?GROUP=last-30-days&FORMAT=tle - -const longstr1 = `1 63157U 25045A 25069.35219743 .00000545 -65692-6 00000+0 0 9992`; -const longstr2 = `2 63157 19.0062 64.6364 7327661 179.7218 141.4162 2.26206155 28`; +const longstr1 = `1 62949U 25029B 25070.91668981 .00039463 00000+0 99294-3 0 9990`; +const longstr2 = `2 62949 53.1596 120.9032 0001355 101.1211 35.9659 15.39574303 5809`; export const TLE_LIST = [ - /* `ISS (ZARYA) - 1 25544U 98067A 08264.51782528 -.00002182 00000-0 -11606-4 0 2927 - 2 25544 51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537`, */ - `2025-045A + `STARLINK-32857 ${longstr1} ${longstr2}`, - `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`, + `STARLINK-32915 +1 63152U 25043W 25070.91668981 .00451203 87802-4 12020-2 0 9994 +2 63152 43.0011 279.4620 0003944 269.6759 119.1758 15.93738994 2341`, + `STARLINK-32915 [测修改1] +1 00000U 00000W 25070.91668981 .00000000 00000-0 00000-0 0 0000 +2 00000 43.0011 279.4620 0003944 269.6759 119.1758 15.93738994 0000`, ]; -// https://celestrak.org/NORAD/elements/gp.php?GROUP=last-30-days&FORMAT=json export const TLE_LIST_JSON = [ { - OBJECT_NAME: '2025-045A', - OBJECT_ID: '2025-045A', - EPOCH: '2025-03-10T08:27:09.857952', - MEAN_MOTION: 2.26206155, // 平均运动(Mean Motion),单位是圈/天,表示卫星每天绕地球运行的圈数,此处约为 2.26 圈(周期约 10.6 小时)。 - ECCENTRICITY: 0.7327661, // 偏心率(Eccentricity),无单位,科学记数法为 0.7327661,表示轨道是一个高度椭圆的形状(接近 1 表示非常扁平)。 - INCLINATION: 19.0062, // 轨道倾角(Inclination),单位是度,表示轨道平面与地球赤道的夹角。此处为 19.0062°,属于低倾角轨道。 - RA_OF_ASC_NODE: 64.6364, // 升交点赤经(RAAN, Right Ascension of Ascending Node),单位是度,表示轨道平面在赤道上的交叉点位置。 ARG_OF_PERICENTER: 179.7218, // 近地点角距(Argument of Perigee),单位是度,表示近地点相对于升交点的角度。 - MEAN_ANOMALY: 141.4162, // 平近点角(Mean Anomaly),单位是度,表示卫星在轨道上的位置。 - EPHEMERIS_TYPE: 0, // 轨道模型类型(通常为 0,表示 SGP4 模型)。 - CLASSIFICATION_TYPE: 'U', // U 表示未分类(可能是临时编号)。 - NORAD_CAT_ID: 63157, // NORAD - ELEMENT_SET_NO: 999, // 校验码或元素集编号,表示这是第 999 次更新的 TLE 数据。 - REV_AT_EPOCH: 2, // Checksum 校验和 BSTAR: 0, // 轨道模型类型(0=SGP4模型)。 - MEAN_MOTION_DOT: 5.45e-6, // 0.00000545 // 平均运动的一阶导数(每天的轨道变化率),单位是圈/天²,这里非常小,表示轨道衰减缓慢。 + CLASSIFICATION_TYPE: 'U', // U 表示未分类(可能是临时编号)。 + ECCENTRICITY: 0.732_766_1, // 偏心率(Eccentricity),无单位,科学记数法为 0.7327661,表示轨道是一个高度椭圆的形状(接近 1 表示非常扁平)。 + ELEMENT_SET_NO: 999, // 校验码或元素集编号,表示这是第 999 次更新的 TLE 数据。 + EPHEMERIS_TYPE: 0, // 轨道模型类型(通常为 0,表示 SGP4 模型)。 + EPOCH: '2025-03-10T08:27:09.857952', + INCLINATION: 19.0062, // 轨道倾角(Inclination),单位是度,表示轨道平面与地球赤道的夹角。此处为 19.0062°,属于低倾角轨道。 + MEAN_ANOMALY: 141.4162, // 平近点角(Mean Anomaly),单位是度,表示卫星在轨道上的位置。 + MEAN_MOTION: 2.262_061_55, // 平均运动(Mean Motion),单位是圈/天,表示卫星每天绕地球运行的圈数,此处约为 2.26 圈(周期约 10.6 小时)。 MEAN_MOTION_DDOT: -6.5692e-7, // 平均运动的二阶导数(科学记数法:-6.5692 × 10⁻⁶),表示轨道受摄动(如大气阻力)的加速度变化。 + MEAN_MOTION_DOT: 5.45e-6, // 0.00000545 // 平均运动的一阶导数(每天的轨道变化率),单位是圈/天²,这里非常小,表示轨道衰减缓慢。 + NORAD_CAT_ID: 63_157, // NORAD + OBJECT_ID: '2025-045A', + OBJECT_NAME: '2025-045A', + RA_OF_ASC_NODE: 64.6364, // 升交点赤经(RAAN, Right Ascension of Ascending Node),单位是度,表示轨道平面在赤道上的交叉点位置。 + REV_AT_EPOCH: 2, // Checksum 校验和 }, ]; // 为了twoline2satrec函数需要哪些参数 // https://github.com/shashwatak/satellite-js/blob/0e921026d20b75f42553366994af70eed63a304f/src/io.js#L62 function twoline2satrecFake(longstr1: string, longstr2: string) { - console.group('twoline2satrec'); + console.group('twoline2satrecFake'); const satrec = {} as Record; satrec.error = 0; - satrec.satnum = longstr1.substring(2, 7); - console.debug(`longstr1.substring(2, 7) :>> `, `"${longstr1.substring(2, 7)}"`); + satrec.satnum = longstr1.slice(2, 7); + console.debug(`longstr1.substring(2, 7) :>>`, `"${longstr1.slice(2, 7)}"`); - satrec.epochyr = parseInt(longstr1.substring(18, 20), 10); - console.debug(`longstr1.substring(18, 20) :>> `, `"${longstr1.substring(18, 20)}"`); + satrec.epochyr = Number.parseInt(longstr1.slice(18, 20), 10); + console.debug(`longstr1.substring(18, 20) :>>`, `"${longstr1.slice(18, 20)}"`); - satrec.epochdays = parseFloat(longstr1.substring(20, 32)); - console.debug(`longstr1.substring(20, 32) :>> `, `"${longstr1.substring(20, 32)}"`); + satrec.epochdays = Number.parseFloat(longstr1.slice(20, 32)); + console.debug(`longstr1.substring(20, 32) :>>`, `"${longstr1.slice(20, 32)}"`); - satrec.ndot = parseFloat(longstr1.substring(33, 43)); - console.debug(`longstr1.substring(33, 43) :>> `, `"${longstr1.substring(33, 43)}"`); + satrec.ndot = Number.parseFloat(longstr1.slice(33, 43)); + console.debug(`longstr1.substring(33, 43) :>>`, `"${longstr1.slice(33, 43)}"`); - satrec.nddot = parseFloat(`.${parseInt(longstr1.substring(44, 50), 10)}E${longstr1.substring(50, 52)}`); - console.debug(`longstr1.substring(44, 50) :>> `, `"${longstr1.substring(44, 50)}"`); - console.debug(`longstr1.substring(50, 52) :>> `, `"${longstr1.substring(50, 52)}"`); + satrec.nddot = Number.parseFloat(`.${Number.parseInt(longstr1.slice(44, 50), 10)}E${longstr1.slice(50, 52)}`); + console.debug(`longstr1.substring(44, 50) :>>`, `"${longstr1.slice(44, 50)}"`); + console.debug(`longstr1.substring(50, 52) :>>`, `"${longstr1.slice(50, 52)}"`); - satrec.bstar = parseFloat( - `${longstr1.substring(53, 54)}.${parseInt(longstr1.substring(54, 59), 10)}E${longstr1.substring(59, 61)}`, + satrec.bstar = Number.parseFloat( + `${longstr1.slice(53, 54)}.${Number.parseInt(longstr1.slice(54, 59), 10)}E${longstr1.slice(59, 61)}`, ); - console.debug(`longstr1.substring(53, 54) :>> `, `"${longstr1.substring(53, 54)}"`); - console.debug(`longstr1.substring(54, 59) :>> `, `"${longstr1.substring(54, 59)}"`); - console.debug(`longstr1.substring(59, 61) :>> `, `"${longstr1.substring(59, 61)}"`); + console.debug(`longstr1.substring(53, 54) :>>`, `"${longstr1.slice(53, 54)}"`); + console.debug(`longstr1.substring(54, 59) :>>`, `"${longstr1.slice(54, 59)}"`); + console.debug(`longstr1.substring(59, 61) :>>`, `"${longstr1.slice(59, 61)}"`); // satrec.satnum = longstr2.substring(2, 7); - satrec.inclo = parseFloat(longstr2.substring(8, 16)); - console.debug(`longstr2.substring(8, 16) :>> `, `"${longstr2.substring(8, 16)}"`); + satrec.inclo = Number.parseFloat(longstr2.slice(8, 16)); + console.debug(`longstr2.substring(8, 16) :>>`, `"${longstr2.slice(8, 16)}"`); - satrec.nodeo = parseFloat(longstr2.substring(17, 25)); - console.debug(`longstr2.substring(17, 25) :>> `, `"${longstr2.substring(17, 25)}"`); + satrec.nodeo = Number.parseFloat(longstr2.slice(17, 25)); + console.debug(`longstr2.substring(17, 25) :>>`, `"${longstr2.slice(17, 25)}"`); - satrec.ecco = parseFloat(`.${longstr2.substring(26, 33)}`); - console.debug(`longstr2.substring(26, 33) :>> `, `"${longstr2.substring(26, 33)}"`); - satrec.argpo = parseFloat(longstr2.substring(34, 42)); - console.debug(`longstr2.substring(34, 42) :>> `, `"${longstr2.substring(34, 42)}"`); - satrec.mo = parseFloat(longstr2.substring(43, 51)); - console.debug(`longstr2.substring(43, 51) :>> `, `"${longstr2.substring(43, 51)}"`); - satrec.no = parseFloat(longstr2.substring(52, 63)); - console.debug(`longstr2.substring(52, 63) :>> `, `"${longstr2.substring(52, 63)}"`); + satrec.ecco = Number.parseFloat(`.${longstr2.slice(26, 33)}`); + console.debug(`longstr2.substring(26, 33) :>>`, `"${longstr2.slice(26, 33)}"`); + satrec.argpo = Number.parseFloat(longstr2.slice(34, 42)); + console.debug(`longstr2.substring(34, 42) :>>`, `"${longstr2.slice(34, 42)}"`); + satrec.mo = Number.parseFloat(longstr2.slice(43, 51)); + console.debug(`longstr2.substring(43, 51) :>>`, `"${longstr2.slice(43, 51)}"`); + satrec.no = Number.parseFloat(longstr2.slice(52, 63)); + console.debug(`longstr2.substring(52, 63) :>>`, `"${longstr2.slice(52, 63)}"`); console.groupEnd(); return satrec; } -// console.debug(`twoline2satrecFake(longstr1, longstr2) :>> `, twoline2satrecFake(longstr1, longstr2)); -const satrec1 = twoline2satrec(longstr1, longstr2); -const satrec2 = twoline2satrec( +// if ($__DEV__) +// console.debug( +// `twoline2satrecFake(longstr1, longstr2) :>>`, +// twoline2satrecFake(longstr1, longstr2), +// ); +const 真正需要的是 = twoline2satrec( `1 63157 25069.35219743 .00000545 -65692-6 00000+0 `, `2 19.0062 64.6364 7327661 179.7218 141.4162 2.26206155 `, ); +const item = { + gdzj: '7', + wxzj: '2025029F', + wxmc: 'STARLINK-32884', + wxbh: '62953', + lysj: '25070.91668981', + ysjbh: '999', + xllx: '0', + bstarqzxt: '-0.01591824', + pjyddyjds: '-0.01591824', + drry: null, + drsj: null, + xgry: null, + xgsj: null, + isFlag: 0, + pjyddejds: '0', + gdqj: '53.1597', + sjdcj: '125.942', + pxl: '0.0001413', + jddfj: '92.4266', + pjdj: '189.6779', + pjyd: '15.48632226', + fsyldgdqs: '556', +}; + +const r = { + ARG_OF_PERICENTER: 101.1211, + BSTAR: 0.00099294, + CLASSIFICATION_TYPE: 'U', + ECCENTRICITY: 0.0001355, + ELEMENT_SET_NO: 999, + EPHEMERIS_TYPE: 0, + EPOCH: '2025-03-11T22:00:01.999584', + INCLINATION: 53.1596, + MEAN_ANOMALY: 35.9659, + MEAN_MOTION: 15.39574303, + MEAN_MOTION_DDOT: 0, + MEAN_MOTION_DOT: 0.00039463, + NORAD_CAT_ID: 62949, + OBJECT_ID: '2025-029B', + OBJECT_NAME: 'STARLINK-32857', + RA_OF_ASC_NODE: 120.9032, + REV_AT_EPOCH: 580, +}; +const satrec1 = twoline2satrec(longstr1, longstr2); // 正确结果 +let line1 = ''; +line1 += '1'; // +line1 += ' '; // +line1 += '62949'; // 卫星编号 +line1 += 'U'; // 卫星分类 +line1 += ' '; +line1 += '25'; +line1 += '029'; +line1 += 'B'.padEnd(3, ' '); +line1 += ' '; +line1 += '25070.91668981'; // 🛰️ 历元时间 25070.91668981(年份 2025,第 70 天加 0.91668981 天) +line1 += ' '; +line1 += '.00039463'.padStart(10, ' '); // +line1 += '00000+0'.padStart(9, ' '); // +line1 += '99294-3'.padStart(9, ' '); // +line1 += ' '; +line1 += '0'; +line1 += ' '; +line1 += '999'.padStart(4, ' '); +line1 += '0'; + +let line2 = ''; +line2 += '2'; +line2 += ' '; +line2 += '62949'; +line2 += ' '; +line2 += '53.1596'.padStart(8, ' '); // 🛰️ 轨道倾角(度) +line2 += ' '; +line2 += '120.9032'; // 🛰️ 升交点赤经(度) +line2 += ' '; +line2 += '0001355'; // 🛰️ 偏心率 +line2 += ' '; +line2 += '101.1211'; // 🛰️ 近地点角距(度) +line2 += ' '; +line2 += '35.9659'.padStart(8, ' '); // 🛰️ 平近点角(度) +line2 += ' '; +line2 += '15.39574303'; // 🛰️ 平均运动(圈/天) +line2 += '580'.padStart(5, ' '); +line2 += '9'; + +// console.debug(`xxxline2 :>>`, `"${line2}"`); +// console.debug('正确↓'); +// console.debug(`longstr2 :>>`, `"${longstr2}"`); +// twoline2satrecFake('', line2); +// twoline2satrecFake('', longstr2); +// const numbers = '0123456789'; +// twoline2satrecFake( +// `${numbers}${numbers}${numbers}${numbers}${numbers}${numbers}`, +// '', +// ); +const satrec2 = twoline2satrec( + `1 62949 25070.91668981 .00039463 00000+0 99294-3 `, + `2 53.1596 120.9032 0001355 101.1211 35.9659 15.39574303 `, +); const satrec1_str = JSON.stringify(satrec1, null, 2); const satrec2_str = JSON.stringify(satrec2, null, 2); -if ($__DEV__) console.debug(`satrec1_str === satrec2_str :>> `, satrec1_str === satrec2_str); +if ($__DEV__) console.debug(`satrec1_str === satrec2_str :>>`, satrec1_str === satrec2_str); // longstr1.substring(2, 7) :>> "63157" // longstr1.substring(18, 20) :>> "25"