summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2018-07-07 00:31:02 +0300
committerBruno de Oliveira Abinader <bruno@mapbox.com>2018-07-09 22:02:49 +0300
commit68bed94cd1492e49e2aa191a293ead54b80ac918 (patch)
tree5f78f66c03e0c6e230aad35a56ac5a7a99805c32
parent37e680c66b99b28d9fae9e15a1690a94760cb3a9 (diff)
downloadqtlocation-mapboxgl-68bed94cd1492e49e2aa191a293ead54b80ac918.tar.gz
[core] Harden Projection::project()
-rw-r--r--include/mbgl/util/projection.hpp3
-rw-r--r--test/util/projection.test.cpp43
2 files changed, 45 insertions, 1 deletions
diff --git a/include/mbgl/util/projection.hpp b/include/mbgl/util/projection.hpp
index 65a84d8dc2..9619a380b4 100644
--- a/include/mbgl/util/projection.hpp
+++ b/include/mbgl/util/projection.hpp
@@ -94,9 +94,10 @@ public:
private:
static Point<double> project_(const LatLng& latLng, double worldSize) {
+ const double latitude = util::clamp(latLng.latitude(), -util::LATITUDE_MAX, util::LATITUDE_MAX);
return Point<double> {
util::LONGITUDE_MAX + latLng.longitude(),
- util::LONGITUDE_MAX - util::RAD2DEG * std::log(std::tan(M_PI / 4 + latLng.latitude() * M_PI / util::DEGREES_MAX))
+ util::LONGITUDE_MAX - util::RAD2DEG * std::log(std::tan(M_PI / 4 + latitude * M_PI / util::DEGREES_MAX))
} * worldSize / util::DEGREES_MAX;
}
};
diff --git a/test/util/projection.test.cpp b/test/util/projection.test.cpp
index a489320dde..abe0b8bcfe 100644
--- a/test/util/projection.test.cpp
+++ b/test/util/projection.test.cpp
@@ -7,6 +7,49 @@
using namespace mbgl;
+TEST(Projection, Boundaries) {
+ LatLng sw { -90.0, -180.0 };
+ LatLng ne { 90.0, 180.0 };
+
+ const double minScale = std::pow(2, 0);
+ const double maxScale = std::pow(2, util::DEFAULT_MAX_ZOOM);
+
+ Point<double> projected {};
+ LatLng unprojected {};
+
+ projected = Projection::project(sw, minScale);
+ EXPECT_DOUBLE_EQ(projected.x, 0.0);
+ EXPECT_DOUBLE_EQ(projected.y, util::tileSize);
+
+ unprojected = Projection::unproject(projected, minScale);
+ EXPECT_DOUBLE_EQ(unprojected.latitude(), -util::LATITUDE_MAX);
+ EXPECT_DOUBLE_EQ(unprojected.longitude(), sw.longitude());
+
+ projected = Projection::project(sw, maxScale);
+ EXPECT_DOUBLE_EQ(projected.x, 0.0);
+ EXPECT_DOUBLE_EQ(projected.y, util::tileSize * maxScale);
+
+ unprojected = Projection::unproject(projected, maxScale);
+ EXPECT_DOUBLE_EQ(unprojected.latitude(), -util::LATITUDE_MAX);
+ EXPECT_DOUBLE_EQ(unprojected.longitude(), sw.longitude());
+
+ projected = Projection::project(ne, minScale);
+ EXPECT_DOUBLE_EQ(projected.x, util::tileSize);
+ ASSERT_NEAR(projected.y, 0.0, 1e-10);
+
+ unprojected = Projection::unproject(projected, minScale);
+ EXPECT_DOUBLE_EQ(unprojected.latitude(), util::LATITUDE_MAX);
+ EXPECT_DOUBLE_EQ(unprojected.longitude(), ne.longitude());
+
+ projected = Projection::project(ne, maxScale);
+ EXPECT_DOUBLE_EQ(projected.x, util::tileSize * maxScale);
+ ASSERT_NEAR(projected.y, 0.0, 1e-6);
+
+ unprojected = Projection::unproject(projected, maxScale);
+ EXPECT_DOUBLE_EQ(unprojected.latitude(), util::LATITUDE_MAX);
+ EXPECT_DOUBLE_EQ(unprojected.longitude(), ne.longitude());
+}
+
TEST(Projection, MetersPerPixelAtLatitude) {
double zoom = 0;
EXPECT_DOUBLE_EQ(Projection::getMetersPerPixelAtLatitude(0, zoom), 78271.516964020484);