diff --git a/features/guidance/turn.feature b/features/guidance/turn.feature index d3816c73a7f..80913f16bf9 100644 --- a/features/guidance/turn.feature +++ b/features/guidance/turn.feature @@ -1372,3 +1372,64 @@ Feature: Simple Turns | waypoints | route | turns | | a,d | ab,bcd,bcd | depart,fork slight right,arrive | | a,g | ab,befg,befg | depart,fork slight left,arrive | + + # https://www.openstreetmap.org/#map=18/52.25130/10.42545 + Scenario: Turn for roads with no name, ref changes + Given the node map + """ + d + . + . + e c . . f + . + . + b + . + . + a + """ + + And the ways + | nodes | highway | ref | name | + | abc | tertiary | K 57 | | + | cd | tertiary | K 56 | | + | cf | tertiary | K 56 | | + | ce | residential | | Heinrichshöhe | + + When I route I should get + | waypoints | route | turns | + | a,f | ,, | depart,turn right,arrive | + + # https://www.openstreetmap.org/#map=18/52.24071/10.29066 + Scenario: Turn for roads with no name, ref changes + Given the node map + """ + x + . + . + d + . . + . . + . . + e. . t . c . p. .f + . . + . . + . . + b + . + . + a + """ + + And the ways + | nodes | highway | ref | name | oneway | + | abp | tertiary | K 23 | | yes | + | pdx | tertiary | K 23 | | yes | + | xdt | tertiary | K 23 | | yes | + | tba | tertiary | K 23 | | yes | + | etcpf | primary | B 1 | | no | + + When I route I should get + | waypoints | route | turns | + | e,x | ,,, | depart,turn sharp left,turn right,arrive | + | f,a | ,, | depart,turn left,arrive | diff --git a/src/engine/guidance/collapse_scenario_detection.cpp b/src/engine/guidance/collapse_scenario_detection.cpp index d8ab058dcda..562b75e5e89 100644 --- a/src/engine/guidance/collapse_scenario_detection.cpp +++ b/src/engine/guidance/collapse_scenario_detection.cpp @@ -41,15 +41,14 @@ bool noIntermediaryIntersections(const RouteStep &step) } // Link roads, as far as we are concerned, are short unnamed segments between to named segments. -bool isLinkroad(const RouteStep &pre_link_step, +bool isLinkRoad(const RouteStep &pre_link_step, const RouteStep &link_step, const RouteStep &post_link_step) { const constexpr double MAX_LINK_ROAD_LENGTH = 2 * MAX_COLLAPSE_DISTANCE; const auto is_short = link_step.distance <= MAX_LINK_ROAD_LENGTH; - const auto unnamed = link_step.name_id == EMPTY_NAMEID; - const auto between_named = - (pre_link_step.name_id != EMPTY_NAMEID) && (post_link_step.name_id != EMPTY_NAMEID); + const auto unnamed = link_step.name.empty(); + const auto between_named = !pre_link_step.name.empty() && !post_link_step.name.empty(); return is_short && unnamed && between_named && noIntermediaryIntersections(link_step); } @@ -196,7 +195,7 @@ bool isUTurn(const RouteStepIterator step_prior_to_intersection, const auto only_allowed_turn = (numberOfAllowedTurns(*step_leaving_intersection) == 1) && noIntermediaryIntersections(*step_entering_intersection); - return collapsable || isLinkroad(*step_prior_to_intersection, + return collapsable || isLinkRoad(*step_prior_to_intersection, *step_entering_intersection, *step_leaving_intersection) || only_allowed_turn; diff --git a/src/extractor/guidance/intersection_handler.cpp b/src/extractor/guidance/intersection_handler.cpp index dd43a4ba226..756ee321798 100644 --- a/src/extractor/guidance/intersection_handler.cpp +++ b/src/extractor/guidance/intersection_handler.cpp @@ -71,17 +71,19 @@ TurnType::Enum IntersectionHandler::findBasicTurnType(const EdgeID via_edge, if (!on_ramp && onto_ramp) return TurnType::OnRamp; - const auto &in_name = + const auto &in_name_id = node_data_container.GetAnnotation(node_based_graph.GetEdgeData(via_edge).annotation_data) .name_id; - const auto &out_name = + const auto &out_name_id = node_data_container.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data) .name_id; + const auto &in_name_empty = name_table.GetNameForID(in_name_id).empty(); + const auto &out_name_empty = name_table.GetNameForID(out_name_id).empty(); const auto same_name = !util::guidance::requiresNameAnnounced( - in_name, out_name, name_table, street_name_suffix_table); + in_name_id, out_name_id, name_table, street_name_suffix_table); - if (in_name != EMPTY_NAMEID && out_name != EMPTY_NAMEID && same_name) + if (!in_name_empty && !out_name_empty && same_name) { return TurnType::Continue; } @@ -488,8 +490,8 @@ bool IntersectionHandler::isSameName(const EdgeID source_edge_id, const EdgeID t const auto &target_edge_data = node_data_container.GetAnnotation( node_based_graph.GetEdgeData(target_edge_id).annotation_data); - return source_edge_data.name_id != EMPTY_NAMEID && // - target_edge_data.name_id != EMPTY_NAMEID && // + return !name_table.GetNameForID(source_edge_data.name_id).empty() && // + !name_table.GetNameForID(target_edge_data.name_id).empty() && // !util::guidance::requiresNameAnnounced(source_edge_data.name_id, target_edge_data.name_id, name_table, diff --git a/src/extractor/guidance/mergable_road_detector.cpp b/src/extractor/guidance/mergable_road_detector.cpp index 6d04b686fdf..4773d631d6e 100644 --- a/src/extractor/guidance/mergable_road_detector.cpp +++ b/src/extractor/guidance/mergable_road_detector.cpp @@ -23,6 +23,8 @@ namespace guidance namespace { // check a connected road for equality of a name +// returns 'true' if no equality because this is used as a filter elsewhere, i.e. filter if fn +// returns 'true' inline auto makeCheckRoadForName(const NameID name_id, const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, @@ -32,15 +34,18 @@ inline auto makeCheckRoadForName(const NameID name_id, return [name_id, &node_based_graph, &node_data_container, &name_table, &suffix_table]( const MergableRoadDetector::MergableRoadData &road) { // since we filter here, we don't want any other name than the one we are looking for - const auto road_name = + const auto road_name_id = node_data_container .GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data) .name_id; - if (name_id == EMPTY_NAMEID || road_name == EMPTY_NAMEID) + const auto road_name_empty = name_table.GetNameForID(road_name_id).empty(); + const auto in_name_empty = name_table.GetNameForID(name_id).empty(); + if (in_name_empty || road_name_empty) return true; const auto requires_announcement = - util::guidance::requiresNameAnnounced(name_id, road_name, name_table, suffix_table) || - util::guidance::requiresNameAnnounced(road_name, name_id, name_table, suffix_table); + util::guidance::requiresNameAnnounced( + name_id, road_name_id, name_table, suffix_table) || + util::guidance::requiresNameAnnounced(road_name_id, name_id, name_table, suffix_table); return requires_announcement; }; @@ -465,16 +470,18 @@ bool MergableRoadDetector::IsTrafficIsland(const NodeID intersection_node, .name_id; const auto has_required_name = [this, required_name_id](const auto edge_id) { - const auto road_name = + const auto road_name_id = node_data_container .GetAnnotation(node_based_graph.GetEdgeData(edge_id).annotation_data) .name_id; - if (required_name_id == EMPTY_NAMEID || road_name == EMPTY_NAMEID) + const auto &road_name_empty = name_table.GetNameForID(road_name_id).empty(); + const auto &required_name_empty = name_table.GetNameForID(required_name_id).empty(); + if (required_name_empty && road_name_empty) return false; return !util::guidance::requiresNameAnnounced( - required_name_id, road_name, name_table, street_name_suffix_table) || + required_name_id, road_name_id, name_table, street_name_suffix_table) || !util::guidance::requiresNameAnnounced( - road_name, required_name_id, name_table, street_name_suffix_table); + road_name_id, required_name_id, name_table, street_name_suffix_table); }; /* the beautiful way would be: diff --git a/src/extractor/guidance/motorway_handler.cpp b/src/extractor/guidance/motorway_handler.cpp index 04da12c477f..4689286f1e8 100644 --- a/src/extractor/guidance/motorway_handler.cpp +++ b/src/extractor/guidance/motorway_handler.cpp @@ -379,11 +379,15 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters // // 7 1 // 0 + const auto &first_intersection_name_empty = + name_table.GetNameForID(first_intersection_data.name_id).empty(); + const auto &second_intersection_name_empty = + name_table.GetNameForID(second_intersection_data.name_id).empty(); if (intersection[1].entry_allowed) { if (isMotorwayClass(intersection[1].eid, node_based_graph) && - second_intersection_data.name_id != EMPTY_NAMEID && - first_intersection_data.name_id != EMPTY_NAMEID && first_second_same_name) + !second_intersection_name_empty && !first_intersection_name_empty && + first_second_same_name) { // circular order indicates a merge to the left (0-3 onto 4 if (angularDeviation(intersection[1].angle, STRAIGHT_ANGLE) < @@ -407,8 +411,8 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters { BOOST_ASSERT(intersection[2].entry_allowed); if (isMotorwayClass(intersection[2].eid, node_based_graph) && - second_intersection_data.name_id != EMPTY_NAMEID && - first_intersection_data.name_id != EMPTY_NAMEID && first_second_same_name) + !second_intersection_name_empty && !first_intersection_name_empty && + first_second_same_name) { // circular order (5-0) onto 4 if (angularDeviation(intersection[2].angle, STRAIGHT_ANGLE) < diff --git a/src/extractor/guidance/roundabout_handler.cpp b/src/extractor/guidance/roundabout_handler.cpp index 1aa8f595197..4bea638fe1f 100644 --- a/src/extractor/guidance/roundabout_handler.cpp +++ b/src/extractor/guidance/roundabout_handler.cpp @@ -295,7 +295,8 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const return SPECIAL_EDGEID; } - if (EMPTY_NAMEID != edge_data.name_id) + const auto &edge_name_empty = name_table.GetNameForID(edge_data.name_id).empty(); + if (!edge_name_empty) { const auto announce = [&](unsigned id) { @@ -306,7 +307,6 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const if (std::all_of(begin(roundabout_name_ids), end(roundabout_name_ids), announce)) roundabout_name_ids.insert(edge_data.name_id); } - continue_edge = edge_id; } else if (!edge.flags.roundabout && !edge.flags.circular) diff --git a/src/extractor/guidance/sliproad_handler.cpp b/src/extractor/guidance/sliproad_handler.cpp index c2290327cf5..96fa4cfde21 100644 --- a/src/extractor/guidance/sliproad_handler.cpp +++ b/src/extractor/guidance/sliproad_handler.cpp @@ -1,5 +1,6 @@ #include "extractor/guidance/sliproad_handler.hpp" #include "extractor/guidance/constants.hpp" +#include "util/assert.hpp" #include "util/bearing.hpp" #include "util/coordinate_calculation.hpp" #include "util/guidance/name_announcements.hpp" @@ -474,7 +475,7 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter // Name mismatch: check roads at `c` and `d` for same name const auto name_mismatch = [&](const NameID road_name_id) { - const auto unnamed = road_name_id == EMPTY_NAMEID; + const auto unnamed = name_table.GetNameForID(road_name_id).empty(); return unnamed || util::guidance::requiresNameAnnounced(road_name_id, // @@ -499,11 +500,15 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter node_data_container .GetAnnotation(node_based_graph.GetEdgeData(main_road.eid).annotation_data) .name_id; + const auto main_road_name_empty = name_table.GetNameForID(main_road_name_id).empty(); const auto &sliproad_annotation = node_data_container.GetAnnotation(sliproad_edge_data.annotation_data); + const auto sliproad_name_empty = + name_table.GetNameForID(sliproad_annotation.name_id).empty(); + const auto candidate_road_name_empty = + name_table.GetNameForID(candidate_data.name_id).empty(); if (!sliproad_edge_data.flags.road_classification.IsLinkClass() && - sliproad_annotation.name_id != EMPTY_NAMEID && main_road_name_id != EMPTY_NAMEID && - candidate_data.name_id != EMPTY_NAMEID && + !sliproad_name_empty && !main_road_name_empty && !candidate_road_name_empty && util::guidance::requiresNameAnnounced(main_road_name_id, sliproad_annotation.name_id, name_table, @@ -575,8 +580,9 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter intersection[*obvious].instruction.direction_modifier = getTurnDirection(intersection[*obvious].angle); } - else if (main_annotation.name_id != EMPTY_NAMEID) + else if (!name_table.GetNameForID(main_annotation.name_id).empty()) { + OSRM_ASSERT(false, coordinates[intersection_node_id]); intersection[*obvious].instruction.type = TurnType::NewName; intersection[*obvious].instruction.direction_modifier = getTurnDirection(intersection[*obvious].angle); diff --git a/src/extractor/guidance/turn_handler.cpp b/src/extractor/guidance/turn_handler.cpp index 5b520066540..a4be7ede6aa 100644 --- a/src/extractor/guidance/turn_handler.cpp +++ b/src/extractor/guidance/turn_handler.cpp @@ -199,7 +199,8 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge, const bool turn_is_perfectly_straight = angularDeviation(road.angle, STRAIGHT_ANGLE) < std::numeric_limits::epsilon(); - if (via_data.name_id != EMPTY_NAMEID) + const auto &via_name_empty = name_table.GetNameForID(via_data.name_id).empty(); + if (!via_name_empty) { const auto same_name = !util::guidance::requiresNameAnnounced( via_data.name_id, road_data.name_id, name_table, street_name_suffix_table);