diff --git a/features/guidance/new-name.feature b/features/guidance/new-name.feature index 1fdf1ce42..984ae7bb2 100644 --- a/features/guidance/new-name.feature +++ b/features/guidance/new-name.feature @@ -133,3 +133,34 @@ Feature: New-Name Instructions When I route I should get | waypoints | route | turns | | a,c | ab,bc,bc | depart,new name slight right,arrive | + + Scenario: Empty road names - Announce Change From, suppress Change To + Given the node map + | a | | b | | c | | d | + + And the ways + | nodes | name | + | ab | ab | + | bc | | + | cd | cd | + + When I route I should get + | waypoints | route | turns | + | a,d | ab,cd,cd | depart,new name straight,arrive | + | a,c | ab, | depart,arrive | + + Scenario: Empty road names - Loose name shortly + Given the node map + | a | | b | | c | | d | | e | + + And the ways + | nodes | name | + | ab | name | + | bc | with-name | + | cd | | + | de | with-name | + + When I route I should get + | waypoints | route | turns | + | a,e | name,with-name,with-name | depart,new name straight,arrive | + | b,e | with-name,with-name | depart,arrive | diff --git a/include/extractor/guidance/toolkit.hpp b/include/extractor/guidance/toolkit.hpp index 26573a04d..f7d0f614a 100644 --- a/include/extractor/guidance/toolkit.hpp +++ b/include/extractor/guidance/toolkit.hpp @@ -325,6 +325,10 @@ inline bool requiresNameAnnounced(const std::string &from, const std::string &to, const SuffixTable &suffix_table) { + //first is empty and the second is not + if(from.empty() && !to.empty()) + return true; + // FIXME, handle in profile to begin with? // this uses the encoding of references in the profile, which is very BAD // Input for this function should be a struct separating streetname, suffix (e.g. road, diff --git a/src/engine/guidance/post_processing.cpp b/src/engine/guidance/post_processing.cpp index 1526e2aa5..e52ac3724 100644 --- a/src/engine/guidance/post_processing.cpp +++ b/src/engine/guidance/post_processing.cpp @@ -33,10 +33,7 @@ namespace { // invalidate a step and set its content to nothing -void invalidateStep(RouteStep &step) -{ - step = getInvalidRouteStep(); -} +void invalidateStep(RouteStep &step) { step = getInvalidRouteStep(); } void print(const std::vector &steps) { @@ -512,6 +509,9 @@ std::vector postProcess(std::vector steps) // Post Processing to collapse unnecessary sets of combined instructions into a single one std::vector collapseTurns(std::vector steps) { + if (steps.size() <= 2) + return steps; + // Get the previous non-invalid instruction const auto getPreviousIndex = [&steps](std::size_t index) { BOOST_ASSERT(index > 0); @@ -523,6 +523,17 @@ std::vector collapseTurns(std::vector steps) return index; }; + // Check for an initial unwanted new-name + { + const auto ¤t_step = steps[1]; + if (TurnType::NewName == current_step.maneuver.instruction.type && + current_step.name == steps[0].name) + { + steps[0] = elongate(std::move(steps[0]), steps[1]); + invalidateStep(steps[1]); + } + } + // first and last instructions are waypoints that cannot be collapsed for (std::size_t step_index = 2; step_index < steps.size(); ++step_index) { @@ -538,14 +549,22 @@ std::vector collapseTurns(std::vector steps) const auto two_back_index = getPreviousIndex(one_back_index); BOOST_ASSERT(two_back_index < steps.size()); + // Due to empty segments, we can get name-changes from A->A + // These have to be handled in post-processing + if (TurnType::NewName == current_step.maneuver.instruction.type && + current_step.name == steps[one_back_index].name) + { + steps[one_back_index] = elongate(std::move(steps[one_back_index]), steps[step_index]); + invalidateStep(steps[step_index]); + } // If we look at two consecutive name changes, we can check for a name oszillation. // A name oszillation changes from name A shortly to name B and back to A. // In these cases, the name change will be suppressed. - if (TurnType::NewName == current_step.maneuver.instruction.type && - TurnType::NewName == one_back_step.maneuver.instruction.type) + else if (TurnType::NewName == current_step.maneuver.instruction.type && + TurnType::NewName == one_back_step.maneuver.instruction.type) { // valid due to step_index starting at 2 - const auto &coming_from_name = steps[step_index - 2].name; + const auto &coming_from_name = steps[two_back_index].name; if (current_step.name == coming_from_name) { if (current_step.mode == one_back_step.mode &&