From c306a5985476b4008885296b1abd02912097c161 Mon Sep 17 00:00:00 2001 From: Moritz Kobitzsch Date: Thu, 8 Sep 2016 14:03:02 +0200 Subject: [PATCH] make sure to not-collapse different travel modes --- features/guidance/collapse.feature | 46 ++++++++++++++++++ src/engine/guidance/post_processing.cpp | 49 +++++++++++++------- src/extractor/guidance/turn_lane_matcher.cpp | 2 +- 3 files changed, 79 insertions(+), 18 deletions(-) diff --git a/features/guidance/collapse.feature b/features/guidance/collapse.feature index c66ee2813..f8e666627 100644 --- a/features/guidance/collapse.feature +++ b/features/guidance/collapse.feature @@ -792,3 +792,49 @@ Feature: Collapse When I route I should get | waypoints | route | turns | | a,e | main,main | depart,arrive | + + Scenario: Don't collapse different travel modes + Given the node map + | g | | | | | | | h | | + | a | b | | c | | | | e | f | + | | | | | | d | | | | + | | | | i | j | | | | | + + And the ways + | nodes | highway | route | name | + | ab | primary | | road | + | bc | primary | ferry | | + | cd | primary | | road | + | de | | ferry | | + | ef | primary | | road | + | bg | service | | turn | + | ci | service | | turn | + | dj | service | | turn | + | eh | service | | turn | + + When I route I should get + | waypoints | route | + | a,f | road,,road,,road,road | + + Scenario: U-Turn onto a Ferry + Given the node map + | | | | | | | i | | | + | j | e | | | | | d | c | h | + | | | | | | | | | | + | | | | | | | | | | + | k | g | | | | | a | b | f | + + And the ways + | nodes | highway | route | name | oneway | + | bf | primary | | road | yes | + | hcd | primary | | road | yes | + | bc | primary | | | yes | + | di | service | | serv | yes | + | ed | | ferry | ferry | | + | gab | | ferry | ferry | | + | kg | primary | | on | yes | + | ej | primary | | off | yes | + + When I route I should get + | waypoints | route | turns | + | k,j | on,ferry,,ferry,off,off | depart,new name straight,continue uturn,turn straight,new name straight,arrive | diff --git a/src/engine/guidance/post_processing.cpp b/src/engine/guidance/post_processing.cpp index 4f0582ab9..29f07136a 100644 --- a/src/engine/guidance/post_processing.cpp +++ b/src/engine/guidance/post_processing.cpp @@ -474,16 +474,19 @@ void collapseTurnAt(std::vector &steps, { steps[one_back_index] = elongate(std::move(steps[one_back_index]), steps[step_index]); invalidateStep(steps[step_index]); - if (u_turn_with_name_change) + if (u_turn_with_name_change && + compatible(steps[one_back_index], steps[next_step_index])) { steps[one_back_index] = elongate(std::move(steps[one_back_index]), steps[next_step_index]); invalidateStep(steps[next_step_index]); // will be skipped due to the // continue statement at the // beginning of this function - } - forwardStepSignage(steps[one_back_index], steps[two_back_index]); + forwardStepSignage(steps[one_back_index], steps[two_back_index]); + } + if (direct_u_turn) + forwardStepSignage(steps[one_back_index], steps[two_back_index]); steps[one_back_index].maneuver.instruction.type = TurnType::Continue; steps[one_back_index].maneuver.instruction.direction_modifier = DirectionModifier::UTurn; @@ -541,6 +544,7 @@ RouteStep elongate(RouteStep step, const RouteStep &by_step) { step.duration += by_step.duration; step.distance += by_step.distance; + BOOST_ASSERT(step.mode == by_step.mode); // by_step comes after step -> we append at the end if (step.geometry_end == by_step.geometry_begin + 1) @@ -738,6 +742,8 @@ std::vector collapseTurns(std::vector steps) if (steps[index].maneuver.instruction.type != TurnType::Suppressed && steps[index].maneuver.instruction.type != TurnType::NewName) return false; + if (index + 1 < end_index && !compatible(steps[index], steps[index + 1])) + return false; } return true; }; @@ -823,6 +829,7 @@ std::vector collapseTurns(std::vector steps) else if (isCollapsableInstruction(current_step.maneuver.instruction) && current_step.maneuver.instruction.type != TurnType::Suppressed && steps[getPreviousNameIndex(step_index)].name_id == current_step.name_id && + // canCollapseAll is also checking for compatible(step,step+1) for all indices canCollapseAll(getPreviousNameIndex(step_index) + 1, next_step_index)) { BOOST_ASSERT(step_index > 0); @@ -863,14 +870,17 @@ std::vector collapseTurns(std::vector steps) else if (nameSegmentLength(one_back_index, steps) < name_segment_cutoff_length && isBasicNameChange(one_back_step) && isBasicNameChange(current_step)) { - steps[two_back_index] = - elongate(std::move(steps[two_back_index]), steps[one_back_index]); - invalidateStep(steps[one_back_index]); - if (nameSegmentLength(step_index, steps) < name_segment_cutoff_length) + if (compatible(steps[two_back_index], steps[one_back_index])) { steps[two_back_index] = - elongate(std::move(steps[two_back_index]), steps[step_index]); - invalidateStep(steps[step_index]); + elongate(std::move(steps[two_back_index]), steps[one_back_index]); + invalidateStep(steps[one_back_index]); + if (nameSegmentLength(step_index, steps) < name_segment_cutoff_length) + { + steps[two_back_index] = + elongate(std::move(steps[two_back_index]), steps[step_index]); + invalidateStep(steps[step_index]); + } } } else if (step_index + 2 < steps.size() && @@ -878,14 +888,18 @@ std::vector collapseTurns(std::vector steps) steps[next_step_index].maneuver.instruction.type == TurnType::NewName && one_back_step.name_id == steps[next_step_index].name_id) { - // if we are crossing an intersection and go immediately after into a name change, - // we don't wan't to collapse the initial intersection. - // a - b ---BRIDGE -- c - steps[one_back_index] = - elongate(std::move(steps[one_back_index]), - elongate(std::move(steps[step_index]), steps[next_step_index])); - invalidateStep(steps[step_index]); - invalidateStep(steps[next_step_index]); + if (compatible(steps[step_index], steps[next_step_index])) + { + // if we are crossing an intersection and go immediately after into a name + // change, + // we don't wan't to collapse the initial intersection. + // a - b ---BRIDGE -- c + steps[one_back_index] = + elongate(std::move(steps[one_back_index]), + elongate(std::move(steps[step_index]), steps[next_step_index])); + invalidateStep(steps[step_index]); + invalidateStep(steps[next_step_index]); + } } else if (choiceless(current_step, one_back_step) || one_back_step.distance <= MAX_COLLAPSE_DISTANCE) @@ -903,6 +917,7 @@ std::vector collapseTurns(std::vector steps) // check for one of the multiple collapse scenarios and, if possible, collapse the turn const auto two_back_index = getPreviousIndex(one_back_index); BOOST_ASSERT(two_back_index < steps.size()); + // all turns that are handled lower down are also compatible collapseTurnAt(steps, two_back_index, one_back_index, step_index); } } diff --git a/src/extractor/guidance/turn_lane_matcher.cpp b/src/extractor/guidance/turn_lane_matcher.cpp index 7f2d46c38..5df9448ed 100644 --- a/src/extractor/guidance/turn_lane_matcher.cpp +++ b/src/extractor/guidance/turn_lane_matcher.cpp @@ -108,7 +108,7 @@ double getMatchingQuality(const TurnLaneType::Mask tag, const ConnectedRoad &roa const auto modifier = getMatchingModifier(tag); BOOST_ASSERT(static_cast(modifier) < sizeof(idealized_turn_angles) / sizeof(*idealized_turn_angles)); - const auto idealized_angle = idealized_turn_angles[getMatchingModifier(tag)]; + const auto idealized_angle = idealized_turn_angles[modifier]; return angularDeviation(idealized_angle, road.turn.angle); }