From 68bed94cd1492e49e2aa191a293ead54b80ac918 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Sat, 7 Jul 2018 00:31:02 +0300 Subject: [core] Harden Projection::project() --- include/mbgl/util/projection.hpp | 3 ++- test/util/projection.test.cpp | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) 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 project_(const LatLng& latLng, double worldSize) { + const double latitude = util::clamp(latLng.latitude(), -util::LATITUDE_MAX, util::LATITUDE_MAX); return Point { 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 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); -- cgit v1.2.1