diff options
-rw-r--r-- | include/mbgl/tile/tile_id.hpp | 11 | ||||
-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 |
4 files changed, 42 insertions, 6 deletions
diff --git a/include/mbgl/tile/tile_id.hpp b/include/mbgl/tile/tile_id.hpp index 11fb5ce537..3b52596f6c 100644 --- a/include/mbgl/tile/tile_id.hpp +++ b/include/mbgl/tile/tile_id.hpp @@ -58,10 +58,11 @@ public: uint32_t overscaleFactor() const; OverscaledTileID scaledTo(uint8_t z) const; UnwrappedTileID toUnwrapped() const; + OverscaledTileID unwrapTo(int16_t wrap); - const uint8_t overscaledZ; - const int16_t wrap; - const CanonicalTileID canonical; + uint8_t overscaledZ; + int16_t wrap; + CanonicalTileID canonical; }; ::std::ostream& operator<<(::std::ostream& os, const OverscaledTileID& rhs); @@ -191,6 +192,10 @@ inline UnwrappedTileID OverscaledTileID::toUnwrapped() const { return { wrap, canonical }; } +inline OverscaledTileID OverscaledTileID::unwrapTo(int16_t newWrap) { + return { overscaledZ, newWrap, canonical }; +} + inline UnwrappedTileID::UnwrappedTileID(uint8_t z_, int64_t x_, int64_t y_) : wrap((x_ < 0 ? x_ - (1ll << z_) + 1 : x_) / (1ll << z_)), canonical( 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(); |