Skip to content

Commit b11bb3b

Browse files
committed
Update Mount Everest height and minor test restructuring
1 parent f00fa35 commit b11bb3b

File tree

2 files changed

+51
-30
lines changed

2 files changed

+51
-30
lines changed

earth/earth.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,18 @@ const (
4444
Radius = 6371.01 * unit.Kilometer
4545

4646
// LowestAltitude is the altitude of the lowest known point on Earth,
47-
// the Challenger Deep, below the surface of the spherical earth.
48-
LowestAltitude = -10.898 * unit.Kilometer
47+
// the Challenger Deep, below the surface of the spherical Earth. This value
48+
// is the same as the C++ and Java implementations of S2Earth. The value may
49+
// change as more precise measurements are made.
50+
51+
LowestAltitude = -10898 * unit.Meter
4952

5053
// HighestAltitude is the altitude of the highest known point on Earth,
51-
// Mount Everest, above the surface of the spherical earth.
52-
HighestAltitude = 8.846 * unit.Kilometer
54+
// Mount Everest, above the surface of the spherical Earth. This value is the
55+
// same as the C++ and Java implementations of S2Earth. The value may change
56+
// as more precise measurements are made.
57+
58+
HighestAltitude = 8848 * unit.Meter
5359
)
5460

5561
// AngleFromLength returns the angle from a given distance on the spherical
@@ -110,5 +116,4 @@ func InitialBearingFromLatLngs(a, b s2.LatLng) s1.Angle {
110116
func haversine(radians float64) float64 {
111117
sinHalf := math.Sin(radians / 2)
112118
return sinHalf * sinHalf
113-
114119
}

earth/earth_test.go

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ func TestLengthFromLatLngs(t *testing.T) {
9696
{-37, 25, -66, -155, 8562022.790666264 * unit.Meter},
9797
{0, 165, 0, -80, 12787436.635410652 * unit.Meter},
9898
{47, -127, -47, 53, 20015118.077688109 * unit.Meter},
99+
{51.961951, -180.227156, 51.782383, 181.126878, 95.0783566198074 * unit.Kilometer},
99100
}
100101
for _, test := range tests {
101102
ll1 := s2.LatLngFromDegrees(test.lat1, test.lng1)
@@ -106,13 +107,14 @@ func TestLengthFromLatLngs(t *testing.T) {
106107
}
107108
}
108109

109-
func TestAreaFromSteradians(t *testing.T) {
110-
const earthArea = 6371.01 * 6371.01 * math.Pi * 4 * unit.SquareKilometer
111-
tests := []struct {
110+
var (
111+
earthArea = unit.Area(Radius.Meters()*Radius.Meters()) * math.Pi * 4
112+
steradiansToArea = []struct {
112113
steradians float64
113114
area unit.Area
114115
}{
115116
{1, earthArea / 4 / math.Pi},
117+
{4 * math.Pi, earthArea},
116118
{s2.PolygonFromLoops([]*s2.Loop{s2.FullLoop()}).Area(), earthArea},
117119
{s2.PolygonFromLoops([]*s2.Loop{s2.LoopFromPoints([]s2.Point{
118120
s2.PointFromLatLng(s2.LatLngFromDegrees(-90, 0)),
@@ -126,34 +128,18 @@ func TestAreaFromSteradians(t *testing.T) {
126128
{s2.AvgAreaMetric.Value(30), 73.73529927808979 * unit.SquareMillimeter}, // average area of level 30 cells
127129
{s2.PolygonFromLoops([]*s2.Loop{s2.EmptyLoop()}).Area(), 0 * unit.SquareMeter},
128130
}
129-
for _, test := range tests {
131+
)
132+
133+
func TestAreaFromSteradians(t *testing.T) {
134+
for _, test := range steradiansToArea {
130135
if got, want := AreaFromSteradians(test.steradians), test.area; !float64Eq(got.SquareMeters(), want.SquareMeters()) {
131136
t.Errorf("AreaFromSteradians(%v) = %v, want %v", test.steradians, got, want)
132137
}
133138
}
134139
}
135140

136141
func TestSteradiansFromArea(t *testing.T) {
137-
const earthArea = 6371.01 * 6371.01 * math.Pi * 4 * unit.SquareKilometer
138-
tests := []struct {
139-
steradians float64
140-
area unit.Area
141-
}{
142-
{1, earthArea / 4 / math.Pi},
143-
{s2.PolygonFromLoops([]*s2.Loop{s2.FullLoop()}).Area(), earthArea},
144-
{s2.PolygonFromLoops([]*s2.Loop{s2.LoopFromPoints([]s2.Point{
145-
s2.PointFromLatLng(s2.LatLngFromDegrees(-90, 0)),
146-
s2.PointFromLatLng(s2.LatLngFromDegrees(0, 0)),
147-
s2.PointFromLatLng(s2.LatLngFromDegrees(90, 0)),
148-
s2.PointFromLatLng(s2.LatLngFromDegrees(0, -90)),
149-
})}).Area(), earthArea / 4},
150-
{s2.CellFromCellID(s2.CellIDFromFace(2)).ExactArea(), earthArea / 6},
151-
{s2.AvgAreaMetric.Value(10), 81.07281893380302 * unit.SquareKilometer}, // average area of level 10 cells
152-
{s2.AvgAreaMetric.Value(20), 77.31706517582228 * unit.SquareMeter}, // average area of level 20 cells
153-
{s2.AvgAreaMetric.Value(30), 73.73529927808979 * unit.SquareMillimeter}, // average area of level 30 cells
154-
{s2.PolygonFromLoops([]*s2.Loop{s2.EmptyLoop()}).Area(), 0 * unit.SquareMeter},
155-
}
156-
for _, test := range tests {
142+
for _, test := range steradiansToArea {
157143
if got, want := SteradiansFromArea(test.area), test.steradians; !float64Eq(got, want) {
158144
t.Errorf("SteradiansFromArea(%v) = %v, want %v", test.area, got, want)
159145
}
@@ -186,7 +172,37 @@ func TestInitialBearingFromLatLngs(t *testing.T) {
186172
t.Run(tc.name, func(t *testing.T) {
187173
got := InitialBearingFromLatLngs(tc.a, tc.b)
188174
if diff := (got - tc.want).Abs(); diff > 0.01 {
189-
t.Errorf("InitialBearingsFromLatLngs(%s, %s): got %s, want %s, diff %s", tc.a, tc.b, got, tc.want, diff)
175+
t.Errorf("InitialBearingFromLatLngs(%s, %s): got %s, want %s, diff %s", tc.a, tc.b, got, tc.want, diff)
176+
}
177+
})
178+
}
179+
}
180+
181+
func TestInitialBearingFromLatLngsUndefinedResultDoesNotCrash(t *testing.T) {
182+
// InitialBearingFromLatLngs says if a == b, a == -b, or a is one of Earth's
183+
// poles, the return value is undefined. Make sure it returns a real value
184+
// (but don't assert what it is) rather than panicking or NaN.
185+
// Bearing from a pole is undefined because 0° is north, but the observer
186+
// can't face north from the north pole, so the calculation depends on the
187+
// latitude value at the pole, even though 90°N 123°E and 90°N 45°W represent
188+
// the same point. Bearing is undefined when a == b because the observer can
189+
// point any direction and still be present. Bearing is undefined when
190+
// a == -b (two antipodal points) because there are two possible paths.
191+
for _, tc := range []struct {
192+
name string
193+
a, b s2.LatLng
194+
}{
195+
{"North pole prime meridian to Null Island", s2.LatLngFromDegrees(90, 0), s2.LatLngFromDegrees(0, 0)},
196+
{"North pole facing east to Guatemala", s2.LatLngFromDegrees(90, 90), s2.LatLngFromDegrees(15, -90)},
197+
{"South pole facing west to McMurdo", s2.LatLngFromDegrees(-90, -90), s2.LatLngFromDegrees(-78, 166)},
198+
{"South pole anti-prime meridian to Null Island", s2.LatLngFromDegrees(-90, -180), s2.LatLngFromDegrees(0, 0)},
199+
{"Jakarta and antipode", s2.LatLngFromDegrees(-6.109, 106.668), s2.LatLngFromDegrees(6.109, -180+106.668)},
200+
{"Alert and antipode", s2.LatLngFromDegrees(82.499, -62.350), s2.LatLngFromDegrees(-82.499, 180-62.350)},
201+
} {
202+
t.Run(tc.name, func(t *testing.T) {
203+
got := InitialBearingFromLatLngs(tc.a, tc.b)
204+
if math.IsNaN(got.Radians()) || math.IsInf(got.Radians(), 0) {
205+
t.Errorf("InitialBearingFromLatLngs(%s, %s): got %s, want a real value", tc.a, tc.b, got)
190206
}
191207
})
192208
}

0 commit comments

Comments
 (0)