diff options
author | Ansis Brammanis <ansis@mapbox.com> | 2018-05-17 11:30:04 -0400 |
---|---|---|
committer | Ansis Brammanis <ansis.brammanis@gmail.com> | 2018-05-22 14:58:11 -0400 |
commit | 5e36f669acd756d26e2dfa6db1a2a94bd1ceb701 (patch) | |
tree | 553489b2de586e872c9c89d7d4038d5e93f5ce2d /src | |
parent | 60505b03174b5ec02ae723beafa7683f6ed54a62 (diff) | |
download | qtlocation-mapboxgl-5e36f669acd756d26e2dfa6db1a2a94bd1ceb701.tar.gz |
[core] avoid symbol flickering when longitude is wrapped
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/renderer/renderer_impl.cpp | 3 | ||||
-rw-r--r-- | src/mbgl/text/cross_tile_symbol_index.cpp | 30 | ||||
-rw-r--r-- | src/mbgl/text/cross_tile_symbol_index.hpp | 4 |
3 files changed, 34 insertions, 3 deletions
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<RenderSymbolLayer>()) { - if (crossTileSymbolIndex.addLayer(*it->layer.as<RenderSymbolLayer>())) symbolBucketsChanged = true; + const float lng = parameters.state.getLatLng().longitude(); + if (crossTileSymbolIndex.addLayer(*it->layer.as<RenderSymbolLayer>(), 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<SymbolInstance>& 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<uint8_t, std::map<OverscaledTileID,TileLayerIndex>> newIndexes; + for (auto& zoomIndex : indexes) { + std::map<OverscaledTileID,TileLayerIndex> 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<uint CrossTileSymbolIndex::CrossTileSymbolIndex() {} -bool CrossTileSymbolIndex::addLayer(RenderSymbolLayer& symbolLayer) { +bool CrossTileSymbolIndex::addLayer(RenderSymbolLayer& symbolLayer, float lng) { auto& layerIndex = layerIndexes[symbolLayer.getID()]; bool symbolBucketsChanged = false; std::unordered_set<uint32_t> 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<uint32_t>& currentIDs); + void handleWrapJump(float newLng); private: void removeBucketCrossTileIDs(uint8_t zoom, const TileLayerIndex& removedBucket); std::map<uint8_t, std::map<OverscaledTileID,TileLayerIndex>> indexes; std::map<uint8_t, std::set<uint32_t>> usedCrossTileIDs; + float lng = 0; }; class CrossTileSymbolIndex { public: CrossTileSymbolIndex(); - bool addLayer(RenderSymbolLayer&); + bool addLayer(RenderSymbolLayer&, float lng); void pruneUnusedLayers(const std::set<std::string>&); void reset(); |