summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shalamov <alexander.shalamov@mapbox.com>2019-02-21 11:37:06 +0200
committerAlexander Shalamov <alexander.shalamov@mapbox.com>2019-02-25 13:22:05 +0200
commitf44d0da6d1bb6e94093bb3199a1689ca80d39693 (patch)
tree14e1c4d00434195c524144448b33e6e1c696bf91
parentfee22273be2d33049311de72ff6bf973b6b05164 (diff)
downloadqtlocation-mapboxgl-f44d0da6d1bb6e94093bb3199a1689ca80d39693.tar.gz
[core] Filter out child tiles that overlap with parent render tile
-rw-r--r--src/mbgl/renderer/layers/render_circle_layer.cpp42
-rw-r--r--src/mbgl/renderer/layers/render_circle_layer.hpp1
2 files changed, 43 insertions, 0 deletions
diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp
index 65550991a9..81509c1882 100644
--- a/src/mbgl/renderer/layers/render_circle_layer.cpp
+++ b/src/mbgl/renderer/layers/render_circle_layer.cpp
@@ -14,6 +14,19 @@ namespace mbgl {
using namespace style;
+namespace {
+template <typename Iterator>
+bool isCoveredByParent(const UnwrappedTileID& child, Iterator begin, Iterator end) {
+ for (auto it = begin; it != end; ++it) {
+ const auto& tileId = it->get().id;
+ if (child != tileId && child.isChildOf(tileId)) {
+ return true;
+ }
+ }
+ return false;
+}
+} // namespace
+
RenderCircleLayer::RenderCircleLayer(Immutable<style::CircleLayer::Impl> _impl)
: RenderLayer(std::move(_impl)),
unevaluated(impl().paint.untransitioned()) {
@@ -187,4 +200,33 @@ bool RenderCircleLayer::queryIntersectsFeature(
return false;
}
+RenderLayer::RenderTiles RenderCircleLayer::filterRenderTiles(RenderTiles tiles_) const {
+ RenderTiles tiles = RenderLayer::filterRenderTiles(tiles_);
+
+ // Tiles are sorted by tile id / zoom level, if first and last tiles are from different
+ // zoom levels, check whether tile vector contains parents covering children area.
+ // This might happen when map is panned (or zoomed) and missing tile is not yet loaded,
+ // thus, cached parent tile is used to cover missing area, therefore, loaded child tiles
+ // will be drawn together with the parent.
+
+ if (tiles.size() > 1 &&
+ tiles.front().get().id.canonical.z != tiles.back().get().id.canonical.z) {
+
+ RenderTiles filtered;
+ filtered.reserve(tiles.size());
+
+ auto lowerBound = tiles.end();
+ for (auto it = tiles.rbegin(); it != tiles.rend(); ++it) {
+ if (!isCoveredByParent(it->get().id, tiles.begin(), --lowerBound)) {
+ filtered.emplace_back(it->get());
+ }
+ }
+
+ std::reverse(filtered.begin(), filtered.end());
+ return filtered;
+ }
+
+ return tiles;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/renderer/layers/render_circle_layer.hpp b/src/mbgl/renderer/layers/render_circle_layer.hpp
index 5515aa0452..552299f166 100644
--- a/src/mbgl/renderer/layers/render_circle_layer.hpp
+++ b/src/mbgl/renderer/layers/render_circle_layer.hpp
@@ -16,6 +16,7 @@ public:
bool hasTransition() const override;
bool hasCrossfade() const override;
void render(PaintParameters&, RenderSource*) override;
+ RenderTiles filterRenderTiles(RenderTiles) const override;
bool queryIntersectsFeature(
const GeometryCoordinates&,