2bf8478639
- 新增日月食中心带、偏食带、阴影足迹、等时线、食分线及升落边界计算,支持极区与混合食拓扑 - 新增日食单时刻阴影求解器、站心状态查询、批量采样和 ΔT 覆盖接口 - 重构恒星与行星月掩路径,补充有限盘面接触、站心修正、掩带宽度、极区投影及升落边界 - 扩展 SVG 与 GeoJSON 输出,支持详细面板、全球/极区/地球投影、边界闭合、时间标记和拓扑签名 - 扩展日月食候选搜索、局地搜索、沙罗序列预计算与范围外推,补充系列锚点和成员一致性校验 - 补齐古历纪年、儒略历独有闰日、多公历候选、历法改革跨日及精确日期运算接口 - 优化 ΔT、章动、恒星时、月球地平线、事件根搜索和本地星历缓存,降低重复计算开销并提升边界稳定
63 lines
2.5 KiB
Go
63 lines
2.5 KiB
Go
package geojson_test
|
|
|
|
import (
|
|
"math"
|
|
"testing"
|
|
"time"
|
|
|
|
"b612.me/astro/internal/geodata"
|
|
"b612.me/astro/internal/occultationgeo"
|
|
)
|
|
|
|
func TestMars20250729TotalBandIsSingleMergedFace(t *testing.T) {
|
|
collection := mars20250729TestFixture(t, time.Minute, true).collection
|
|
totalBand := featureWithRole(t, collection, "total-band")
|
|
rings := geoJSONMultiPolygonOuterRings(t, totalBand)
|
|
if len(rings) != 1 {
|
|
t.Fatalf("total-band polygons=%d, want one merged face", len(rings))
|
|
}
|
|
for _, test := range []struct {
|
|
name string
|
|
probe geodata.GeoPoint
|
|
inside bool
|
|
}{
|
|
{name: "visible-sweep", probe: geodata.GeoPoint{Longitude: -129.8230, Latitude: -77.4030}, inside: true},
|
|
{name: "selected-west", probe: geodata.GeoPoint{Longitude: -134.6060, Latitude: -78.5601}, inside: true},
|
|
{name: "selected-center", probe: geodata.GeoPoint{Longitude: -134.2300, Latitude: -78.0725}, inside: true},
|
|
} {
|
|
inside := geodata.SphericalPolygonsContainPoints(rings, []geodata.GeoPoint{test.probe})[0]
|
|
if inside != test.inside {
|
|
t.Fatalf("total-band probe %s (%.4f, %.4f) inside=%v, want %v", test.name, test.probe.Longitude, test.probe.Latitude, inside, test.inside)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMars20250729FinalTotalBandHasWidePolarShoulderRepair(t *testing.T) {
|
|
collection := mars20250729TestFixture(t, time.Minute, true).collection
|
|
partial := geoJSONMultiPolygonOuterRings(t, featureWithRole(t, collection, "partial-band"))
|
|
total := geoJSONMultiPolygonOuterRings(t, featureWithRole(t, collection, "total-band"))
|
|
|
|
// The final GeoJSON pass must already have applied the total-only broad
|
|
// polar repair. Reapplying it should therefore be geometrically inert.
|
|
rerounded := occultationgeo.RoundAuthoritativeTotalBandJunctions(total)
|
|
remainingRepairKM := math.Max(
|
|
geodata.SphericalPolygonsPathMissDistanceKM(total, rerounded, true),
|
|
geodata.SphericalPolygonsPathMissDistanceKM(rerounded, total, true),
|
|
)
|
|
if remainingRepairKM > 1 {
|
|
t.Fatalf("final total-band still has a %.1f km repairable polar shoulder", remainingRepairKM)
|
|
}
|
|
if miss := geodata.SphericalPolygonsPathMissDistanceKM(partial, total, true); miss > 1 {
|
|
t.Fatalf("smoothed total-band lies %.1f km outside partial-band", miss)
|
|
}
|
|
|
|
roundedPartial := occultationgeo.RoundAuthoritativeBandJunctions(partial)
|
|
partialChangeKM := math.Max(
|
|
geodata.SphericalPolygonsPathMissDistanceKM(partial, roundedPartial, true),
|
|
geodata.SphericalPolygonsPathMissDistanceKM(roundedPartial, partial, true),
|
|
)
|
|
if partialChangeKM > 1 {
|
|
t.Fatalf("final partial-band unexpectedly needs %.1f km of further repair", partialChangeKM)
|
|
}
|
|
}
|