mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-19 21:13:35 +00:00
[traffic] Exclude roundabouts from decoded locations (with exceptions)
Signed-off-by: mvglasow <michael -at- vonglasow.com>
This commit is contained in:
58
data/test_data/traff/DE-RoundaboutEndpoint.xml
Executable file
58
data/test_data/traff/DE-RoundaboutEndpoint.xml
Executable file
@@ -0,0 +1,58 @@
|
|||||||
|
<!--
|
||||||
|
Test cases for reference points inside a roundabout.
|
||||||
|
If the roundabout itself is included in the decoded location, the message would
|
||||||
|
affect all roads which connect to it, resulting in incorrect routing, especially
|
||||||
|
in the case of closure events. For this reason, we must truncate roundabouts if
|
||||||
|
they occur at the start or end of the decoded location.
|
||||||
|
-->
|
||||||
|
<feed>
|
||||||
|
<message id="tmc:d.1.12:d.1.13962.p.5,11" receive_time="2018-07-27T10:22:22+02:00" update_time="2018-07-27T08:43:15Z" expiration_time="2018-07-27T09:43:15Z" urgency="URGENT">
|
||||||
|
<location fuzziness="LOW_RES" directionality="BOTH_DIRECTIONS" road_class="SECONDARY" road_ref="L87">
|
||||||
|
<from junction_name="Rheinau-Freistett/B36">+48.661098 +7.936800</from>
|
||||||
|
<to junction_name="Gambsheim (F)">+48.683701 +7.916600</to>
|
||||||
|
</location>
|
||||||
|
<events>
|
||||||
|
<event class="CONSTRUCTION" type="CONSTRUCTION_CONSTRUCTION_WORK">
|
||||||
|
</event>
|
||||||
|
<event class="RESTRICTION" type="RESTRICTION_CLOSED">
|
||||||
|
</event>
|
||||||
|
</events>
|
||||||
|
</message>
|
||||||
|
<message id="tmc:d.1.12:d.1.26212.p.5,11" receive_time="2018-07-27T10:21:49+02:00" update_time="2018-07-27T08:42:41Z" expiration_time="2018-07-27T09:42:41Z" urgency="URGENT">
|
||||||
|
<location fuzziness="LOW_RES" directionality="BOTH_DIRECTIONS" road_class="PRIMARY" road_ref="B428">
|
||||||
|
<from junction_name="Hackenheim">+49.822948 +7.906900</from>
|
||||||
|
<to junction_name="Frei-Laubersheim">+49.803650 +7.901450</to>
|
||||||
|
</location>
|
||||||
|
<events>
|
||||||
|
<event class="CONSTRUCTION" type="CONSTRUCTION_LONGTERM_ROADWORKS">
|
||||||
|
</event>
|
||||||
|
<event class="RESTRICTION" type="RESTRICTION_CLOSED">
|
||||||
|
</event>
|
||||||
|
</events>
|
||||||
|
</message>
|
||||||
|
<message id="tmc:d.1.12:d.1.48638.n.9,11" receive_time="2018-07-27T10:11:06+02:00" update_time="2018-07-27T08:31:43Z" expiration_time="2018-07-27T09:31:43Z" urgency="URGENT">
|
||||||
|
<location fuzziness="LOW_RES" directionality="BOTH_DIRECTIONS" road_class="PRIMARY" road_ref="B272">
|
||||||
|
<from junction_name="Hochstadt">+49.239750 +8.222300</from>
|
||||||
|
<to junction_name="Weingarten">+49.253448 +8.268100</to>
|
||||||
|
</location>
|
||||||
|
<events>
|
||||||
|
<event class="CONSTRUCTION" type="CONSTRUCTION_ROADWORKS">
|
||||||
|
</event>
|
||||||
|
<event class="RESTRICTION" type="RESTRICTION_CLOSED_AHEAD">
|
||||||
|
</event>
|
||||||
|
</events>
|
||||||
|
</message>
|
||||||
|
<message id="tmc:d.1.12:d.1.56576.n.9,11" receive_time="2018-07-27T10:22:53+02:00" update_time="2018-07-27T08:43:45Z" expiration_time="2018-07-27T09:43:45Z" urgency="URGENT">
|
||||||
|
<location fuzziness="LOW_RES" directionality="ONE_DIRECTION" road_class="PRIMARY" road_ref="B417">
|
||||||
|
<from junction_name="Diez">+50.372398 +8.038500</from>
|
||||||
|
<to junction_name="Diez">+50.370850 +8.004050</to>
|
||||||
|
</location>
|
||||||
|
<events>
|
||||||
|
<event class="CONSTRUCTION" type="CONSTRUCTION_RESURFACING_WORK">
|
||||||
|
</event>
|
||||||
|
<event class="RESTRICTION" type="RESTRICTION_CLOSED">
|
||||||
|
<supplementary_info class="VEHICLE" type="S_VEHICLE_THROUGH_TRAFFIC"/>
|
||||||
|
</event>
|
||||||
|
</events>
|
||||||
|
</message>
|
||||||
|
</feed>
|
||||||
@@ -85,6 +85,7 @@ void DirectionsEngine::LoadPathAttributes(FeatureID const & featureId, LoadedPat
|
|||||||
pathSegment.m_isOneWay = m_onewayChecker(types);
|
pathSegment.m_isOneWay = m_onewayChecker(types);
|
||||||
|
|
||||||
pathSegment.m_roadNameInfo.m_isLink = pathSegment.m_isLink;
|
pathSegment.m_roadNameInfo.m_isLink = pathSegment.m_isLink;
|
||||||
|
pathSegment.m_roadNameInfo.m_onRoundabout = pathSegment.m_onRoundabout;
|
||||||
pathSegment.m_roadNameInfo.m_junction_ref = ft->GetMetadata(feature::Metadata::FMD_JUNCTION_REF);
|
pathSegment.m_roadNameInfo.m_junction_ref = ft->GetMetadata(feature::Metadata::FMD_JUNCTION_REF);
|
||||||
pathSegment.m_roadNameInfo.m_destination_ref = ft->GetMetadata(feature::Metadata::FMD_DESTINATION_REF);
|
pathSegment.m_roadNameInfo.m_destination_ref = ft->GetMetadata(feature::Metadata::FMD_DESTINATION_REF);
|
||||||
pathSegment.m_roadNameInfo.m_destination = ft->GetMetadata(feature::Metadata::FMD_DESTINATION);
|
pathSegment.m_roadNameInfo.m_destination = ft->GetMetadata(feature::Metadata::FMD_DESTINATION);
|
||||||
|
|||||||
@@ -121,6 +121,10 @@ public:
|
|||||||
* @brief Whether the road is of a link type.
|
* @brief Whether the road is of a link type.
|
||||||
*/
|
*/
|
||||||
bool m_isLink = false;
|
bool m_isLink = false;
|
||||||
|
/**
|
||||||
|
* @brief Whether the road is part of a roundabout.
|
||||||
|
*/
|
||||||
|
bool m_onRoundabout = false;
|
||||||
|
|
||||||
RoadNameInfo() = default;
|
RoadNameInfo() = default;
|
||||||
RoadNameInfo(std::string name) : m_name(std::move(name)) {}
|
RoadNameInfo(std::string name) : m_name(std::move(name)) {}
|
||||||
|
|||||||
@@ -1030,6 +1030,32 @@ void RoutingTraffDecoder::DecodeLocationDirection(traffxml::TraffMessage & messa
|
|||||||
|
|
||||||
TruncateRoute(rsegments, checkpoints);
|
TruncateRoute(rsegments, checkpoints);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `m_onRoundabout` is set only for the first segment after the junction. In order to identify
|
||||||
|
* all roundabout segments, cache the last segment with `m_onRoundabout` set. Any subsequent
|
||||||
|
* segment with the same MWM and feature ID is also a roundabout segment.
|
||||||
|
*/
|
||||||
|
routing::Segment lastRoundaboutSegment;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We usually discard roundabouts, unless the location is a point (`at` point set) or the entire
|
||||||
|
* decoded location is a roundabout.
|
||||||
|
*/
|
||||||
|
bool keepRoundabouts = true;
|
||||||
|
|
||||||
|
if (!message.m_location.value().m_at)
|
||||||
|
for (auto & rsegment : rsegments)
|
||||||
|
{
|
||||||
|
if (rsegment.GetRoadNameInfo().m_onRoundabout)
|
||||||
|
lastRoundaboutSegment = rsegment.GetSegment();
|
||||||
|
else if ((rsegment.GetSegment().GetMwmId() != lastRoundaboutSegment.GetMwmId())
|
||||||
|
|| (rsegment.GetSegment().GetFeatureId() != lastRoundaboutSegment.GetFeatureId()))
|
||||||
|
{
|
||||||
|
keepRoundabouts = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!backwards && message.m_location.value().m_at && !message.m_location.value().m_to)
|
if (!backwards && message.m_location.value().m_at && !message.m_location.value().m_to)
|
||||||
// from–at in forward direction, add last segment
|
// from–at in forward direction, add last segment
|
||||||
AddDecodedSegment(decoded, rsegments.back().GetSegment());
|
AddDecodedSegment(decoded, rsegments.back().GetSegment());
|
||||||
@@ -1070,6 +1096,19 @@ void RoutingTraffDecoder::DecodeLocationDirection(traffxml::TraffMessage & messa
|
|||||||
{
|
{
|
||||||
routing::Segment & segment = rsegment.GetSegment();
|
routing::Segment & segment = rsegment.GetSegment();
|
||||||
|
|
||||||
|
// Skip roundabouts to avoid side effects on crossing roads
|
||||||
|
if (!keepRoundabouts)
|
||||||
|
{
|
||||||
|
if (rsegment.GetRoadNameInfo().m_onRoundabout)
|
||||||
|
{
|
||||||
|
lastRoundaboutSegment = segment;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ((segment.GetMwmId() == lastRoundaboutSegment.GetMwmId())
|
||||||
|
&& (segment.GetFeatureId() == lastRoundaboutSegment.GetFeatureId()))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// If we have more than two checkpoints, fake segments can occur in the middle, skip them.
|
// If we have more than two checkpoints, fake segments can occur in the middle, skip them.
|
||||||
if (segment.GetMwmId() == routing::kFakeNumMwmId)
|
if (segment.GetMwmId() == routing::kFakeNumMwmId)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user