diff --git a/libs/routing/edge_estimator.hpp b/libs/routing/edge_estimator.hpp index 9d8daa854..e0149dc60 100644 --- a/libs/routing/edge_estimator.hpp +++ b/libs/routing/edge_estimator.hpp @@ -144,6 +144,18 @@ public: */ virtual double GetFerryLandingPenalty(Purpose purpose) const = 0; + /** + * @brief Whether access restrictions are ignored. + * + * A return value of false indicates that access restrictions should be observed, which is the + * default behavior for a routing use case. If true, it indicates that routing should ignore + * access restrictions. This is needed to resolve traffic message locations; it could also be + * used e.g. for emergency vehicle use cases. + * + * This implementation always returns false. + */ + virtual bool IsAccessIgnored() { return false; } + /** * @brief Creates an `EdgeEstimator` based on maximum speeds. * diff --git a/libs/routing/index_graph.hpp b/libs/routing/index_graph.hpp index 881956d63..8a56b4ce8 100644 --- a/libs/routing/index_graph.hpp +++ b/libs/routing/index_graph.hpp @@ -217,6 +217,9 @@ template bool IndexGraph::IsAccessNoForSure(AccessPositionType const & accessPositionType, RouteWeight const & weight, bool useAccessConditional) const { + if (m_estimator->IsAccessIgnored()) + return false; + auto const [accessType, confidence] = useAccessConditional ? m_roadAccess.GetAccess(accessPositionType, weight) : m_roadAccess.GetAccessWithoutConditional(accessPositionType); diff --git a/libs/traffxml/traff_decoder.cpp b/libs/traffxml/traff_decoder.cpp index e2353e0ea..70070a69f 100644 --- a/libs/traffxml/traff_decoder.cpp +++ b/libs/traffxml/traff_decoder.cpp @@ -252,12 +252,12 @@ void TraffDecoder::DecodeMessage(traffxml::TraffMessage & message) if (!message.m_location) return; // Decode events into consolidated traffic impact - std::optional impact = message.GetTrafficImpact(); + m_trafficImpact = message.GetTrafficImpact(); - LOG(LINFO, (" Impact: ", impact)); + LOG(LINFO, (" Impact: ", m_trafficImpact)); // Skip further processing if there is no impact - if (!impact) + if (!m_trafficImpact) return; traffxml::MultiMwmColoring decoded; @@ -278,7 +278,7 @@ void TraffDecoder::DecodeMessage(traffxml::TraffMessage & message) LOG(LINFO, (" Location for message", message.m_id, "can be reused from cache")); std::optional cachedImpact = it->second.GetTrafficImpact(); - if (cachedImpact.has_value() && cachedImpact.value() == impact.value()) + if (cachedImpact.has_value() && cachedImpact.value() == m_trafficImpact.value()) { LOG(LINFO, (" Impact for message", message.m_id, "unchanged, reusing cached coloring")); @@ -300,10 +300,11 @@ void TraffDecoder::DecodeMessage(traffxml::TraffMessage & message) if (!isDecoded) DecodeLocation(message, decoded); - if (impact) + if (m_trafficImpact) { - ApplyTrafficImpact(impact.value(), decoded); + ApplyTrafficImpact(m_trafficImpact.value(), decoded); std::swap(message.m_decoded, decoded); + m_trafficImpact = std::nullopt; } } @@ -693,6 +694,12 @@ double RoutingTraffDecoder::TraffEstimator::CalcSegmentWeight(routing::Segment c return result; } +bool RoutingTraffDecoder::TraffEstimator::IsAccessIgnored() +{ + ASSERT(m_decoder.m_trafficImpact, ("Traffic impact for current message is not set")); + return (m_decoder.m_trafficImpact.value().m_speedGroup == traffic::SpeedGroup::TempBlock); +} + RoutingTraffDecoder::DecoderRouter::DecoderRouter(CountryParentNameGetterFn const & countryParentNameGetterFn, routing::TCountryFileFn const & countryFileFn, routing::CountryRectFn const & countryRectFn, diff --git a/libs/traffxml/traff_decoder.hpp b/libs/traffxml/traff_decoder.hpp index 4ccbe382d..08db50870 100644 --- a/libs/traffxml/traff_decoder.hpp +++ b/libs/traffxml/traff_decoder.hpp @@ -88,6 +88,11 @@ protected: */ std::map & m_messageCache; + /** + * @brief Consolidated traffic impact of the message currently being decoded + */ + std::optional m_trafficImpact; + private: }; @@ -321,6 +326,18 @@ public: routing::RoadGeometry const & to_road, bool is_left_hand_traffic = false) const override; double GetFerryLandingPenalty(Purpose /* purpose */) const override; + /** + * @brief Whether access restrictions are ignored. + * + * A return value of false indicates that access restrictions should be observed, which is the + * default behavior for a routing use case. If true, it indicates that routing should ignore + * access restrictions. This is needed to resolve traffic message locations; it could also be + * used e.g. for emergency vehicle use cases. + * + * This implementation may return true or false, depending on the location being decoded. + */ + bool IsAccessIgnored() override; + private: RoutingTraffDecoder & m_decoder; };