From 1ee25054e59e15e75df120d208a8566da6e8748e Mon Sep 17 00:00:00 2001 From: Asheem Mamoowala Date: Mon, 19 Feb 2018 13:46:24 -0800 Subject: [core] Cleanup TileCount and remove extra Projection code --- include/mbgl/util/projection.hpp | 15 +++-------- platform/default/mbgl/storage/offline.cpp | 2 +- src/mbgl/util/tile_cover.cpp | 42 +++++++++++++++---------------- src/mbgl/util/tile_cover.hpp | 2 +- test/util/tile_cover.test.cpp | 21 ++++++++++++++-- test/util/tile_range.test.cpp | 8 +++--- 6 files changed, 49 insertions(+), 41 deletions(-) diff --git a/include/mbgl/util/projection.hpp b/include/mbgl/util/projection.hpp index b4a34521a4..9c467c0305 100644 --- a/include/mbgl/util/projection.hpp +++ b/include/mbgl/util/projection.hpp @@ -78,8 +78,8 @@ public: return project_(latLng, worldSize(scale)); } - static Point project(const LatLng& latLng, uint8_t zoom) { - return project_(latLng, std::pow(2.0, zoom)); + static Point project(const LatLng& latLng, int32_t zoom) { + return project_(latLng, 1 << zoom); } static LatLng unproject(const Point& p, double scale, LatLng::WrapMode wrapMode = LatLng::Unwrapped) { @@ -90,16 +90,7 @@ public: wrapMode }; } - - // Project lat, lon to point in a zoom-dependent world size - static Point project(const LatLng& point, uint8_t zoom, uint16_t tileSize) { - const double t2z = tileSize * std::pow(2, zoom); - Point pt = project_(point, t2z); - // Flip y coordinate - auto x = ::round(std::min(pt.x, t2z)); - auto y = ::round(std::min(t2z - pt.y, t2z)); - return { x, y }; - } + private: static Point project_(const LatLng& latLng, double worldSize) { return Point { diff --git a/platform/default/mbgl/storage/offline.cpp b/platform/default/mbgl/storage/offline.cpp index 7670790be9..598a0b182b 100644 --- a/platform/default/mbgl/storage/offline.cpp +++ b/platform/default/mbgl/storage/offline.cpp @@ -43,7 +43,7 @@ uint64_t OfflineTilePyramidRegionDefinition::tileCount(style::SourceType type, u const Range clampedZoomRange = coveringZoomRange(type, tileSize, zoomRange); unsigned long result = 0;; for (uint8_t z = clampedZoomRange.min; z <= clampedZoomRange.max; z++) { - result += util::tileCount(bounds, z, tileSize); + result += util::tileCount(bounds, z); } return result; diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp index 39b562d811..7277680fd0 100644 --- a/src/mbgl/util/tile_cover.cpp +++ b/src/mbgl/util/tile_cover.cpp @@ -147,11 +147,11 @@ std::vector tileCover(const LatLngBounds& bounds_, int32_t z) { { std::min(bounds_.north(), util::LATITUDE_MAX), bounds_.east() }); return tileCover( - TileCoordinate::fromLatLng(z, bounds.northwest()).p, - TileCoordinate::fromLatLng(z, bounds.northeast()).p, - TileCoordinate::fromLatLng(z, bounds.southeast()).p, - TileCoordinate::fromLatLng(z, bounds.southwest()).p, - TileCoordinate::fromLatLng(z, bounds.center()).p, + Projection::project(bounds.northwest(), z), + Projection::project(bounds.northeast(), z), + Projection::project(bounds.southeast(), z), + Projection::project(bounds.southwest(), z), + Projection::project(bounds.center(), z), z); } @@ -172,23 +172,23 @@ std::vector tileCover(const TransformState& state, int32_t z) { // Taken from https://github.com/mapbox/sphericalmercator#xyzbbox-zoom-tms_style-srs // Computes the projected tiles for the lower left and upper right points of the bounds // and uses that to compute the tile cover count -uint64_t tileCount(const LatLngBounds& bounds, uint8_t zoom, uint16_t tileSize_){ - - auto sw = Projection::project(bounds.southwest().wrapped(), zoom, tileSize_); - auto ne = Projection::project(bounds.northeast().wrapped(), zoom, tileSize_); - - auto x1 = floor(sw.x/ tileSize_); - auto x2 = floor((ne.x - 1) / tileSize_); - auto y1 = floor(sw.y/ tileSize_); - auto y2 = floor((ne.y - 1) / tileSize_); - - auto minX = ::fmax(std::min(x1, x2), 0); - auto maxX = std::max(x1, x2); - auto minY = (std::pow(2, zoom) - 1) - std::max(y1, y2); - auto maxY = (std::pow(2, zoom) - 1) - ::fmax(std::min(y1, y2), 0); - - return (maxX - minX + 1) * (maxY - minY + 1); +uint64_t tileCount(const LatLngBounds& bounds, uint8_t zoom){ + if (zoom == 0) { + return 1; + } + auto sw = Projection::project(bounds.southwest(), zoom); + auto ne = Projection::project(bounds.northeast(), zoom); + auto maxTile = std::pow(2.0, zoom); + auto x1 = floor(sw.x); + auto x2 = ceil(ne.x) - 1; + auto y1 = util::clamp(floor(sw.y), 0.0, maxTile - 1); + auto y2 = util::clamp(floor(ne.y), 0.0, maxTile - 1); + + auto dx = x1 > x2 ? (maxTile - x1) + x2 : x2 - x1; + auto dy = y1 - y2; + return (dx + 1) * (dy + 1); } + } // namespace util } // namespace mbgl diff --git a/src/mbgl/util/tile_cover.hpp b/src/mbgl/util/tile_cover.hpp index b2098b59b8..50fb8bcaef 100644 --- a/src/mbgl/util/tile_cover.hpp +++ b/src/mbgl/util/tile_cover.hpp @@ -19,7 +19,7 @@ std::vector tileCover(const TransformState&, int32_t z); std::vector tileCover(const LatLngBounds&, int32_t z); // Compute only the count of tiles needed for tileCover -uint64_t tileCount(const LatLngBounds&, uint8_t z, uint16_t tileSize); +uint64_t tileCount(const LatLngBounds&, uint8_t z); } // namespace util } // namespace mbgl diff --git a/test/util/tile_cover.test.cpp b/test/util/tile_cover.test.cpp index 933c18b5ea..7f21936527 100644 --- a/test/util/tile_cover.test.cpp +++ b/test/util/tile_cover.test.cpp @@ -85,11 +85,28 @@ TEST(TileCover, SanFranciscoZ0Wrapped) { util::tileCover(sanFranciscoWrapped, 0)); } +TEST(TileCount, World) { + EXPECT_EQ(1u, util::tileCount(LatLngBounds::world(), 0)); + EXPECT_EQ(4u, util::tileCount(LatLngBounds::world(), 1)); +} + TEST(TileCount, SanFranciscoZ10) { - EXPECT_EQ(4u, util::tileCount(sanFrancisco, 10, util::tileSize)); + EXPECT_EQ(4u, util::tileCount(sanFrancisco, 10)); +} + +TEST(TileCount, SanFranciscoWrappedZ10) { + EXPECT_EQ(4u, util::tileCount(sanFranciscoWrapped, 10)); } TEST(TileCount, SanFranciscoZ22) { - EXPECT_EQ(7254450u, util::tileCount(sanFrancisco, 22, util::tileSize)); + EXPECT_EQ(7254450u, util::tileCount(sanFrancisco, 22)); +} + +TEST(TileCount, BoundsCrossingAntimeridian) { + auto crossingBounds = LatLngBounds::hull({-20.9615, -214.309}, {19.477, -155.830}); + + EXPECT_EQ(1u, util::tileCount(crossingBounds, 0)); + EXPECT_EQ(4u, util::tileCount(crossingBounds, 3)); + EXPECT_EQ(8u, util::tileCount(crossingBounds, 4)); } diff --git a/test/util/tile_range.test.cpp b/test/util/tile_range.test.cpp index c4c37c74d7..83ac5096a5 100644 --- a/test/util/tile_range.test.cpp +++ b/test/util/tile_range.test.cpp @@ -52,14 +52,14 @@ TEST(TileRange, ContainsWrappedBounds) { TEST(TileRange, ContainsBoundsCrossingAntimeridian) { { - auto cossingBounds = LatLngBounds::hull({-20.9615, -214.309}, {19.477, -155.830}); - auto range = util::TileRange::fromLatLngBounds(cossingBounds, 1); + auto crossingBounds = LatLngBounds::hull({-20.9615, -214.309}, {19.477, -155.830}); + auto range = util::TileRange::fromLatLngBounds(crossingBounds, 1); EXPECT_TRUE(range.contains(CanonicalTileID(1, 1, 1))); EXPECT_TRUE(range.contains(CanonicalTileID(1, 0, 0))); } { - auto cossingBounds = LatLngBounds::hull({-20.9615, -214.309}, {19.477, -155.830}); - auto range = util::TileRange::fromLatLngBounds(cossingBounds, 6); + auto crossingBounds = LatLngBounds::hull({-20.9615, -214.309}, {19.477, -155.830}); + auto range = util::TileRange::fromLatLngBounds(crossingBounds, 6); EXPECT_FALSE(range.contains(CanonicalTileID(6, 55, 34))); EXPECT_FALSE(range.contains(CanonicalTileID(6, 5, 28))); EXPECT_TRUE(range.contains(CanonicalTileID(6, 63, 28))); -- cgit v1.2.1