From 5e36f669acd756d26e2dfa6db1a2a94bd1ceb701 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Thu, 17 May 2018 11:30:04 -0400 Subject: [core] avoid symbol flickering when longitude is wrapped --- src/mbgl/renderer/renderer_impl.cpp | 3 ++- src/mbgl/text/cross_tile_symbol_index.cpp | 30 +++++++++++++++++++++++++++++- src/mbgl/text/cross_tile_symbol_index.hpp | 4 +++- 3 files changed, 34 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 4380ef24a1..ca9e809977 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -380,7 +380,8 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { } for (auto it = order.rbegin(); it != order.rend(); ++it) { if (it->layer.is()) { - if (crossTileSymbolIndex.addLayer(*it->layer.as())) symbolBucketsChanged = true; + const float lng = parameters.state.getLatLng().longitude(); + if (crossTileSymbolIndex.addLayer(*it->layer.as(), lng)) symbolBucketsChanged = true; } } diff --git a/src/mbgl/text/cross_tile_symbol_index.cpp b/src/mbgl/text/cross_tile_symbol_index.cpp index b0c3511ce3..8df26ca117 100644 --- a/src/mbgl/text/cross_tile_symbol_index.cpp +++ b/src/mbgl/text/cross_tile_symbol_index.cpp @@ -61,6 +61,32 @@ void TileLayerIndex::findMatches(std::vector& symbolInstances, c CrossTileSymbolLayerIndex::CrossTileSymbolLayerIndex() { } +/* + * Sometimes when a user pans across the antimeridian the longitude value gets wrapped. + * To prevent labels from flashing out and in we adjust the tileID values in the indexes + * so that they match the new wrapped version of the map. + */ +void CrossTileSymbolLayerIndex::handleWrapJump(float newLng) { + + const int wrapDelta = ::round((newLng - lng) / 360); + if (wrapDelta != 0) { + std::map> newIndexes; + for (auto& zoomIndex : indexes) { + std::map newZoomIndex; + for (auto& index : zoomIndex.second) { + // change the tileID's wrap and move its index + index.second.coord = index.second.coord.unwrapTo(index.second.coord.wrap + wrapDelta); + newZoomIndex.emplace(index.second.coord, std::move(index.second)); + } + newIndexes.emplace(zoomIndex.first, std::move(newZoomIndex)); + } + + indexes = std::move(newIndexes); + } + + lng = newLng; +} + bool CrossTileSymbolLayerIndex::addBucket(const OverscaledTileID& tileID, SymbolBucket& bucket, uint32_t& maxCrossTileID) { const auto& thisZoomIndexes = indexes[tileID.overscaledZ]; auto previousIndex = thisZoomIndexes.find(tileID); @@ -138,13 +164,15 @@ bool CrossTileSymbolLayerIndex::removeStaleBuckets(const std::unordered_set currentBucketIDs; + layerIndex.handleWrapJump(lng); + for (RenderTile& renderTile : symbolLayer.renderTiles) { if (!renderTile.tile.isRenderable()) { continue; diff --git a/src/mbgl/text/cross_tile_symbol_index.hpp b/src/mbgl/text/cross_tile_symbol_index.hpp index 541c2e3661..051573e1d2 100644 --- a/src/mbgl/text/cross_tile_symbol_index.hpp +++ b/src/mbgl/text/cross_tile_symbol_index.hpp @@ -45,18 +45,20 @@ public: CrossTileSymbolLayerIndex(); bool addBucket(const OverscaledTileID&, SymbolBucket&, uint32_t& maxCrossTileID); bool removeStaleBuckets(const std::unordered_set& currentIDs); + void handleWrapJump(float newLng); private: void removeBucketCrossTileIDs(uint8_t zoom, const TileLayerIndex& removedBucket); std::map> indexes; std::map> usedCrossTileIDs; + float lng = 0; }; class CrossTileSymbolIndex { public: CrossTileSymbolIndex(); - bool addLayer(RenderSymbolLayer&); + bool addLayer(RenderSymbolLayer&, float lng); void pruneUnusedLayers(const std::set&); void reset(); -- cgit v1.2.1