-- Test coordinate transform functions CREATE EXTENSION IF NOT EXISTS pg_orrery; NOTICE: extension "pg_orrery" already exists, skipping -- Subsatellite point 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(geodetic_lat(subsatellite_point(t, '2024-01-01 12:00:00+00'))::numeric, 2) AS lat, round(geodetic_lon(subsatellite_point(t, '2024-01-01 12:00:00+00'))::numeric, 2) AS lon, round(geodetic_alt(subsatellite_point(t, '2024-01-01 12:00:00+00'))::numeric, 0) AS alt_km FROM iss; lat | lon | alt_km -------+-------+-------- 51.75 | 21.48 | 420 (1 row) -- Subsatellite point 30 minutes later 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:30:00+00'))::numeric, 2) AS lat_30m, round(geodetic_lon(subsatellite_point(t, '2024-01-01 12:30:00+00'))::numeric, 2) AS lon_30m, round(geodetic_alt(subsatellite_point(t, '2024-01-01 12:30:00+00'))::numeric, 0) AS alt_30m FROM iss; lat_30m | lon_30m | alt_30m ---------+---------+--------- -21.98 | 119.17 | 427 (1 row) -- eci_to_geodetic: propagate ISS then convert 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(eci_to_geodetic(sgp4_propagate(t, '2024-01-01 12:00:00+00'), '2024-01-01 12:00:00+00'))::numeric, 2) AS eci_lat, round(geodetic_lon(eci_to_geodetic(sgp4_propagate(t, '2024-01-01 12:00:00+00'), '2024-01-01 12:00:00+00'))::numeric, 2) AS eci_lon, round(geodetic_alt(eci_to_geodetic(sgp4_propagate(t, '2024-01-01 12:00:00+00'), '2024-01-01 12:00:00+00'))::numeric, 0) AS eci_alt FROM iss; eci_lat | eci_lon | eci_alt ---------+---------+--------- 51.75 | 21.48 | 420 (1 row) -- Topocentric from Boulder, CO 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(topo_azimuth(eci_to_topocentric(sgp4_propagate(t, '2024-01-01 12:00:00+00'), '40.0N 105.3W 1655m'::observer, '2024-01-01 12:00:00+00'))::numeric, 1) AS az_deg, round(topo_elevation(eci_to_topocentric(sgp4_propagate(t, '2024-01-01 12:00:00+00'), '40.0N 105.3W 1655m'::observer, '2024-01-01 12:00:00+00'))::numeric, 1) AS el_deg, round(topo_range(eci_to_topocentric(sgp4_propagate(t, '2024-01-01 12:00:00+00'), '40.0N 105.3W 1655m'::observer, '2024-01-01 12:00:00+00'))::numeric, 0) AS range_km FROM iss; az_deg | el_deg | range_km --------+--------+---------- 30.6 | -36.4 | 8245 (1 row) -- Ground track: 5 points over 40 minutes 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 count(*) AS track_points, round(min(lat)::numeric, 0) AS min_lat, round(max(lat)::numeric, 0) AS max_lat FROM iss, ground_track(t, '2024-01-01 12:00:00+00', '2024-01-01 12:40:00+00', '10 minutes'); track_points | min_lat | max_lat --------------+---------+--------- 5 | -46 | 52 (1 row) -- Geodetic type I/O round-trip SELECT geodetic_lat('(51.75, 21.48, 420.0)'::geodetic) AS lat, geodetic_lon('(51.75, 21.48, 420.0)'::geodetic) AS lon, geodetic_alt('(51.75, 21.48, 420.0)'::geodetic) AS alt; lat | lon | alt -------+-------+----- 51.75 | 21.48 | 420 (1 row) -- Topocentric type I/O round-trip SELECT round(topo_azimuth('(45.0, 30.0, 500.0, -2.5)'::topocentric)::numeric, 1) AS az, round(topo_elevation('(45.0, 30.0, 500.0, -2.5)'::topocentric)::numeric, 1) AS el, round(topo_range('(45.0, 30.0, 500.0, -2.5)'::topocentric)::numeric, 1) AS rng, round(topo_range_rate('(45.0, 30.0, 500.0, -2.5)'::topocentric)::numeric, 1) AS rr; az | el | rng | rr ------+------+-------+------ 45.0 | 30.0 | 500.0 | -2.5 (1 row) -- ISS latitude should stay within inclination bounds (51.64 deg) 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 abs(geodetic_lat(subsatellite_point(t, '2024-01-01 12:00:00+00'))) <= 52.0 AS within_inc FROM iss; within_inc ------------ t (1 row)