diff --git a/CHANGELOG.md b/CHANGELOG.md index b19c12d7dbf..846ec53733c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - MLD uses a unidirectional Dijkstra for 1-to-N and N-to-1 matrices - Guidance - Fixed some cases of sliproads pre-processing (https://github.com/Project-OSRM/osrm-backend/issues/4348) + - don't suppress name announcements via sliproad handler # 5.12.0 - Changes from 5.11: diff --git a/features/guidance/dedicated-turn-roads.feature b/features/guidance/dedicated-turn-roads.feature index dede9aab8dc..dbede0e6959 100644 --- a/features/guidance/dedicated-turn-roads.feature +++ b/features/guidance/dedicated-turn-roads.feature @@ -1023,3 +1023,31 @@ Feature: Slipways and Dedicated Turn Lanes When I route I should get | waypoints | route | turns | locations | | s,f | sab,dbcf,dbcf | depart,turn right,arrive | s,a,f | + + + @sliproads + Scenario: Sliproad with a single intersection in a cross-road + Given the node map + """ + d + . + s . a . b + ` . + ' c . g + .. + e + . + f + """ + + And the ways + | nodes | highway | name | oneway | + | sab | primary | sab | | + | dbcef | primary | dbcef | | + | ae | primary_link | sab | yes | + | cg | primary | cg | | + + + When I route I should get + | waypoints | route | turns | locations | + | s,f | sab,dbcef,dbcef | depart,turn right,arrive | s,a,f | diff --git a/features/guidance/roundabout.feature b/features/guidance/roundabout.feature index ed0eb7a83d2..e63b8bbdff0 100644 --- a/features/guidance/roundabout.feature +++ b/features/guidance/roundabout.feature @@ -829,16 +829,16 @@ Feature: Basic Roundabout """ And the ways - | nodes | highway | junction | oneway | # | - | abcda | tertiary | roundabout | | circle | - | ebds | tertiary | | | road | - | cm | tertiary | | | | - | ds | tertiary | | | road | - | rstur | tertiary | roundabout | | circle2 | - | ufghl | tertiary | | | road | - | tv | tertiary | | | | - | gi | tertiary | | yes | sliproad | - | jhik | tertiary | | | crossroad | + | nodes | highway | junction | oneway | # | + | abcda | tertiary | roundabout | | circle | + | ebds | tertiary | | | road | + | cm | tertiary | | | | + | ds | tertiary | | | road | + | rstur | tertiary | roundabout | | circle2 | + | ufghl | tertiary | | | road | + | tv | tertiary | | | | + | gi | tertiary_link | | yes | sliproad | + | jhik | tertiary | | | crossroad | When I route I should get diff --git a/src/extractor/guidance/sliproad_handler.cpp b/src/extractor/guidance/sliproad_handler.cpp index c6e42817cb8..2bbc96c46f5 100644 --- a/src/extractor/guidance/sliproad_handler.cpp +++ b/src/extractor/guidance/sliproad_handler.cpp @@ -394,7 +394,7 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter using namespace util::coordinate_calculation; // In addition, if it's a right/left turn we expect the rightmost/leftmost - // turn at `c` to be more or less ~90 degree for a Sliproad scenario. + // turn at `c` to be more than a minimal angle (40°) for a Sliproad scenario. double deviation_from_straight = 0; if (is_right_sliproad_turn) @@ -423,7 +423,7 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter const auto length = haversineDistance(coordinates[intersection_node_id], coordinates[main_road_intersection->node]); - const double perpendicular_angle = 90 + FUZZY_ANGLE_DIFFERENCE; + const double minimal_crossroad_angle_of_intersection = 40.; if (length >= MIN_LENGTH) { @@ -433,7 +433,7 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter } // Check sliproads with skew main intersections - if (deviation_from_straight > perpendicular_angle && + if (deviation_from_straight > 180. - minimal_crossroad_angle_of_intersection && !node_based_graph.GetEdgeData(sliproad.eid).road_classification.IsLinkClass()) { continue; @@ -487,13 +487,45 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter continue; } + // Check if main road -> sliproad (non-link) -> candidate road requires two name + // announcements then don't suppress one announcement via sliproad handler + const auto main_road_name_id = node_based_graph.GetEdgeData(main_road.eid).name_id; + if (!sliproad_data.road_classification.IsLinkClass() && + sliproad_data.name_id != EMPTY_NAMEID && main_road_name_id != EMPTY_NAMEID && + candidate_data.name_id != EMPTY_NAMEID && + util::guidance::requiresNameAnnounced(main_road_name_id, + sliproad_data.name_id, + name_table, + street_name_suffix_table) && + util::guidance::requiresNameAnnounced(sliproad_data.name_id, + candidate_data.name_id, + name_table, + street_name_suffix_table)) + { + continue; + } + // If the Sliproad `bd` is a link, `bc` and `cd` must not be links. if (!isValidSliproadLink(sliproad, main_road, candidate_road)) { continue; } - if (node_based_graph.GetTarget(candidate_road.eid) == main_road_intersection->node) + // Check that the cross-road `candidate_road_target` that starts at `d` ends at + // main intersection node `c` or has a common node `e` with a cross-road from `c` + // a ... b .... c a ... b .... c + // ` . ` . + // ` . ` e... + // ` . ` . + // d d + // + const auto candidate_road_target = node_based_graph.GetTarget(candidate_road.eid); + if ((candidate_road_target == main_road_intersection->node) || + (candidate_road_target == node_based_graph.GetTarget(crossing_road.eid) && + util::bearing::angleBetween(candidate_road.bearing, crossing_road.bearing) < + FUZZY_ANGLE_DIFFERENCE && + (getTurnDirection(candidate_road.angle) == DirectionModifier::SharpRight || + getTurnDirection(candidate_road.angle) == DirectionModifier::SharpLeft))) { sliproad.instruction.type = TurnType::Sliproad; sliproad_found = true;