summaryrefslogtreecommitdiff
path: root/src/third_party/s2/s2latlng_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/s2/s2latlng_test.cc')
-rw-r--r--src/third_party/s2/s2latlng_test.cc136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/third_party/s2/s2latlng_test.cc b/src/third_party/s2/s2latlng_test.cc
new file mode 100644
index 00000000000..68ae7739a70
--- /dev/null
+++ b/src/third_party/s2/s2latlng_test.cc
@@ -0,0 +1,136 @@
+// Copyright 2005 Google Inc. All Rights Reserved.
+
+#include "s2latlng.h"
+#include "base/macros.h"
+#include "base/stringprintf.h"
+#include "strings/split.h"
+#include "testing/base/public/gunit.h"
+#include "testing/base/public/benchmark.h"
+#include "s2testing.h"
+
+TEST(S2LatLng, TestBasic) {
+ S2LatLng ll_rad = S2LatLng::FromRadians(M_PI_4, M_PI_2);
+ EXPECT_EQ(M_PI_4, ll_rad.lat().radians());
+ EXPECT_EQ(M_PI_2, ll_rad.lng().radians());
+ EXPECT_TRUE(ll_rad.is_valid());
+ S2LatLng ll_deg = S2LatLng::FromDegrees(45, 90);
+ EXPECT_EQ(ll_rad, ll_deg);
+ EXPECT_TRUE(ll_deg.is_valid());
+ EXPECT_FALSE(S2LatLng::FromDegrees(-91, 0).is_valid());
+ EXPECT_FALSE(S2LatLng::FromDegrees(0, 181).is_valid());
+
+ S2LatLng bad = S2LatLng::FromDegrees(120, 200);
+ EXPECT_FALSE(bad.is_valid());
+ S2LatLng better = bad.Normalized();
+ EXPECT_TRUE(better.is_valid());
+ EXPECT_EQ(S1Angle::Degrees(90), better.lat());
+ EXPECT_DOUBLE_EQ(S1Angle::Degrees(-160).radians(), better.lng().radians());
+
+ bad = S2LatLng::FromDegrees(-100, -360);
+ EXPECT_FALSE(bad.is_valid());
+ better = bad.Normalized();
+ EXPECT_TRUE(better.is_valid());
+ EXPECT_EQ(S1Angle::Degrees(-90), better.lat());
+ EXPECT_DOUBLE_EQ(0.0, better.lng().radians());
+
+ EXPECT_TRUE((S2LatLng::FromDegrees(10, 20) + S2LatLng::FromDegrees(20, 30)).
+ ApproxEquals(S2LatLng::FromDegrees(30, 50)));
+ EXPECT_TRUE((S2LatLng::FromDegrees(10, 20) - S2LatLng::FromDegrees(20, 30)).
+ ApproxEquals(S2LatLng::FromDegrees(-10, -10)));
+ EXPECT_TRUE((0.5 * S2LatLng::FromDegrees(10, 20)).
+ ApproxEquals(S2LatLng::FromDegrees(5, 10)));
+
+ // Check that Invalid() returns an invalid point.
+ S2LatLng invalid = S2LatLng::Invalid();
+ EXPECT_FALSE(invalid.is_valid());
+
+ // Check that the default constructor sets latitude and longitude to 0.
+ S2LatLng default_ll;
+ EXPECT_TRUE(default_ll.is_valid());
+ EXPECT_EQ(0, default_ll.lat().radians());
+ EXPECT_EQ(0, default_ll.lng().radians());
+}
+
+TEST(S2LatLng, TestConversion) {
+ // Test special cases: poles, "date line"
+ EXPECT_DOUBLE_EQ(90.0,
+ S2LatLng(S2LatLng::FromDegrees(90.0, 65.0).ToPoint())
+ .lat().degrees());
+ EXPECT_EQ(-M_PI_2,
+ S2LatLng(S2LatLng::FromRadians(-M_PI_2, 1).ToPoint())
+ .lat().radians());
+ EXPECT_DOUBLE_EQ(180.0,
+ fabs(S2LatLng(S2LatLng::FromDegrees(12.2, 180.0).ToPoint())
+ .lng().degrees()));
+ EXPECT_EQ(M_PI,
+ fabs(S2LatLng(S2LatLng::FromRadians(0.1, -M_PI).ToPoint())
+ .lng().radians()));
+
+ // Test a bunch of random points.
+ for (int i = 0; i < 100000; ++i) {
+ S2Point p = S2Testing::RandomPoint();
+ EXPECT_TRUE(S2::ApproxEquals(p, S2LatLng(p).ToPoint())) << p;
+ }
+}
+
+TEST(S2LatLng, TestDistance) {
+ EXPECT_EQ(0.0,
+ S2LatLng::FromDegrees(90, 0).GetDistance(
+ S2LatLng::FromDegrees(90, 0)).radians());
+ EXPECT_NEAR(77.0,
+ S2LatLng::FromDegrees(-37, 25).GetDistance(
+ S2LatLng::FromDegrees(-66, -155)).degrees(),
+ 1e-13);
+ EXPECT_NEAR(115.0,
+ S2LatLng::FromDegrees(0, 165).GetDistance(
+ S2LatLng::FromDegrees(0, -80)).degrees(),
+ 1e-13);
+ EXPECT_NEAR(180.0,
+ S2LatLng::FromDegrees(47, -127).GetDistance(
+ S2LatLng::FromDegrees(-47, 53)).degrees(),
+ 2e-6);
+}
+
+TEST(S2LatLng, TestToString) {
+ struct {
+ double lat, lng;
+ double expected_lat, expected_lng;
+ } values[] = {
+ {0, 0, 0, 0},
+ {1.5, 91.7, 1.5, 91.7},
+ {9.9, -0.31, 9.9, -0.31},
+ {sqrt(2), -sqrt(5), 1.414214, -2.236068},
+ {91.3, 190.4, 90, -169.6},
+ {-100, -710, -90, 10},
+ };
+ for (int i = 0; i < ARRAYSIZE(values); ++i) {
+ SCOPED_TRACE(StringPrintf("Iteration %d", i));
+ S2LatLng p = S2LatLng::FromDegrees(values[i].lat, values[i].lng);
+ string output;
+ p.ToStringInDegrees(&output);
+
+ const char *ptr = output.c_str();
+ double lat, lng;
+ EXPECT_TRUE(SplitOneDoubleToken(&ptr, ",", &lat));
+ ASSERT_TRUE(ptr != NULL);
+ EXPECT_TRUE(SplitOneDoubleToken(&ptr, ",", &lng));
+ EXPECT_NEAR(values[i].expected_lat, lat, 1e-8);
+ EXPECT_NEAR(values[i].expected_lng, lng, 1e-8);
+ }
+}
+
+// Test the variant that returns a string.
+TEST(S2LatLng, TestToStringReturnsString) {
+ string s;
+ S2LatLng::FromDegrees(0, 1).ToStringInDegrees(&s);
+ EXPECT_EQ(S2LatLng::FromDegrees(0, 1).ToStringInDegrees(), s);
+}
+
+
+static void BM_ToPoint(int iters) {
+ S2LatLng ll(S1Angle::E7(0x150bc888), S1Angle::E7(0x5099d63f));
+ for (int i = 0; i < iters; i++) {
+ ll.ToPoint();
+ }
+}
+BENCHMARK(BM_ToPoint);