diff options
-rw-r--r-- | src/mbgl/renderer/painter.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/style.cpp | 32 | ||||
-rw-r--r-- | src/mbgl/style/style.hpp | 2 |
3 files changed, 30 insertions, 6 deletions
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 6502845494..2949cee1d9 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -125,7 +125,7 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp spriteAtlas = style.spriteAtlas.get(); lineAtlas = style.lineAtlas.get(); - RenderData renderData = style.getRenderData(frame.debugOptions); + RenderData renderData = style.getRenderData(frame.debugOptions, state.getAngle()); const std::vector<RenderItem>& order = renderData.order; const std::unordered_set<Source*>& sources = renderData.sources; diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index d2c8798614..6b80202093 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -353,7 +353,7 @@ bool Style::isLoaded() const { return true; } -RenderData Style::getRenderData(MapDebugOptions debugOptions) const { +RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const { RenderData result; for (const auto& source : sources) { @@ -362,6 +362,9 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const { } } + const bool isLeft = std::abs(angle) > M_PI_2; + const bool isBottom = angle < 0; + for (const auto& layer : layers) { if (!layer->baseImpl->needsRendering(zoomHistory.lastZoom)) { continue; @@ -395,8 +398,29 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const { continue; } - for (auto& pair : source->baseImpl->getRenderTiles()) { - auto& tile = pair.second; + auto& renderTiles = source->baseImpl->getRenderTiles(); + const bool symbolLayer = layer->is<SymbolLayer>(); + + // Sort symbol tiles in opposite y position, so tiles with overlapping + // symbols are drawn on top of each other, with lower symbols being + // drawn on top of higher symbols. + std::vector<std::reference_wrapper<RenderTile>> sortedTiles; + std::transform(renderTiles.begin(), renderTiles.end(), std::back_inserter(sortedTiles), + [](auto& pair) { return std::ref(pair.second); }); + if (symbolLayer) { + std::sort(sortedTiles.begin(), sortedTiles.end(), + [isLeft, isBottom](const RenderTile& a, const RenderTile& b) { + bool sortX = a.id.canonical.x > b.id.canonical.x; + bool sortW = a.id.wrap > b.id.wrap; + bool sortY = a.id.canonical.y > b.id.canonical.y; + return + a.id.canonical.y != b.id.canonical.y ? (isLeft ? sortY : !sortY) : + a.id.wrap != b.id.wrap ? (isBottom ? sortW : !sortW) : (isBottom ? sortX : !sortX); + }); + } + + for (auto& tileRef : sortedTiles) { + auto& tile = tileRef.get(); if (!tile.tile.isRenderable()) { continue; } @@ -404,7 +428,7 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const { // We're not clipping symbol layers, so when we have both parents and children of symbol // layers, we drop all children in favor of their parent to avoid duplicate labels. // See https://github.com/mapbox/mapbox-gl-native/issues/2482 - if (layer->is<SymbolLayer>()) { + if (symbolLayer) { bool skip = false; // Look back through the buckets we decided to render to find out whether there is // already a bucket from this layer that is a parent of this tile. Tiles are ordered diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index 1af020d6c2..4ad540acd1 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -90,7 +90,7 @@ public: bool hasClass(const std::string&) const; std::vector<std::string> getClasses() const; - RenderData getRenderData(MapDebugOptions) const; + RenderData getRenderData(MapDebugOptions, float angle) const; std::vector<Feature> queryRenderedFeatures(const QueryParameters&) const; |