diff --git a/map/framework.cpp b/map/framework.cpp index 25a63094e..f5f5d2b9b 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -432,9 +432,9 @@ void Framework::OnCountryFileDownloaded(storage::CountryId const &, MwmSet::MwmId const & id = res.first; if (id.IsAlive()) rect = id.GetInfo()->m_bordersRect; + m_trafficManager.Invalidate(id); } - m_trafficManager.Invalidate(); m_transitManager.Invalidate(); m_isolinesManager.Invalidate(); diff --git a/map/traffic_manager.cpp b/map/traffic_manager.cpp index df7382df4..9811f0a33 100644 --- a/map/traffic_manager.cpp +++ b/map/traffic_manager.cpp @@ -290,6 +290,58 @@ void TrafficManager::Invalidate() UpdateMyPosition(m_currentPosition.first); } +void TrafficManager::Invalidate(MwmSet::MwmId const & mwmId) +{ + auto const mwmRect = mwmId.GetInfo()->m_bordersRect; // m2::RectD + traffxml::TraffFeed invalidated; + + { + std::lock_guard lock(m_mutex); + + for (auto it = m_messageCache.begin(); it != m_messageCache.end(); ) + { + if (!it->second.m_location) + continue; + + bool isInvalid = false; + + // invalidate if decoded location uses a previous version of the MWM + for (auto const & [decodedMwmId, coloring] : it->second.m_decoded) + if (decodedMwmId.GetInfo()->GetCountryName() == mwmId.GetInfo()->GetCountryName()) + isInvalid = true; + + // invalidate if bounding rect of reference points intersects with bounding rect of MWM + if (!isInvalid) + { + m2::RectD locationRect; + for (auto const & point : {it->second.m_location.value().m_from, + it->second.m_location.value().m_via, + it->second.m_location.value().m_at, + it->second.m_location.value().m_to}) + if (point) + locationRect.Add(mercator::FromLatLon(point.value().m_coordinates)); + isInvalid = locationRect.IsIntersect(mwmRect); + } + + if (isInvalid) + { + traffxml::TraffMessage message(it->second); + message.m_decoded.clear(); + invalidated.push_back(message); + it = m_messageCache.erase(it); + } + else + ++it; + } + + if (!invalidated.empty()) + { + m_feedQueue.insert(m_feedQueue.begin(), invalidated); + m_condition.notify_one(); + } + } +} + void TrafficManager::UpdateActiveMwms(m2::RectD const & rect, std::vector & lastMwmsByRect, std::set & activeMwms) diff --git a/map/traffic_manager.hpp b/map/traffic_manager.hpp index 46cb20d4f..d03238e20 100644 --- a/map/traffic_manager.hpp +++ b/map/traffic_manager.hpp @@ -188,6 +188,18 @@ public: */ void Invalidate(); + /** + * @brief Invalidates traffic information. + * + * Invalidation happens when a new MWM file is downloaded (it may or may not replace an older + * version), and pertains to that MWM. Locations which refer to any version of this MWM, or whose + * enclosing rectangle overlaps with that of the MWM, are discarded and recreated to ensure the + * new MWM is considered. + * + * @param mwmId The newly addded MWM. + */ + void Invalidate(MwmSet::MwmId const & mwmId); + void OnDestroySurface(); void OnRecoverSurface(); void OnMwmDeregistered(platform::LocalCountryFile const & countryFile);