mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
Read a satellite's launch year from one TLE parser
The catalog stored the designator on satrec.intldesg for internationalDesignatorYear, while the active-TLE lookup parsed the same columns with tleLineLaunchYear. Each catalog entry now keeps launchYear from tleLineLaunchYear, which moves to src/sources/tle.js beside the other TLE field readers, and internationalDesignatorYear goes. A blank designator now reads as an unknown year in both lookups; the active-TLE lookup read it as 2000.
This commit is contained in:
1 parent
bfeec17c81
commit
4779432e48
5 files changed
+46
-23
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import * as Cesium from 'cesium';
|
||||
import { twoline2satrec } from 'satellite.js';
|
||||
import { noradIdFromSatnum } from '../../sources/tle.js';
|
||||
import { noradIdFromSatnum, tleLineLaunchYear } from '../../sources/tle.js';
|
||||
import {
|
||||
DENSE_REFRESH_FRAMES,
|
||||
DENSE_GROUP_PATH,
|
||||
@@ -114,8 +114,6 @@ export function createCatalog({ state: layerState, services, parts, source }) {
|
||||
const entry = entries[i];
|
||||
const satrec = twoline2satrec(entry.line1, entry.line2);
|
||||
if (!satrec || satrec.error !== 0) continue;
|
||||
// satellite.js omits the designator the launch-year match reads.
|
||||
satrec.intldesg = entry.line1.slice(9, 17).trim();
|
||||
const noradId = noradIdFromSatnum(satrec.satnum);
|
||||
if (layerState._catalog.has(noradId)) continue; // core catalog keeps priority
|
||||
const pos = parts.orbits.propagatePosition(satrec, now);
|
||||
@@ -125,6 +123,7 @@ export function createCatalog({ state: layerState, services, parts, source }) {
|
||||
name: entry.name,
|
||||
satrec,
|
||||
group: 'dense',
|
||||
launchYear: tleLineLaunchYear(entry.line1),
|
||||
});
|
||||
const point = layerState._pointCollection.add({
|
||||
position: Cesium.Cartesian3.fromDegrees(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { twoline2satrec } from 'satellite.js';
|
||||
import * as Cesium from 'cesium';
|
||||
import { msg } from '../../i18n/index.js';
|
||||
import { noradIdFromSatnum } from '../../sources/tle.js';
|
||||
import { noradIdFromSatnum, tleLineLaunchYear } from '../../sources/tle.js';
|
||||
import { CATALOG_GROUPS, ISS_NORAD, POINT_STYLES } from './policy.js';
|
||||
|
||||
export function createIngestion({
|
||||
@@ -119,8 +119,6 @@ export function createIngestion({
|
||||
for (const entry of allEntries) {
|
||||
const satrec = twoline2satrec(entry.line1, entry.line2);
|
||||
if (!satrec || satrec.error !== 0) continue;
|
||||
// satellite.js omits the designator the launch-year match reads.
|
||||
satrec.intldesg = entry.line1.slice(9, 17).trim();
|
||||
|
||||
const noradId = noradIdFromSatnum(satrec.satnum);
|
||||
if (seen.has(noradId)) continue;
|
||||
@@ -131,6 +129,8 @@ export function createIngestion({
|
||||
name: entry.name,
|
||||
satrec,
|
||||
group: entry.group,
|
||||
// satellite.js does not keep the designator the year match reads.
|
||||
launchYear: tleLineLaunchYear(entry.line1),
|
||||
});
|
||||
|
||||
coreStale ||= entry.stale;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { parseTleText } from '../../sources/tle.js';
|
||||
import { parseTleText, tleLineLaunchYear } from '../../sources/tle.js';
|
||||
import { createIngestion } from './ingestion.js';
|
||||
import { createOrbits } from './orbits.js';
|
||||
|
||||
@@ -98,3 +98,24 @@ test('a mission payload does not match a loaded satellite from another launch ye
|
||||
assert.equal(track('2026-06-29T02:25:00Z')?.noradId, 69728);
|
||||
assert.equal(track('2030-06-29T02:25:00Z'), null);
|
||||
});
|
||||
|
||||
test('a satellite with a blank designator keeps matching by name', async (t) => {
|
||||
t.mock.method(console, 'log', () => {});
|
||||
t.mock.method(console, 'warn', () => {});
|
||||
const { state, update } = ingestionFor(
|
||||
[
|
||||
'SXM-11',
|
||||
'1 69728U 26208.65166678 .00000015 00000+0 00000+0 0 9990',
|
||||
'2 69728 0.0784 264.9826 0001797 240.4588 273.9506 1.00271527 440',
|
||||
].join('\n'),
|
||||
);
|
||||
await update();
|
||||
const { getSatelliteOrbitTrack } = createOrbits({ state });
|
||||
assert.equal(tleLineLaunchYear('1 69728U 26208.65166678'), null);
|
||||
assert.equal(
|
||||
getSatelliteOrbitTrack('Sirius SXM-11', {
|
||||
launchTime: '2030-06-29T02:25:00Z',
|
||||
})?.noradId,
|
||||
69728,
|
||||
);
|
||||
});
|
||||
@@ -8,7 +8,11 @@ import {
|
||||
twoline2satrec,
|
||||
} from 'satellite.js';
|
||||
import { findNextSatellitePass } from '../../data/satellitePass.js';
|
||||
import { noradIdFromSatnum, parseTleText } from '../../sources/tle.js';
|
||||
import {
|
||||
noradIdFromSatnum,
|
||||
parseTleText,
|
||||
tleLineLaunchYear,
|
||||
} from '../../sources/tle.js';
|
||||
import { ORBIT_PATH_STEPS, ISS_NORAD } from './policy.js';
|
||||
|
||||
export function createOrbits({ state: layerState, services, parts, source }) {
|
||||
@@ -258,13 +262,6 @@ export function createOrbits({ state: layerState, services, parts, source }) {
|
||||
return score;
|
||||
}
|
||||
|
||||
function internationalDesignatorYear(satrec) {
|
||||
const match = String(satrec?.intldesg || '').match(/^(\d{2})/);
|
||||
if (!match) return null;
|
||||
const shortYear = Number(match[1]);
|
||||
return shortYear >= 57 ? 1900 + shortYear : 2000 + shortYear;
|
||||
}
|
||||
|
||||
function lookupTleEntries(tleText) {
|
||||
if (tleText !== layerState._lookupTleText) {
|
||||
layerState._lookupTleText = tleText;
|
||||
@@ -273,12 +270,6 @@ export function createOrbits({ state: layerState, services, parts, source }) {
|
||||
return layerState._lookupTleEntries;
|
||||
}
|
||||
|
||||
function tleLineLaunchYear(line1) {
|
||||
const shortYear = Number(String(line1 || '').slice(9, 11));
|
||||
if (!Number.isFinite(shortYear)) return null;
|
||||
return shortYear >= 57 ? 1900 + shortYear : 2000 + shortYear;
|
||||
}
|
||||
|
||||
function orbitTrackFromRecord(name, satrec) {
|
||||
const referenceDate = new Date();
|
||||
const current = propagatePosition(satrec, referenceDate);
|
||||
@@ -350,7 +341,7 @@ export function createOrbits({ state: layerState, services, parts, source }) {
|
||||
: null;
|
||||
let bestScore = 0;
|
||||
for (const [id, sat] of layerState._catalog) {
|
||||
const designatorYear = internationalDesignatorYear(sat.satrec);
|
||||
const designatorYear = sat.launchYear ?? null;
|
||||
if (
|
||||
launchYear !== null &&
|
||||
designatorYear !== null &&
|
||||
@@ -379,7 +370,6 @@ export function createOrbits({ state: layerState, services, parts, source }) {
|
||||
getNextSatellitePass,
|
||||
resolveSatelliteForPass,
|
||||
scoreSatelliteNameMatch,
|
||||
internationalDesignatorYear,
|
||||
lookupTleEntries,
|
||||
tleLineLaunchYear,
|
||||
orbitTrackFromRecord,
|
||||
|
||||
@@ -72,3 +72,16 @@ export function tleCatalogNumber(line) {
|
||||
const field = String(line).slice(2, 7);
|
||||
return decodeCatalogField(field.replace(/^ +/, ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch year from TLE line 1's international designator (columns 10-11);
|
||||
* null when the designator is blank.
|
||||
* @param {string} line1
|
||||
* @returns {number|null}
|
||||
*/
|
||||
export function tleLineLaunchYear(line1) {
|
||||
const digits = String(line1 || '').slice(9, 11);
|
||||
if (!/^\d{2}$/.test(digits)) return null;
|
||||
const shortYear = Number(digits);
|
||||
return shortYear >= 57 ? 1900 + shortYear : 2000 + shortYear;
|
||||
}
|
||||
Reference in new issue
Block a user