From e7acc9df7649e87e6035770900537ea9046720b8 Mon Sep 17 00:00:00 2001 From: themylogin Date: Wed, 4 Jul 2018 22:14:58 +0300 Subject: [PATCH] Fix turn.roads_on_the_left and turn.roads_on_the right for two-way roads #5128 --- CHANGELOG.md | 1 + .../options/extract/turn_function.feature | 27 +++++++ src/extractor/edge_based_graph_factory.cpp | 78 +++++++++++++------ 3 files changed, 81 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ff20e4f6..ffdab7cf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - FIXED: Reduce copying in API parameter constructors [#5925](https://github.com/Project-OSRM/osrm-backend/pull/5925) - Misc: - CHANGED: Unify `.osrm.turn_penalites_index` dump processing same with `.osrm.turn_weight_penalties` and `.osrm.turn_duration_penalties` [#5868](https://github.com/Project-OSRM/osrm-backend/pull/5868) + - FIXED: turn.roads_on_the_left not containing incoming roads and turn.roads_on_the_right not containing outgoing roads on two-way roads [#5128](https://github.com/Project-OSRM/osrm-backend/issues/5128) - Profile: - ADDED: Profile debug script which fetches a way from OSM then outputs the result of the profile. [#5908](https://github.com/Project-OSRM/osrm-backend/pull/5908) - Infrastructure diff --git a/features/options/extract/turn_function.feature b/features/options/extract/turn_function.feature index a1db9339f..eecb29604 100644 --- a/features/options/extract/turn_function.feature +++ b/features/options/extract/turn_function.feature @@ -180,3 +180,30 @@ Feature: Turn Function Information And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 3, access_turn_classification: 0/ # turning abc, give information about about db And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 0, access_turn_classification: 1/ + + Scenario: Turns should have correct information of two-way roads at intersection + Given the node map + """ + b + | + a-c-d + | + e + """ + And the ways + | nodes | highway | oneway | + | ac | motorway | yes | + | cd | motorway_link | yes | + | bc | trunk | yes | + | cb | trunk_link | yes | + | ce | primary | yes | + | ec | primary_link | yes | + And the data has been saved to disk + + When I run "osrm-extract --profile {profile_file} {osm_file}" + Then it should exit successfully + # Turn acd + # on the left there should be cb (and bc) + And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: true, highway_turn_classification: [0-9]+, access_turn_classification: 0, priority_class: 3/ + # on the right there should be ce and ec + And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: true, highway_turn_classification: [0-9]+, access_turn_classification: 0, priority_class: 4/ diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index ba9b1e85b..4a73d1d3d 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -714,16 +714,15 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( { ++node_based_edge_counter; - const auto intersection_view = - convertToIntersectionView(m_node_based_graph, - m_edge_based_node_container, - unconditional_node_restriction_map, - m_barrier_nodes, - edge_geometries, - turn_lanes_data, - incoming_edge, - outgoing_edges, - merged_edge_ids); + const auto connected_roads = + extractor::intersection::getConnectedRoads(m_node_based_graph, + m_edge_based_node_container, + m_coordinates, + m_compressed_edge_container, + unconditional_node_restriction_map, + m_barrier_nodes, + turn_lanes_data, + incoming_edge); // check if this edge is part of a restriction via-way const auto is_restriction_via_edge = @@ -746,12 +745,12 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( continue; const auto turn = - std::find_if(intersection_view.begin(), - intersection_view.end(), + std::find_if(connected_roads.begin(), + connected_roads.end(), [edge = outgoing_edge.edge](const auto &road) { return road.eid == edge; }); - OSRM_ASSERT(turn != intersection_view.end(), + OSRM_ASSERT(turn != connected_roads.end(), m_coordinates[intersection_node]); std::vector road_legs_on_the_right; @@ -760,6 +759,37 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( auto get_connected_road_info = [&](const auto &connected_edge) { const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge.eid); + + bool is_incoming, is_outgoing; + if (edge_data.reversed) + { + // If getConnectedRoads adds reversed edge it means + // this edge is incoming-only + is_incoming = true; + is_outgoing = false; + } + else + { + // It does not add incoming edge if there is outgoing so we should + // find it ourselves + is_incoming = false; + auto reversed_edge = m_node_based_graph.FindEdge( + m_node_based_graph.GetTarget(connected_edge.eid), + intersection_node); + if (reversed_edge != SPECIAL_EDGEID) + { + const auto &reversed_edge_data = + m_node_based_graph.GetEdgeData(reversed_edge); + + if (!reversed_edge_data.reversed) + { + is_incoming = true; + } + } + + is_outgoing = true; + } + return ExtractionTurnLeg( edge_data.flags.restricted, edge_data.flags.road_classification.IsMotorwayClass(), @@ -772,10 +802,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data.duration) * 36, edge_data.flags.road_classification.GetPriority(), - !connected_edge.entry_allowed || - (edge_data.flags.forward && - edge_data.flags.backward), // is incoming - connected_edge.entry_allowed); + is_incoming, + is_outgoing); }; // all connected roads on the right of a u turn @@ -783,35 +811,35 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( guidance::DirectionModifier::UTurn; if (is_uturn) { - if (turn != intersection_view.begin()) + if (turn != connected_roads.begin()) { - std::transform(intersection_view.begin() + 1, + std::transform(connected_roads.begin() + 1, turn, std::back_inserter(road_legs_on_the_right), get_connected_road_info); } std::transform(turn + 1, - intersection_view.end(), + connected_roads.end(), std::back_inserter(road_legs_on_the_right), get_connected_road_info); } else { - if (intersection_view.begin() != turn) + if (connected_roads.begin() != turn) { - std::transform(intersection_view.begin() + 1, + std::transform(connected_roads.begin() + 1, turn, std::back_inserter(road_legs_on_the_right), get_connected_road_info); } std::transform(turn + 1, - intersection_view.end(), + connected_roads.end(), std::back_inserter(road_legs_on_the_left), get_connected_road_info); } - if (is_uturn && turn != intersection_view.begin()) + if (is_uturn && turn != connected_roads.begin()) { util::Log(logWARNING) << "Turn is a u turn but not turning to the first connected " @@ -819,7 +847,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( << intersection_node << ", OSM link: " << toOSMLink(m_coordinates[intersection_node]); } - else if (turn == intersection_view.begin() && !is_uturn) + else if (turn == connected_roads.begin() && !is_uturn) { util::Log(logWARNING) << "Turn is a u turn but not classified as a u turn. Node ID: "