feat: 引入可切换星历模型并扩展天象观测链路

- 新增半解析、旧模型、自定义与多源堆叠星历实例,提供 Context、Instance、SPK 读取及状态与视位置计算
- 统一太阳、月球和行星实例接口,扩展黄经穿越、留、相位、最近角距、偕日可见、任意高度升落、轨道节点及凌日等天象查询
- 完善日月食、月掩与凌日的月缘剖面、有限盘面接触、站心修正、局地可见性、全球路径和地图输出
- 新增 SVG、GeoJSON、KML 天象输出及凌日、月掩和月缘地形相关缓存与几何求解
- 新增恒星星表导入与查询,支持 CSV、Hipparcos、BSC5、Stellarium 等格式及名称、交叉标识、锥面检索和星等过滤
- 补充 IAU 2006、地球定向、折射消光、大气观测、轨道传播及半解析行星/月球数据支持
- 将默认未来民用时标切换为 TimeScaleLeapHour,更新 2027–2400 农历速查表、中文日期解析和时区边界处理
- 增加事件基线、跨模型回归、几何边界、月缘地形和输出契约测试,完善中英文手册、示例资源、NOTICE 与忽略规则
This commit is contained in:
2026-10-15 23:54:15 +08:00
parent 16c62a97d5
commit 044f2f4381
674 changed files with 62983 additions and 8396 deletions
+71 -31
View File
@@ -6,9 +6,20 @@
An astronomy library I have used for years for my own interest in astronomy and calendars.
Based on Jean Meeus's *Astronomical Algorithms*. Solar and planetary calculations use built-in VSOP87 terms; lunar calculations use ELP2000/82-style truncated series. No external ephemeris files are required.
> ### ⚠️ Time-scale change: UTC switches to leap hours on 2027-05-20
>
> On 15 October 2026 the 28th General Conference on Weights and Measures (CGPM) adopted [Resolution 5, "On the technical actions needed to ensure the continuity of UTC"](https://www.bipm.org/en/cgpm-2026/resolution-5) (`Resolution-CGPM-28-5`, DOI `10.59161/CGPM2026RES5E`): **continuous UTC becomes effective on 20 May 2027** and the maximum value of `|UT1−UTC|` is widened from 0.9 seconds to **3600 seconds (1 hour)** — a leap hour in place of a leap second.
>
> [IERS Bulletin C 72 (2026-07-06)](https://datacenter.iers.org/data/latestVersion/bulletinC.txt) confirms that **no leap second will be introduced at the end of December 2026**; the leap-second mechanism ends on 2027-05-20, so the possible insertion point at the end of June 2027 will not carry one either.
>
> From this release the library keeps **1972–2026 on the definitive leap-second table** (those historical values are unchanged) and changes the default policy beyond the built-in window (which ends 2026-10-01) from `TimeScaleLeapSecond` to **`TimeScaleLeapHour`**; past the window TT−UTC stays at 69.184 seconds. The numeric values of the `SetTimeScaleFuturePolicy` constants changed accordingly (`TimeScaleLeapHour` is now the zero value), so callers passing raw integers must update. See [Time scales](doc/manual/en/timescale.md).
Intended for calendar calculations, amateur observation and studying astronomical algorithms.
The library ships two ephemerides, selectable in one process or used side by side:
1. **Semianalytic model** (`ModelSemianalytic`, default): the argument structure and initial amplitudes of VSOP2013/TOP2013 (planets) and ELP/MPP02 (Moon), refitted to the DE ephemerides — DE441 for the planetary long range, DE440 for the modern segment and DE441 for the Moon — and folded into a single compact series table. The planetary table is about 452 KiB and the lunar table about 42 KiB, with no external ephemeris files. Its geocentric apparent direction error (RMS) in the modern range is about 0.007″ (Sun) and 0.076″ (Moon).
2. **Legacy model** (`ModelLegacy`): the VSOP87/ELP2000-82 series with added long-term and per-body corrections. Switch to it to reproduce old values; its geocentric apparent direction error (RMS) in the modern range is about 0.04″ (Sun) and 0.75″ (Moon). See [Accuracy and Performance](doc/manual/en/accuracy.md).
External ephemerides can also be supplied through SPK or a custom engine.
## Install
@@ -19,15 +30,17 @@ go get b612.me/astro
## Highlights
- Civil and Chinese calendar conversion from 721 BCE to 3000 CE, solar terms, sexagenary dates, era names and historical calendars.
- Positions, rise/set, transit, distances, angular diameters and physical ephemerides for the Sun, Moon and seven planets; lightweight Sun and Moon algorithms are also available.
- Solar and lunar eclipses, stellar and planetary lunar occultations, local contacts and global paths.
- SVG charts, GeoJSON data and KML for viewing and time playback in Google Earth.
- A built-in catalog of 9,100 stars, with constellation lookup, coordinate corrections and rise/set calculations.
- Coordinate transformations, sidereal time, precession, nutation, refraction, small-body orbits, sundials and astronomical formulas.
- Positions, rise/set, transit, distance, apparent diameter and physical ephemerides for the Sun, Moon and seven planets; lightweight Sun and Moon algorithms are also included.
- Solar and lunar eclipses, stellar and planetary lunar occultations, event searches, local contact times and global paths.
- Generic sky-event searches: ecliptic-longitude crossings, stationary points, phases, closest approach, rise/set at any altitude, perihelion/aphelion and heliacal visibility.
- Switchable ephemeris models, multiple instances used in parallel in one process, SPK multi-source stacking and optional perturbed propagation.
- SVG sky-event charts, GeoJSON geographic data and KML for viewing and time playback in Google Earth.
- A built-in catalog of 9100 stars with constellation lookup, coordinate corrections and rise/set calculations; CSV, Hipparcos, BSC5 and Stellarium external catalogs are also available.
- Celestial coordinate transformations, sidereal time, precession and nutation, refraction, astronomical formulas, sundial geometry and an optional lunar-limb terrain correction.
## Example
Calculate sunrise in Xi'an, the lunar phase and the Chinese calendar date:
Calculate the sunrise time, lunar phase and Chinese calendar date for a day in Xi'an:
```go
package main
@@ -61,49 +74,76 @@ func main() {
}
```
Longitude and latitude are in degrees, positive east and north. The example uses a height of 0 metres and enables refraction with `true`. Rise/set functions return errors for polar conditions or a missing event on that date.
Longitude and latitude are in degrees, positive east and north; the example uses a height of 0 metres and `true` makes the rise/set calculation account for atmospheric refraction. Rise/set functions return an error during polar day, polar night or when no event occurs on that date.
Calendar and phase descriptions in this example are returned in Chinese.
Package-level functions use the process-wide ephemeris model (semianalytic in default builds). To pin a model for a calculation, use `astro.NewContext`; multiple contexts can be used in parallel in one process:
```go
func compareModels(date time.Time) {
legacy, err := astro.NewContext(astro.ModelLegacy)
if err != nil {
panic(err)
}
modern, err := astro.NewContext(astro.ModelSemianalytic)
if err != nil {
panic(err)
}
fmt.Println(legacy.Moon().PhaseDesc(date), modern.Moon().PhaseDesc(date))
riseLegacy, _ := legacy.Sun().RiseTime(date, 108.93, 34.27, 0, true)
riseModern, _ := modern.Sun().RiseTime(date, 108.93, 34.27, 0, true)
fmt.Println(riseLegacy.Format("15:04:05"), riseModern.Format("15:04:05"))
}
```
A context exposes per-module entry points such as `Sun()`, `Moon()`, `Mars()`, `Eclipse()` and `Phenomena()`, with the same signatures as their package-level counterparts. Models isolate the ephemeris only; ΔT, TT−UTC and civil time-scale policy remain process-wide settings. See [Explicit ephemeris instances](doc/manual/en/ephemeris.md) for custom engines, SPK and multi-source stacking.
## Package Overview
| Package | Purpose and documentation |
| --- | --- |
| `calendar` | [Calendar conversion, solar terms, sexagenary dates and historical calendars](doc/manual/en/calendar.md) |
| `sun` / `moon` / `lite/sun` / `lite/moon` | [Sun and Moon positions, rise/set, phases and physical quantities](doc/manual/en/sun-moon.md) |
| `mercury` / `venus` / `mars` / `jupiter` / `saturn` / `uranus` / `neptune` / `earth` | [Planetary positions, events, Jupiter's satellites and Saturn's rings](doc/manual/en/planets.md) |
| `eclipse` / `eclipse/svg` | [Eclipse searches, local visibility, paths and charts](doc/manual/en/eclipse.md) |
| `moon` / `moon/svg` | [Stellar and planetary lunar occultations, contacts and bands](doc/manual/en/occultation.md) |
| `sun` / `moon` / `lite/sun` / `lite/moon` | [Sun and Moon positions, rise/set, lunar phases and physical quantities](doc/manual/en/sun-moon.md) |
| `mercury` / `venus` / `mars` / `jupiter` / `saturn` / `uranus` / `neptune` / `earth` | [Planetary positions, special events, Jupiter's satellites and Saturn's rings](doc/manual/en/planets.md) |
| `eclipse` / `eclipse/svg` | [Solar and lunar eclipse and transit searches, local visibility, paths and charts](doc/manual/en/eclipse.md) |
| `moon` / `moon/svg` / `moon/limb` | [Stellar and planetary lunar occultations, contact times, bands and the optional lunar-limb terrain correction](doc/manual/en/occultation.md) |
| `phenomena` | [Ecliptic-longitude crossings, stationary points, phases, closest approach, heliacal visibility and rise/set at any altitude for any two bodies](doc/manual/en/phenomena.md) |
| `geojson` / `kml` | [Event maps, GeoJSON and KML](doc/manual/en/map-geojson.md) |
| `star` | [Star catalog, constellations and observing quantities](doc/manual/en/star.md) |
| `coord` | [Coordinates, sidereal time, precession, nutation and refraction](doc/manual/en/coord.md) |
| `orbit` | [Asteroid and comet two-body orbits, visual binaries](doc/manual/en/orbit.md) |
| `star` / `star/catalog` | [Star database, constellations, observing quantities and external catalogs](doc/manual/en/star.md#external-catalogs) |
| `coord` | [Coordinate conversion, sidereal time, precession, nutation and refraction](doc/manual/en/coord.md) |
| `orbit` | [Asteroid and comet two-body or optional perturbed propagation, visual binaries](doc/manual/en/orbit.md) |
| `sundial` | [Apparent solar time and sundial geometry](doc/manual/en/sundial.md) |
| `formula` | [Radiation, magnitudes, synodic periods and telescope formulas](doc/manual/en/formula.md) |
| `astro` (root) | [UTC, UT1, TT and ΔT models](doc/manual/en/timescale.md) |
| `formula` | [Radiation, magnitudes, telescopes, atmospheric refraction, extinction and Earth-orientation tools](doc/manual/en/formula.md) |
| `astro` / `basic` / `planet/spk` | [Ephemeris models and instances, multi-source ephemerides and custom engines](doc/manual/en/ephemeris.md) |
| `astro` (root) | [UTC, UT1, TT conversion and ΔT models](doc/manual/en/timescale.md) |
`basic` contains the underlying algorithms, `planet` holds analytical series, and `tools` provides numerical helpers. Most applications can use the packages above.
Full signatures are also available in the [Go API documentation](https://pkg.go.dev/b612.me/astro).
`basic` contains the underlying algorithms, `planet` holds the built-in models and series, `planet/spk` reads external kernels, and `tools` provides numerical helpers. See [Accuracy and performance](doc/manual/en/accuracy.md) for model composition, measured errors and performance; full signatures are also available in the [Go API documentation](https://pkg.go.dev/b612.me/astro).
## Time Scale Conventions
Most observing APIs accept a civil instant as `time.Time` and handle UTC, UT1 and TT conversions internally. Before 1972 the library treats civil time as UT1, and as UTC thereafter. Orbital epochs and some low-level APIs have separate scale requirements.
Most observing APIs accept a civil instant as `time.Time` and handle UTC, UT1 and TT conversions internally. Before 1972 the library treats civil time as UT1, and as UTC thereafter; orbital epochs and some low-level APIs have separate time-scale requirements.
Angles default to degrees, angular diameters to arcseconds, sidereal time to hours, and distances to AU or km as specified by the API. SVG and GeoJSON time labels default to UTC, with explicit UT1 options.
Angles default to degrees, apparent diameters to arcseconds, sidereal time to hours, and distances to AU or km as specified by the API. SVG and GeoJSON time labels default to UTC, with an explicit UT1 option. See [Time scales](doc/manual/en/timescale.md) for the exact conventions.
See [Time scales](doc/manual/en/timescale.md).
DUT1 and TT−UTC default to extrapolating the current leap-second rule beyond the observed window (through September 2026); `SetTimeScaleFuturePolicy` switches the TT−UTC convention to one of four alternatives: a frozen offset, continued UT1 tracking, the leap-hour rule, or a civil scale permanently identical to UT1.
Beyond the monthly ΔT table, DUT1 and TT−UTC default to **leap-hour** extrapolation (`TimeScaleLeapHour`, matching the continuous UTC effective 2027-05-20); `SetTimeScaleFuturePolicy` switches between `TimeScaleLeapHour` (default), `TimeScaleLeapSecond`, `TimeScaleAssumeUT1Tracking`, `TimeScaleFreezeUTCOffset` and `TimeScaleUT1Civil`.
## Observer Height Convention
Observer height is ellipsoidal height in metres. Convert orthometric height `H` using the local geoid undulation `N`: `height = H + N`. See [Observer height](doc/manual/en/coord.md#observer-height).
Observer height is ellipsoidal height in metres. If only orthometric height `H` is available, convert it with the local geoid undulation `N`: `height = H + N`. See [Observer height](doc/manual/en/coord.md#observer-height).
## Scope And Accuracy
The library uses analytical models and truncated series. Accuracy varies with date, body and calculation. Professional occultation predictions and spacecraft navigation require more precise ephemerides and physical models.
Accuracy varies with model, epoch, body and calculated quantity. The default model has changed from VSOP87/ELP2000-82 to the semianalytic tables: signatures are unchanged but values may differ. `lite/sun` and `lite/moon` use independent approximation chains and do not follow model switches.
`lite/sun` and `lite/moon` suit resource-constrained applications. Some main APIs also provide truncated variants with an `N` suffix.
See [Accuracy and performance](doc/manual/en/accuracy.md) for model composition, error conventions and measured results. Professional occultation prediction, spacecraft navigation and similar uses also need ephemerides, time scales and physical models of matching accuracy; loading an SPK alone does not make every high-level result as accurate as the kernel.
Model ranges, measured differences and benchmarks are documented under [Accuracy and performance](doc/manual/en/accuracy.md).
## License
The code and documentation are licensed under [Apache-2.0](LICENSE). The third-party data embedded in this repository is **not** covered by Apache-2.0 and follows the terms of its own source; see [NOTICE](NOTICE) for the item-by-item statement:
- **SELENE (KAGUYA) LALT lunar limb profile** (`moon/limb/kaguya_lalt.bin`): ISAS/JAXA, distributed under the ISAS Data Policy, which states that its rules are compatible with CC BY 4.0.
- **This project's own refits of VSOP2013/TOP2013 and ELP/MPP02** (`planet/internal/semianalytic/`): the underlying theories are IMCCE / SYRTE. This project can neither grant nor restrict rights in those theories; Apache-2.0 applies only to this project's own code and compilation.
- **JPL DE440/DE441 and Horizons data** (`*/testdata/`, `planet/spk/testdata/`): NASA/JPL.
- **Astrometry in the built-in star catalogue** (`basic/star_catalog.dat`): derived from the Yale Bright Star Catalogue (VizieR [V/50](https://cdsarc.cds.unistra.fr/viz-bin/cat/V/50)).
- **Natural Earth 1:50m physical land** (`internal/svgmap/land_*.path`): public domain.