diff options
author | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2019-02-21 11:37:06 +0200 |
---|---|---|
committer | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2019-04-29 17:42:30 +0300 |
commit | 67f01c45e7265eb695113dd32062d99c87adaeab (patch) | |
tree | 290e7f11d427a51fd89679e93d921e16c7a36cd2 /src | |
parent | a31734ddada70d9bab144a564a9508726e046480 (diff) | |
download | qtlocation-mapboxgl-67f01c45e7265eb695113dd32062d99c87adaeab.tar.gz |
[core] Filter out child tiles that overlap with parent render tile
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/renderer/layers/render_circle_layer.cpp | 42 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_circle_layer.hpp | 1 |
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 e96dee0cf5..d6e6fe2c19 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -19,6 +19,21 @@ inline const style::CircleLayer::Impl& impl(const Immutable<style::Layer::Impl>& return static_cast<const style::CircleLayer::Impl&>(*impl); } +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(makeMutable<CircleLayerProperties>(std::move(_impl))), unevaluated(impl(baseImpl).paint.untransitioned()) { @@ -187,4 +202,31 @@ bool RenderCircleLayer::queryIntersectsFeature( return false; } +void RenderCircleLayer::setRenderTiles(RenderTiles tiles_, const TransformState& state) { + RenderLayer::setRenderTiles(std::move(tiles_), state); + + // 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 (renderTiles.size() > 1 && + renderTiles.front().get().id.canonical.z != renderTiles.back().get().id.canonical.z) { + + RenderTiles filtered; + filtered.reserve(renderTiles.size()); + + auto lowerBound = renderTiles.end(); + for (auto it = renderTiles.rbegin(); it != renderTiles.rend(); ++it) { + if (!isCoveredByParent(it->get().id, renderTiles.begin(), --lowerBound)) { + filtered.emplace_back(it->get()); + } + } + + std::reverse(filtered.begin(), filtered.end()); + renderTiles = std::move(filtered); + } +} + } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_circle_layer.hpp b/src/mbgl/renderer/layers/render_circle_layer.hpp index fbe67c91ac..383ca8b88f 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.hpp +++ b/src/mbgl/renderer/layers/render_circle_layer.hpp @@ -17,6 +17,7 @@ private: bool hasTransition() const override; bool hasCrossfade() const override; void render(PaintParameters&, RenderSource*) override; + void setRenderTiles(RenderTiles tiles, const TransformState&) override; bool queryIntersectsFeature( const GeometryCoordinates&, |