diff --git a/include/llmr/map/source.hpp b/include/llmr/map/source.hpp index da2d87ae8..40b3bf4cf 100644 --- a/include/llmr/map/source.hpp +++ b/include/llmr/map/source.hpp @@ -69,7 +69,7 @@ private: const int32_t min_zoom; const int32_t max_zoom; - std::forward_list tiles; + std::map> tiles; std::map> tile_data; }; diff --git a/src/map/source.cpp b/src/map/source.cpp index 5571f74c7..a5985668f 100644 --- a/src/map/source.cpp +++ b/src/map/source.cpp @@ -34,7 +34,8 @@ bool Source::update() { } void Source::updateClipIDs(const std::map &mapping) { - std::for_each(tiles.begin(), tiles.end(), [&mapping](Tile &tile) { + std::for_each(tiles.begin(), tiles.end(), [&mapping](std::pair> &pair) { + Tile &tile = *pair.second; auto it = mapping.find(tile.id); if (it != mapping.end()) { tile.clip = it->second; @@ -48,7 +49,8 @@ size_t Source::prepareRender(const TransformState &transform) { if (!enabled) return 0; size_t masks = 0; - for (Tile& tile : tiles) { + for (std::pair> &pair : tiles) { + Tile &tile = *pair.second; gl::group group(util::sprintf<32>("mask %d/%d/%d", tile.id.z, tile.id.y, tile.id.z)); transform.matrixFor(tile.matrix, tile.id); matrix::multiply(tile.matrix, painter.projMatrix, tile.matrix); @@ -63,7 +65,8 @@ void Source::render(const LayerDescription& layer_desc, const BucketDescription if (!enabled) return; gl::group group(std::string("layer: ") + layer_desc.name); - for (const Tile& tile : tiles) { + for (std::pair> &pair : tiles) { + Tile &tile = *pair.second; if (tile.data && tile.data->state == TileData::State::parsed) { painter.renderTileLayer(tile, layer_desc); } @@ -73,7 +76,8 @@ void Source::render(const LayerDescription& layer_desc, const BucketDescription void Source::finishRender() { if (!enabled) return; - for (const Tile& tile : tiles) { + for (std::pair> &pair : tiles) { + Tile &tile = *pair.second; painter.renderTileDebug(tile); } } @@ -81,14 +85,18 @@ void Source::finishRender() { std::forward_list Source::getIDs() const { std::forward_list ptrs; - std::transform(tiles.begin(), tiles.end(), std::front_inserter(ptrs), [](const Tile &tile) { + + std::transform(tiles.begin(), tiles.end(), std::front_inserter(ptrs), [](const std::pair> &pair) { + Tile &tile = *pair.second; return tile.id; }); return ptrs; } TileData::State Source::hasTile(const Tile::ID& id) { - for (const Tile& tile : tiles) { + auto it = tiles.find(id); + if (it != tiles.end()) { + Tile &tile = *it->second; if (tile.id == id && tile.data) { return tile.data->state; } @@ -104,8 +112,8 @@ TileData::State Source::addTile(const Tile::ID& id) { return state; } - tiles.emplace_front(id); - Tile& new_tile = tiles.front(); + auto pos = tiles.emplace(id, std::make_unique(id)); + Tile& new_tile = *pos.first->second; // We couldn't find the tile in the list. Create a new one. // Try to find the associated TileData object. @@ -249,31 +257,26 @@ bool Source::updateTiles() { // Remove tiles that we definitely don't need, i.e. tiles that are not on // the required list. - std::forward_list retain_data; - tiles.remove_if([&retain, &retain_data, &changed](const Tile & tile) { + std::set retain_data; + std::erase_if(tiles, [&retain, &retain_data, &changed](std::pair> &pair) { + Tile &tile = *pair.second; bool obsolete = std::find(retain.begin(), retain.end(), tile.id) == retain.end(); if (obsolete) { changed = true; } else { - retain_data.push_front(tile.data->id); + retain_data.insert(tile.data->id); } return obsolete; }); - // Sort tiles by zoom level, front to back. - // We're painting front-to-back, so we want to draw more detailed tiles first - // before filling in other parts with lower zoom levels. - tiles.sort([](const Tile & a, const Tile & b) { - return a.id.z < b.id.z; - }); - // Remove all the expired pointers from the set. - std::erase_if(tile_data, [&retain_data](const std::pair>& pair) { + std::erase_if(tile_data, [&retain_data](std::pair> &pair) { const std::shared_ptr tile = pair.second.lock(); if (!tile) { return true; } - bool obsolete = std::find(retain_data.begin(), retain_data.end(), tile->id) == retain_data.end(); + + bool obsolete = retain_data.find(tile->id) == retain_data.end(); if (obsolete) { tile->cancel(); return true;