feat: 引入可切换星历模型并扩展天象观测链路
- 新增半解析、旧模型、自定义与多源堆叠星历实例,提供 Context、Instance、SPK 读取及状态与视位置计算 - 统一太阳、月球和行星实例接口,扩展黄经穿越、留、相位、最近角距、偕日可见、任意高度升落、轨道节点及凌日等天象查询 - 完善日月食、月掩与凌日的月缘剖面、有限盘面接触、站心修正、局地可见性、全球路径和地图输出 - 新增 SVG、GeoJSON、KML 天象输出及凌日、月掩和月缘地形相关缓存与几何求解 - 新增恒星星表导入与查询,支持 CSV、Hipparcos、BSC5、Stellarium 等格式及名称、交叉标识、锥面检索和星等过滤 - 补充 IAU 2006、地球定向、折射消光、大气观测、轨道传播及半解析行星/月球数据支持 - 将默认未来民用时标切换为 TimeScaleLeapHour,更新 2027–2400 农历速查表、中文日期解析和时区边界处理 - 增加事件基线、跨模型回归、几何边界、月缘地形和输出契约测试,完善中英文手册、示例资源、NOTICE 与忽略规则
This commit is contained in:
+7
-15
@@ -21,7 +21,7 @@ import (
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"b612.me/astro"
|
||||
"b612.me/astro/basic"
|
||||
"b612.me/astro/internal/geodata"
|
||||
)
|
||||
|
||||
@@ -75,7 +75,7 @@ type TimeMarkerOptions struct {
|
||||
// 并在集合上输出 time_scale 成员消歧(RFC 3339 的 Z 后缀严格说不等于 UT1)。此时 Location 必须是 nil 或 UTC。
|
||||
// TimeScale selects the scale of time properties: the zero value is UTC; TimeScaleUT1 writes UT1 labels
|
||||
// and adds a time_scale member (a RFC 3339 Z suffix is not exactly UT1). Location must then be nil or UTC.
|
||||
TimeScale astro.TimeScale
|
||||
TimeScale basic.TimeScale
|
||||
}
|
||||
|
||||
// dropFeaturesByRole 按 role 属性丢弃要素;空列表原样返回。
|
||||
@@ -108,7 +108,7 @@ func marshalEmptyFeatureCollection() ([]byte, error) {
|
||||
return encodeFeatureCollection(make([]feature, 0))
|
||||
}
|
||||
|
||||
func marshalFeatureCollectionWithTimeScale(features []feature, scale astro.TimeScale) ([]byte, error) {
|
||||
func marshalFeatureCollectionWithTimeScale(features []feature, scale basic.TimeScale) ([]byte, error) {
|
||||
if len(features) == 0 {
|
||||
return nil, fmt.Errorf("geojson: no geographic features")
|
||||
}
|
||||
@@ -116,12 +116,12 @@ func marshalFeatureCollectionWithTimeScale(features []feature, scale astro.TimeS
|
||||
}
|
||||
|
||||
func encodeFeatureCollection(features []feature) ([]byte, error) {
|
||||
return encodeFeatureCollectionWithTimeScale(features, astro.TimeScaleUTC)
|
||||
return encodeFeatureCollectionWithTimeScale(features, basic.TimeScaleUTC)
|
||||
}
|
||||
|
||||
func encodeFeatureCollectionWithTimeScale(features []feature, scale astro.TimeScale) ([]byte, error) {
|
||||
func encodeFeatureCollectionWithTimeScale(features []feature, scale basic.TimeScale) ([]byte, error) {
|
||||
member := ""
|
||||
if scale == astro.TimeScaleUT1 {
|
||||
if scale == basic.TimeScaleUT1 {
|
||||
member = "UT1"
|
||||
}
|
||||
value, err := json.Marshal(featureCollection{Type: featureCollectionType, Features: features, TimeScale: member})
|
||||
@@ -304,7 +304,7 @@ func interpolateTimeMarker(a, b pathSample, fraction float64, value time.Time) p
|
||||
}
|
||||
return pathSample{
|
||||
Time: value,
|
||||
Longitude: normalizeLongitude(a.Longitude + fraction*deltaLongitude),
|
||||
Longitude: geodata.NormalizeLongitude(a.Longitude + fraction*deltaLongitude),
|
||||
Latitude: a.Latitude + fraction*(b.Latitude-a.Latitude),
|
||||
}
|
||||
}
|
||||
@@ -613,11 +613,3 @@ func formatTime(value time.Time) string {
|
||||
}
|
||||
return value.UTC().Format(time.RFC3339Nano)
|
||||
}
|
||||
|
||||
func normalizeLongitude(value float64) float64 {
|
||||
value = math.Mod(value+180, 360)
|
||||
if value < 0 {
|
||||
value += 360
|
||||
}
|
||||
return value - 180
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user