From 755ca0229002cb4cf8f0d3034c45e7edbf6bcba8 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Fri, 16 Jun 2017 13:43:53 +0300 Subject: [PATCH 1/3] [core] tileCover zoom is uint8_t --- src/mbgl/util/tile_cover.cpp | 34 +++++++++++++++++----------------- src/mbgl/util/tile_cover.hpp | 4 ++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp index b53e91162c1..5408d84a136 100644 --- a/src/mbgl/util/tile_cover.cpp +++ b/src/mbgl/util/tile_cover.cpp @@ -80,8 +80,8 @@ std::vector tileCover(const Point& tl, const Point& br, const Point& bl, const Point& c, - int32_t z) { - const int32_t tiles = 1 << z; + uint8_t zoom) { + const int32_t tiles = 1 << zoom; struct ID { int32_t x, y; @@ -119,7 +119,7 @@ std::vector tileCover(const Point& tl, std::vector result; for (const auto& id : t) { - result.emplace_back(z, id.x, id.y); + result.emplace_back(zoom, id.x, id.y); } return result; } @@ -135,7 +135,7 @@ int32_t coveringZoomLevel(double zoom, SourceType type, uint16_t size) { } } -std::vector tileCover(const LatLngBounds& bounds_, int32_t z) { +std::vector tileCover(const LatLngBounds& bounds_, uint8_t zoom) { if (bounds_.isEmpty() || bounds_.south() > util::LATITUDE_MAX || bounds_.north() < -util::LATITUDE_MAX) { @@ -147,26 +147,26 @@ 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, - z); + TileCoordinate::fromLatLng(zoom, bounds.northwest()).p, + TileCoordinate::fromLatLng(zoom, bounds.northeast()).p, + TileCoordinate::fromLatLng(zoom, bounds.southeast()).p, + TileCoordinate::fromLatLng(zoom, bounds.southwest()).p, + TileCoordinate::fromLatLng(zoom, bounds.center()).p, + zoom); } -std::vector tileCover(const TransformState& state, int32_t z) { +std::vector tileCover(const TransformState& state, uint8_t zoom) { assert(state.valid()); const double w = state.getSize().width; const double h = state.getSize().height; return tileCover( - TileCoordinate::fromScreenCoordinate(state, z, { 0, 0 }).p, - TileCoordinate::fromScreenCoordinate(state, z, { w, 0 }).p, - TileCoordinate::fromScreenCoordinate(state, z, { w, h }).p, - TileCoordinate::fromScreenCoordinate(state, z, { 0, h }).p, - TileCoordinate::fromScreenCoordinate(state, z, { w/2, h/2 }).p, - z); + TileCoordinate::fromScreenCoordinate(state, zoom, { 0, 0 }).p, + TileCoordinate::fromScreenCoordinate(state, zoom, { w, 0 }).p, + TileCoordinate::fromScreenCoordinate(state, zoom, { w, h }).p, + TileCoordinate::fromScreenCoordinate(state, zoom, { 0, h }).p, + TileCoordinate::fromScreenCoordinate(state, zoom, { w/2, h/2 }).p, + zoom); } } // namespace util diff --git a/src/mbgl/util/tile_cover.hpp b/src/mbgl/util/tile_cover.hpp index 2d32d8bf41f..d74d4fe0b7f 100644 --- a/src/mbgl/util/tile_cover.hpp +++ b/src/mbgl/util/tile_cover.hpp @@ -15,8 +15,8 @@ namespace util { int32_t coveringZoomLevel(double z, SourceType type, uint16_t tileSize); -std::vector tileCover(const TransformState&, int32_t z); -std::vector tileCover(const LatLngBounds&, int32_t z); +std::vector tileCover(const TransformState&, uint8_t zoom); +std::vector tileCover(const LatLngBounds&, uint8_t zoom); } // namespace util } // namespace mbgl From dc181e3e05f5987d602c7bb73c9b6030c822a1fd Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Fri, 16 Jun 2017 13:48:12 +0300 Subject: [PATCH 2/3] [core] Reserve memory for tileCover container elements --- benchmark/fixtures/api/cache.db | Bin 405504 -> 405504 bytes src/mbgl/util/tile_cover.cpp | 31 +++++++++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/benchmark/fixtures/api/cache.db b/benchmark/fixtures/api/cache.db index a62a3b0f00ccfd5bc6d21f6e7472a090dd4f45c5..611de14077d4b43e834fff4ef60ff7b7a6a2d31f 100644 GIT binary patch delta 1005 zcmZ9IOHWf#6oq^4-Q{5-x0M$9P+OspLXp-tNQJgM4EVwaN)_~~KS2I~NoS5sN*d-J zI+Ql;8R}1{GlzAcV-hEjG^uNq+YTJ8Z|!sL-DmA{3e7;F87PJa4_q$Sd&s*VTTlmw z_8%*2VCfR>o4{?NuZIWx;3Gzf01+fYoi_d#FMaZiuW`>$Ot=BF11=|tDPo#P5HrLW zF-wdPDPp*Ejtq+K~bEc{a?Z|$)f6I^aUqH{HE$A8a6nX+ZhBl#l(0%A3^awf+EkPM53+13?Xa!n@ z*7Z(GeX+De)v-0eU~FF1;!$l&jcVDXPiXl{Pt}AL&~jwJgEcW>AuR>7W%2f5EoE+v zqk+D3+Hg@zij5JR%k3!Q=$EihAJdYd&mxZ=)AF5uS4)FFsijGuLNJo*wt+a#THiAg zXFHWnel!|}`vQiTu8H911j6Vu2%}#{m>fsCcT8%rdFFvY%c{v_{ z{bi?b#pzph`qoeTv}wzUbNPbwo}pLSsBp!@U5v1e=fusmS(a8(jno@r7L^aV?)Eoz Ij^48V0ZIMl2LJ#7 delta 977 zcmYL`%Tg0T6o#i~P7tgzlV}LJpox&AfB*?zK@bu^yx=9?K~bYTfO!GSsdC}Yij@~& z=T?(SdZ~|)rORw|O_dudrYipbnCRmF{&Tv|={eowbRteCQjHHehGFbN!yi+N%K1|M zX%{V|w@kng=rPj?FJ&~qwIDGbbv|j%HdSc7}!SxMVq8La&u=;^{#F8Ow9oE~w zY(H!IEAG*Ta=HnAWkgF!b#0Z_l7wq3pbqRo7Gv{_mTy?xMraH}yU;7>B~*r9K+mCP z&Wr4M)lI0J=eD|`rNYzakaNlf8KwI|)23bxu}Rn-Yx M*Vp~3!gSaE1B`dr82|tP diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp index 5408d84a136..dc39d172971 100644 --- a/src/mbgl/util/tile_cover.cpp +++ b/src/mbgl/util/tile_cover.cpp @@ -81,21 +81,27 @@ std::vector tileCover(const Point& tl, const Point& bl, const Point& c, uint8_t zoom) { - const int32_t tiles = 1 << zoom; + const int32_t maxTilesPerAxis = 1 << zoom; - struct ID { + struct CoverID { int32_t x, y; double sqDist; }; - std::vector t; + std::vector coverIDs; + // Simple bbox for pre-reserving coverIDs elements. + const auto maxX = util::max(tl.x, tr.x, br.x, bl.x); + const auto minX = util::min(tl.x, tr.x, br.x, bl.x); + const auto maxY = util::max(tl.y, tr.x, br.x, bl.x); + const auto minY = util::min(tl.y, tr.y, br.y, bl.y); + coverIDs.reserve(util::clamp(0lu, size_t((maxX - minX) * (maxY - minY)), std::numeric_limits::max())); auto scanLine = [&](int32_t x0, int32_t x1, int32_t y) { int32_t x; - if (y >= 0 && y <= tiles) { + if (y >= 0 && y <= maxTilesPerAxis) { for (x = x0; x < x1; ++x) { const auto dx = x + 0.5 - c.x, dy = y + 0.5 - c.y; - t.emplace_back(ID{ x, y, dx * dx + dy * dy }); + coverIDs.emplace_back(CoverID { x, y, dx * dx + dy * dy }); } } }; @@ -104,22 +110,23 @@ std::vector tileCover(const Point& tl, // \---+ // | \ | // +---\. - scanTriangle(tl, tr, br, 0, tiles, scanLine); - scanTriangle(br, bl, tl, 0, tiles, scanLine); + scanTriangle(tl, tr, br, 0, maxTilesPerAxis, scanLine); + scanTriangle(br, bl, tl, 0, maxTilesPerAxis, scanLine); // Sort first by distance, then by x/y. - std::sort(t.begin(), t.end(), [](const ID& a, const ID& b) { + std::sort(coverIDs.begin(), coverIDs.end(), [](const CoverID& a, const CoverID& b) { return std::tie(a.sqDist, a.x, a.y) < std::tie(b.sqDist, b.x, b.y); }); // Erase duplicate tile IDs (they typically occur at the common side of both triangles). - t.erase(std::unique(t.begin(), t.end(), [](const ID& a, const ID& b) { + coverIDs.erase(std::unique(coverIDs.begin(), coverIDs.end(), [](const CoverID& a, const CoverID& b) { return a.x == b.x && a.y == b.y; - }), t.end()); + }), coverIDs.end()); std::vector result; - for (const auto& id : t) { - result.emplace_back(zoom, id.x, id.y); + result.reserve(coverIDs.size()); + for (const auto& coverID : coverIDs) { + result.emplace_back(zoom, coverID.x, coverID.y); } return result; } From 20adbdeaa3293a0561e9a1f91fcf2d0143b91066 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Fri, 16 Jun 2017 16:32:52 +0300 Subject: [PATCH 3/3] [core] Increase pitch limit to 80 degrees --- include/mbgl/util/constants.hpp | 2 +- src/mbgl/util/tile_cover.cpp | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/mbgl/util/constants.hpp b/include/mbgl/util/constants.hpp index 14aaa752bc1..bc0fb2998a2 100644 --- a/include/mbgl/util/constants.hpp +++ b/include/mbgl/util/constants.hpp @@ -32,7 +32,7 @@ constexpr double EARTH_RADIUS_M = 6378137; constexpr double LATITUDE_MAX = 85.051128779806604; constexpr double LONGITUDE_MAX = 180; constexpr double DEGREES_MAX = 360; -constexpr double PITCH_MAX = M_PI / 3; +constexpr double PITCH_MAX = 1.39626; // ~80 degrees. constexpr double MIN_ZOOM = 0.0; constexpr double MAX_ZOOM = 25.5; constexpr float MIN_ZOOM_F = MIN_ZOOM; diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp index dc39d172971..a0fe3fe21c2 100644 --- a/src/mbgl/util/tile_cover.cpp +++ b/src/mbgl/util/tile_cover.cpp @@ -167,12 +167,20 @@ std::vector tileCover(const TransformState& state, uint8_t zoom const double w = state.getSize().width; const double h = state.getSize().height; + + // Limit tile coverage when pitch >= 60 degrees (M_PI / 3). + const double clampedH = [&]() { + const double clampedPitch = state.getPitch() - M_PI / 3; + return clampedPitch <= 0 ? h : h - (h * std::sin(clampedPitch)); + }(); + + // top-left, top-right, bottom-right, bottom-left, center return tileCover( - TileCoordinate::fromScreenCoordinate(state, zoom, { 0, 0 }).p, - TileCoordinate::fromScreenCoordinate(state, zoom, { w, 0 }).p, - TileCoordinate::fromScreenCoordinate(state, zoom, { w, h }).p, - TileCoordinate::fromScreenCoordinate(state, zoom, { 0, h }).p, - TileCoordinate::fromScreenCoordinate(state, zoom, { w/2, h/2 }).p, + TileCoordinate::fromScreenCoordinate(state, zoom, { 0, 0 }).p, + TileCoordinate::fromScreenCoordinate(state, zoom, { w, 0 }).p, + TileCoordinate::fromScreenCoordinate(state, zoom, { w, clampedH }).p, + TileCoordinate::fromScreenCoordinate(state, zoom, { 0, clampedH }).p, + TileCoordinate::fromScreenCoordinate(state, zoom, { w/2, h/2 }).p, zoom); }