feat(satellites): CelesTrak GP JSON satellites API with SGP4 propagation #43

Merged
sirius merged 4 commits from osint-dashboard/t_fe710941-osint-celestrak-get-api-satellites into master 2026-08-31 23:18:08 -04:00
Owner

Summary

New GET /api/satellites?groups=stations,weather overlay endpoint.

Fetches CelesTrak GP JSON (OMM mean elements, not TLE) at most once per 2 hours per group, caches the element blob, and propagates positions on every request with the real sgp4 library (TEME -> geodetic) — not two-body Kepler. The OMM path consumes the GP JSON fields verbatim via sgp4.omm.initialize, so NORAD catalog numbers >= 100000 work (no TLE round-trip).

Changes

  • app/satellites.py — parser + SGP4 propagation + 2h per-group TTL cache with a last-good blob fallback for 403 / "has not updated since" responses; SatNOGS TLE fallback only when the CelesTrak cache is empty.
  • GET /api/satellites — default groups stations,weather; optional gps-ops; starlink only when explicitly requested; bbox viewport culling; unknown group -> 400.
  • overlay_catalog() — new satellites entry (kind=points, endpoint /api/satellites).
  • app/requirements.txt — add sgp4>=2.23.

Tests

tests/test_satellites.py — parser on a tiny JSON fixture, 2h cache does not refetch, unknown group 400, bbox culling, SatNOGS fallback parser. Full suite: 192 passed, 17 skipped.

Live verify

  • Default groups: 96 satellites (stations+weather), source=celestrak.
  • gps-ops: 32 satellites.
  • bbox=-125,24,-66,50 (CONUS): all results within box.
  • groups=bogus -> HTTP 400.
## Summary New `GET /api/satellites?groups=stations,weather` overlay endpoint. Fetches CelesTrak GP **JSON** (OMM mean elements, not TLE) at most once per 2 hours per group, caches the element blob, and propagates positions on every request with the real `sgp4` library (TEME -> geodetic) — not two-body Kepler. The OMM path consumes the GP JSON fields verbatim via `sgp4.omm.initialize`, so NORAD catalog numbers >= 100000 work (no TLE round-trip). ## Changes - `app/satellites.py` — parser + SGP4 propagation + 2h per-group TTL cache with a last-good blob fallback for 403 / "has not updated since" responses; SatNOGS TLE fallback only when the CelesTrak cache is empty. - `GET /api/satellites` — default groups `stations,weather`; optional `gps-ops`; `starlink` only when explicitly requested; `bbox` viewport culling; unknown group -> 400. - `overlay_catalog()` — new `satellites` entry (kind=points, endpoint `/api/satellites`). - `app/requirements.txt` — add `sgp4>=2.23`. ## Tests `tests/test_satellites.py` — parser on a tiny JSON fixture, 2h cache does not refetch, unknown group 400, bbox culling, SatNOGS fallback parser. Full suite: 192 passed, 17 skipped. ## Live verify - Default groups: 96 satellites (stations+weather), source=celestrak. - `gps-ops`: 32 satellites. - `bbox=-125,24,-66,50` (CONUS): all results within box. - `groups=bogus` -> HTTP 400.
sirius added 1 commit 2026-08-31 21:41:35 -04:00
GET /api/satellites?groups=stations,weather returns last-known satellite
positions propagated from CelesTrak GP JSON (OMM mean elements, not TLE)
via the real sgp4 library (TEME->geodetic), not two-body Kepler.

- Fetch gp.php?GROUP=...&FORMAT=JSON at most once per 2h per group,
  cached with a last-good blob fallback for 403 / stale responses.
- SatNOGS TLE fallback only when the CelesTrak cache is empty.
- bbox viewport culling; unknown group -> 400.
- overlay_catalog() gains id=satellites (kind=points, /api/satellites).
- OMM path handles NORAD cat numbers >= 100000 (no TLE round-trip).
sirius added 1 commit 2026-08-31 22:11:07 -04:00
Keep both overlay_catalog entries: satellites (this PR) and
conflicts (already on master). Disjoint layers.
sirius added 1 commit 2026-08-31 22:26:23 -04:00
Keep /api/satellites (this PR) and /api/infrastructure from #36,
plus both overlay_catalog entries. Disjoint layers.
sirius added 1 commit 2026-08-31 23:13:10 -04:00
Keep satellites import (this PR) and place.reverse_geocode from #37.
sirius merged commit ef27e13e50 into master 2026-08-31 23:18:08 -04:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: sirius/osint-dashboard#43
No description provided.