summaryrefslogtreecommitdiff
path: root/src/mbgl/util/tile_cover.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/util/tile_cover.cpp')
-rw-r--r--src/mbgl/util/tile_cover.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp
index 5189b79f26..11e1a97f4c 100644
--- a/src/mbgl/util/tile_cover.cpp
+++ b/src/mbgl/util/tile_cover.cpp
@@ -173,6 +173,59 @@ std::vector<UnwrappedTileID> tileCover(const TransformState& state, int32_t z) {
z);
}
+std::vector<UnwrappedTileID> tileCoverWithLOD(const TransformState& state, int32_t z, int32_t minZ) {
+ assert(state.valid());
+
+ const double w = state.getSize().width;
+ const double h = state.getSize().height;
+
+ const auto offset = state.getCenterOffset();
+ constexpr double zoomDiff = 1.0;
+ constexpr double coefLOD[] = {
+ 0.55 * zoomDiff / (zoomDiff + 1),
+ 0.55 * (zoomDiff + 1) / (zoomDiff + 2),
+ 0.55 * (zoomDiff + 2) / (zoomDiff + 3)
+ };
+ // Tangens of field of view above center.
+ const double tanFov = (h * 0.5 + offset.y) / (1.5 * h);
+
+ std::vector<UnwrappedTileID> result;
+ double top = 0.0;
+ double bottom = 0.0;
+
+ for (size_t i = 0; top < h && i <= std::extent<decltype(coefLOD)>::value; i++, z--) {
+ if (z == minZ || i == std::extent<decltype(coefLOD)>::value) {
+ top = h; // final pass, get all to the top.
+ } else {
+ const double treshold = state.getPitch() ? : (h * 0.5 + offset.y);
+ top = std::min(h, treshold );
+ top = state.getPitch()
+ ? std::min(h, h * 0.5 - offset.y + h * coefLOD[i] / (tanFov * std::tan(state.getPitch())))
+ : h;
+ }
+ std::vector<UnwrappedTileID> cover = tileCover(
+ TileCoordinate::fromScreenCoordinate(state, z, { 0, top }).p,
+ TileCoordinate::fromScreenCoordinate(state, z, { w, top }).p,
+ TileCoordinate::fromScreenCoordinate(state, z, { w, bottom }).p,
+ TileCoordinate::fromScreenCoordinate(state, z, { 0, bottom }).p,
+ TileCoordinate::fromScreenCoordinate(state, z, { w/2, h/2 }).p,
+ z);
+ bottom = top;
+ if (i == 0) {
+ if (top == h) {
+ return cover;
+ }
+ std::swap(result, cover);
+ continue;
+ }
+ result.insert(
+ result.end(),
+ std::make_move_iterator(cover.begin()),
+ std::make_move_iterator(cover.end()));
+ }
+ return result;
+}
+
std::vector<UnwrappedTileID> tileCover(const Geometry<double>& geometry, int32_t z) {
std::vector<UnwrappedTileID> result;
TileCover tc(geometry, z, true);