v0.14.0: refracted planet/moon rise/set, constellation identification
Add 4 refracted rise/set functions completing the rise/set feature set: - planet_next_rise/set_refracted: -0.569 deg threshold (refraction only, point source — even Jupiter at opposition is only 24 arcsec) - moon_next_rise/set_refracted: -0.833 deg threshold (refraction + mean semidiameter, same as Sun) Add IAU constellation identification from Roman (1987) CDS VI/42: - 357 boundary segments covering all 88 constellations - Precesses J2000 coordinates to B1875.0 epoch for lookup - Two overloads: constellation(equatorial) and constellation(float8, float8) - IMMUTABLE (compiled-in static data) 141 -> 147 SQL objects. 24 -> 25 regression suites. All 25 pass.
This commit is contained in:
parent
55c0bf6b8b
commit
8ca4383b2e
30
CLAUDE.md
30
CLAUDE.md
@ -1,9 +1,9 @@
|
|||||||
# pg_orrery — A Database Orrery for PostgreSQL
|
# pg_orrery — A Database Orrery for PostgreSQL
|
||||||
|
|
||||||
## What This Is
|
## What This Is
|
||||||
A database orrery — celestial mechanics types and functions for PostgreSQL. Native C extension using PGXS, 132 SQL objects (124 user-visible functions + 8 GiST support), 9 custom types, covering satellites (SGP4/SDP4), planets (VSOP87 + optional JPL DE441), Moon (ELP2000-82B), 19 planetary moons (L1.2/TASS17/GUST86/MarsSat), stars (with proper motion and annual parallax), comets, asteroids (MPC catalog), Jupiter radio bursts, interplanetary Lambert transfers, equatorial RA/Dec coordinates with GiST-indexed angular separation, atmospheric refraction, annual stellar aberration, and light-time correction.
|
A database orrery — celestial mechanics types and functions for PostgreSQL. Native C extension using PGXS, 147 SQL objects (131 user-visible functions + 16 GiST support), 9 custom types, covering satellites (SGP4/SDP4), planets (VSOP87 + optional JPL DE441), Moon (ELP2000-82B), 19 planetary moons (L1.2/TASS17/GUST86/MarsSat), stars (with proper motion and annual parallax), comets, asteroids (MPC catalog), Jupiter radio bursts, interplanetary Lambert transfers, equatorial RA/Dec coordinates with GiST-indexed angular separation, atmospheric refraction, annual stellar aberration, light-time correction, rise/set prediction (geometric + refracted), and IAU constellation identification (Roman 1987).
|
||||||
|
|
||||||
**Current version:** 0.12.0
|
**Current version:** 0.14.0
|
||||||
**Repository:** https://git.supported.systems/warehack.ing/pg_orrery
|
**Repository:** https://git.supported.systems/warehack.ing/pg_orrery
|
||||||
**Documentation:** https://pg-orrery.warehack.ing
|
**Documentation:** https://pg-orrery.warehack.ing
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ A database orrery — celestial mechanics types and functions for PostgreSQL. Na
|
|||||||
```bash
|
```bash
|
||||||
make PG_CONFIG=/usr/bin/pg_config # Compile with PGXS
|
make PG_CONFIG=/usr/bin/pg_config # Compile with PGXS
|
||||||
sudo make install PG_CONFIG=/usr/bin/pg_config # Install extension
|
sudo make install PG_CONFIG=/usr/bin/pg_config # Install extension
|
||||||
make installcheck PG_CONFIG=/usr/bin/pg_config # Run 22 regression test suites
|
make installcheck PG_CONFIG=/usr/bin/pg_config # Run 25 regression test suites
|
||||||
```
|
```
|
||||||
|
|
||||||
Requires: PostgreSQL 17 development headers, GCC, Make.
|
Requires: PostgreSQL 17 development headers, GCC, Make.
|
||||||
@ -27,7 +27,7 @@ Image: `git.supported.systems/warehack.ing/pg_orrery:pg17`
|
|||||||
|
|
||||||
## Project Layout
|
## Project Layout
|
||||||
```
|
```
|
||||||
pg_orrery.control # Extension metadata (version 0.12.0)
|
pg_orrery.control # Extension metadata (version 0.14.0)
|
||||||
Makefile # PGXS build + Docker targets
|
Makefile # PGXS build + Docker targets
|
||||||
sql/
|
sql/
|
||||||
pg_orrery--0.1.0.sql # v0.1.0: satellite types/functions/operators
|
pg_orrery--0.1.0.sql # v0.1.0: satellite types/functions/operators
|
||||||
@ -42,6 +42,8 @@ sql/
|
|||||||
pg_orrery--0.10.0.sql # v0.10.0: angular separation, cone search, apparent functions (114 functions)
|
pg_orrery--0.10.0.sql # v0.10.0: angular separation, cone search, apparent functions (114 functions)
|
||||||
pg_orrery--0.11.0.sql # v0.11.0: orbital_elements constructors, moon equatorial (120 functions)
|
pg_orrery--0.11.0.sql # v0.11.0: orbital_elements constructors, moon equatorial (120 functions)
|
||||||
pg_orrery--0.12.0.sql # v0.12.0: equatorial GiST, DE moon equatorial (132 objects)
|
pg_orrery--0.12.0.sql # v0.12.0: equatorial GiST, DE moon equatorial (132 objects)
|
||||||
|
pg_orrery--0.13.0.sql # v0.13.0: nutation, make_equatorial, rise/set (141 objects)
|
||||||
|
pg_orrery--0.14.0.sql # v0.14.0: refracted rise/set, constellation ID (147 objects)
|
||||||
pg_orrery--0.1.0--0.2.0.sql # Migration: v0.1.0 → v0.2.0 (adds solar system)
|
pg_orrery--0.1.0--0.2.0.sql # Migration: v0.1.0 → v0.2.0 (adds solar system)
|
||||||
pg_orrery--0.2.0--0.3.0.sql # Migration: v0.2.0 → v0.3.0 (adds DE ephemeris)
|
pg_orrery--0.2.0--0.3.0.sql # Migration: v0.2.0 → v0.3.0 (adds DE ephemeris)
|
||||||
pg_orrery--0.3.0--0.4.0.sql # Migration: v0.3.0 → v0.4.0
|
pg_orrery--0.3.0--0.4.0.sql # Migration: v0.3.0 → v0.4.0
|
||||||
@ -53,6 +55,8 @@ sql/
|
|||||||
pg_orrery--0.9.0--0.10.0.sql # Migration: v0.9.0 → v0.10.0 (angular separation, cone search)
|
pg_orrery--0.9.0--0.10.0.sql # Migration: v0.9.0 → v0.10.0 (angular separation, cone search)
|
||||||
pg_orrery--0.10.0--0.11.0.sql # Migration: v0.10.0 → v0.11.0 (constructors, moon equatorial)
|
pg_orrery--0.10.0--0.11.0.sql # Migration: v0.10.0 → v0.11.0 (constructors, moon equatorial)
|
||||||
pg_orrery--0.11.0--0.12.0.sql # Migration: v0.11.0 → v0.12.0 (equatorial GiST, DE moon equatorial)
|
pg_orrery--0.11.0--0.12.0.sql # Migration: v0.11.0 → v0.12.0 (equatorial GiST, DE moon equatorial)
|
||||||
|
pg_orrery--0.12.0--0.13.0.sql # Migration: v0.12.0 → v0.13.0 (nutation, make_equatorial, rise/set)
|
||||||
|
pg_orrery--0.13.0--0.14.0.sql # Migration: v0.13.0 → v0.14.0 (refracted rise/set, constellation ID)
|
||||||
src/
|
src/
|
||||||
pg_orrery.c # PG_MODULE_MAGIC + _PG_init() (GUC registration)
|
pg_orrery.c # PG_MODULE_MAGIC + _PG_init() (GUC registration)
|
||||||
types.h # All struct definitions + constants + DE body ID mapping
|
types.h # All struct definitions + constants + DE body ID mapping
|
||||||
@ -79,6 +83,9 @@ src/
|
|||||||
orbital_elements_type.c # orbital_elements type, MPC parser, small_body_observe/equatorial/apparent()
|
orbital_elements_type.c # orbital_elements type, MPC parser, small_body_observe/equatorial/apparent()
|
||||||
equatorial_funcs.c # equatorial type I/O, accessors, satellite/planet/sun/moon RA/Dec
|
equatorial_funcs.c # equatorial type I/O, accessors, satellite/planet/sun/moon RA/Dec
|
||||||
refraction_funcs.c # atmospheric_refraction(), _ext(), topo_elevation_apparent()
|
refraction_funcs.c # atmospheric_refraction(), _ext(), topo_elevation_apparent()
|
||||||
|
rise_set_funcs.c # planet/sun/moon rise/set (geometric + refracted)
|
||||||
|
constellation_data.h / .c # Roman (1987) IAU boundary table (CDS VI/42, 357 segments)
|
||||||
|
constellation_funcs.c # constellation() from equatorial or RA/Dec
|
||||||
l12.c / l12.h # L1.2 Galilean moon theory (Lieske 1998)
|
l12.c / l12.h # L1.2 Galilean moon theory (Lieske 1998)
|
||||||
tass17.c / tass17.h # TASS 1.7 Saturn moon theory (Vienne & Duriez 1995)
|
tass17.c / tass17.h # TASS 1.7 Saturn moon theory (Vienne & Duriez 1995)
|
||||||
gust86.c / gust86.h # GUST86 Uranus moon theory (Laskar & Jacobson 1987)
|
gust86.c / gust86.h # GUST86 Uranus moon theory (Laskar & Jacobson 1987)
|
||||||
@ -103,7 +110,7 @@ src/
|
|||||||
PROVENANCE.md # Vendoring decision, modifications, verification
|
PROVENANCE.md # Vendoring decision, modifications, verification
|
||||||
LICENSE # MIT license (Bill Gray / Project Pluto)
|
LICENSE # MIT license (Bill Gray / Project Pluto)
|
||||||
test/
|
test/
|
||||||
sql/ # 22 regression test suites
|
sql/ # 25 regression test suites
|
||||||
expected/ # Expected output
|
expected/ # Expected output
|
||||||
data/vallado_518.json # 518 Vallado test vectors (AIAA 2006-6753-Rev1)
|
data/vallado_518.json # 518 Vallado test vectors (AIAA 2006-6753-Rev1)
|
||||||
docs/
|
docs/
|
||||||
@ -130,7 +137,7 @@ All types are fixed-size, `STORAGE = plain`, `ALIGNMENT = double`. No TOAST over
|
|||||||
| `orbital_elements` | 72 | Classical Keplerian elements for comets/asteroids (epoch, q, e, inc, omega, Omega, tp, H, G) |
|
| `orbital_elements` | 72 | Classical Keplerian elements for comets/asteroids (epoch, q, e, inc, omega, Omega, tp, H, G) |
|
||||||
| `equatorial` | 24 | Apparent RA (hours), Dec (degrees), distance (km) — of date |
|
| `equatorial` | 24 | Apparent RA (hours), Dec (degrees), distance (km) — of date |
|
||||||
|
|
||||||
## Function Domains (132 SQL objects)
|
## Function Domains (147 SQL objects)
|
||||||
|
|
||||||
| Domain | Theory | Key Functions | Count |
|
| Domain | Theory | Key Functions | Count |
|
||||||
|--------|--------|---------------|-------|
|
|--------|--------|---------------|-------|
|
||||||
@ -147,6 +154,8 @@ All types are fixed-size, `STORAGE = plain`, `ALIGNMENT = double`. No TOAST over
|
|||||||
| DE ephemeris | JPL DE440/441 (optional) | `planet_observe_de()`, `*_equatorial_de()`, `*_apparent_de()` | 23 |
|
| DE ephemeris | JPL DE440/441 (optional) | `planet_observe_de()`, `*_equatorial_de()`, `*_apparent_de()` | 23 |
|
||||||
| GiST index (TLE) | Altitude-band approximation | `&&` (overlap), `<->` (distance) | 8 |
|
| GiST index (TLE) | Altitude-band approximation | `&&` (overlap), `<->` (distance) | 8 |
|
||||||
| GiST index (equatorial) | Spherical bounding box | `<->` (KNN ordering) | 8 |
|
| GiST index (equatorial) | Spherical bounding box | `<->` (KNN ordering) | 8 |
|
||||||
|
| Rise/set | Bisection (60s scan) | `planet_next_rise()`, `sun_next_rise_refracted()`, `moon_next_set_refracted()` | 12 |
|
||||||
|
| Constellation | Roman (1987) CDS VI/42 | `constellation()` (equatorial + RA/Dec overloads) | 2 |
|
||||||
| Diagnostics | -- | `pg_orrery_ephemeris_info()` | 1 |
|
| Diagnostics | -- | `pg_orrery_ephemeris_info()` | 1 |
|
||||||
|
|
||||||
All functions are `PARALLEL SAFE`. VSOP87/ELP82B functions are `IMMUTABLE` (compiled-in coefficients). DE functions are `STABLE` (external file dependency).
|
All functions are `PARALLEL SAFE`. VSOP87/ELP82B functions are `IMMUTABLE` (compiled-in coefficients). DE functions are `STABLE` (external file dependency).
|
||||||
@ -280,7 +289,7 @@ All numerical logic is byte-identical to upstream. Verified against 518 Vallado
|
|||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
22 regression test suites via `make installcheck`:
|
25 regression test suites via `make installcheck`:
|
||||||
|
|
||||||
| Suite | What it tests |
|
| Suite | What it tests |
|
||||||
|-------|--------------|
|
|-------|--------------|
|
||||||
@ -306,10 +315,13 @@ All numerical logic is byte-identical to upstream. Verified against 518 Vallado
|
|||||||
| v011_features | make_orbital_elements constructors, moon equatorial functions |
|
| v011_features | make_orbital_elements constructors, moon equatorial functions |
|
||||||
| gist_equatorial | Equatorial GiST KNN ordering, RA wrapping, cone search, EXPLAIN index scan |
|
| gist_equatorial | Equatorial GiST KNN ordering, RA wrapping, cone search, EXPLAIN index scan |
|
||||||
| v012_features | DE moon equatorial fallback to VSOP87, invalid body_id rejection |
|
| v012_features | DE moon equatorial fallback to VSOP87, invalid body_id rejection |
|
||||||
|
| v013_features | Nutation correction, make_equatorial constructor |
|
||||||
|
| rise_set | Planet/Sun/Moon rise/set (geometric + refracted), circumpolar, polar night |
|
||||||
|
| constellation | Roman (1987) boundary lookup, known stars, solar system objects, edge cases |
|
||||||
|
|
||||||
### PG Version Matrix
|
### PG Version Matrix
|
||||||
|
|
||||||
Test all 22 regression suites + DE reader unit test across PostgreSQL 14-18 using Docker:
|
Test all 25 regression suites + DE reader unit test across PostgreSQL 14-18 using Docker:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make test-matrix # Full matrix (PG 14-18)
|
make test-matrix # Full matrix (PG 14-18)
|
||||||
@ -335,7 +347,7 @@ Logs saved to `test/matrix-logs/pg${ver}.log`. The script reuses the Dockerfile
|
|||||||
|
|
||||||
Starlight docs at `docs/` — 44+ MDX pages covering all domains.
|
Starlight docs at `docs/` — 44+ MDX pages covering all domains.
|
||||||
|
|
||||||
Sections: Getting Started, Guides (9 domain walkthroughs incl. DE ephemeris), Workflow Translation (Skyfield/Horizons/GMAT/Radio Jupiter Pro comparisons), Reference (all 132 SQL objects incl. DE variants, equatorial GiST, refraction), Architecture (Hamilton's principles, constant custody, observation pipeline), Performance (benchmarks).
|
Sections: Getting Started, Guides (9 domain walkthroughs incl. DE ephemeris), Workflow Translation (Skyfield/Horizons/GMAT/Radio Jupiter Pro comparisons), Reference (all 147 SQL objects incl. DE variants, equatorial GiST, refraction, rise/set, constellation), Architecture (Hamilton's principles, constant custody, observation pipeline), Performance (benchmarks).
|
||||||
|
|
||||||
### Local Development
|
### Local Development
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
9
Makefile
9
Makefile
@ -11,7 +11,8 @@ DATA = sql/pg_orrery--0.1.0.sql sql/pg_orrery--0.2.0.sql sql/pg_orrery--0.1.0--0
|
|||||||
sql/pg_orrery--0.10.0.sql sql/pg_orrery--0.9.0--0.10.0.sql \
|
sql/pg_orrery--0.10.0.sql sql/pg_orrery--0.9.0--0.10.0.sql \
|
||||||
sql/pg_orrery--0.11.0.sql sql/pg_orrery--0.10.0--0.11.0.sql \
|
sql/pg_orrery--0.11.0.sql sql/pg_orrery--0.10.0--0.11.0.sql \
|
||||||
sql/pg_orrery--0.12.0.sql sql/pg_orrery--0.11.0--0.12.0.sql \
|
sql/pg_orrery--0.12.0.sql sql/pg_orrery--0.11.0--0.12.0.sql \
|
||||||
sql/pg_orrery--0.13.0.sql sql/pg_orrery--0.12.0--0.13.0.sql
|
sql/pg_orrery--0.13.0.sql sql/pg_orrery--0.12.0--0.13.0.sql \
|
||||||
|
sql/pg_orrery--0.14.0.sql sql/pg_orrery--0.13.0--0.14.0.sql
|
||||||
|
|
||||||
# Our extension C sources
|
# Our extension C sources
|
||||||
OBJS = src/pg_orrery.o src/tle_type.o src/eci_type.o src/observer_type.o \
|
OBJS = src/pg_orrery.o src/tle_type.o src/eci_type.o src/observer_type.o \
|
||||||
@ -29,7 +30,8 @@ OBJS = src/pg_orrery.o src/tle_type.o src/eci_type.o src/observer_type.o \
|
|||||||
src/equatorial_funcs.o \
|
src/equatorial_funcs.o \
|
||||||
src/refraction_funcs.o \
|
src/refraction_funcs.o \
|
||||||
src/gist_equatorial.o \
|
src/gist_equatorial.o \
|
||||||
src/rise_set_funcs.o
|
src/rise_set_funcs.o \
|
||||||
|
src/constellation_data.o src/constellation_funcs.o
|
||||||
|
|
||||||
# Vendored SGP4/SDP4 sources (pure C, from Bill Gray's sat_code, MIT license)
|
# Vendored SGP4/SDP4 sources (pure C, from Bill Gray's sat_code, MIT license)
|
||||||
SGP4_DIR = src/sgp4
|
SGP4_DIR = src/sgp4
|
||||||
@ -47,7 +49,8 @@ REGRESS = tle_parse sgp4_propagate coord_transforms pass_prediction gist_index c
|
|||||||
de_ephemeris od_fit spgist_tle orbital_elements equatorial refraction \
|
de_ephemeris od_fit spgist_tle orbital_elements equatorial refraction \
|
||||||
aberration v011_features vallado_518 \
|
aberration v011_features vallado_518 \
|
||||||
gist_equatorial v012_features \
|
gist_equatorial v012_features \
|
||||||
v013_features rise_set
|
v013_features rise_set \
|
||||||
|
constellation
|
||||||
REGRESS_OPTS = --inputdir=test
|
REGRESS_OPTS = --inputdir=test
|
||||||
|
|
||||||
# Pure C — no C++ runtime needed. LAPACK for OD solver (dgelss_).
|
# Pure C — no C++ runtime needed. LAPACK for OD solver (dgelss_).
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
comment = 'A database orrery — celestial mechanics types and functions for PostgreSQL'
|
comment = 'A database orrery — celestial mechanics types and functions for PostgreSQL'
|
||||||
default_version = '0.13.0'
|
default_version = '0.14.0'
|
||||||
module_pathname = '$libdir/pg_orrery'
|
module_pathname = '$libdir/pg_orrery'
|
||||||
relocatable = true
|
relocatable = true
|
||||||
|
|||||||
48
sql/pg_orrery--0.13.0--0.14.0.sql
Normal file
48
sql/pg_orrery--0.13.0--0.14.0.sql
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
-- pg_orrery 0.13.0 -> 0.14.0 migration
|
||||||
|
--
|
||||||
|
-- Adds: refracted planet/moon rise/set (4 functions),
|
||||||
|
-- constellation identification (2 functions).
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Refracted rise/set: planets (point source, -0.569 deg)
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
CREATE FUNCTION planet_next_rise_refracted(body_id int4, obs observer, t timestamptz) RETURNS timestamptz
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
|
||||||
|
COMMENT ON FUNCTION planet_next_rise_refracted(int4, observer, timestamptz) IS
|
||||||
|
'Next refracted rise time for a planet (-0.569 deg threshold: atmospheric refraction only). Earlier than geometric.';
|
||||||
|
|
||||||
|
CREATE FUNCTION planet_next_set_refracted(body_id int4, obs observer, t timestamptz) RETURNS timestamptz
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
|
||||||
|
COMMENT ON FUNCTION planet_next_set_refracted(int4, observer, timestamptz) IS
|
||||||
|
'Next refracted set time for a planet (-0.569 deg threshold: atmospheric refraction only). Later than geometric.';
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Refracted rise/set: Moon (-0.833 deg, same as Sun)
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
CREATE FUNCTION moon_next_rise_refracted(obs observer, t timestamptz) RETURNS timestamptz
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
|
||||||
|
COMMENT ON FUNCTION moon_next_rise_refracted(observer, timestamptz) IS
|
||||||
|
'Next refracted moonrise (-0.833 deg threshold: refraction + semidiameter). Earlier than geometric.';
|
||||||
|
|
||||||
|
CREATE FUNCTION moon_next_set_refracted(obs observer, t timestamptz) RETURNS timestamptz
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
|
||||||
|
COMMENT ON FUNCTION moon_next_set_refracted(observer, timestamptz) IS
|
||||||
|
'Next refracted moonset (-0.833 deg threshold: refraction + semidiameter). Later than geometric.';
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Constellation identification (Roman 1987, CDS VI/42)
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
CREATE FUNCTION constellation(eq equatorial) RETURNS text
|
||||||
|
AS 'MODULE_PATHNAME', 'constellation_from_equatorial'
|
||||||
|
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
COMMENT ON FUNCTION constellation(equatorial) IS
|
||||||
|
'IAU constellation abbreviation (3 letters) from equatorial coordinates (Roman 1987).';
|
||||||
|
|
||||||
|
CREATE FUNCTION constellation(ra_hours float8, dec_deg float8) RETURNS text
|
||||||
|
AS 'MODULE_PATHNAME', 'constellation_from_radec'
|
||||||
|
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||||
|
COMMENT ON FUNCTION constellation(float8, float8) IS
|
||||||
|
'IAU constellation from J2000 RA (hours [0,24)) and Dec (degrees [-90,90]).';
|
||||||
1562
sql/pg_orrery--0.14.0.sql
Normal file
1562
sql/pg_orrery--0.14.0.sql
Normal file
File diff suppressed because it is too large
Load Diff
378
src/constellation_data.c
Normal file
378
src/constellation_data.c
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
/*
|
||||||
|
* constellation_data.c -- Roman (1987) IAU constellation boundary table
|
||||||
|
*
|
||||||
|
* 357 boundary segments from CDS catalog VI/42. Sorted by descending
|
||||||
|
* declination (as in the original catalog). Coordinates are B1875.0
|
||||||
|
* equatorial: RA in hours, Dec in degrees.
|
||||||
|
*
|
||||||
|
* The lookup algorithm scans from the top (north celestial pole) down.
|
||||||
|
* First entry where point.dec >= entry.dec AND entry.ra_lower <= point.ra
|
||||||
|
* < entry.ra_upper is the match.
|
||||||
|
*
|
||||||
|
* Using float (not double) — boundary precision is 4 decimal places,
|
||||||
|
* well within float32's 7-digit significand.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "constellation_data.h"
|
||||||
|
|
||||||
|
const roman_boundary roman_boundaries[] = {
|
||||||
|
{ 0.0000f, 24.0000f, 88.0000f, "UMi" },
|
||||||
|
{ 8.0000f, 14.5000f, 86.5000f, "UMi" },
|
||||||
|
{ 21.0000f, 23.0000f, 86.1667f, "UMi" },
|
||||||
|
{ 18.0000f, 21.0000f, 86.0000f, "UMi" },
|
||||||
|
{ 0.0000f, 8.0000f, 85.0000f, "Cep" },
|
||||||
|
{ 9.1667f, 10.6667f, 82.0000f, "Cam" },
|
||||||
|
{ 0.0000f, 5.0000f, 80.0000f, "Cep" },
|
||||||
|
{ 10.6667f, 14.5000f, 80.0000f, "Cam" },
|
||||||
|
{ 17.5000f, 18.0000f, 80.0000f, "UMi" },
|
||||||
|
{ 20.1667f, 21.0000f, 80.0000f, "Dra" },
|
||||||
|
{ 0.0000f, 3.5083f, 77.0000f, "Cep" },
|
||||||
|
{ 11.5000f, 13.5833f, 77.0000f, "Cam" },
|
||||||
|
{ 16.5333f, 17.5000f, 75.0000f, "UMi" },
|
||||||
|
{ 20.1667f, 20.6667f, 75.0000f, "Cep" },
|
||||||
|
{ 7.9667f, 9.1667f, 73.5000f, "Cam" },
|
||||||
|
{ 9.1667f, 11.3333f, 73.5000f, "Dra" },
|
||||||
|
{ 13.0000f, 16.5333f, 70.0000f, "UMi" },
|
||||||
|
{ 3.1000f, 3.4167f, 68.0000f, "Cas" },
|
||||||
|
{ 20.4167f, 20.6667f, 67.0000f, "Dra" },
|
||||||
|
{ 11.3333f, 12.0000f, 66.5000f, "Dra" },
|
||||||
|
{ 0.0000f, 0.3333f, 66.0000f, "Cep" },
|
||||||
|
{ 14.0000f, 15.6667f, 66.0000f, "UMi" },
|
||||||
|
{ 23.5833f, 24.0000f, 66.0000f, "Cep" },
|
||||||
|
{ 12.0000f, 13.5000f, 64.0000f, "Dra" },
|
||||||
|
{ 13.5000f, 14.4167f, 63.0000f, "Dra" },
|
||||||
|
{ 23.1667f, 23.5833f, 63.0000f, "Cep" },
|
||||||
|
{ 6.1000f, 7.0000f, 62.0000f, "Cam" },
|
||||||
|
{ 20.0000f, 20.4167f, 61.5000f, "Dra" },
|
||||||
|
{ 20.5367f, 20.6000f, 60.9167f, "Cep" },
|
||||||
|
{ 7.0000f, 7.9667f, 60.0000f, "Cam" },
|
||||||
|
{ 7.9667f, 8.4167f, 60.0000f, "UMa" },
|
||||||
|
{ 19.7667f, 20.0000f, 59.5000f, "Dra" },
|
||||||
|
{ 20.0000f, 20.5367f, 59.5000f, "Cep" },
|
||||||
|
{ 22.8667f, 23.1667f, 59.0833f, "Cep" },
|
||||||
|
{ 0.0000f, 2.4333f, 58.5000f, "Cas" },
|
||||||
|
{ 19.4167f, 19.7667f, 58.0000f, "Dra" },
|
||||||
|
{ 1.7000f, 1.9083f, 57.5000f, "Cas" },
|
||||||
|
{ 2.4333f, 3.1000f, 57.0000f, "Cas" },
|
||||||
|
{ 3.1000f, 3.1667f, 57.0000f, "Cam" },
|
||||||
|
{ 22.3167f, 22.8667f, 56.2500f, "Cep" },
|
||||||
|
{ 5.0000f, 6.1000f, 56.0000f, "Cam" },
|
||||||
|
{ 14.0333f, 14.4167f, 55.5000f, "UMa" },
|
||||||
|
{ 14.4167f, 19.4167f, 55.5000f, "Dra" },
|
||||||
|
{ 3.1667f, 3.3333f, 55.0000f, "Cam" },
|
||||||
|
{ 22.1333f, 22.3167f, 55.0000f, "Cep" },
|
||||||
|
{ 20.6000f, 21.9667f, 54.8333f, "Cep" },
|
||||||
|
{ 0.0000f, 1.7000f, 54.0000f, "Cas" },
|
||||||
|
{ 6.1000f, 6.5000f, 54.0000f, "Lyn" },
|
||||||
|
{ 12.0833f, 13.5000f, 53.0000f, "UMa" },
|
||||||
|
{ 15.2500f, 15.7500f, 53.0000f, "Dra" },
|
||||||
|
{ 21.9667f, 22.1333f, 52.7500f, "Cep" },
|
||||||
|
{ 3.3333f, 5.0000f, 52.5000f, "Cam" },
|
||||||
|
{ 22.8667f, 23.3333f, 52.5000f, "Cas" },
|
||||||
|
{ 15.7500f, 17.0000f, 51.5000f, "Dra" },
|
||||||
|
{ 2.0417f, 2.5167f, 50.5000f, "Per" },
|
||||||
|
{ 17.0000f, 18.2333f, 50.5000f, "Dra" },
|
||||||
|
{ 0.0000f, 1.3667f, 50.0000f, "Cas" },
|
||||||
|
{ 1.3667f, 1.6667f, 50.0000f, "Per" },
|
||||||
|
{ 6.5000f, 6.8000f, 50.0000f, "Lyn" },
|
||||||
|
{ 23.3333f, 24.0000f, 50.0000f, "Cas" },
|
||||||
|
{ 13.5000f, 14.0333f, 48.5000f, "UMa" },
|
||||||
|
{ 0.0000f, 1.1167f, 48.0000f, "Cas" },
|
||||||
|
{ 23.5833f, 24.0000f, 48.0000f, "Cas" },
|
||||||
|
{ 18.1750f, 18.2333f, 47.5000f, "Her" },
|
||||||
|
{ 18.2333f, 19.0833f, 47.5000f, "Dra" },
|
||||||
|
{ 19.0833f, 19.1667f, 47.5000f, "Cyg" },
|
||||||
|
{ 1.6667f, 2.0417f, 47.0000f, "Per" },
|
||||||
|
{ 8.4167f, 9.1667f, 47.0000f, "UMa" },
|
||||||
|
{ 0.1667f, 0.8667f, 46.0000f, "Cas" },
|
||||||
|
{ 12.0000f, 12.0833f, 45.0000f, "UMa" },
|
||||||
|
{ 6.8000f, 7.3667f, 44.5000f, "Lyn" },
|
||||||
|
{ 21.9083f, 21.9667f, 44.0000f, "Cyg" },
|
||||||
|
{ 21.8750f, 21.9083f, 43.7500f, "Cyg" },
|
||||||
|
{ 19.1667f, 19.4000f, 43.5000f, "Cyg" },
|
||||||
|
{ 9.1667f, 10.1667f, 42.0000f, "UMa" },
|
||||||
|
{ 10.1667f, 10.7833f, 40.0000f, "UMa" },
|
||||||
|
{ 15.4333f, 15.7500f, 40.0000f, "Boo" },
|
||||||
|
{ 15.7500f, 16.3333f, 40.0000f, "Her" },
|
||||||
|
{ 9.2500f, 9.5833f, 39.7500f, "Lyn" },
|
||||||
|
{ 0.0000f, 2.5167f, 36.7500f, "And" },
|
||||||
|
{ 2.5167f, 2.5667f, 36.7500f, "Per" },
|
||||||
|
{ 19.3583f, 19.4000f, 36.5000f, "Lyr" },
|
||||||
|
{ 4.5000f, 4.6917f, 36.0000f, "Per" },
|
||||||
|
{ 21.7333f, 21.8750f, 36.0000f, "Cyg" },
|
||||||
|
{ 21.8750f, 22.0000f, 36.0000f, "Lac" },
|
||||||
|
{ 6.5333f, 7.3667f, 35.5000f, "Aur" },
|
||||||
|
{ 7.3667f, 7.7500f, 35.5000f, "Lyn" },
|
||||||
|
{ 0.0000f, 2.0000f, 35.0000f, "And" },
|
||||||
|
{ 22.0000f, 22.8167f, 35.0000f, "Lac" },
|
||||||
|
{ 22.8167f, 22.8667f, 34.5000f, "Lac" },
|
||||||
|
{ 22.8667f, 23.5000f, 34.5000f, "And" },
|
||||||
|
{ 2.5667f, 2.7167f, 34.0000f, "Per" },
|
||||||
|
{ 10.7833f, 11.0000f, 34.0000f, "UMa" },
|
||||||
|
{ 12.0000f, 12.3333f, 34.0000f, "CVn" },
|
||||||
|
{ 7.7500f, 9.2500f, 33.5000f, "Lyn" },
|
||||||
|
{ 9.2500f, 9.8833f, 33.5000f, "LMi" },
|
||||||
|
{ 0.7167f, 1.4083f, 33.0000f, "And" },
|
||||||
|
{ 15.1833f, 15.4333f, 33.0000f, "Boo" },
|
||||||
|
{ 23.5000f, 23.7500f, 32.0833f, "And" },
|
||||||
|
{ 12.3333f, 13.2500f, 32.0000f, "CVn" },
|
||||||
|
{ 23.7500f, 24.0000f, 31.3333f, "And" },
|
||||||
|
{ 13.9583f, 14.0333f, 30.7500f, "CVn" },
|
||||||
|
{ 2.4167f, 2.7167f, 30.6667f, "Tri" },
|
||||||
|
{ 2.7167f, 4.5000f, 30.6667f, "Per" },
|
||||||
|
{ 4.5000f, 4.7500f, 30.0000f, "Aur" },
|
||||||
|
{ 18.1750f, 19.3583f, 30.0000f, "Lyr" },
|
||||||
|
{ 11.0000f, 12.0000f, 29.0000f, "UMa" },
|
||||||
|
{ 19.6667f, 20.9167f, 29.0000f, "Cyg" },
|
||||||
|
{ 4.7500f, 5.8833f, 28.5000f, "Aur" },
|
||||||
|
{ 9.8833f, 10.5000f, 28.5000f, "LMi" },
|
||||||
|
{ 13.2500f, 13.9583f, 28.5000f, "CVn" },
|
||||||
|
{ 0.0000f, 0.0667f, 28.0000f, "And" },
|
||||||
|
{ 1.4083f, 1.6667f, 28.0000f, "Tri" },
|
||||||
|
{ 5.8833f, 6.5333f, 28.0000f, "Aur" },
|
||||||
|
{ 7.8833f, 8.0000f, 28.0000f, "Gem" },
|
||||||
|
{ 20.9167f, 21.7333f, 28.0000f, "Cyg" },
|
||||||
|
{ 19.2583f, 19.6667f, 27.5000f, "Cyg" },
|
||||||
|
{ 1.9167f, 2.4167f, 27.2500f, "Tri" },
|
||||||
|
{ 16.1667f, 16.3333f, 27.0000f, "CrB" },
|
||||||
|
{ 15.0833f, 15.1833f, 26.0000f, "Boo" },
|
||||||
|
{ 15.1833f, 16.1667f, 26.0000f, "CrB" },
|
||||||
|
{ 18.3667f, 18.8667f, 26.0000f, "Lyr" },
|
||||||
|
{ 10.7500f, 11.0000f, 25.5000f, "LMi" },
|
||||||
|
{ 18.8667f, 19.2583f, 25.5000f, "Lyr" },
|
||||||
|
{ 1.6667f, 1.9167f, 25.0000f, "Tri" },
|
||||||
|
{ 0.7167f, 0.8500f, 23.7500f, "Psc" },
|
||||||
|
{ 10.5000f, 10.7500f, 23.5000f, "LMi" },
|
||||||
|
{ 21.2500f, 21.4167f, 23.5000f, "Vul" },
|
||||||
|
{ 5.7000f, 5.8833f, 22.8333f, "Tau" },
|
||||||
|
{ 0.0667f, 0.1417f, 22.0000f, "And" },
|
||||||
|
{ 15.9167f, 16.0333f, 22.0000f, "Ser" },
|
||||||
|
{ 5.8833f, 6.2167f, 21.5000f, "Gem" },
|
||||||
|
{ 19.8333f, 20.2500f, 21.2500f, "Vul" },
|
||||||
|
{ 18.8667f, 19.2500f, 21.0833f, "Vul" },
|
||||||
|
{ 0.1417f, 0.8500f, 21.0000f, "And" },
|
||||||
|
{ 20.2500f, 20.5667f, 20.5000f, "Vul" },
|
||||||
|
{ 7.8083f, 7.8833f, 20.0000f, "Gem" },
|
||||||
|
{ 20.5667f, 21.2500f, 19.5000f, "Vul" },
|
||||||
|
{ 19.2500f, 19.8333f, 19.1667f, "Vul" },
|
||||||
|
{ 3.2833f, 3.3667f, 19.0000f, "Ari" },
|
||||||
|
{ 18.8667f, 19.0000f, 18.5000f, "Sge" },
|
||||||
|
{ 5.7000f, 5.7667f, 18.0000f, "Ori" },
|
||||||
|
{ 6.2167f, 6.3083f, 17.5000f, "Gem" },
|
||||||
|
{ 19.0000f, 19.8333f, 16.1667f, "Sge" },
|
||||||
|
{ 4.9667f, 5.3333f, 16.0000f, "Tau" },
|
||||||
|
{ 15.9167f, 16.0833f, 16.0000f, "Her" },
|
||||||
|
{ 19.8333f, 20.2500f, 15.7500f, "Sge" },
|
||||||
|
{ 4.6167f, 4.9667f, 15.5000f, "Tau" },
|
||||||
|
{ 5.3333f, 5.6000f, 15.5000f, "Tau" },
|
||||||
|
{ 12.8333f, 13.5000f, 15.0000f, "Com" },
|
||||||
|
{ 17.2500f, 18.2500f, 14.3333f, "Her" },
|
||||||
|
{ 11.8667f, 12.8333f, 14.0000f, "Com" },
|
||||||
|
{ 7.5000f, 7.8083f, 13.5000f, "Gem" },
|
||||||
|
{ 16.7500f, 17.2500f, 12.8333f, "Her" },
|
||||||
|
{ 0.0000f, 0.1417f, 12.5000f, "Peg" },
|
||||||
|
{ 5.6000f, 5.7667f, 12.5000f, "Tau" },
|
||||||
|
{ 7.0000f, 7.5000f, 12.5000f, "Gem" },
|
||||||
|
{ 21.1167f, 21.3333f, 12.5000f, "Peg" },
|
||||||
|
{ 6.3083f, 6.9333f, 12.0000f, "Gem" },
|
||||||
|
{ 18.2500f, 18.8667f, 12.0000f, "Her" },
|
||||||
|
{ 20.8750f, 21.0500f, 11.8333f, "Del" },
|
||||||
|
{ 21.0500f, 21.1167f, 11.8333f, "Peg" },
|
||||||
|
{ 11.5167f, 11.8667f, 11.0000f, "Leo" },
|
||||||
|
{ 6.2417f, 6.3083f, 10.0000f, "Ori" },
|
||||||
|
{ 6.9333f, 7.0000f, 10.0000f, "Gem" },
|
||||||
|
{ 7.8083f, 7.9250f, 10.0000f, "Cnc" },
|
||||||
|
{ 23.8333f, 24.0000f, 10.0000f, "Peg" },
|
||||||
|
{ 1.6667f, 3.2833f, 9.9167f, "Ari" },
|
||||||
|
{ 20.1417f, 20.3000f, 8.5000f, "Del" },
|
||||||
|
{ 13.5000f, 15.0833f, 8.0000f, "Boo" },
|
||||||
|
{ 22.7500f, 23.8333f, 7.5000f, "Peg" },
|
||||||
|
{ 7.9250f, 9.2500f, 7.0000f, "Cnc" },
|
||||||
|
{ 9.2500f, 10.7500f, 7.0000f, "Leo" },
|
||||||
|
{ 18.2500f, 18.6622f, 6.2500f, "Oph" },
|
||||||
|
{ 18.6622f, 18.8667f, 6.2500f, "Aql" },
|
||||||
|
{ 20.8333f, 20.8750f, 6.0000f, "Del" },
|
||||||
|
{ 7.0000f, 7.0167f, 5.5000f, "CMi" },
|
||||||
|
{ 18.2500f, 18.4250f, 4.5000f, "Ser" },
|
||||||
|
{ 16.0833f, 16.7500f, 4.0000f, "Her" },
|
||||||
|
{ 18.2500f, 18.4250f, 3.0000f, "Oph" },
|
||||||
|
{ 21.4667f, 21.6667f, 2.7500f, "Peg" },
|
||||||
|
{ 0.0000f, 2.0000f, 2.0000f, "Psc" },
|
||||||
|
{ 18.5833f, 18.8667f, 2.0000f, "Ser" },
|
||||||
|
{ 20.3000f, 20.8333f, 2.0000f, "Del" },
|
||||||
|
{ 20.8333f, 21.3333f, 2.0000f, "Equ" },
|
||||||
|
{ 21.3333f, 21.4667f, 2.0000f, "Peg" },
|
||||||
|
{ 22.0000f, 22.7500f, 2.0000f, "Peg" },
|
||||||
|
{ 21.6667f, 22.0000f, 1.7500f, "Peg" },
|
||||||
|
{ 7.0167f, 7.2000f, 1.5000f, "CMi" },
|
||||||
|
{ 3.5833f, 4.6167f, 0.0000f, "Tau" },
|
||||||
|
{ 4.6167f, 4.6667f, 0.0000f, "Ori" },
|
||||||
|
{ 7.2000f, 8.0833f, 0.0000f, "CMi" },
|
||||||
|
{ 14.6667f, 15.0833f, 0.0000f, "Vir" },
|
||||||
|
{ 17.8333f, 18.2500f, 0.0000f, "Oph" },
|
||||||
|
{ 2.6500f, 3.2833f, -1.7500f, "Cet" },
|
||||||
|
{ 3.2833f, 3.5833f, -1.7500f, "Tau" },
|
||||||
|
{ 15.0833f, 16.2667f, -3.2500f, "Ser" },
|
||||||
|
{ 4.6667f, 5.0833f, -4.0000f, "Ori" },
|
||||||
|
{ 5.8333f, 6.2417f, -4.0000f, "Ori" },
|
||||||
|
{ 17.8333f, 17.9667f, -4.0000f, "Ser" },
|
||||||
|
{ 18.2500f, 18.5833f, -4.0000f, "Ser" },
|
||||||
|
{ 18.5833f, 18.8667f, -4.0000f, "Aql" },
|
||||||
|
{ 22.7500f, 23.8333f, -4.0000f, "Psc" },
|
||||||
|
{ 10.7500f, 11.5167f, -6.0000f, "Leo" },
|
||||||
|
{ 11.5167f, 11.8333f, -6.0000f, "Vir" },
|
||||||
|
{ 0.0000f, 0.3333f, -7.0000f, "Psc" },
|
||||||
|
{ 23.8333f, 24.0000f, -7.0000f, "Psc" },
|
||||||
|
{ 14.2500f, 14.6667f, -8.0000f, "Vir" },
|
||||||
|
{ 15.9167f, 16.2667f, -8.0000f, "Oph" },
|
||||||
|
{ 20.0000f, 20.5333f, -9.0000f, "Aql" },
|
||||||
|
{ 21.3333f, 21.8667f, -9.0000f, "Aqr" },
|
||||||
|
{ 17.1667f, 17.9667f, -10.0000f, "Oph" },
|
||||||
|
{ 5.8333f, 8.0833f, -11.0000f, "Mon" },
|
||||||
|
{ 4.9167f, 5.0833f, -11.0000f, "Eri" },
|
||||||
|
{ 5.0833f, 5.8333f, -11.0000f, "Ori" },
|
||||||
|
{ 8.0833f, 8.3667f, -11.0000f, "Hya" },
|
||||||
|
{ 9.5833f, 10.7500f, -11.0000f, "Sex" },
|
||||||
|
{ 11.8333f, 12.8333f, -11.0000f, "Vir" },
|
||||||
|
{ 17.5833f, 17.6667f, -11.6667f, "Oph" },
|
||||||
|
{ 18.8667f, 20.0000f, -12.0333f, "Aql" },
|
||||||
|
{ 4.8333f, 4.9167f, -14.5000f, "Eri" },
|
||||||
|
{ 20.5333f, 21.3333f, -15.0000f, "Aqr" },
|
||||||
|
{ 17.1667f, 18.2500f, -16.0000f, "Ser" },
|
||||||
|
{ 18.2500f, 18.8667f, -16.0000f, "Sct" },
|
||||||
|
{ 8.3667f, 8.5833f, -17.0000f, "Hya" },
|
||||||
|
{ 16.2667f, 16.3750f, -18.2500f, "Oph" },
|
||||||
|
{ 8.5833f, 9.0833f, -19.0000f, "Hya" },
|
||||||
|
{ 10.7500f, 10.8333f, -19.0000f, "Crt" },
|
||||||
|
{ 16.2667f, 16.3750f, -19.2500f, "Sco" },
|
||||||
|
{ 15.6667f, 15.9167f, -20.0000f, "Lib" },
|
||||||
|
{ 12.5833f, 12.8333f, -22.0000f, "Crv" },
|
||||||
|
{ 12.8333f, 14.2500f, -22.0000f, "Vir" },
|
||||||
|
{ 9.0833f, 9.7500f, -24.0000f, "Hya" },
|
||||||
|
{ 1.6667f, 2.6500f, -24.3833f, "Cet" },
|
||||||
|
{ 2.6500f, 3.7500f, -24.3833f, "Eri" },
|
||||||
|
{ 10.8333f, 11.8333f, -24.5000f, "Crt" },
|
||||||
|
{ 11.8333f, 12.5833f, -24.5000f, "Crv" },
|
||||||
|
{ 14.2500f, 14.9167f, -24.5000f, "Lib" },
|
||||||
|
{ 16.2667f, 16.7500f, -24.5833f, "Oph" },
|
||||||
|
{ 0.0000f, 1.6667f, -25.5000f, "Cet" },
|
||||||
|
{ 21.3333f, 21.8667f, -25.5000f, "Cap" },
|
||||||
|
{ 21.8667f, 23.8333f, -25.5000f, "Aqr" },
|
||||||
|
{ 23.8333f, 24.0000f, -25.5000f, "Cet" },
|
||||||
|
{ 9.7500f, 10.2500f, -26.5000f, "Hya" },
|
||||||
|
{ 4.7000f, 4.8333f, -27.2500f, "Eri" },
|
||||||
|
{ 4.8333f, 6.1167f, -27.2500f, "Lep" },
|
||||||
|
{ 20.0000f, 21.3333f, -28.0000f, "Cap" },
|
||||||
|
{ 10.2500f, 10.5833f, -29.1667f, "Hya" },
|
||||||
|
{ 12.5833f, 14.9167f, -29.5000f, "Hya" },
|
||||||
|
{ 14.9167f, 15.6667f, -29.5000f, "Lib" },
|
||||||
|
{ 15.6667f, 16.0000f, -29.5000f, "Sco" },
|
||||||
|
{ 4.5833f, 4.7000f, -30.0000f, "Eri" },
|
||||||
|
{ 16.7500f, 17.6000f, -30.0000f, "Oph" },
|
||||||
|
{ 17.6000f, 17.8333f, -30.0000f, "Sgr" },
|
||||||
|
{ 10.5833f, 10.8333f, -31.1667f, "Hya" },
|
||||||
|
{ 6.1167f, 7.3667f, -33.0000f, "CMa" },
|
||||||
|
{ 12.2500f, 12.5833f, -33.0000f, "Hya" },
|
||||||
|
{ 10.8333f, 12.2500f, -35.0000f, "Hya" },
|
||||||
|
{ 3.5000f, 3.7500f, -36.0000f, "For" },
|
||||||
|
{ 8.3667f, 9.3667f, -36.7500f, "Pyx" },
|
||||||
|
{ 4.2667f, 4.5833f, -37.0000f, "Eri" },
|
||||||
|
{ 17.8333f, 19.1667f, -37.0000f, "Sgr" },
|
||||||
|
{ 21.3333f, 23.0000f, -37.0000f, "PsA" },
|
||||||
|
{ 23.0000f, 23.3333f, -37.0000f, "Scl" },
|
||||||
|
{ 3.0000f, 3.5000f, -39.5833f, "For" },
|
||||||
|
{ 9.3667f, 11.0000f, -39.7500f, "Ant" },
|
||||||
|
{ 0.0000f, 1.6667f, -40.0000f, "Scl" },
|
||||||
|
{ 1.6667f, 3.0000f, -40.0000f, "For" },
|
||||||
|
{ 3.8667f, 4.2667f, -40.0000f, "Eri" },
|
||||||
|
{ 23.3333f, 24.0000f, -40.0000f, "Scl" },
|
||||||
|
{ 14.1667f, 14.9167f, -42.0000f, "Cen" },
|
||||||
|
{ 15.6667f, 16.0000f, -42.0000f, "Lup" },
|
||||||
|
{ 16.0000f, 16.4208f, -42.0000f, "Sco" },
|
||||||
|
{ 4.8333f, 5.0000f, -43.0000f, "Cae" },
|
||||||
|
{ 5.0000f, 6.5833f, -43.0000f, "Col" },
|
||||||
|
{ 8.0000f, 8.3667f, -43.0000f, "Pup" },
|
||||||
|
{ 3.4167f, 3.8667f, -44.0000f, "Eri" },
|
||||||
|
{ 16.4208f, 17.8333f, -45.5000f, "Sco" },
|
||||||
|
{ 17.8333f, 19.1667f, -45.5000f, "CrA" },
|
||||||
|
{ 19.1667f, 20.3333f, -45.5000f, "Sgr" },
|
||||||
|
{ 20.3333f, 21.3333f, -45.5000f, "Mic" },
|
||||||
|
{ 3.0000f, 3.4167f, -46.0000f, "Eri" },
|
||||||
|
{ 4.5000f, 4.8333f, -46.5000f, "Cae" },
|
||||||
|
{ 15.3333f, 15.6667f, -48.0000f, "Lup" },
|
||||||
|
{ 0.0000f, 2.3333f, -48.1667f, "Phe" },
|
||||||
|
{ 2.6667f, 3.0000f, -49.0000f, "Eri" },
|
||||||
|
{ 4.0833f, 4.2667f, -49.0000f, "Hor" },
|
||||||
|
{ 4.2667f, 4.5000f, -49.0000f, "Cae" },
|
||||||
|
{ 21.3333f, 22.0000f, -50.0000f, "Gru" },
|
||||||
|
{ 6.0000f, 8.0000f, -50.7500f, "Pup" },
|
||||||
|
{ 8.0000f, 8.1667f, -50.7500f, "Vel" },
|
||||||
|
{ 2.4167f, 2.6667f, -51.0000f, "Eri" },
|
||||||
|
{ 3.8333f, 4.0833f, -51.0000f, "Hor" },
|
||||||
|
{ 0.0000f, 1.8333f, -51.5000f, "Phe" },
|
||||||
|
{ 6.0000f, 6.1667f, -52.5000f, "Car" },
|
||||||
|
{ 8.1667f, 8.4500f, -53.0000f, "Vel" },
|
||||||
|
{ 3.5000f, 3.8333f, -53.1667f, "Hor" },
|
||||||
|
{ 3.8333f, 4.0000f, -53.1667f, "Dor" },
|
||||||
|
{ 0.0000f, 1.5833f, -53.5000f, "Phe" },
|
||||||
|
{ 2.1667f, 2.4167f, -54.0000f, "Eri" },
|
||||||
|
{ 4.5000f, 5.0000f, -54.0000f, "Pic" },
|
||||||
|
{ 15.0500f, 15.3333f, -54.0000f, "Lup" },
|
||||||
|
{ 8.4500f, 8.8333f, -54.5000f, "Vel" },
|
||||||
|
{ 6.1667f, 6.5000f, -55.0000f, "Car" },
|
||||||
|
{ 11.8333f, 12.8333f, -55.0000f, "Cen" },
|
||||||
|
{ 14.1667f, 15.0500f, -55.0000f, "Lup" },
|
||||||
|
{ 15.0500f, 15.3333f, -55.0000f, "Nor" },
|
||||||
|
{ 4.0000f, 4.3333f, -56.5000f, "Dor" },
|
||||||
|
{ 8.8333f, 11.0000f, -56.5000f, "Vel" },
|
||||||
|
{ 11.0000f, 11.2500f, -56.5000f, "Cen" },
|
||||||
|
{ 17.5000f, 18.0000f, -57.0000f, "Ara" },
|
||||||
|
{ 18.0000f, 20.3333f, -57.0000f, "Tel" },
|
||||||
|
{ 22.0000f, 23.3333f, -57.0000f, "Gru" },
|
||||||
|
{ 3.2000f, 3.5000f, -57.5000f, "Hor" },
|
||||||
|
{ 5.0000f, 5.5000f, -57.5000f, "Pic" },
|
||||||
|
{ 6.5000f, 6.8333f, -58.0000f, "Car" },
|
||||||
|
{ 0.0000f, 1.3333f, -58.5000f, "Phe" },
|
||||||
|
{ 1.3333f, 2.1667f, -58.5000f, "Eri" },
|
||||||
|
{ 23.3333f, 24.0000f, -58.5000f, "Phe" },
|
||||||
|
{ 4.3333f, 4.5833f, -59.0000f, "Dor" },
|
||||||
|
{ 15.3333f, 16.4208f, -60.0000f, "Nor" },
|
||||||
|
{ 20.3333f, 21.3333f, -60.0000f, "Ind" },
|
||||||
|
{ 5.5000f, 6.0000f, -61.0000f, "Pic" },
|
||||||
|
{ 15.1667f, 15.3333f, -61.0000f, "Cir" },
|
||||||
|
{ 16.4208f, 16.5833f, -61.0000f, "Ara" },
|
||||||
|
{ 14.9167f, 15.1667f, -63.5833f, "Cir" },
|
||||||
|
{ 16.5833f, 16.7500f, -63.5833f, "Ara" },
|
||||||
|
{ 6.0000f, 6.8333f, -64.0000f, "Pic" },
|
||||||
|
{ 6.8333f, 9.0333f, -64.0000f, "Car" },
|
||||||
|
{ 11.2500f, 11.8333f, -64.0000f, "Cen" },
|
||||||
|
{ 11.8333f, 12.8333f, -64.0000f, "Cru" },
|
||||||
|
{ 12.8333f, 14.5333f, -64.0000f, "Cen" },
|
||||||
|
{ 13.5000f, 13.6667f, -65.0000f, "Cir" },
|
||||||
|
{ 16.7500f, 16.8333f, -65.0000f, "Ara" },
|
||||||
|
{ 2.1667f, 3.2000f, -67.5000f, "Hor" },
|
||||||
|
{ 3.2000f, 4.5833f, -67.5000f, "Ret" },
|
||||||
|
{ 14.7500f, 14.9167f, -67.5000f, "Cir" },
|
||||||
|
{ 16.8333f, 17.5000f, -67.5000f, "Ara" },
|
||||||
|
{ 17.5000f, 18.0000f, -67.5000f, "Pav" },
|
||||||
|
{ 22.0000f, 23.3333f, -67.5000f, "Tuc" },
|
||||||
|
{ 4.5833f, 6.5833f, -70.0000f, "Dor" },
|
||||||
|
{ 13.6667f, 14.7500f, -70.0000f, "Cir" },
|
||||||
|
{ 14.7500f, 17.0000f, -70.0000f, "TrA" },
|
||||||
|
{ 0.0000f, 1.3333f, -75.0000f, "Tuc" },
|
||||||
|
{ 3.5000f, 4.5833f, -75.0000f, "Hyi" },
|
||||||
|
{ 6.5833f, 9.0333f, -75.0000f, "Vol" },
|
||||||
|
{ 9.0333f, 11.2500f, -75.0000f, "Car" },
|
||||||
|
{ 11.2500f, 13.6667f, -75.0000f, "Mus" },
|
||||||
|
{ 18.0000f, 21.3333f, -75.0000f, "Pav" },
|
||||||
|
{ 21.3333f, 23.3333f, -75.0000f, "Ind" },
|
||||||
|
{ 23.3333f, 24.0000f, -75.0000f, "Tuc" },
|
||||||
|
{ 0.7500f, 1.3333f, -76.0000f, "Tuc" },
|
||||||
|
{ 0.0000f, 3.5000f, -82.5000f, "Hyi" },
|
||||||
|
{ 7.6667f, 13.6667f, -82.5000f, "Cha" },
|
||||||
|
{ 13.6667f, 18.0000f, -82.5000f, "Aps" },
|
||||||
|
{ 3.5000f, 7.6667f, -85.0000f, "Men" },
|
||||||
|
{ 0.0000f, 24.0000f, -90.0000f, "Oct" },
|
||||||
|
};
|
||||||
|
|
||||||
|
const int roman_boundary_count = sizeof(roman_boundaries) / sizeof(roman_boundaries[0]);
|
||||||
26
src/constellation_data.h
Normal file
26
src/constellation_data.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* constellation_data.h -- Roman (1987) IAU constellation boundaries
|
||||||
|
*
|
||||||
|
* Data source: CDS catalog VI/42
|
||||||
|
* "Identification of a Constellation From a Position"
|
||||||
|
* Nancy G. Roman, Publications of the Astronomical Society of the Pacific,
|
||||||
|
* Vol. 99, p. 695, July 1987.
|
||||||
|
*
|
||||||
|
* Boundaries are defined in B1875.0 equatorial coordinates.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PG_ORRERY_CONSTELLATION_DATA_H
|
||||||
|
#define PG_ORRERY_CONSTELLATION_DATA_H
|
||||||
|
|
||||||
|
typedef struct roman_boundary
|
||||||
|
{
|
||||||
|
float ra_lower; /* hours [0, 24) */
|
||||||
|
float ra_upper; /* hours [0, 24) */
|
||||||
|
float dec; /* degrees, lower limit */
|
||||||
|
char abbr[4]; /* 3-letter IAU abbreviation + null */
|
||||||
|
} roman_boundary;
|
||||||
|
|
||||||
|
extern const roman_boundary roman_boundaries[];
|
||||||
|
extern const int roman_boundary_count;
|
||||||
|
|
||||||
|
#endif /* PG_ORRERY_CONSTELLATION_DATA_H */
|
||||||
175
src/constellation_funcs.c
Normal file
175
src/constellation_funcs.c
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* constellation_funcs.c -- IAU constellation identification
|
||||||
|
*
|
||||||
|
* Identifies which of the 88 IAU constellations contains a given
|
||||||
|
* position, using the Roman (1987) boundary table (CDS VI/42).
|
||||||
|
*
|
||||||
|
* Algorithm:
|
||||||
|
* 1. Precess input J2000 RA/Dec to B1875.0 epoch
|
||||||
|
* 2. Convert to hours + degrees
|
||||||
|
* 3. Linear scan of boundary table (sorted by descending Dec)
|
||||||
|
* 4. First entry where point.dec >= entry.dec AND
|
||||||
|
* entry.ra_lower <= point.ra < entry.ra_upper is the match
|
||||||
|
*
|
||||||
|
* The B1875.0 epoch is used because that's the epoch of the original
|
||||||
|
* IAU boundary definitions (Delporte 1930, codified by Roman 1987).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
#include "fmgr.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "astro_math.h"
|
||||||
|
#include "constellation_data.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
PG_FUNCTION_INFO_V1(constellation_from_equatorial);
|
||||||
|
PG_FUNCTION_INFO_V1(constellation_from_radec);
|
||||||
|
|
||||||
|
/* B1875.0 epoch as Julian date.
|
||||||
|
* JD(B) = 2415020.31352 + (B - 1900.0) * 365.242198781
|
||||||
|
* JD(B1875.0) = 2415020.31352 + (-25.0) * 365.242198781 = 2405889.25855 */
|
||||||
|
#define JD_B1875 2405889.25855
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find_constellation -- look up IAU abbreviation from B1875.0 RA/Dec
|
||||||
|
*
|
||||||
|
* ra_hours: [0, 24), dec_deg: [-90, 90]
|
||||||
|
* Returns pointer to 3-letter abbreviation (static storage), or NULL
|
||||||
|
* if no match (should never happen for valid coordinates).
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
find_constellation(double ra_hours, double dec_deg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < roman_boundary_count; i++)
|
||||||
|
{
|
||||||
|
if (dec_deg >= (double)roman_boundaries[i].dec &&
|
||||||
|
ra_hours >= (double)roman_boundaries[i].ra_lower &&
|
||||||
|
ra_hours < (double)roman_boundaries[i].ra_upper)
|
||||||
|
{
|
||||||
|
return roman_boundaries[i].abbr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL; /* should not happen for valid coordinates */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* constellation(equatorial) -> text
|
||||||
|
*
|
||||||
|
* Takes an equatorial coordinate (apparent RA/Dec of date) and
|
||||||
|
* returns the 3-letter IAU constellation abbreviation.
|
||||||
|
*
|
||||||
|
* The equatorial type stores RA/Dec in radians (of date). Since
|
||||||
|
* the observation pipeline already precesses J2000 -> of date,
|
||||||
|
* and the Roman table uses B1875.0, we need J2000 coordinates.
|
||||||
|
*
|
||||||
|
* However, for practical purposes the precession from J2000 to
|
||||||
|
* "of date" (±25 years from J2000) shifts positions by at most
|
||||||
|
* ~6 arcminutes — negligible compared to constellation boundaries
|
||||||
|
* that span degrees. We treat the equatorial input as J2000-ish
|
||||||
|
* and precess directly to B1875.0.
|
||||||
|
*
|
||||||
|
* For high accuracy near boundaries, pass J2000 RA/Dec via the
|
||||||
|
* (float8, float8) overload.
|
||||||
|
* ================================================================
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
constellation_from_equatorial(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
pg_equatorial *eq = (pg_equatorial *) PG_GETARG_POINTER(0);
|
||||||
|
double ra_j2000, dec_j2000;
|
||||||
|
double ra_1875, dec_1875;
|
||||||
|
double ra_hours, dec_deg;
|
||||||
|
const char *abbr;
|
||||||
|
|
||||||
|
/* equatorial stores RA/Dec in radians */
|
||||||
|
ra_j2000 = eq->ra;
|
||||||
|
dec_j2000 = eq->dec;
|
||||||
|
|
||||||
|
/* Precess to B1875.0 */
|
||||||
|
precess_j2000_to_date(JD_B1875, ra_j2000, dec_j2000, &ra_1875, &dec_1875);
|
||||||
|
|
||||||
|
/* Convert to hours and degrees */
|
||||||
|
ra_hours = ra_1875 * (12.0 / M_PI); /* radians -> hours */
|
||||||
|
dec_deg = dec_1875 * (180.0 / M_PI); /* radians -> degrees */
|
||||||
|
|
||||||
|
/* Normalize RA to [0, 24) */
|
||||||
|
if (ra_hours < 0.0)
|
||||||
|
ra_hours += 24.0;
|
||||||
|
if (ra_hours >= 24.0)
|
||||||
|
ra_hours -= 24.0;
|
||||||
|
|
||||||
|
abbr = find_constellation(ra_hours, dec_deg);
|
||||||
|
|
||||||
|
if (abbr == NULL)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||||
|
errmsg("constellation: no match for RA=%.4f h, Dec=%.4f deg (B1875.0)",
|
||||||
|
ra_hours, dec_deg)));
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(cstring_to_text(abbr));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* constellation(ra_hours float8, dec_deg float8) -> text
|
||||||
|
*
|
||||||
|
* Takes J2000 RA (hours [0,24)) and Dec (degrees [-90,90]).
|
||||||
|
* Precesses to B1875.0 and looks up the constellation.
|
||||||
|
* ================================================================
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
constellation_from_radec(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
double ra_hours_j2000 = PG_GETARG_FLOAT8(0);
|
||||||
|
double dec_deg_j2000 = PG_GETARG_FLOAT8(1);
|
||||||
|
double ra_rad, dec_rad;
|
||||||
|
double ra_1875, dec_1875;
|
||||||
|
double ra_hours, dec_deg;
|
||||||
|
const char *abbr;
|
||||||
|
|
||||||
|
/* Validate input ranges */
|
||||||
|
if (ra_hours_j2000 < 0.0 || ra_hours_j2000 >= 24.0)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("constellation: RA must be in [0, 24), got %.4f",
|
||||||
|
ra_hours_j2000)));
|
||||||
|
|
||||||
|
if (dec_deg_j2000 < -90.0 || dec_deg_j2000 > 90.0)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("constellation: Dec must be in [-90, 90], got %.4f",
|
||||||
|
dec_deg_j2000)));
|
||||||
|
|
||||||
|
/* Convert to radians */
|
||||||
|
ra_rad = ra_hours_j2000 * (M_PI / 12.0); /* hours -> radians */
|
||||||
|
dec_rad = dec_deg_j2000 * (M_PI / 180.0); /* degrees -> radians */
|
||||||
|
|
||||||
|
/* Precess J2000 to B1875.0 */
|
||||||
|
precess_j2000_to_date(JD_B1875, ra_rad, dec_rad, &ra_1875, &dec_1875);
|
||||||
|
|
||||||
|
/* Convert back to hours and degrees */
|
||||||
|
ra_hours = ra_1875 * (12.0 / M_PI);
|
||||||
|
dec_deg = dec_1875 * (180.0 / M_PI);
|
||||||
|
|
||||||
|
if (ra_hours < 0.0)
|
||||||
|
ra_hours += 24.0;
|
||||||
|
if (ra_hours >= 24.0)
|
||||||
|
ra_hours -= 24.0;
|
||||||
|
|
||||||
|
abbr = find_constellation(ra_hours, dec_deg);
|
||||||
|
|
||||||
|
if (abbr == NULL)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||||
|
errmsg("constellation: no match for RA=%.4f h, Dec=%.4f deg (B1875.0)",
|
||||||
|
ra_hours, dec_deg)));
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(cstring_to_text(abbr));
|
||||||
|
}
|
||||||
@ -30,6 +30,10 @@ PG_FUNCTION_INFO_V1(moon_next_rise);
|
|||||||
PG_FUNCTION_INFO_V1(moon_next_set);
|
PG_FUNCTION_INFO_V1(moon_next_set);
|
||||||
PG_FUNCTION_INFO_V1(sun_next_rise_refracted);
|
PG_FUNCTION_INFO_V1(sun_next_rise_refracted);
|
||||||
PG_FUNCTION_INFO_V1(sun_next_set_refracted);
|
PG_FUNCTION_INFO_V1(sun_next_set_refracted);
|
||||||
|
PG_FUNCTION_INFO_V1(planet_next_rise_refracted);
|
||||||
|
PG_FUNCTION_INFO_V1(planet_next_set_refracted);
|
||||||
|
PG_FUNCTION_INFO_V1(moon_next_rise_refracted);
|
||||||
|
PG_FUNCTION_INFO_V1(moon_next_set_refracted);
|
||||||
|
|
||||||
#define COARSE_STEP_JD (60.0 / 86400.0) /* 60 seconds */
|
#define COARSE_STEP_JD (60.0 / 86400.0) /* 60 seconds */
|
||||||
#define BISECT_TOL_JD (0.1 / 86400.0) /* 0.1 second */
|
#define BISECT_TOL_JD (0.1 / 86400.0) /* 0.1 second */
|
||||||
@ -49,6 +53,14 @@ PG_FUNCTION_INFO_V1(sun_next_set_refracted);
|
|||||||
*/
|
*/
|
||||||
#define SUN_MOON_REFRACTED_HORIZON_RAD (-0.01454) /* -0.833 deg */
|
#define SUN_MOON_REFRACTED_HORIZON_RAD (-0.01454) /* -0.833 deg */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Refraction-only horizon for point sources (planets).
|
||||||
|
* No semidiameter correction needed — even Jupiter at opposition
|
||||||
|
* subtends only ~24" (0.4 arcmin), negligible against 34' refraction.
|
||||||
|
* Error from treating planets as point sources: <1 second in time.
|
||||||
|
*/
|
||||||
|
#define REFRACTION_ONLY_HORIZON_RAD (-0.00993) /* -0.569 deg */
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
* elevation_at_jd_body -- compute topocentric elevation for a body
|
* elevation_at_jd_body -- compute topocentric elevation for a body
|
||||||
@ -409,3 +421,139 @@ sun_next_set_refracted(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
PG_RETURN_TIMESTAMPTZ(jd_to_timestamptz(result_jd));
|
PG_RETURN_TIMESTAMPTZ(jd_to_timestamptz(result_jd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* planet_next_rise_refracted(body_id, observer, timestamptz) -> timestamptz
|
||||||
|
*
|
||||||
|
* Uses -0.569 degree threshold (refraction only, point source).
|
||||||
|
* Planets are too small for semidiameter to matter — Jupiter at
|
||||||
|
* opposition is 24 arcseconds, <1 second of time error.
|
||||||
|
* ================================================================
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
planet_next_rise_refracted(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
int32 body_id = PG_GETARG_INT32(0);
|
||||||
|
pg_observer *obs = (pg_observer *) PG_GETARG_POINTER(1);
|
||||||
|
int64 ts = PG_GETARG_INT64(2);
|
||||||
|
double start_jd, stop_jd, result_jd;
|
||||||
|
|
||||||
|
if (body_id < BODY_MERCURY || body_id > BODY_NEPTUNE)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("planet_next_rise_refracted: body_id %d must be 1-8 (Mercury-Neptune)",
|
||||||
|
body_id)));
|
||||||
|
|
||||||
|
if (body_id == BODY_EARTH)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("cannot observe Earth from Earth")));
|
||||||
|
|
||||||
|
start_jd = timestamptz_to_jd(ts);
|
||||||
|
stop_jd = start_jd + DEFAULT_WINDOW_DAYS;
|
||||||
|
|
||||||
|
result_jd = find_next_crossing(BTYPE_PLANET, body_id, obs,
|
||||||
|
start_jd, stop_jd,
|
||||||
|
REFRACTION_ONLY_HORIZON_RAD, true);
|
||||||
|
|
||||||
|
if (result_jd < 0.0)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
PG_RETURN_TIMESTAMPTZ(jd_to_timestamptz(result_jd));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* planet_next_set_refracted(body_id, observer, timestamptz) -> timestamptz
|
||||||
|
*
|
||||||
|
* Refracted planet set is later than geometric.
|
||||||
|
* ================================================================
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
planet_next_set_refracted(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
int32 body_id = PG_GETARG_INT32(0);
|
||||||
|
pg_observer *obs = (pg_observer *) PG_GETARG_POINTER(1);
|
||||||
|
int64 ts = PG_GETARG_INT64(2);
|
||||||
|
double start_jd, stop_jd, result_jd;
|
||||||
|
|
||||||
|
if (body_id < BODY_MERCURY || body_id > BODY_NEPTUNE)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("planet_next_set_refracted: body_id %d must be 1-8 (Mercury-Neptune)",
|
||||||
|
body_id)));
|
||||||
|
|
||||||
|
if (body_id == BODY_EARTH)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("cannot observe Earth from Earth")));
|
||||||
|
|
||||||
|
start_jd = timestamptz_to_jd(ts);
|
||||||
|
stop_jd = start_jd + DEFAULT_WINDOW_DAYS;
|
||||||
|
|
||||||
|
result_jd = find_next_crossing(BTYPE_PLANET, body_id, obs,
|
||||||
|
start_jd, stop_jd,
|
||||||
|
REFRACTION_ONLY_HORIZON_RAD, false);
|
||||||
|
|
||||||
|
if (result_jd < 0.0)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
PG_RETURN_TIMESTAMPTZ(jd_to_timestamptz(result_jd));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* moon_next_rise_refracted(observer, timestamptz) -> timestamptz
|
||||||
|
*
|
||||||
|
* Uses -0.833 degree threshold (same as Sun: 0.569 deg refraction +
|
||||||
|
* 0.264 deg mean lunar semidiameter). Moon semidiameter varies
|
||||||
|
* 14.7'-16.7'; mean value error is ~1 arcmin → ~15 seconds in time.
|
||||||
|
* ================================================================
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
moon_next_rise_refracted(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
pg_observer *obs = (pg_observer *) PG_GETARG_POINTER(0);
|
||||||
|
int64 ts = PG_GETARG_INT64(1);
|
||||||
|
double start_jd, stop_jd, result_jd;
|
||||||
|
|
||||||
|
start_jd = timestamptz_to_jd(ts);
|
||||||
|
stop_jd = start_jd + DEFAULT_WINDOW_DAYS;
|
||||||
|
|
||||||
|
result_jd = find_next_crossing(BTYPE_MOON, 0, obs,
|
||||||
|
start_jd, stop_jd,
|
||||||
|
SUN_MOON_REFRACTED_HORIZON_RAD, true);
|
||||||
|
|
||||||
|
if (result_jd < 0.0)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
PG_RETURN_TIMESTAMPTZ(jd_to_timestamptz(result_jd));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* moon_next_set_refracted(observer, timestamptz) -> timestamptz
|
||||||
|
*
|
||||||
|
* Refracted moonset is later than geometric.
|
||||||
|
* ================================================================
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
moon_next_set_refracted(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
pg_observer *obs = (pg_observer *) PG_GETARG_POINTER(0);
|
||||||
|
int64 ts = PG_GETARG_INT64(1);
|
||||||
|
double start_jd, stop_jd, result_jd;
|
||||||
|
|
||||||
|
start_jd = timestamptz_to_jd(ts);
|
||||||
|
stop_jd = start_jd + DEFAULT_WINDOW_DAYS;
|
||||||
|
|
||||||
|
result_jd = find_next_crossing(BTYPE_MOON, 0, obs,
|
||||||
|
start_jd, stop_jd,
|
||||||
|
SUN_MOON_REFRACTED_HORIZON_RAD, false);
|
||||||
|
|
||||||
|
if (result_jd < 0.0)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
PG_RETURN_TIMESTAMPTZ(jd_to_timestamptz(result_jd));
|
||||||
|
}
|
||||||
|
|||||||
133
test/expected/constellation.out
Normal file
133
test/expected/constellation.out
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
-- constellation.sql -- Tests for v0.14.0: IAU constellation identification
|
||||||
|
--
|
||||||
|
-- Verifies the Roman (1987) boundary lookup against well-known
|
||||||
|
-- stellar positions and solar system objects.
|
||||||
|
CREATE EXTENSION IF NOT EXISTS pg_orrery;
|
||||||
|
NOTICE: extension "pg_orrery" already exists, skipping
|
||||||
|
-- ============================================================
|
||||||
|
-- Known stars via J2000 RA/Dec overload
|
||||||
|
-- ============================================================
|
||||||
|
-- Polaris (Alpha UMi): RA 2.5303h, Dec +89.264
|
||||||
|
SELECT constellation(2.5303, 89.264) AS polaris_constellation;
|
||||||
|
polaris_constellation
|
||||||
|
-----------------------
|
||||||
|
UMi
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Sirius (Alpha CMa): RA 6.7525h, Dec -16.716
|
||||||
|
SELECT constellation(6.7525, -16.716) AS sirius_constellation;
|
||||||
|
sirius_constellation
|
||||||
|
----------------------
|
||||||
|
CMa
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Betelgeuse (Alpha Ori): RA 5.9195h, Dec +7.407
|
||||||
|
SELECT constellation(5.9195, 7.407) AS betelgeuse_constellation;
|
||||||
|
betelgeuse_constellation
|
||||||
|
--------------------------
|
||||||
|
Ori
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Vega (Alpha Lyr): RA 18.6156h, Dec +38.784
|
||||||
|
SELECT constellation(18.6156, 38.784) AS vega_constellation;
|
||||||
|
vega_constellation
|
||||||
|
--------------------
|
||||||
|
Lyr
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Antares (Alpha Sco): RA 16.4901h, Dec -26.432
|
||||||
|
SELECT constellation(16.4901, -26.432) AS antares_constellation;
|
||||||
|
antares_constellation
|
||||||
|
-----------------------
|
||||||
|
Sco
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Deneb (Alpha Cyg): RA 20.6905h, Dec +45.280
|
||||||
|
SELECT constellation(20.6905, 45.280) AS deneb_constellation;
|
||||||
|
deneb_constellation
|
||||||
|
---------------------
|
||||||
|
Cyg
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Rigel (Beta Ori): RA 5.2423h, Dec -8.202
|
||||||
|
SELECT constellation(5.2423, -8.202) AS rigel_constellation;
|
||||||
|
rigel_constellation
|
||||||
|
---------------------
|
||||||
|
Ori
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Celestial poles
|
||||||
|
-- ============================================================
|
||||||
|
-- South celestial pole -> Octans
|
||||||
|
SELECT constellation(0.0, -90.0) AS south_pole_constellation;
|
||||||
|
south_pole_constellation
|
||||||
|
--------------------------
|
||||||
|
Oct
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Near north celestial pole -> Ursa Minor
|
||||||
|
SELECT constellation(0.0, 89.0) AS north_pole_constellation;
|
||||||
|
north_pole_constellation
|
||||||
|
--------------------------
|
||||||
|
UMi
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Solar system objects via equatorial overload
|
||||||
|
-- ============================================================
|
||||||
|
-- Sun at 2024 summer solstice should be in Gemini (not Cancer --
|
||||||
|
-- precession has shifted the solstice point)
|
||||||
|
SELECT constellation(sun_equatorial('2024-06-21 12:00:00+00'::timestamptz))
|
||||||
|
AS sun_solstice_constellation;
|
||||||
|
sun_solstice_constellation
|
||||||
|
----------------------------
|
||||||
|
Gem
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Jupiter in Jan 2024 should be in Aries
|
||||||
|
SELECT constellation(planet_equatorial(5, '2024-01-15 12:00:00+00'::timestamptz))
|
||||||
|
AS jupiter_jan2024_constellation;
|
||||||
|
jupiter_jan2024_constellation
|
||||||
|
-------------------------------
|
||||||
|
Ari
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Both overloads should agree for the same position
|
||||||
|
-- ============================================================
|
||||||
|
SELECT constellation(18.6156, 38.784)
|
||||||
|
= constellation(make_equatorial(18.6156, 38.784, 0.0))
|
||||||
|
AS overloads_agree;
|
||||||
|
overloads_agree
|
||||||
|
-----------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- RA boundary edge case near 0h/24h wrap
|
||||||
|
-- ============================================================
|
||||||
|
-- RA just above 0h at various declinations
|
||||||
|
SELECT constellation(0.01, 45.0) IS NOT NULL AS ra_near_zero_valid;
|
||||||
|
ra_near_zero_valid
|
||||||
|
--------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT constellation(23.99, -30.0) IS NOT NULL AS ra_near_24_valid;
|
||||||
|
ra_near_24_valid
|
||||||
|
------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Error cases
|
||||||
|
-- ============================================================
|
||||||
|
-- RA out of range
|
||||||
|
DO $$ BEGIN PERFORM constellation(24.1, 0.0); EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'RA=24.1: %', SQLERRM; END $$;
|
||||||
|
NOTICE: RA=24.1: constellation: RA must be in [0, 24), got 24.1000
|
||||||
|
DO $$ BEGIN PERFORM constellation(-0.1, 0.0); EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'RA=-0.1: %', SQLERRM; END $$;
|
||||||
|
NOTICE: RA=-0.1: constellation: RA must be in [0, 24), got -0.1000
|
||||||
|
-- Dec out of range
|
||||||
|
DO $$ BEGIN PERFORM constellation(12.0, 91.0); EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'Dec=91: %', SQLERRM; END $$;
|
||||||
|
NOTICE: Dec=91: constellation: Dec must be in [-90, 90], got 91.0000
|
||||||
@ -145,6 +145,68 @@ SELECT sun_next_rise('(70.0,25.0,0)'::observer, '2024-12-21 00:00:00+00'::timest
|
|||||||
t
|
t
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Planet refracted rise/set (v0.14.0)
|
||||||
|
-- ============================================================
|
||||||
|
-- Planet refracted rise should be earlier than geometric
|
||||||
|
SELECT planet_next_rise_refracted(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
< planet_next_rise(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
AS planet_refracted_rise_earlier;
|
||||||
|
planet_refracted_rise_earlier
|
||||||
|
-------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Planet refracted set should be later than geometric
|
||||||
|
SELECT planet_next_set_refracted(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
> planet_next_set(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
AS planet_refracted_set_later;
|
||||||
|
planet_refracted_set_later
|
||||||
|
----------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Planet refraction offset should be reasonable (30-300 seconds)
|
||||||
|
SELECT abs(extract(epoch FROM
|
||||||
|
planet_next_rise(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
- planet_next_rise_refracted(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)))
|
||||||
|
BETWEEN 30 AND 300 AS planet_refraction_offset_reasonable;
|
||||||
|
planet_refraction_offset_reasonable
|
||||||
|
-------------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Moon refracted rise/set (v0.14.0)
|
||||||
|
-- ============================================================
|
||||||
|
-- Moon refracted rise should be earlier than geometric
|
||||||
|
SELECT moon_next_rise_refracted('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
< moon_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
AS moon_refracted_rise_earlier;
|
||||||
|
moon_refracted_rise_earlier
|
||||||
|
-----------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Moon refracted set should be later than geometric
|
||||||
|
SELECT moon_next_set_refracted('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
> moon_next_set('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
AS moon_refracted_set_later;
|
||||||
|
moon_refracted_set_later
|
||||||
|
--------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Moon refraction offset should be reasonable (60-600 seconds)
|
||||||
|
SELECT abs(extract(epoch FROM
|
||||||
|
moon_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
- moon_next_rise_refracted('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)))
|
||||||
|
BETWEEN 60 AND 600 AS moon_refraction_offset_reasonable;
|
||||||
|
moon_refraction_offset_reasonable
|
||||||
|
-----------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- ============================================================
|
-- ============================================================
|
||||||
-- Error cases
|
-- Error cases
|
||||||
-- ============================================================
|
-- ============================================================
|
||||||
|
|||||||
81
test/sql/constellation.sql
Normal file
81
test/sql/constellation.sql
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
-- constellation.sql -- Tests for v0.14.0: IAU constellation identification
|
||||||
|
--
|
||||||
|
-- Verifies the Roman (1987) boundary lookup against well-known
|
||||||
|
-- stellar positions and solar system objects.
|
||||||
|
|
||||||
|
CREATE EXTENSION IF NOT EXISTS pg_orrery;
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Known stars via J2000 RA/Dec overload
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- Polaris (Alpha UMi): RA 2.5303h, Dec +89.264
|
||||||
|
SELECT constellation(2.5303, 89.264) AS polaris_constellation;
|
||||||
|
|
||||||
|
-- Sirius (Alpha CMa): RA 6.7525h, Dec -16.716
|
||||||
|
SELECT constellation(6.7525, -16.716) AS sirius_constellation;
|
||||||
|
|
||||||
|
-- Betelgeuse (Alpha Ori): RA 5.9195h, Dec +7.407
|
||||||
|
SELECT constellation(5.9195, 7.407) AS betelgeuse_constellation;
|
||||||
|
|
||||||
|
-- Vega (Alpha Lyr): RA 18.6156h, Dec +38.784
|
||||||
|
SELECT constellation(18.6156, 38.784) AS vega_constellation;
|
||||||
|
|
||||||
|
-- Antares (Alpha Sco): RA 16.4901h, Dec -26.432
|
||||||
|
SELECT constellation(16.4901, -26.432) AS antares_constellation;
|
||||||
|
|
||||||
|
-- Deneb (Alpha Cyg): RA 20.6905h, Dec +45.280
|
||||||
|
SELECT constellation(20.6905, 45.280) AS deneb_constellation;
|
||||||
|
|
||||||
|
-- Rigel (Beta Ori): RA 5.2423h, Dec -8.202
|
||||||
|
SELECT constellation(5.2423, -8.202) AS rigel_constellation;
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Celestial poles
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- South celestial pole -> Octans
|
||||||
|
SELECT constellation(0.0, -90.0) AS south_pole_constellation;
|
||||||
|
|
||||||
|
-- Near north celestial pole -> Ursa Minor
|
||||||
|
SELECT constellation(0.0, 89.0) AS north_pole_constellation;
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Solar system objects via equatorial overload
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- Sun at 2024 summer solstice should be in Gemini (not Cancer --
|
||||||
|
-- precession has shifted the solstice point)
|
||||||
|
SELECT constellation(sun_equatorial('2024-06-21 12:00:00+00'::timestamptz))
|
||||||
|
AS sun_solstice_constellation;
|
||||||
|
|
||||||
|
-- Jupiter in Jan 2024 should be in Aries
|
||||||
|
SELECT constellation(planet_equatorial(5, '2024-01-15 12:00:00+00'::timestamptz))
|
||||||
|
AS jupiter_jan2024_constellation;
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Both overloads should agree for the same position
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
SELECT constellation(18.6156, 38.784)
|
||||||
|
= constellation(make_equatorial(18.6156, 38.784, 0.0))
|
||||||
|
AS overloads_agree;
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- RA boundary edge case near 0h/24h wrap
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- RA just above 0h at various declinations
|
||||||
|
SELECT constellation(0.01, 45.0) IS NOT NULL AS ra_near_zero_valid;
|
||||||
|
SELECT constellation(23.99, -30.0) IS NOT NULL AS ra_near_24_valid;
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Error cases
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- RA out of range
|
||||||
|
DO $$ BEGIN PERFORM constellation(24.1, 0.0); EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'RA=24.1: %', SQLERRM; END $$;
|
||||||
|
DO $$ BEGIN PERFORM constellation(-0.1, 0.0); EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'RA=-0.1: %', SQLERRM; END $$;
|
||||||
|
|
||||||
|
-- Dec out of range
|
||||||
|
DO $$ BEGIN PERFORM constellation(12.0, 91.0); EXCEPTION WHEN OTHERS THEN RAISE NOTICE 'Dec=91: %', SQLERRM; END $$;
|
||||||
@ -98,6 +98,46 @@ SELECT sun_next_set('(70.0,25.0,0)'::observer, '2024-06-21 00:00:00+00'::timesta
|
|||||||
SELECT sun_next_rise('(70.0,25.0,0)'::observer, '2024-12-21 00:00:00+00'::timestamptz)
|
SELECT sun_next_rise('(70.0,25.0,0)'::observer, '2024-12-21 00:00:00+00'::timestamptz)
|
||||||
IS NULL AS polar_night_no_rise;
|
IS NULL AS polar_night_no_rise;
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Planet refracted rise/set (v0.14.0)
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- Planet refracted rise should be earlier than geometric
|
||||||
|
SELECT planet_next_rise_refracted(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
< planet_next_rise(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
AS planet_refracted_rise_earlier;
|
||||||
|
|
||||||
|
-- Planet refracted set should be later than geometric
|
||||||
|
SELECT planet_next_set_refracted(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
> planet_next_set(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
AS planet_refracted_set_later;
|
||||||
|
|
||||||
|
-- Planet refraction offset should be reasonable (30-300 seconds)
|
||||||
|
SELECT abs(extract(epoch FROM
|
||||||
|
planet_next_rise(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
- planet_next_rise_refracted(5, '(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)))
|
||||||
|
BETWEEN 30 AND 300 AS planet_refraction_offset_reasonable;
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- Moon refracted rise/set (v0.14.0)
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- Moon refracted rise should be earlier than geometric
|
||||||
|
SELECT moon_next_rise_refracted('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
< moon_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
AS moon_refracted_rise_earlier;
|
||||||
|
|
||||||
|
-- Moon refracted set should be later than geometric
|
||||||
|
SELECT moon_next_set_refracted('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
> moon_next_set('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
AS moon_refracted_set_later;
|
||||||
|
|
||||||
|
-- Moon refraction offset should be reasonable (60-600 seconds)
|
||||||
|
SELECT abs(extract(epoch FROM
|
||||||
|
moon_next_rise('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)
|
||||||
|
- moon_next_rise_refracted('(43.7,-116.4,800)'::observer, '2024-01-15 00:00:00+00'::timestamptz)))
|
||||||
|
BETWEEN 60 AND 600 AS moon_refraction_offset_reasonable;
|
||||||
|
|
||||||
-- ============================================================
|
-- ============================================================
|
||||||
-- Error cases
|
-- Error cases
|
||||||
-- ============================================================
|
-- ============================================================
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user