mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 03:14:00 +00:00
Merge pull request #1101 from VG31OP/fix/tle-catalog-matching
fix(satellites): reject TLE pairs with mismatched catalog numbers (#906, #936)
This commit is contained in:
4 files changed
+67
-5
No files matched your search
@@ -0,0 +1,3 @@
|
|||||||
|
- Skip TLE sets whose line 1 and line 2 carry different catalog numbers, so a
|
||||||
|
spliced catalog cannot pair one satellite's elements with another's; the next
|
||||||
|
valid set still parses (VG31OP, #1101).
|
||||||
@@ -1474,7 +1474,10 @@ access. Callers retain validation, transport and response policy.
|
|||||||
|
|
||||||
The shared TLE text parser skips incomplete named sets and resumes at the next
|
The shared TLE text parser skips incomplete named sets and resumes at the next
|
||||||
complete set. A missing orbital line does not discard the later satellites in
|
complete set. A missing orbital line does not discard the later satellites in
|
||||||
the catalog; satellite layers and next-pass tools use the same parser.
|
the catalog. A set whose two lines carry different catalog numbers, or a
|
||||||
|
malformed catalog number, is skipped the same way, so a spliced catalog cannot
|
||||||
|
pair one satellite's elements with another's. Satellite layers and next-pass
|
||||||
|
tools use the same parser.
|
||||||
|
|
||||||
## Build configuration and local provider boundaries
|
## Build configuration and local provider boundaries
|
||||||
|
|
||||||
|
|||||||
+11
-4
@@ -13,7 +13,14 @@ export function parseTleText(text) {
|
|||||||
const name = lines[i];
|
const name = lines[i];
|
||||||
const line1 = lines[i + 1];
|
const line1 = lines[i + 1];
|
||||||
const line2 = lines[i + 2];
|
const line2 = lines[i + 2];
|
||||||
if (line1.startsWith('1 ') && line2.startsWith('2 ')) {
|
const cat1 = tleCatalogNumber(line1);
|
||||||
|
const cat2 = tleCatalogNumber(line2);
|
||||||
|
if (
|
||||||
|
line1.startsWith('1 ') &&
|
||||||
|
line2.startsWith('2 ') &&
|
||||||
|
cat1 !== null &&
|
||||||
|
cat1 === cat2
|
||||||
|
) {
|
||||||
result.push({ name, line1, line2 });
|
result.push({ name, line1, line2 });
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
@@ -60,8 +67,8 @@ export function noradIdFromSatnum(satnum) {
|
|||||||
return decodeCatalogField(String(satnum ?? '').trim()) ?? Number.NaN;
|
return decodeCatalogField(String(satnum ?? '').trim()) ?? Number.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The NORAD catalog number from TLE line 1 (columns 3–7), or null. */
|
/** The NORAD catalog number from TLE line 1 or 2 (columns 3–7), or null. */
|
||||||
export function tleCatalogNumber(line1) {
|
export function tleCatalogNumber(line) {
|
||||||
const field = String(line1).slice(2, 7);
|
const field = String(line).slice(2, 7);
|
||||||
return decodeCatalogField(field.replace(/^ +/, ''));
|
return decodeCatalogField(field.replace(/^ +/, ''));
|
||||||
}
|
}
|
||||||
@@ -56,6 +56,55 @@ for (const missingLine of [1, 2]) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test('TLE parsing rejects pairs with mismatched catalog numbers and resumes', () => {
|
||||||
|
const text = `SAT A
|
||||||
|
1 25544U 98067A 24001.50000000 .00016717 00000-0 30270-3 0 9994
|
||||||
|
2 48274 41.4697 175.8913 0005643 312.8370 141.6893 15.61287398150000
|
||||||
|
SAT B
|
||||||
|
1 48274U 21035A 24001.50000000 .00020137 00000-0 24481-3 0 9993
|
||||||
|
2 48274 41.4697 175.8913 0005643 312.8370 141.6893 15.61287398150000
|
||||||
|
`;
|
||||||
|
const entries = parseTleText(text);
|
||||||
|
assert.deepEqual(
|
||||||
|
entries.map((entry) => entry.name),
|
||||||
|
['SAT B'],
|
||||||
|
);
|
||||||
|
assert.equal(tleCatalogNumber(entries[0].line1), 48274);
|
||||||
|
assert.equal(tleCatalogNumber(entries[0].line2), 48274);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('TLE parsing accepts matching Alpha-5 pairs and rejects mismatched Alpha-5 pairs', () => {
|
||||||
|
const text = `SAT MISMATCH
|
||||||
|
1 A0000U 98067A 24001.50000000 .00016717 00000-0 30270-3 0 9994
|
||||||
|
2 A0001 41.4697 175.8913 0005643 312.8370 141.6893 15.61287398150000
|
||||||
|
SAT ALPHA5
|
||||||
|
1 A0000U 98067A 24001.50000000 .00016717 00000-0 30270-3 0 9994
|
||||||
|
2 A0000 41.4697 175.8913 0005643 312.8370 141.6893 15.61287398150000
|
||||||
|
`;
|
||||||
|
const entries = parseTleText(text);
|
||||||
|
assert.deepEqual(
|
||||||
|
entries.map((entry) => entry.name),
|
||||||
|
['SAT ALPHA5'],
|
||||||
|
);
|
||||||
|
assert.equal(tleCatalogNumber(entries[0].line1), 100000);
|
||||||
|
assert.equal(tleCatalogNumber(entries[0].line2), 100000);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('TLE parsing rejects a pair whose catalog fields are malformed and resumes', () => {
|
||||||
|
// Read as digits up to the first non-digit, both fields would be 2554.
|
||||||
|
const text = `SAT MALFORMED
|
||||||
|
1 2554AU 98067A 24001.50000000 .00016717 00000-0 30270-3 0 9994
|
||||||
|
2 2554B 51.6416 247.4627 0006703 130.5360 325.0288 15.50377579432414
|
||||||
|
SAT HALF MALFORMED
|
||||||
|
1 2554AU 98067A 24001.50000000 .00016717 00000-0 30270-3 0 9994
|
||||||
|
2 02554 51.6416 247.4627 0006703 130.5360 325.0288 15.50377579432414
|
||||||
|
${TLE}`;
|
||||||
|
assert.deepEqual(
|
||||||
|
parseTleText(text).map((entry) => entry.name),
|
||||||
|
['ISS (ZARYA)', 'CSS (TIANHE)'],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test('Alpha-5 catalog numbers decode, skipping I and O', () => {
|
test('Alpha-5 catalog numbers decode, skipping I and O', () => {
|
||||||
for (const [field, id] of [
|
for (const [field, id] of [
|
||||||
['A0000', 100000],
|
['A0000', 100000],
|
||||||
|
|||||||
Reference in new issue
Block a user