pg_orrery/test/expected/tle_parse.out
Ryan Malloy 3915d1784f Rename pg_orbit to pg_orrery
An existing product called PG Orbit (a mobile PostgreSQL client)
creates a naming conflict. pg_orrery — a database orrery built from
Keplerian parameters and SQL instead of brass gears.

Build system: control file, Makefile, Dockerfile, docker init script.
C source: GUC prefix, PG_FUNCTION_INFO_V1 symbol, header guards,
ereport prefixes, comments across ~30 files including vendored SGP4.
SQL: all 5 install/migration scripts, function name pg_orrery_ephemeris_info.
Tests: 9 SQL suites, 8 expected outputs, standalone DE reader test.
Documentation: CLAUDE.md, README.md, DESIGN.md, Starlight site infra,
36 MDX pages, OG renderer, logo SVG, docker-compose, agent threads.

All 13 regression suites pass. Docs site builds (37 pages).
2026-02-17 13:36:22 -07:00

117 lines
3.7 KiB
Plaintext

-- Test TLE type: parsing, round-trip, accessors
CREATE EXTENSION IF NOT EXISTS pg_orrery;
-- Parse a valid ISS TLE
SELECT '1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9025
2 25544 51.6400 208.9163 0006703 30.1694 61.7520 15.50100486 00001'::tle IS NOT NULL AS parse_ok;
parse_ok
----------
t
(1 row)
-- Accessor functions
WITH iss AS (
SELECT '1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9025
2 25544 51.6400 208.9163 0006703 30.1694 61.7520 15.50100486 00001'::tle AS t
)
SELECT
tle_norad_id(t) AS norad_id,
round(tle_inclination(t)::numeric, 4) AS inc_deg,
round(tle_eccentricity(t)::numeric, 7) AS ecc,
round(tle_mean_motion(t)::numeric, 8) AS mm_rev_day,
round(tle_period(t)::numeric, 2) AS period_min,
round(tle_perigee(t)::numeric, 1) AS perigee_km,
round(tle_apogee(t)::numeric, 1) AS apogee_km,
tle_intl_desig(t) AS cospar
FROM iss;
norad_id | inc_deg | ecc | mm_rev_day | period_min | perigee_km | apogee_km | cospar
----------+---------+-----------+-------------+------------+------------+-----------+----------
25544 | 51.6400 | 0.0006703 | 15.50100486 | 92.90 | 411.9 | 421.0 | 98067A
(1 row)
-- Observer type parsing
SELECT '40.0N 105.3W 1655m'::observer IS NOT NULL AS observer_ok;
observer_ok
-------------
t
(1 row)
SELECT observer_lat('40.0N 105.3W 1655m'::observer) AS lat,
observer_lon('40.0N 105.3W 1655m'::observer) AS lon;
lat | lon
-----+--------
40 | -105.3
(1 row)
-- ECI type parsing
SELECT '(1000.0,2000.0,3000.0,1.0,2.0,3.0)'::eci_position IS NOT NULL AS eci_ok;
eci_ok
--------
t
(1 row)
SELECT eci_x('(1000.0,2000.0,3000.0,1.0,2.0,3.0)'::eci_position) AS x;
x
------
1000
(1 row)
-- SGP4 propagation at epoch
WITH iss AS (
SELECT '1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9025
2 25544 51.6400 208.9163 0006703 30.1694 61.7520 15.50100486 00001'::tle AS t
)
SELECT
round(eci_speed(sgp4_propagate(t, '2024-01-01 12:00:00+00'))::numeric, 2) AS speed_kms,
round(eci_altitude(sgp4_propagate(t, '2024-01-01 12:00:00+00'))::numeric, 0) AS alt_km
FROM iss;
speed_kms | alt_km
-----------+--------
7.67 | 407
(1 row)
-- Altitude overlap operator
WITH sats AS (
SELECT '1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9025
2 25544 51.6400 208.9163 0006703 30.1694 61.7520 15.50100486 00001'::tle AS iss,
'1 28874U 05038A 24001.50000000 .00000012 00000+0 00000+0 0 9993
2 28874 55.4408 300.3467 0117034 51.6543 309.5420 2.00557079 00006'::tle AS gps
)
SELECT
iss && iss AS same_overlap,
iss && gps AS different_no_overlap
FROM sats;
same_overlap | different_no_overlap
--------------+----------------------
t | f
(1 row)
-- Subsatellite point
WITH iss AS (
SELECT '1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9025
2 25544 51.6400 208.9163 0006703 30.1694 61.7520 15.50100486 00001'::tle AS t
)
SELECT
round(geodetic_lat(subsatellite_point(t, '2024-01-01 12:00:00+00'))::numeric, 2) AS lat,
round(geodetic_alt(subsatellite_point(t, '2024-01-01 12:00:00+00'))::numeric, 0) AS alt_km
FROM iss;
lat | alt_km
-------+--------
51.75 | 420
(1 row)
-- GiST index creation
CREATE TABLE test_sats (id serial, tle tle);
INSERT INTO test_sats (tle) VALUES (
'1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9025
2 25544 51.6400 208.9163 0006703 30.1694 61.7520 15.50100486 00001');
CREATE INDEX test_sats_gist ON test_sats USING gist (tle);
SELECT count(*) FROM test_sats WHERE tle && (
'1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9025
2 25544 51.6400 208.9163 0006703 30.1694 61.7520 15.50100486 00001'::tle);
count
-------
1
(1 row)
DROP TABLE test_sats;