From 1ecc913fc28d9ab19d1f04d704b23996571a5bf9 Mon Sep 17 00:00:00 2001 From: Michael Krasnyk Date: Tue, 1 Aug 2017 17:15:39 +0200 Subject: [PATCH] Fix sliproad scenario with 4 roads in a target intersection, #4348/1 --- .../guidance/dedicated-turn-roads.feature | 6 +-- src/extractor/guidance/sliproad_handler.cpp | 50 ++++++++++++++++++- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/features/guidance/dedicated-turn-roads.feature b/features/guidance/dedicated-turn-roads.feature index f3e267c07..1cffe003c 100644 --- a/features/guidance/dedicated-turn-roads.feature +++ b/features/guidance/dedicated-turn-roads.feature @@ -968,6 +968,6 @@ Feature: Slipways and Dedicated Turn Lanes | ec | primary_link | ec | yes | When I route I should get - | waypoints | route | turns | locations | - | s,f | sabct,ae,dbef,dbef | depart,turn right,turn slight right,arrive | s,a,e,f | - | f,t | dbef,sabct,sabct | depart,turn right,arrive | f,e,t | + | waypoints | route | turns | locations | + | s,f | sabct,dbef,dbef | depart,turn right,arrive | s,a,f | + | f,t | dbef,sabct,sabct | depart,turn right,arrive | f,e,t | diff --git a/src/extractor/guidance/sliproad_handler.cpp b/src/extractor/guidance/sliproad_handler.cpp index 7188ee6f6..69e483606 100644 --- a/src/extractor/guidance/sliproad_handler.cpp +++ b/src/extractor/guidance/sliproad_handler.cpp @@ -263,8 +263,9 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter if (!allSameMode(source_edge_id, sliproad.eid, find_valid(target_intersection)->eid)) continue; - // Constrain the Sliproad's target to sliproad, outgoing, incoming from main intersection - if (target_intersection.size() != 3) + // Constrain the sliproad's target intersection to 1 or 2 sliproads, outgoing road + // and incoming one from the main intersection + if (target_intersection.size() < 3 || target_intersection.size() > 4) { continue; } @@ -279,6 +280,51 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter continue; } + if (target_intersection.size() == 4) + { + // Handle target intersections at `d` with 4 roads + // + // | `main_road_intersection` is intersection at `c` + // v + // a ... b .... c .... e <- fo + // ` . ' + // ` . ' + // ` . ' + // d < `target_intersection` is intersection at `d` + // | + // Conditions for road `bd` to be a sliproad: + // - target_intersection at `d` has 4 roads + // - main_road_intersection at `c` has at least 3 roads + // - target nodes of `db` and `cd` roads is the same node `d` + // - target nodes of `ce` and `de` roads is the same node `e` + // - angle `bde` is sharp + + // Check `c` has at least 3 roads at `c` and roads `bd` and `cd` share the node `d` + if (main_road_intersection->intersection.size() < 3 || + sliproad_edge_target != node_based_graph.GetTarget(crossing_road.eid)) + { + continue; + } + + // Find a road at `d` that shares the same node `e` with `ce` and ∠ `bde` is sharp + auto next_to_crossing_idx = + is_left_sliproad_turn ? main_road_intersection->intersection.size() - 2 : 2; + auto next_to_crossing_road = main_road_intersection->intersection[next_to_crossing_idx]; + auto next_to_crossing_node = node_based_graph.GetTarget(next_to_crossing_road.eid); + auto found_common_node = std::find_if( + begin(target_intersection), end(target_intersection), [&](const auto &road) { + if (next_to_crossing_node == node_based_graph.GetTarget(road.eid)) + { + auto direction = getTurnDirection(road.angle); + return direction == DirectionModifier::SharpRight || + direction == DirectionModifier::SharpLeft; + } + return false; + }); + if (found_common_node == target_intersection.end()) + continue; + } + // If the sliproad candidate is a through street, we cannot handle it as a sliproad. if (isThroughStreet(sliproad_edge, target_intersection)) {