diff --git a/CHANGELOG.md b/CHANGELOG.md index 89af59c55..b8c7de28c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Reduced semantic of merge to refer only to merges from a lane onto a motorway-like road - Bugfixes - Fixed an issue that would result in segfaults for viaroutes with an invalid intermediate segment when u-turns were allowed at the via-location + - Invalid only_* restrictions could result in loss of connectivity. As a fallback, we assume all turns allowed when the restriction is not valid # 5.3.0 Changes from 5.3.0-rc.3 diff --git a/features/car/restrictions.feature b/features/car/restrictions.feature index b730bb8d7..294e587d7 100644 --- a/features/car/restrictions.feature +++ b/features/car/restrictions.feature @@ -149,11 +149,27 @@ Feature: Car - Turn restrictions | type | way:from | way:to | node:via | restriction | | restriction | sj | wj | j | only_left_turn | + Scenario: Car - Only right turn, invalid + Given the node map + | | n | | | + | w | j | e | r | + | | s | | | + + And the ways + | nodes | oneway | + | sj | yes | + | nj | -1 | + | wj | -1 | + | ej | -1 | + | re | -1 | + + And the relations + | type | way:from | way:to | node:via | restriction | + | restriction | sj | er | j | only_right_on | + When I route I should get - | from | to | route | - | s | w | sj,wj,wj | - | s | n | | - | s | e | | + | from | to | route | + | s | r | sj,ej,re,re | @only_turning Scenario: Car - Only right turn diff --git a/src/extractor/guidance/intersection_generator.cpp b/src/extractor/guidance/intersection_generator.cpp index 9b8711f7b..049cea59e 100644 --- a/src/extractor/guidance/intersection_generator.cpp +++ b/src/extractor/guidance/intersection_generator.cpp @@ -55,8 +55,21 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node, { Intersection intersection; const NodeID turn_node = node_based_graph.GetTarget(via_eid); - const NodeID only_restriction_to_node = - restriction_map.CheckForEmanatingIsOnlyTurn(from_node, turn_node); + const NodeID only_restriction_to_node = [&]() { + // If only restrictions refer to invalid ways somewhere far away, we rather ignore the + // restriction than to not route over the intersection at all. + const auto only_restriction_to_node = + restriction_map.CheckForEmanatingIsOnlyTurn(from_node, turn_node); + if (only_restriction_to_node != SPECIAL_NODEID) + { + // check if we can find an edge in the edge-rage + for (const auto onto_edge : node_based_graph.GetAdjacentEdgeRange(turn_node)) + if (only_restriction_to_node == node_based_graph.GetTarget(onto_edge)) + return only_restriction_to_node; + } + // Ignore broken only restrictions. + return SPECIAL_NODEID; + }(); const bool is_barrier_node = barrier_nodes.find(turn_node) != barrier_nodes.end(); bool has_uturn_edge = false; diff --git a/src/extractor/restriction_map.cpp b/src/extractor/restriction_map.cpp index 8cba4b6fa..183e95d0e 100644 --- a/src/extractor/restriction_map.cpp +++ b/src/extractor/restriction_map.cpp @@ -143,11 +143,9 @@ bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID node_u, { return true; } - if (node_w != restriction_target.target_node && // target not found - restriction_target.is_only) // and is an only restriction - { - return true; - } + // We could be tempted to check for `only` restrictions here as well. However, that check is + // actually perfomed in intersection generation where we can also verify if the only + // restriction is valid at all. } return false; }