feat: 引入可切换星历模型并扩展天象观测链路
- 新增半解析、旧模型、自定义与多源堆叠星历实例,提供 Context、Instance、SPK 读取及状态与视位置计算 - 统一太阳、月球和行星实例接口,扩展黄经穿越、留、相位、最近角距、偕日可见、任意高度升落、轨道节点及凌日等天象查询 - 完善日月食、月掩与凌日的月缘剖面、有限盘面接触、站心修正、局地可见性、全球路径和地图输出 - 新增 SVG、GeoJSON、KML 天象输出及凌日、月掩和月缘地形相关缓存与几何求解 - 新增恒星星表导入与查询,支持 CSV、Hipparcos、BSC5、Stellarium 等格式及名称、交叉标识、锥面检索和星等过滤 - 补充 IAU 2006、地球定向、折射消光、大气观测、轨道传播及半解析行星/月球数据支持 - 将默认未来民用时标切换为 TimeScaleLeapHour,更新 2027–2400 农历速查表、中文日期解析和时区边界处理 - 增加事件基线、跨模型回归、几何边界、月缘地形和输出契约测试,完善中英文手册、示例资源、NOTICE 与忽略规则
This commit is contained in:
@@ -238,13 +238,13 @@ func TestSmoothOccultationHairpinsKeepsShortDisplayEdges(t *testing.T) {
|
||||
maximumEdge := 0.0
|
||||
maximumDetour := 0.0
|
||||
for index := 1; index < len(smoothed); index++ {
|
||||
maximumEdge = math.Max(maximumEdge, geoDistanceKM(smoothed[index-1], smoothed[index]))
|
||||
maximumEdge = math.Max(maximumEdge, geodata.EquatorialDistanceKM(smoothed[index-1], smoothed[index]))
|
||||
}
|
||||
for index := 1; index+1 < len(smoothed); index++ {
|
||||
maximumDetour = math.Max(maximumDetour,
|
||||
geoDistanceKM(smoothed[index-1], smoothed[index])+
|
||||
geoDistanceKM(smoothed[index], smoothed[index+1])-
|
||||
geoDistanceKM(smoothed[index-1], smoothed[index+1]))
|
||||
geodata.EquatorialDistanceKM(smoothed[index-1], smoothed[index])+
|
||||
geodata.EquatorialDistanceKM(smoothed[index], smoothed[index+1])-
|
||||
geodata.EquatorialDistanceKM(smoothed[index-1], smoothed[index+1]))
|
||||
}
|
||||
if maximumEdge > 50.01 {
|
||||
t.Fatalf("smoothed maximum edge=%.1f km, want <=50 km", maximumEdge)
|
||||
@@ -300,10 +300,10 @@ func TestSmoothOccultationOrdinaryWobblesHandlesHighLatitudeArc(t *testing.T) {
|
||||
}
|
||||
changed := false
|
||||
for index := 1; index+1 < len(points); index++ {
|
||||
if geoDistanceKM(points[index], smoothed[index]) > 0.001 {
|
||||
if geodata.EquatorialDistanceKM(points[index], smoothed[index]) > 0.001 {
|
||||
changed = true
|
||||
if geoDistanceKM(points[index], smoothed[index]) > 20 {
|
||||
t.Fatalf("high-latitude smoothing moved point %d by %.2f km", index, geoDistanceKM(points[index], smoothed[index]))
|
||||
if geodata.EquatorialDistanceKM(points[index], smoothed[index]) > 20 {
|
||||
t.Fatalf("high-latitude smoothing moved point %d by %.2f km", index, geodata.EquatorialDistanceKM(points[index], smoothed[index]))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -321,7 +321,7 @@ func TestDensifyOccultationPolygonsIncludesClosingEdge(t *testing.T) {
|
||||
}
|
||||
densified := densifyOccultationPolygons([][]geodata.GeoPoint{points}, 50)
|
||||
ring := densified[0]
|
||||
maximumEdge := geoDistanceKM(ring[len(ring)-1], ring[0])
|
||||
maximumEdge := geodata.EquatorialDistanceKM(ring[len(ring)-1], ring[0])
|
||||
if maximumEdge > 50.01 {
|
||||
t.Fatalf("closing edge=%.1f km, want <=50 km", maximumEdge)
|
||||
}
|
||||
@@ -449,7 +449,7 @@ func TestVisibleBandPolygons20250105SaturnEnvelopeCandidates(t *testing.T) {
|
||||
}
|
||||
for _, polygon := range final {
|
||||
for index := 1; index < len(polygon); index++ {
|
||||
if distance := geoDistanceKM(polygon[index-1], polygon[index]); distance > BoundaryBranchJumpKM {
|
||||
if distance := geodata.EquatorialDistanceKM(polygon[index-1], polygon[index]); distance > BoundaryBranchJumpKM {
|
||||
t.Fatalf("band ring spans a %.1f km edge", distance)
|
||||
}
|
||||
}
|
||||
@@ -519,7 +519,7 @@ func TestSmoothOccultationOrdinaryWobblesPreservesEndpointsAndBoundedMotion(t *t
|
||||
t.Fatalf("ordinary smoothing changed open endpoints: %#v", cleaned)
|
||||
}
|
||||
for index, point := range cleaned {
|
||||
if move := geoDistanceKM(point, ring[index]); move > 20.001 {
|
||||
if move := geodata.EquatorialDistanceKM(point, ring[index]); move > 20.001 {
|
||||
t.Fatalf("point %d moved %.2f km, want <=20 km", index, move)
|
||||
}
|
||||
}
|
||||
@@ -585,7 +585,7 @@ func occultationTestWindowTouchesHorizon(
|
||||
}
|
||||
for offset := -2; offset <= 2; offset++ {
|
||||
for _, horizon := range horizons {
|
||||
if geoDistanceKM(polygon[index+offset], horizon) <= windowKM {
|
||||
if geodata.EquatorialDistanceKM(polygon[index+offset], horizon) <= windowKM {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -716,7 +716,7 @@ func TestVisibleBandPolygons20250729MarsStitchesEndRiseFold(t *testing.T) {
|
||||
minimumTurn := 180.0
|
||||
for index := 1; index+1 < len(polygon); index++ {
|
||||
first, middle, last := polygon[index-1], polygon[index], polygon[index+1]
|
||||
detour := geoDistanceKM(first, middle) + geoDistanceKM(middle, last) - geoDistanceKM(first, last)
|
||||
detour := geodata.EquatorialDistanceKM(first, middle) + geodata.EquatorialDistanceKM(middle, last) - geodata.EquatorialDistanceKM(first, last)
|
||||
if detour > maximumDetour {
|
||||
maximumDetour = detour
|
||||
}
|
||||
@@ -1027,7 +1027,7 @@ func TestOccultationPhaseBoundaryCycleExcludesGreatestInteriorLine(t *testing.T)
|
||||
minimum := math.Inf(1)
|
||||
for _, line := range phaseLines {
|
||||
for _, candidate := range line {
|
||||
minimum = math.Min(minimum, geoDistanceKM(point, candidate))
|
||||
minimum = math.Min(minimum, geodata.EquatorialDistanceKM(point, candidate))
|
||||
}
|
||||
}
|
||||
if minimum > 1 {
|
||||
@@ -1135,7 +1135,7 @@ func TestVisibleBandPolygons20250729MarsTotalRiseSetRemovesPolarBacktrack(t *tes
|
||||
limit = len(polygon) - 1
|
||||
}
|
||||
for endIndex := startIndex + 1; endIndex <= limit; endIndex++ {
|
||||
edge := geoDistanceKM(polygon[endIndex-1], polygon[endIndex])
|
||||
edge := geodata.EquatorialDistanceKM(polygon[endIndex-1], polygon[endIndex])
|
||||
arcLength += edge
|
||||
if edge > maximumEdge {
|
||||
maximumEdge = edge
|
||||
@@ -1143,7 +1143,7 @@ func TestVisibleBandPolygons20250729MarsTotalRiseSetRemovesPolarBacktrack(t *tes
|
||||
if endIndex < startIndex+3 {
|
||||
continue
|
||||
}
|
||||
closure := geoDistanceKM(polygon[startIndex], polygon[endIndex])
|
||||
closure := geodata.EquatorialDistanceKM(polygon[startIndex], polygon[endIndex])
|
||||
if closure <= 180 && arcLength-closure >= 35 {
|
||||
t.Fatalf("total polygon %d retains a large polar backtrack: start=%d end=%d closure=%.1f km detour=%.1f km",
|
||||
polygonIndex, startIndex, endIndex, closure, arcLength-closure)
|
||||
|
||||
Reference in New Issue
Block a user