summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shalamov <alexander.shalamov@mapbox.com>2019-02-21 11:37:06 +0200
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-04-29 17:42:30 +0300
commit67f01c45e7265eb695113dd32062d99c87adaeab (patch)
tree290e7f11d427a51fd89679e93d921e16c7a36cd2
parenta31734ddada70d9bab144a564a9508726e046480 (diff)
downloadqtlocation-mapboxgl-67f01c45e7265eb695113dd32062d99c87adaeab.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 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&,