From c1f833c80ff4cb61047ae790dacfa20adf43c4f4 Mon Sep 17 00:00:00 2001 From: Moritz Kobitzsch Date: Wed, 11 Jan 2017 11:09:53 +0100 Subject: [PATCH] fix forks exiting a ferry --- features/guidance/collapse-ferry.feature | 22 +++++++++++++++++ include/util/debug.hpp | 2 +- .../guidance/intersection_handler.cpp | 24 +++++++++++++++---- .../guidance/suppress_mode_handler.cpp | 2 +- src/extractor/guidance/turn_handler.cpp | 8 ++++++- 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/features/guidance/collapse-ferry.feature b/features/guidance/collapse-ferry.feature index a17a82048..ee2aedf0b 100644 --- a/features/guidance/collapse-ferry.feature +++ b/features/guidance/collapse-ferry.feature @@ -119,3 +119,25 @@ Feature: Collapse When I route I should get | waypoints | route | turns | | g,e | land-bottom,ferry,land-right,land-right | depart,notification straight,notification right,arrive | + + @negative + Scenario: Don't Detect Suppressed/Obvious Forks on Ferries + Given the node map + """ + . . . . . . . . .d + a - b ~ ~ ~ ~ ~ c < + ' ' ' ' ' ' ' ' 'e + """ + + And the ways + | nodes | highway | route | name | + | ab | primary | | cursed-island | + | bc | | ferry | beagle | + | cd | service | | forker | + | ce | primary | | screw-me-not | + + #the turns here could be better, but intersection classification shows you if you go left or right. But we cannot fork here + When I route I should get + | waypoints | route | turns | + | a,d | cursed-island,beagle,forker,forker | depart,notification straight,turn straight,arrive | + | a,e | cursed-island,beagle,screw-me-not,screw-me-not | depart,notification straight,turn straight,arrive | diff --git a/include/util/debug.hpp b/include/util/debug.hpp index 79aabdda6..45bc6a00f 100644 --- a/include/util/debug.hpp +++ b/include/util/debug.hpp @@ -29,7 +29,7 @@ inline void print(const engine::guidance::RouteStep &step) << " " << " Duration: " << step.duration << " Distance: " << step.distance << " Geometry: " << step.geometry_begin << " " << step.geometry_end - << " Exit: " << step.maneuver.exit + << " Exit: " << step.maneuver.exit << " Mode: " << (int)step.mode << "\n\tIntersections: " << step.intersections.size() << " ["; for (const auto &intersection : step.intersections) diff --git a/src/extractor/guidance/intersection_handler.cpp b/src/extractor/guidance/intersection_handler.cpp index 53b4c9a28..771feae24 100644 --- a/src/extractor/guidance/intersection_handler.cpp +++ b/src/extractor/guidance/intersection_handler.cpp @@ -174,6 +174,14 @@ void IntersectionHandler::assignFork(const EdgeID via_edge, node_based_graph.GetEdgeData(left.eid).road_classification.IsLowPriorityRoadClass(); const bool low_priority_right = node_based_graph.GetEdgeData(right.eid).road_classification.IsLowPriorityRoadClass(); + const auto same_mode_left = + in_data.travel_mode == node_based_graph.GetEdgeData(left.eid).travel_mode; + const auto same_mode_right = + in_data.travel_mode == node_based_graph.GetEdgeData(right.eid).travel_mode; + const auto suppressed_left_type = + same_mode_left ? TurnType::Suppressed : TurnType::Notification; + const auto suppressed_right_type = + same_mode_right ? TurnType::Suppressed : TurnType::Notification; if ((angularDeviation(left.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION && angularDeviation(right.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE)) { @@ -205,7 +213,7 @@ void IntersectionHandler::assignFork(const EdgeID via_edge, } else { - left.instruction = {TurnType::Suppressed, DirectionModifier::Straight}; + left.instruction = {suppressed_left_type, DirectionModifier::Straight}; right.instruction = {findBasicTurnType(via_edge, right), DirectionModifier::SlightRight}; } @@ -244,7 +252,7 @@ void IntersectionHandler::assignFork(const EdgeID via_edge, } else { - right.instruction = {TurnType::Suppressed, DirectionModifier::Straight}; + right.instruction = {suppressed_right_type, DirectionModifier::Straight}; left.instruction = {findBasicTurnType(via_edge, left), DirectionModifier::SlightLeft}; } @@ -252,7 +260,7 @@ void IntersectionHandler::assignFork(const EdgeID via_edge, } // left side of fork if (low_priority_right && !low_priority_left) - left.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft}; + left.instruction = {suppressed_left_type, DirectionModifier::SlightLeft}; else { if (low_priority_left && !low_priority_right) @@ -267,7 +275,7 @@ void IntersectionHandler::assignFork(const EdgeID via_edge, // right side of fork if (low_priority_left && !low_priority_right) - right.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft}; + right.instruction = {suppressed_right_type, DirectionModifier::SlightLeft}; else { if (low_priority_right && !low_priority_left) @@ -287,6 +295,12 @@ void IntersectionHandler::assignFork(const EdgeID via_edge, ConnectedRoad &right) const { // TODO handle low priority road classes in a reasonable way + const auto suppressed_type = [&](const ConnectedRoad &road) { + const auto in_mode = node_based_graph.GetEdgeData(via_edge).travel_mode; + const auto out_mode = node_based_graph.GetEdgeData(road.eid).travel_mode; + return in_mode == out_mode ? TurnType::Suppressed : TurnType::Notification; + }; + if (left.entry_allowed && center.entry_allowed && right.entry_allowed) { left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft}; @@ -300,7 +314,7 @@ void IntersectionHandler::assignFork(const EdgeID via_edge, } else { - center.instruction = {TurnType::Suppressed, DirectionModifier::Straight}; + center.instruction = {suppressed_type(center), DirectionModifier::Straight}; } } else diff --git a/src/extractor/guidance/suppress_mode_handler.cpp b/src/extractor/guidance/suppress_mode_handler.cpp index fe3e44a77..ede670e0f 100644 --- a/src/extractor/guidance/suppress_mode_handler.cpp +++ b/src/extractor/guidance/suppress_mode_handler.cpp @@ -39,7 +39,7 @@ bool SuppressModeHandler::canProcess(const NodeID, const auto in_mode = node_based_graph.GetEdgeData(via_eid).travel_mode; const auto suppress_in_mode = std::find(begin(suppressed), end(suppressed), in_mode); - const auto first = begin(intersection) + 1; + const auto first = begin(intersection); const auto last = end(intersection); const auto all_share_mode = std::all_of(first, last, [this, &in_mode](const auto &road) { diff --git a/src/extractor/guidance/turn_handler.cpp b/src/extractor/guidance/turn_handler.cpp index 79acac1da..e4e909aa9 100644 --- a/src/extractor/guidance/turn_handler.cpp +++ b/src/extractor/guidance/turn_handler.cpp @@ -650,8 +650,14 @@ boost::optional TurnHandler::findFork(const EdgeID via_edge, const bool only_valid_entries = intersection.hasAllValidEntries(fork->right, fork->left + 1); + const auto has_compatible_modes = + std::all_of(fork->right, fork->left + 1, [&](const auto &road) { + return node_based_graph.GetEdgeData(road.eid).travel_mode == + node_based_graph.GetEdgeData(via_edge).travel_mode; + }); + if (separated_at_left_side && separated_at_right_side && !has_obvious && - has_compatible_classes && only_valid_entries) + has_compatible_classes && only_valid_entries && has_compatible_modes) { return fork; }