- 新增半解析、旧模型、自定义与多源堆叠星历实例,提供 Context、Instance、SPK 读取及状态与视位置计算 - 统一太阳、月球和行星实例接口,扩展黄经穿越、留、相位、最近角距、偕日可见、任意高度升落、轨道节点及凌日等天象查询 - 完善日月食、月掩与凌日的月缘剖面、有限盘面接触、站心修正、局地可见性、全球路径和地图输出 - 新增 SVG、GeoJSON、KML 天象输出及凌日、月掩和月缘地形相关缓存与几何求解 - 新增恒星星表导入与查询,支持 CSV、Hipparcos、BSC5、Stellarium 等格式及名称、交叉标识、锥面检索和星等过滤 - 补充 IAU 2006、地球定向、折射消光、大气观测、轨道传播及半解析行星/月球数据支持 - 将默认未来民用时标切换为 TimeScaleLeapHour,更新 2027–2400 农历速查表、中文日期解析和时区边界处理 - 增加事件基线、跨模型回归、几何边界、月缘地形和输出契约测试,完善中英文手册、示例资源、NOTICE 与忽略规则
10 KiB
通用天象与偕日可见
phenomena 包按地心视黄经、视黄纬搜索任意两天体的事件,计算行星与恒星的晨昏始见、末见,另外提供任意高度升落和近日点、远日点、过交点。包级入口使用进程当前的星历模型,也可以用 ctx.Phenomena() 固定星历实例;只有恒星的任意高度升落按传入的视坐标计算,不读星历。
目录
快速示例
start := time.Date(2020, 10, 1, 0, 0, 0, 0, time.UTC)
end := time.Date(2021, 3, 1, 0, 0, 0, 0, time.UTC)
events := phenomena.ClosestApproaches(phenomena.Jupiter, phenomena.Saturn, 1, start, end)
fmt.Println(events[0].Time.UTC().Format("2006-01-02 15:04"), fmt.Sprintf("%.4f", events[0].Value))
2020-12-21 18:21 0.1018
ClosestApproaches 返回窗口内两天体角距的局部极小,Value 是当时的角距(度)。窗口内没有小于 maxSeparation 的极小值时返回空切片。
固定星历实例时换成模块方法:
ctx, err := astro.NewContext(astro.ModelLegacy)
if err != nil {
panic(err)
}
events = ctx.Phenomena().ClosestApproaches(phenomena.Jupiter, phenomena.Saturn, 1, start, end)
天体对事件
| 入口 | 事件 | Event.Value |
|---|---|---|
LongitudeCrossings(body, lon, start, end) |
视黄经经过 lon |
事件时刻的视黄经(度) |
Stations(body, start, end) |
视黄经的留(行星) | 留时的视黄经(度) |
AspectCrossings(a, b, angle, start, end) |
lon(a) − lon(b) = angle;0 为黄经合,180 为冲 |
实际的黄经差(度) |
ClosestApproaches(a, b, max, start, end) |
两天体角距的局部极小 | 角距(度) |
StarApproaches(body, star, max, start, end) |
天体与恒星角距的局部极小 | 角距(度) |
各入口只接受上表列出的参数,结果按时间升序返回。各行星包里按赤经定义的留与这里按黄经定义的留口径不同,时刻可差数小时。
// 2026 年前两次水星留
stations := phenomena.Stations(phenomena.Mercury,
time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(2026, 4, 1, 0, 0, 0, 0, time.UTC))
for _, e := range stations {
fmt.Println(e.Time.UTC().Format("01-02 15:04"), fmt.Sprintf("%.3f", e.Value))
}
02-26 06:48 352.565
03-20 19:32 338.491
// 太阳视黄经经过 0°(春分)
crossings := phenomena.LongitudeCrossings(phenomena.Sun, 0,
time.Date(2026, 3, 18, 0, 0, 0, 0, time.UTC), time.Date(2026, 3, 24, 0, 0, 0, 0, time.UTC))
fmt.Println(crossings[0].Time.UTC().Format("2006-01-02 15:04"))
2026-03-20 14:45
恒星坐标
行星与恒星的角距、恒星偕日可见都要传入 StarCoordinate,内嵌 9100 星表可以直接查:
| 入口 | 输入 |
|---|---|
StarCoordinateByName(name) |
星表中文名,例如 "天狼星" |
StarCoordinateByHR(hr) |
HR 编号 |
StarCoordinateFromStarData(star) |
star.StarDataByHR 等取到的星表记录 |
star, err := phenomena.StarCoordinateByName("天狼星")
fmt.Println(err, star.ID, fmt.Sprintf("%.6f %.6f %.2f %.2f", star.RA, star.Dec,
star.ProperMotionRACosDecMasPerYear, star.ProperMotionDecMasPerYear))
<nil> 天狼 101.287083 -16.716111 -553.00 -1205.00
RA、Dec 为度,Epoch 与 Frame 必填;自行字段(ProperMotionRACosDecMasPerYear 等)按星表常见的 dRA·cos(Dec) 约定,单位毫角秒/年。ParallaxMas(或等价的 DistanceLightYear)给出距离,RadialVelocityKmPerSecond 给出视向速度;距离缺失时按二维自行传播,有距离时才计入视向速度。
偕日可见
PlanetHeliacalEvents(body, start, end, lon, lat, options) 与 StarHeliacalEvents(star, magnitude, start, end, lon, lat, options) 逐日扫描太阳高度 −18° 到 0° 的晨昏时段,按天光亮度模型求肉眼极限星等,再与目标视星等比较(行星用 Mallama & Hilton 2018 星等),返回四类事件:
| 常量 | 含义 |
|---|---|
HeliacalMorningFirst |
晨始见(偕日升) |
HeliacalMorningLast |
晨末见 |
HeliacalEveningFirst |
昏始见 |
HeliacalEveningLast |
昏末见(偕日落) |
HeliacalEvent 中 Time 是当次晨昏的最佳可见时刻,TargetAltitude、SunAltitude 是当时目标与太阳的几何高度(度),Margin 是极限星等减目标星等。
HeliacalOptions |
默认 | 说明 |
|---|---|---|
ExtinctionCoefficient |
0.25 |
大气消光,星等/大气质量 |
MinTargetAltitude |
0.5 |
目标最低几何高度(度) |
Moonlight |
false |
计入月光散射(Krisciunas–Schaefer) |
events := phenomena.PlanetHeliacalEvents(phenomena.Venus,
time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(2025, 12, 31, 0, 0, 0, 0, time.UTC),
31.23, 30.04, phenomena.HeliacalOptions{})
for _, e := range events {
fmt.Println(e.Kind, e.Time.UTC().Format("2006-01-02"), fmt.Sprintf("margin=%.2f", e.Margin))
}
3 2025-03-18 margin=0.10
0 2025-03-25 margin=0.58
1 2025-12-01 margin=0.10
Kind 打印出来是常量序号,判断时用常量本身比较。LimitingMagnitude(targetAltitude, sunAltitude, separation, extinction) 单独给出某一时刻无月夜的极限星等,与事件判定同源:
fmt.Println(fmt.Sprintf("%.3f", phenomena.LimitingMagnitude(20, -12, 60, 0.25)))
3.408
结果对消光系数敏感,可见日期差一两天属正常。
任意高度升落
AltitudeCrossing(body, date, lon, lat, height, altitude, options) 求日、月或行星在 date 所在当地民用日内首次穿过视高度 altitude 的升、落时刻。StarAltitudeCrossing(date, ra, dec, lon, lat, altitude, options) 对恒星视坐标做同样计算,它不读星历,也没有模块方法。
AltitudeOptions |
默认 | 说明 |
|---|---|---|
Limb |
LimbUpper |
日月取上缘,也可取 LimbCenter、LimbLower;行星与恒星忽略 |
PressureHPa / TemperatureC |
标准大气(0 值) |
指定实测气象 |
NoRefraction |
false |
为 true 时按几何高度比较 |
AltitudeCrossingResult |
说明 |
|---|---|
Rise、Set |
升、落时刻,没有事件时为零值 |
HasRise、HasSet |
当天是否存在升、落 |
State |
AltitudeCrosses、AltitudeAlwaysAbove、AltitudeAlwaysBelow 或 AltitudeTangent(极值与目标高度相差不足 1″) |
MinResidual、MaxResidual |
当天高度与目标高度之差的最小、最大值(度) |
cst := time.FixedZone("CST", 8*3600)
r, err := phenomena.AltitudeCrossing(phenomena.Sun, time.Date(2026, 3, 21, 12, 0, 0, 0, cst),
116.4, 39.9, 0, -18, phenomena.AltitudeOptions{})
fmt.Println(err, r.State, r.Rise.In(cst).Format("15:04:05"), r.Set.In(cst).Format("15:04:05"),
fmt.Sprintf("%.3f %.3f", r.MinResidual, r.MaxResidual))
<nil> 0 04:44:54 19:59:16 -31.806 68.602
// 北纬 89° 极昼:太阳整天都在 -18° 之上
polar, err := phenomena.AltitudeCrossing(phenomena.Sun, time.Date(2026, 6, 21, 12, 0, 0, 0, time.UTC),
0, 89, 0, -18, phenomena.AltitudeOptions{})
fmt.Println(err, polar.State, polar.HasRise, polar.HasSet, fmt.Sprintf("%.3f", polar.MinResidual))
<nil> 1 false false 40.737
// 天狼星穿过 -0.833° 的升落
sirius, err := phenomena.StarAltitudeCrossing(time.Date(2026, 1, 1, 12, 0, 0, 0, cst),
star.RA, star.Dec, 116.4, 39.9, -0.833, phenomena.AltitudeOptions{Limb: phenomena.LimbCenter})
fmt.Println(err, sirius.State, sirius.Rise.In(cst).Format("15:04:05"), sirius.Set.In(cst).Format("15:04:05"))
<nil> 0 19:04:31 05:27:52
height 只影响月球视差。需要以下沉地平为基准时,由调用方从 altitude 中减去地平俯角。天体不是日、月或行星(例如 phenomena.Earth),或恒星视坐标不是有限值时,返回 basic.ErrInvalidObservationInput。
近日点、远日点与过交点
| 常量 | 事件 |
|---|---|
Perihelion、Aphelion |
近日点、远日点 |
AscendingNode、DescendingNode |
穿过历元平黄道的升交点、降交点 |
Apsides(body, start, end) 接受行星或地球(phenomena.Earth),Nodes(body, start, end) 只接受行星,传地球返回空切片。OrbitalEvent 的 Time 是事件时刻,Kind 是上表常量,DistanceAU 是该时刻的日心距(AU)。
apsides := phenomena.Apsides(phenomena.Earth,
time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(2027, 1, 1, 0, 0, 0, 0, time.UTC))
for _, e := range apsides {
fmt.Println(e.Kind, e.Time.UTC().Format("2006-01-02 15:04"), fmt.Sprintf("%.9f AU", e.DistanceAU))
}
nodes := phenomena.Nodes(phenomena.Jupiter,
time.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(2030, 1, 1, 0, 0, 0, 0, time.UTC))
for _, e := range nodes {
fmt.Println(e.Kind, e.Time.UTC().Format("2006-01-02 15:04"), fmt.Sprintf("%.6f AU", e.DistanceAU))
}
0 2026-01-03 09:15 0.983302049 AU
1 2026-07-06 09:30 1.016643962 AU
3 2020-02-25 18:09 5.207056 AU
2 2025-09-19 11:58 5.174312 AU
极值取日心距本身:太阳绕质心的反射运动会让天王星、海王星的日心距在近日点附近出现多个小极值,同一段出现多个极小值时只返回前后各 0.3 个轨道周期内日心距最小的一个,与吻切轨道近日点可相差数年。
API 参考
ctx.Phenomena() 的方法与同名包级函数签名一致(StarAltitudeCrossing 除外);NewWithInstance 用给定星历实例创建模块。各入口的参数与单位见上文各节。
参数与返回值约定
- 角度一律为度,
OrbitalEvent.DistanceAU为 AU,StarHeliacalEvents的magnitude为 V 星等。 - 时间参数按绝对时刻解释(读取其 UTC 字段),返回时刻换算到
start(升落类为date)所在的时区。 - 事件搜索没有结果时返回空切片,不返回错误;只有任意高度升落在输入非法时返回
basic.ErrInvalidObservationInput。 - 事件搜索会用到星历,可以用模块方法固定模型;
StarAltitudeCrossing、StarCoordinate*与LimitingMagnitude与星历无关。 - 行星视星等、赤经留等口径差异见行星手册;日月升落与观测角语义见太阳与月亮。