Functions: Solar System
Functions for computing planetary positions, observing the Sun, Moon, and planets from an Earth-based observer. Planetary positions use the VSOP87 theory (Bretagnon & Francou, 1988). Lunar position uses ELP2000-82B (Chapront-Touze & Chapront, 1983).
planet_heliocentric
Section titled “planet_heliocentric”Computes the heliocentric ecliptic J2000 position of a solar system body using VSOP87 series C (heliocentric, ecliptic, rectangular). Returns position in Astronomical Units.
Signature
Section titled “Signature”planet_heliocentric(body_id int4, t timestamptz) → heliocentricParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Planet identifier (see table below) |
t | timestamptz | Evaluation time |
Body IDs
Section titled “Body IDs”| ID | Body |
|---|---|
| 0 | Sun (returns origin: 0, 0, 0) |
| 1 | Mercury |
| 2 | Venus |
| 3 | Earth |
| 4 | Mars |
| 5 | Jupiter |
| 6 | Saturn |
| 7 | Uranus |
| 8 | Neptune |
Returns
Section titled “Returns”A heliocentric position in AU (ecliptic J2000 frame). For body_id = 0 (Sun), all components are zero.
Example
Section titled “Example”-- Distance of each planet from the SunSELECT body_id, CASE body_id WHEN 1 THEN 'Mercury' WHEN 2 THEN 'Venus' WHEN 3 THEN 'Earth' WHEN 4 THEN 'Mars' WHEN 5 THEN 'Jupiter' WHEN 6 THEN 'Saturn' WHEN 7 THEN 'Uranus' WHEN 8 THEN 'Neptune' END AS planet, round(helio_distance(planet_heliocentric(body_id, now()))::numeric, 6) AS dist_auFROM generate_series(1, 8) AS body_id;-- Earth's position over one year at weekly intervalsSELECT t, helio_x(h) AS x_au, helio_y(h) AS y_au, helio_z(h) AS z_auFROM generate_series( '2024-01-01'::timestamptz, '2025-01-01'::timestamptz, interval '7 days' ) AS t, planet_heliocentric(3, t) AS h;planet_observe
Section titled “planet_observe”Computes the topocentric position of a planet as seen from an Earth-based observer. Internally computes the heliocentric positions of both Earth and the target planet, applies geometric transformation to geocentric, then converts to topocentric coordinates.
Signature
Section titled “Signature”planet_observe(body_id int4, obs observer, t timestamptz) → topocentricParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Planet identifier (1-8, same as planet_heliocentric excluding 0 and 3) |
obs | observer | Observer location on Earth |
t | timestamptz | Observation time |
Returns
Section titled “Returns”A topocentric with azimuth, elevation, range (km), and range rate (km/s).
Example
Section titled “Example”-- Where is Mars tonight from Greenwich?SELECT topo_azimuth(t) AS az_deg, topo_elevation(t) AS el_deg, topo_range(t) / 149597870.7 AS dist_auFROM planet_observe(4, '51.4769N 0.0005W 11m'::observer, now()) AS t;-- All planets' current positions from BoulderSELECT body_id, CASE body_id WHEN 1 THEN 'Mercury' WHEN 2 THEN 'Venus' WHEN 4 THEN 'Mars' WHEN 5 THEN 'Jupiter' WHEN 6 THEN 'Saturn' WHEN 7 THEN 'Uranus' WHEN 8 THEN 'Neptune' END AS planet, round(topo_azimuth(t)::numeric, 2) AS az, round(topo_elevation(t)::numeric, 2) AS elFROM unnest(ARRAY[1,2,4,5,6,7,8]) AS body_id, planet_observe(body_id, '40.0N 105.3W 1655m'::observer, now()) AS tORDER BY topo_elevation(t) DESC;sun_observe
Section titled “sun_observe”Computes the topocentric position of the Sun from an Earth-based observer.
Signature
Section titled “Signature”sun_observe(obs observer, t timestamptz) → topocentricParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
obs | observer | Observer location on Earth |
t | timestamptz | Observation time |
Returns
Section titled “Returns”A topocentric with azimuth, elevation, range (km), and range rate (km/s).
Example
Section titled “Example”-- Sun position right nowSELECT topo_azimuth(t) AS az, topo_elevation(t) AS el, topo_range(t) / 149597870.7 AS dist_auFROM sun_observe('40.0N 105.3W 1655m'::observer, now()) AS t;-- Find today's solar noon (maximum elevation)SELECT t, round(topo_elevation(s)::numeric, 2) AS elFROM generate_series( now()::date::timestamptz, now()::date::timestamptz + interval '24 hours', interval '1 minute' ) AS t, sun_observe('40.0N 105.3W 1655m'::observer, t) AS sORDER BY topo_elevation(s) DESCLIMIT 1;moon_observe
Section titled “moon_observe”Computes the topocentric position of the Moon from an Earth-based observer. Uses the ELP2000-82B lunar theory (Chapront-Touze & Chapront, 1983).
Signature
Section titled “Signature”moon_observe(obs observer, t timestamptz) → topocentricParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
obs | observer | Observer location on Earth |
t | timestamptz | Observation time |
Returns
Section titled “Returns”A topocentric with azimuth, elevation, range (km), and range rate (km/s). The Moon’s range is typically 356,500 to 406,700 km.
Example
Section titled “Example”-- Current Moon position and distanceSELECT topo_azimuth(t) AS az, topo_elevation(t) AS el, topo_range(t) AS range_kmFROM moon_observe('40.0N 105.3W 1655m'::observer, now()) AS t;-- Moon's path across the sky tonight at 5-minute intervalsSELECT t, round(topo_azimuth(m)::numeric, 1) AS az, round(topo_elevation(m)::numeric, 1) AS el, round(topo_range(m)::numeric, 0) AS range_kmFROM generate_series( '2024-06-15 02:00:00+00', '2024-06-15 10:00:00+00', interval '5 minutes' ) AS t, moon_observe('40.0N 105.3W 1655m'::observer, t) AS mWHERE topo_elevation(m) > 0;