feat: 完善时标与天象几何计算并扩展输出接口
- 新增时标、ΔT 模型、质心时间与 UT1 支持 - 改进日月食、月掩、行星事件及路径边界计算 - 完善恒星三维自行与动态距离传播 - 扩展 SVG、GeoJSON、KML 输出与底层距离换算工具 - 整理中英文手册、示例资源及回归测试
This commit is contained in:
@@ -32,8 +32,9 @@ func TestPolygonFragmentsCentredSeamKeepsGeometry(t *testing.T) {
|
||||
t.Fatalf("fragment has %d points", len(fragment))
|
||||
}
|
||||
for _, point := range fragment {
|
||||
if point.Longitude < -60-1e-6 || point.Longitude > 60+1e-6 {
|
||||
t.Fatalf("fragment longitude %.3f escaped the ring", point.Longitude)
|
||||
// 分段用地图窗口坐标表示(居中经线 ±180),折回 -180…180 后再比对。
|
||||
if longitude := normalizeLongitude180(point.Longitude); longitude < -60-1e-6 || longitude > 60+1e-6 {
|
||||
t.Fatalf("fragment longitude %.3f escaped the ring", longitude)
|
||||
}
|
||||
if math.Abs(point.Latitude) > 30+0.5 {
|
||||
t.Fatalf("fragment latitude %.3f escaped the ring", point.Latitude)
|
||||
|
||||
@@ -455,7 +455,7 @@ func equirectangularSeamShift(view ClipView) float64 {
|
||||
func splitPolylineAtSeam(points []GeoPoint, shift float64) [][]GeoPoint {
|
||||
segments := splitPolylineAntimeridian(rotateLongitudes(points, -shift))
|
||||
for _, segment := range segments {
|
||||
rotateLongitudesInPlace(segment, shift)
|
||||
unshiftLongitudesInPlace(segment, shift)
|
||||
}
|
||||
return segments
|
||||
}
|
||||
@@ -464,7 +464,7 @@ func splitPolylineAtSeam(points []GeoPoint, shift float64) [][]GeoPoint {
|
||||
func splitPolygonAtSeam(points []GeoPoint, shift float64) [][]GeoPoint {
|
||||
fragments := splitPolygonAntimeridian(rotateLongitudes(points, -shift))
|
||||
for _, fragment := range fragments {
|
||||
rotateLongitudesInPlace(fragment, shift)
|
||||
unshiftLongitudesInPlace(fragment, shift)
|
||||
}
|
||||
return fragments
|
||||
}
|
||||
@@ -472,13 +472,25 @@ func splitPolygonAtSeam(points []GeoPoint, shift float64) [][]GeoPoint {
|
||||
func rotateLongitudes(points []GeoPoint, shift float64) []GeoPoint {
|
||||
rotated := make([]GeoPoint, len(points))
|
||||
copy(rotated, points)
|
||||
rotateLongitudesInPlace(rotated, shift)
|
||||
for index := range rotated {
|
||||
rotated[index].Longitude = normalizeLongitude180(rotated[index].Longitude + shift)
|
||||
}
|
||||
return rotated
|
||||
}
|
||||
|
||||
func rotateLongitudesInPlace(points []GeoPoint, shift float64) {
|
||||
// unshiftLongitudesInPlace 把接缝坐标系的分段转回地图窗口,结果落在 [shift-180, shift+180]。
|
||||
// 窗口两端是同一条接缝经线:分段落在 +180 的点贴的是右边缘,折回 -180 会让闭合边横穿整幅图。
|
||||
func unshiftLongitudesInPlace(points []GeoPoint, shift float64) {
|
||||
left := shift - 180
|
||||
for index := range points {
|
||||
points[index].Longitude = normalizeLongitude180(points[index].Longitude + shift)
|
||||
value := points[index].Longitude + shift
|
||||
for value < left {
|
||||
value += 360
|
||||
}
|
||||
for value > left+360 {
|
||||
value -= 360
|
||||
}
|
||||
points[index].Longitude = value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user