From 64d563e203b121a93b7d5a529495c21453121d3b Mon Sep 17 00:00:00 2001 From: DanMat Date: Wed, 19 Aug 2026 13:07:52 -0400 Subject: [PATCH] fix: respect an explicit zero observer/timestamp in getSatelliteInfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getSatelliteInfo used `observerLat || default` (and the same for lng, height, and rawTimestamp), so an explicitly-passed 0 — a valid observer at the equator / prime meridian / sea level, or the Unix epoch — was silently replaced by the default Santa Cruz observer. The function's own docstring example passes elevation 0, so the documented usage hit this. Use nullish coalescing (??) so only undefined falls back to the default. Adds a regression test. --- __tests__/sgp4.js | 14 ++++++++++++++ src/sgp4.js | 8 ++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/__tests__/sgp4.js b/__tests__/sgp4.js index 122a72d..d6f4ff6 100644 --- a/__tests__/sgp4.js +++ b/__tests__/sgp4.js @@ -473,3 +473,17 @@ describe('getVisibleSatellites', () => { expect(allVisible.length).toEqual(1); }); }); + +describe('getSatelliteInfo observer defaults', () => { + test('respects an explicit observer at (0, 0, 0)', () => { + // A falsy check (`observerLat || default`) previously replaced an + // explicit 0 (equator / prime meridian / sea level) with the default + // observer, so an explicit origin observer must match a near-origin one. + const timestamp = 1501039265000; + const atOrigin = getSatelliteInfo(tleStr, timestamp, 0, 0, 0); + const nearOrigin = getSatelliteInfo(tleStr, timestamp, 1e-7, 1e-7, 1e-7); + expect(atOrigin.azimuth).toBeCloseTo(nearOrigin.azimuth, 4); + expect(atOrigin.elevation).toBeCloseTo(nearOrigin.elevation, 4); + expect(atOrigin.range).toBeCloseTo(nearOrigin.range, 2); + }); +}); diff --git a/src/sgp4.js b/src/sgp4.js index 12587e9..daac5db 100644 --- a/src/sgp4.js +++ b/src/sgp4.js @@ -84,7 +84,7 @@ export function clearCache() { * TODO: return error instead of throwing? */ export function getSatelliteInfo(rawTLE, rawTimestamp, observerLat, observerLng, observerHeight) { - const timestamp = rawTimestamp || Date.now(); + const timestamp = rawTimestamp ?? Date.now(); const { tle, error: parseError } = parseTLE(rawTLE); @@ -98,9 +98,9 @@ export function getSatelliteInfo(rawTLE, rawTimestamp, observerLat, observerLng, height: 0.37, }; - const obsLat = observerLat || defaultObserverPosition.lat; - const obsLng = observerLng || defaultObserverPosition.lng; - const obsHeight = observerHeight || defaultObserverPosition.height; + const obsLat = observerLat ?? defaultObserverPosition.lat; + const obsLng = observerLng ?? defaultObserverPosition.lng; + const obsHeight = observerHeight ?? defaultObserverPosition.height; // Memoization const cacheKey = `${tle[0]}-${timestamp}-${observerLat}-${observerLng}