[traffic] Ignore access flags when decoding closure events

Fixes decoding of closures which are mapped in OSM as access restrictions

Signed-off-by: mvglasow <michael -at- vonglasow.com>
This commit is contained in:
mvglasow
2025-11-13 21:16:45 +02:00
parent 9d4801886e
commit d4c002851b
4 changed files with 45 additions and 6 deletions

View File

@@ -144,6 +144,18 @@ public:
*/ */
virtual double GetFerryLandingPenalty(Purpose purpose) const = 0; 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. * @brief Creates an `EdgeEstimator` based on maximum speeds.
* *

View File

@@ -217,6 +217,9 @@ template <typename AccessPositionType>
bool IndexGraph::IsAccessNoForSure(AccessPositionType const & accessPositionType, RouteWeight const & weight, bool IndexGraph::IsAccessNoForSure(AccessPositionType const & accessPositionType, RouteWeight const & weight,
bool useAccessConditional) const bool useAccessConditional) const
{ {
if (m_estimator->IsAccessIgnored())
return false;
auto const [accessType, confidence] = useAccessConditional auto const [accessType, confidence] = useAccessConditional
? m_roadAccess.GetAccess(accessPositionType, weight) ? m_roadAccess.GetAccess(accessPositionType, weight)
: m_roadAccess.GetAccessWithoutConditional(accessPositionType); : m_roadAccess.GetAccessWithoutConditional(accessPositionType);

View File

@@ -252,12 +252,12 @@ void TraffDecoder::DecodeMessage(traffxml::TraffMessage & message)
if (!message.m_location) if (!message.m_location)
return; return;
// Decode events into consolidated traffic impact // Decode events into consolidated traffic impact
std::optional<traffxml::TrafficImpact> impact = message.GetTrafficImpact(); m_trafficImpact = message.GetTrafficImpact();
LOG(LINFO, (" Impact: ", impact)); LOG(LINFO, (" Impact: ", m_trafficImpact));
// Skip further processing if there is no impact // Skip further processing if there is no impact
if (!impact) if (!m_trafficImpact)
return; return;
traffxml::MultiMwmColoring decoded; 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")); LOG(LINFO, (" Location for message", message.m_id, "can be reused from cache"));
std::optional<traffxml::TrafficImpact> cachedImpact = it->second.GetTrafficImpact(); std::optional<traffxml::TrafficImpact> 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")); LOG(LINFO, (" Impact for message", message.m_id, "unchanged, reusing cached coloring"));
@@ -300,10 +300,11 @@ void TraffDecoder::DecodeMessage(traffxml::TraffMessage & message)
if (!isDecoded) if (!isDecoded)
DecodeLocation(message, decoded); DecodeLocation(message, decoded);
if (impact) if (m_trafficImpact)
{ {
ApplyTrafficImpact(impact.value(), decoded); ApplyTrafficImpact(m_trafficImpact.value(), decoded);
std::swap(message.m_decoded, decoded); std::swap(message.m_decoded, decoded);
m_trafficImpact = std::nullopt;
} }
} }
@@ -693,6 +694,12 @@ double RoutingTraffDecoder::TraffEstimator::CalcSegmentWeight(routing::Segment c
return result; 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, RoutingTraffDecoder::DecoderRouter::DecoderRouter(CountryParentNameGetterFn const & countryParentNameGetterFn,
routing::TCountryFileFn const & countryFileFn, routing::TCountryFileFn const & countryFileFn,
routing::CountryRectFn const & countryRectFn, routing::CountryRectFn const & countryRectFn,

View File

@@ -88,6 +88,11 @@ protected:
*/ */
std::map<std::string, traffxml::TraffMessage> & m_messageCache; std::map<std::string, traffxml::TraffMessage> & m_messageCache;
/**
* @brief Consolidated traffic impact of the message currently being decoded
*/
std::optional<traffxml::TrafficImpact> m_trafficImpact;
private: private:
}; };
@@ -321,6 +326,18 @@ public:
routing::RoadGeometry const & to_road, bool is_left_hand_traffic = false) const override; routing::RoadGeometry const & to_road, bool is_left_hand_traffic = false) const override;
double GetFerryLandingPenalty(Purpose /* purpose */) 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: private:
RoutingTraffDecoder & m_decoder; RoutingTraffDecoder & m_decoder;
}; };