pg_orrery/sql/pg_orrery--0.17.0--0.18.0.sql
Ryan Malloy b309980003 Add v0.18.0: Saturn ring tilt, penumbral eclipse, rise/set windows, angular rate
Four features, 10 new SQL functions (174 → 184 objects), 29 test suites:

Saturn ring tilt: saturn_ring_tilt() exposes sub-observer latitude B'.
planet_magnitude() for Saturn now includes Mallama & Hilton Eq. 10
ring correction (-2.60|sin B'| + 1.25 sin²B'), removing the ~1.5 mag
globe-only caveat. IAU 2000 pole direction, ecliptic J2000 projection.

Conical shadow model: Replaces cylindrical shadow with umbra/penumbra
cones using Sun's finite angular size. Four new functions:
satellite_in_penumbra(), satellite_shadow_state(),
satellite_next_penumbra_entry/exit(). Existing eclipse functions are
backward compatible via narrower (more accurate) umbra boundary.

Rise/set event windows: Three SRFs returning TABLE(event_time, event_type)
for all rise/set events within a time window — planet_rise_set_events(),
sun_rise_set_events(), moon_rise_set_events(). Follows predict_passes()
SRF pattern. Optional refracted parameter, 366-day window limit.

Angular separation rate: Vincenty formula extracted to reusable helper.
eq_angular_rate() for generic finite-difference rate, planet_angular_rate()
for solar system body convenience (1-minute dt, handles Sun/planets/Moon).
2026-02-27 23:52:06 -07:00

93 lines
4.7 KiB
SQL

-- pg_orrery 0.17.0 -> 0.18.0: Saturn ring tilt, penumbral eclipse,
-- rise/set event windows, angular separation rate
-- ============================================================
-- Saturn ring tilt (1)
-- ============================================================
CREATE FUNCTION saturn_ring_tilt(timestamptz) RETURNS float8
AS 'MODULE_PATHNAME', 'saturn_ring_tilt'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION saturn_ring_tilt(timestamptz) IS
'Sub-observer latitude B'' of Earth relative to Saturn ring plane (degrees, [-27, +27]). Uses IAU 2000 pole direction.';
-- ============================================================
-- Penumbral eclipse prediction (4)
-- ============================================================
CREATE FUNCTION satellite_in_penumbra(tle, timestamptz) RETURNS bool
AS 'MODULE_PATHNAME', 'satellite_in_penumbra'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION satellite_in_penumbra(tle, timestamptz) IS
'True if the satellite is in Earth penumbral shadow (partial sunlight) at the given time.';
CREATE FUNCTION satellite_shadow_state(tle, timestamptz) RETURNS text
AS 'MODULE_PATHNAME', 'satellite_shadow_state'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION satellite_shadow_state(tle, timestamptz) IS
'Shadow state of satellite: ''sunlit'', ''penumbra'', or ''umbra''. Uses conical shadow model.';
CREATE FUNCTION satellite_next_penumbra_entry(tle, timestamptz) RETURNS timestamptz
AS 'MODULE_PATHNAME', 'satellite_next_penumbra_entry'
LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION satellite_next_penumbra_entry(tle, timestamptz) IS
'Next time the satellite enters Earth penumbral shadow (up to 7-day search). NULL if none found.';
CREATE FUNCTION satellite_next_penumbra_exit(tle, timestamptz) RETURNS timestamptz
AS 'MODULE_PATHNAME', 'satellite_next_penumbra_exit'
LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION satellite_next_penumbra_exit(tle, timestamptz) IS
'Next time the satellite exits Earth penumbral shadow (up to 7-day search). NULL if none found.';
-- ============================================================
-- Rise/set event windows (3 SRFs)
-- ============================================================
CREATE FUNCTION planet_rise_set_events(
body_id int4, observer, start timestamptz, stop timestamptz,
refracted bool DEFAULT false
) RETURNS TABLE(event_time timestamptz, event_type text)
AS 'MODULE_PATHNAME', 'planet_rise_set_events'
LANGUAGE C STABLE STRICT PARALLEL SAFE
ROWS 10;
COMMENT ON FUNCTION planet_rise_set_events(int4, observer, timestamptz, timestamptz, bool) IS
'All rise and set events for a planet within a time window. Returns TABLE(event_time, event_type). Max 366-day window.';
CREATE FUNCTION sun_rise_set_events(
observer, start timestamptz, stop timestamptz,
refracted bool DEFAULT false
) RETURNS TABLE(event_time timestamptz, event_type text)
AS 'MODULE_PATHNAME', 'sun_rise_set_events'
LANGUAGE C STABLE STRICT PARALLEL SAFE
ROWS 10;
COMMENT ON FUNCTION sun_rise_set_events(observer, timestamptz, timestamptz, bool) IS
'All rise and set events for the Sun within a time window. Returns TABLE(event_time, event_type). Max 366-day window.';
CREATE FUNCTION moon_rise_set_events(
observer, start timestamptz, stop timestamptz,
refracted bool DEFAULT false
) RETURNS TABLE(event_time timestamptz, event_type text)
AS 'MODULE_PATHNAME', 'moon_rise_set_events'
LANGUAGE C STABLE STRICT PARALLEL SAFE
ROWS 10;
COMMENT ON FUNCTION moon_rise_set_events(observer, timestamptz, timestamptz, bool) IS
'All rise and set events for the Moon within a time window. Returns TABLE(event_time, event_type). Max 366-day window.';
-- ============================================================
-- Angular separation rate (2)
-- ============================================================
CREATE FUNCTION eq_angular_rate(
equatorial, equatorial, equatorial, equatorial, float8
) RETURNS float8
AS 'MODULE_PATHNAME', 'eq_angular_rate'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION eq_angular_rate(equatorial, equatorial, equatorial, equatorial, float8) IS
'Rate of change of angular separation (deg/hr). Args: pos1_t0, pos2_t0, pos1_t1, pos2_t1, dt_seconds. Positive = separating, negative = approaching.';
CREATE FUNCTION planet_angular_rate(int4, int4, timestamptz) RETURNS float8
AS 'MODULE_PATHNAME', 'planet_angular_rate'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION planet_angular_rate(int4, int4, timestamptz) IS
'Rate of angular separation change between two bodies (deg/hr). Body IDs: 0=Sun, 1-8=planets, 10=Moon. Uses 1-minute finite difference.';