From 0568dca4a313780ec152d467a4415311d882802e Mon Sep 17 00:00:00 2001 From: Michael Krasnyk Date: Tue, 5 Dec 2017 14:54:20 +0100 Subject: [PATCH] Adjust to review findings --- .../guidance/mergable_road_detector.hpp | 5 +- .../intersection/intersection_analysis.hpp | 10 +++ src/extractor/edge_based_graph_factory.cpp | 61 +++++++++---------- .../guidance/mergable_road_detector.cpp | 7 +-- .../intersection/intersection_analysis.cpp | 9 +-- 5 files changed, 47 insertions(+), 45 deletions(-) diff --git a/include/extractor/guidance/mergable_road_detector.hpp b/include/extractor/guidance/mergable_road_detector.hpp index 524d192b3..a6944ebd8 100644 --- a/include/extractor/guidance/mergable_road_detector.hpp +++ b/include/extractor/guidance/mergable_road_detector.hpp @@ -2,6 +2,7 @@ #define OSRM_EXTRACTOR_GUIDANCE_MERGEABLE_ROADS #include "extractor/compressed_edge_container.hpp" +#include "extractor/guidance/coordinate_extractor.hpp" #include "extractor/guidance/intersection.hpp" #include "extractor/guidance/turn_lane_types.hpp" #include "extractor/restriction_index.hpp" @@ -47,7 +48,6 @@ class MergableRoadDetector const RestrictionMap &node_restriction_map, const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, - const CoordinateExtractor &coordinate_extractor, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table); @@ -170,12 +170,13 @@ class MergableRoadDetector const RestrictionMap &node_restriction_map; const std::unordered_set &barrier_nodes; const guidance::TurnLanesIndexedArray &turn_lanes_data; - const CoordinateExtractor &coordinate_extractor; // name detection const util::NameTable &name_table; const SuffixTable &street_name_suffix_table; + const CoordinateExtractor coordinate_extractor; + // limit for detecting circles / parallel roads const static double constexpr distance_to_extract = 150; }; diff --git a/include/extractor/intersection/intersection_analysis.hpp b/include/extractor/intersection/intersection_analysis.hpp index 07503a524..1f86f1eca 100644 --- a/include/extractor/intersection/intersection_analysis.hpp +++ b/include/extractor/intersection/intersection_analysis.hpp @@ -57,6 +57,9 @@ convertToIntersectionView(const util::NodeBasedDynamicGraph &graph, const IntersectionEdges &outgoing_edges, const std::unordered_set &merged_edges); +// Check for restrictions/barriers and generate a list of valid and invalid turns present at +// the node reached from `incoming_edge`. The resulting candidates have to be analyzed +// for their actual instructions later on. guidance::IntersectionView getConnectedRoads(const util::NodeBasedDynamicGraph &graph, const EdgeBasedNodeDataContainer &node_data_container, @@ -67,6 +70,13 @@ getConnectedRoads(const util::NodeBasedDynamicGraph &graph, const guidance::TurnLanesIndexedArray &turn_lanes_data, const IntersectionEdge &incoming_edge); +// Graph Compression cannot compress every setting. For example any barrier/traffic light cannot +// be compressed. As a result, a simple road of the form `a ----- b` might end up as having an +// intermediate intersection, if there is a traffic light in between. If we want to look farther +// down a road, finding the next actual decision requires the look at multiple intersections. +// Here we follow the road until we either reach a dead end or find the next intersection with +// more than a single next road. This function skips over degree two nodes to find correct input +// for getConnectedRoads. IntersectionEdge skipDegreeTwoNodes(const util::NodeBasedDynamicGraph &graph, IntersectionEdge road); } diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 8372fe04b..43e92adfe 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -423,11 +423,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( TurnDataExternalContainer turn_data_container; - // TODO: add a MergableRoadDetector instance, to be deleted later SuffixTable street_name_suffix_table(scripting_environment); const auto &turn_lanes_data = transformTurnLaneMapIntoArrays(lane_description_map); - guidance::CoordinateExtractor coordinate_extractor( - m_node_based_graph, m_compressed_edge_container, m_coordinates); guidance::MergableRoadDetector mergable_road_detector(m_node_based_graph, m_edge_based_node_container, m_coordinates, @@ -435,7 +432,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( node_restriction_map, m_barrier_nodes, turn_lanes_data, - coordinate_extractor, name_table, street_name_suffix_table); @@ -562,14 +558,14 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // the situation of the turn const auto node_along_road_entering, const auto node_based_edge_from, - const auto node_at_center_of_intersection, + const auto intersection_node, const auto node_based_edge_to, const auto incoming_bearing, const auto &turn, const auto entry_class_id) { const auto node_restricted = isRestricted(node_along_road_entering, - node_at_center_of_intersection, + intersection_node, m_node_based_graph.GetTarget(turn.eid), conditional_restriction_map); @@ -581,7 +577,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( conditional = {{edge_based_node_from, edge_based_node_to, {static_cast(-1), - m_coordinates[node_at_center_of_intersection], + m_coordinates[intersection_node], conditions}}}; } @@ -601,10 +597,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( util::guidance::TurnBearing(turn.bearing)}; // compute weight and duration penalties - auto is_traffic_light = m_traffic_lights.count(node_at_center_of_intersection); + auto is_traffic_light = m_traffic_lights.count(intersection_node); ExtractionTurn extracted_turn( turn.angle, - m_node_based_graph.GetOutDegree(node_at_center_of_intersection), + m_node_based_graph.GetOutDegree(intersection_node), turn.instruction.IsUTurn(), is_traffic_light, edge_data1.flags.restricted, @@ -655,8 +651,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( : m_compressed_edge_container.GetLastEdgeSourceID(node_based_edge_from); const auto &to_node = m_compressed_edge_container.GetFirstEdgeTargetID(turn.eid); - lookup::TurnIndexBlock turn_index_block = { - from_node, node_at_center_of_intersection, to_node}; + lookup::TurnIndexBlock turn_index_block = {from_node, intersection_node, to_node}; // insert data into the designated buffer return std::make_pair( @@ -678,25 +673,26 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( if (buffer->nodes_processed == 0) return buffer; - for (auto node_at_center_of_intersection = intersection_node_range.begin(), + for (auto intersection_node = intersection_node_range.begin(), end = intersection_node_range.end(); - node_at_center_of_intersection < end; - ++node_at_center_of_intersection) + intersection_node < end; + ++intersection_node) { // We capture the thread-local work in these objects, then flush // them in a controlled manner at the end of the parallel range - const auto &incoming_edges = intersection::getIncomingEdges( - m_node_based_graph, node_at_center_of_intersection); - const auto &outgoing_edges = intersection::getOutgoingEdges( - m_node_based_graph, node_at_center_of_intersection); - const auto &edge_geometries_and_merged_edges = + const auto &incoming_edges = + intersection::getIncomingEdges(m_node_based_graph, intersection_node); + const auto &outgoing_edges = + intersection::getOutgoingEdges(m_node_based_graph, intersection_node); + + intersection::IntersectionEdgeGeometries edge_geometries; + std::unordered_set merged_edge_ids; + std::tie(edge_geometries, merged_edge_ids) = intersection::getIntersectionGeometries(m_node_based_graph, m_compressed_edge_container, m_coordinates, mergable_road_detector, - node_at_center_of_intersection); - const auto &edge_geometries = edge_geometries_and_merged_edges.first; - const auto &merged_edge_ids = edge_geometries_and_merged_edges.second; + intersection_node); // all nodes in the graph are connected in both directions. We check all // outgoing nodes to find the incoming edge. This is a larger search overhead, @@ -735,15 +731,14 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( auto intersection = turn_analysis.AssignTurnTypes( incoming_edge.node, incoming_edge.edge, intersection_view); - OSRM_ASSERT(intersection.valid(), - m_coordinates[node_at_center_of_intersection]); + OSRM_ASSERT(intersection.valid(), m_coordinates[intersection_node]); intersection = turn_lane_handler.assignTurnLanes( incoming_edge.node, incoming_edge.edge, std::move(intersection)); // the entry class depends on the turn, so we have to classify the // interesction for every edge - const auto turn_classification = classifyIntersection( - intersection, m_coordinates[node_at_center_of_intersection]); + const auto turn_classification = + classifyIntersection(intersection, m_coordinates[intersection_node]); const auto entry_class_id = entry_class_hash.ConcurrentFindOrAdd(turn_classification.first); @@ -754,12 +749,11 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // Note - this is strictly speaking not thread safe, but we know we // should never be touching the same element twice, so we should // be fine. - bearing_class_by_node_based_node[node_at_center_of_intersection] = - bearing_class_id; + bearing_class_by_node_based_node[intersection_node] = bearing_class_id; // check if we are turning off a via way - const auto turning_off_via_way = way_restriction_map.IsViaWay( - incoming_edge.node, node_at_center_of_intersection); + const auto turning_off_via_way = + way_restriction_map.IsViaWay(incoming_edge.node, intersection_node); // Save reversed incoming bearing to compute turn angles const auto reversed_incoming_bearing = util::bearing::reverse( @@ -783,7 +777,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( [edge = outgoing_edge.edge](const auto &road) { return road.eid == edge; }); - BOOST_ASSERT(turn != intersection.end()); + OSRM_ASSERT(turn != intersection.end(), + m_coordinates[intersection_node]); // In case a way restriction starts at a given location, add a turn onto // every artificial node eminating here. @@ -848,7 +843,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( if (turning_off_via_way) { const auto duplicated_nodes = way_restriction_map.DuplicatedNodeIDs( - incoming_edge.node, node_at_center_of_intersection); + incoming_edge.node, intersection_node); // next to the normal restrictions tracked in `entry_allowed`, via // ways might introduce additional restrictions. These are handled @@ -903,7 +898,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( {from_id, nbe_to_ebn_mapping[outgoing_edge.edge], {static_cast(-1), - m_coordinates[node_at_center_of_intersection], + m_coordinates[intersection_node], restriction.condition}}); } } diff --git a/src/extractor/guidance/mergable_road_detector.cpp b/src/extractor/guidance/mergable_road_detector.cpp index e354165a7..e0861122c 100644 --- a/src/extractor/guidance/mergable_road_detector.cpp +++ b/src/extractor/guidance/mergable_road_detector.cpp @@ -1,6 +1,5 @@ #include "extractor/guidance/mergable_road_detector.hpp" #include "extractor/guidance/constants.hpp" -#include "extractor/guidance/coordinate_extractor.hpp" #include "extractor/guidance/node_based_graph_walker.hpp" #include "extractor/intersection/intersection_analysis.hpp" #include "extractor/query_node.hpp" @@ -60,14 +59,14 @@ MergableRoadDetector::MergableRoadDetector( const RestrictionMap &node_restriction_map, const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, - const CoordinateExtractor &coordinate_extractor, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table) : node_based_graph(node_based_graph), node_data_container(node_data_container), node_coordinates(node_coordinates), compressed_geometries(compressed_geometries), node_restriction_map(node_restriction_map), barrier_nodes(barrier_nodes), - turn_lanes_data(turn_lanes_data), coordinate_extractor(coordinate_extractor), - name_table(name_table), street_name_suffix_table(street_name_suffix_table) + turn_lanes_data(turn_lanes_data), name_table(name_table), + street_name_suffix_table(street_name_suffix_table), + coordinate_extractor(node_based_graph, compressed_geometries, node_coordinates) { } diff --git a/src/extractor/intersection/intersection_analysis.cpp b/src/extractor/intersection/intersection_analysis.cpp index fdb3591f8..b159b7e0b 100644 --- a/src/extractor/intersection/intersection_analysis.cpp +++ b/src/extractor/intersection/intersection_analysis.cpp @@ -43,11 +43,7 @@ IntersectionEdges getOutgoingEdges(const util::NodeBasedDynamicGraph &graph, for (const auto outgoing_edge : graph.GetAdjacentEdgeRange(intersection_node)) { - // TODO: to use TurnAnalysis all outgoing edges are required, to be uncommented later - // if (!graph.GetEdgeData(outgoing_edge).reversed) - { - result.push_back({intersection_node, outgoing_edge}); - } + result.push_back({intersection_node, outgoing_edge}); } BOOST_ASSERT(std::is_sorted(result.begin(), result.end())); @@ -558,6 +554,7 @@ bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph, return true; // Allow U-turn if the incoming edge has a U-turn lane + // TODO: revisit the use-case, related PR #2753 const auto &incoming_edge_annotation_id = graph.GetEdgeData(from.edge).annotation_data; const auto lane_description_id = static_cast( node_data_container.GetAnnotation(incoming_edge_annotation_id).lane_description_id); @@ -722,7 +719,7 @@ convertToIntersectionView(const util::NodeBasedDynamicGraph &graph, next != pre_intersection_view.end(); ++curr, ++next) { - // Check the the perceived angles order is the same as the initial OSM one + // Check that the perceived angles order is the same as the initial OSM one if (next->first.angle < curr->first.angle) { // If the true bearing is out of the initial order (next before current) then // adjust the next road angle to keep the order. The adjustment angle is at most