#include #include #include namespace mbgl { namespace style { CustomTileLoader::CustomTileLoader(const TileFunction& fetchTileFn, const TileFunction& cancelTileFn) { fetchTileFunction = fetchTileFn; cancelTileFunction = cancelTileFn; } void CustomTileLoader::fetchTile(const OverscaledTileID& tileID, const ActorRef& tileRef) { std::lock_guard guard(dataMutex); auto cachedTileData = dataCache.find(tileID.canonical); if (cachedTileData != dataCache.end()) { tileRef.invoke(&CustomGeometryTile::setTileData, *(cachedTileData->second)); } auto tileCallbacks = tileCallbackMap.find(tileID.canonical); if (tileCallbacks == tileCallbackMap.end()) { auto tuple = std::make_tuple(tileID.overscaledZ, tileID.wrap, tileRef); tileCallbackMap.insert({ tileID.canonical, std::vector(1, tuple) }); } else { for (auto& iter : tileCallbacks->second) { if (std::get<0>(iter) == tileID.overscaledZ && std::get<1>(iter) == tileID.wrap ) { std::get<2>(iter) = tileRef; return; } } tileCallbacks->second.emplace_back(std::make_tuple(tileID.overscaledZ, tileID.wrap, tileRef)); } if (cachedTileData == dataCache.end()) { invokeTileFetch(tileID.canonical); } } void CustomTileLoader::cancelTile(const OverscaledTileID& tileID) { std::lock_guard guard(dataMutex); if (tileCallbackMap.find(tileID.canonical) != tileCallbackMap.end()) { invokeTileCancel(tileID.canonical); } } void CustomTileLoader::removeTile(const OverscaledTileID& tileID) { std::lock_guard guard(dataMutex); auto tileCallbacks = tileCallbackMap.find(tileID.canonical); if (tileCallbacks == tileCallbackMap.end()) return; for (auto iter = tileCallbacks->second.begin(); iter != tileCallbacks->second.end(); iter++) { if (std::get<0>(*iter) == tileID.overscaledZ && std::get<1>(*iter) == tileID.wrap ) { tileCallbacks->second.erase(iter); invokeTileCancel(tileID.canonical); break; } } if (tileCallbacks->second.empty()) { tileCallbackMap.erase(tileCallbacks); dataCache.erase(tileID.canonical); } } void CustomTileLoader::setTileData(const CanonicalTileID& tileID, const GeoJSON& data) { std::lock_guard guard(dataMutex); auto iter = tileCallbackMap.find(tileID); if (iter == tileCallbackMap.end()) return; auto dataPtr = std::make_unique(data); for (auto tuple : iter->second) { auto actor = std::get<2>(tuple); actor.invoke(&CustomGeometryTile::setTileData, *dataPtr); } dataCache[tileID] = std::move(dataPtr); } void CustomTileLoader::invalidateTile(const CanonicalTileID& tileID) { std::lock_guard guard(dataMutex); auto tileCallbacks = tileCallbackMap.find(tileID); if (tileCallbacks == tileCallbackMap.end()) { return; } for (auto& iter : tileCallbacks->second) { auto actor = std::get<2>(iter); actor.invoke(&CustomGeometryTile::invalidateTileData); invokeTileCancel(tileID); } tileCallbackMap.erase(tileCallbacks); dataCache.erase(tileID); } void CustomTileLoader::invalidateRegion(const LatLngBounds& bounds, Range ) { std::lock_guard guard(dataMutex); std::map tileRanges; for (auto& idtuple : tileCallbackMap) { auto zoom = idtuple.first.z; auto tileRange = tileRanges.find(zoom); if(tileRange == tileRanges.end()) { tileRange = tileRanges.emplace(std::make_pair(zoom, util::TileRange::fromLatLngBounds(bounds, zoom))).first; } if (tileRange->second.contains(idtuple.first)) { for (auto iter = idtuple.second.begin(); iter != idtuple.second.end(); iter++) { auto actor = std::get<2>(*iter); actor.invoke(&CustomGeometryTile::invalidateTileData); invokeTileCancel(idtuple.first); dataCache.erase(idtuple.first); } idtuple.second.clear(); } } } void CustomTileLoader::invokeTileFetch(const CanonicalTileID& tileID) { if (fetchTileFunction != nullptr) { fetchTileFunction(tileID); } } void CustomTileLoader::invokeTileCancel(const CanonicalTileID& tileID) { if (cancelTileFunction != nullptr) { cancelTileFunction(tileID); } } } // namespace style } // namespace mbgl