From db7c76d04d48a99ef253ff7a94df23f2d9fcbc5f Mon Sep 17 00:00:00 2001 From: Michael Krasnyk Date: Sun, 3 Dec 2017 21:32:17 +0100 Subject: [PATCH] Remove GetConnectedRoads from IntersectionGenerator --- .../extractor/guidance/driveway_handler.hpp | 4 + include/extractor/guidance/intersection.hpp | 8 - .../guidance/intersection_generator.hpp | 57 --- .../guidance/intersection_handler.hpp | 23 +- .../guidance/mergable_road_detector.hpp | 12 + .../extractor/guidance/motorway_handler.hpp | 4 + .../guidance/node_based_graph_walker.hpp | 48 +- .../extractor/guidance/roundabout_handler.hpp | 6 +- .../extractor/guidance/sliproad_handler.hpp | 6 + .../extractor/guidance/statistics_handler.hpp | 8 + .../guidance/suppress_mode_handler.hpp | 4 + include/extractor/guidance/turn_analysis.hpp | 7 +- include/extractor/guidance/turn_discovery.hpp | 8 +- include/extractor/guidance/turn_handler.hpp | 4 + .../extractor/guidance/turn_lane_handler.hpp | 11 + .../intersection/intersection_analysis.hpp | 34 +- src/extractor/edge_based_graph_factory.cpp | 45 +- src/extractor/guidance/driveway_handler.cpp | 16 +- .../guidance/intersection_generator.cpp | 417 +----------------- .../guidance/intersection_handler.cpp | 46 +- .../guidance/mergable_road_detector.cpp | 88 +++- src/extractor/guidance/motorway_handler.cpp | 8 + .../guidance/node_based_graph_walker.cpp | 39 +- src/extractor/guidance/roundabout_handler.cpp | 33 +- src/extractor/guidance/sliproad_handler.cpp | 49 +- .../guidance/suppress_mode_handler.cpp | 21 +- src/extractor/guidance/turn_analysis.cpp | 54 ++- src/extractor/guidance/turn_discovery.cpp | 46 +- src/extractor/guidance/turn_handler.cpp | 8 + src/extractor/guidance/turn_lane_handler.cpp | 34 +- .../intersection/intersection_analysis.cpp | 58 ++- 31 files changed, 573 insertions(+), 633 deletions(-) diff --git a/include/extractor/guidance/driveway_handler.hpp b/include/extractor/guidance/driveway_handler.hpp index 7fb1a24c5..ec434cc21 100644 --- a/include/extractor/guidance/driveway_handler.hpp +++ b/include/extractor/guidance/driveway_handler.hpp @@ -18,6 +18,10 @@ class DrivewayHandler final : public IntersectionHandler const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table); diff --git a/include/extractor/guidance/intersection.hpp b/include/extractor/guidance/intersection.hpp index 5a45e93e4..faaf37f3a 100644 --- a/include/extractor/guidance/intersection.hpp +++ b/include/extractor/guidance/intersection.hpp @@ -44,14 +44,6 @@ inline auto makeCompareShapeDataByBearing(const double base_bearing) }; } -inline auto makeCompareShapeDataAngleToBearing(const double base_bearing) -{ - return [base_bearing](const auto &lhs, const auto &rhs) { - return util::bearing::angleBetween(lhs.bearing, base_bearing) < - util::bearing::angleBetween(rhs.bearing, base_bearing); - }; -} - inline auto makeCompareAngularDeviation(const double angle) { return [angle](const auto &lhs, const auto &rhs) { diff --git a/include/extractor/guidance/intersection_generator.hpp b/include/extractor/guidance/intersection_generator.hpp index e0f8c671b..039302876 100644 --- a/include/extractor/guidance/intersection_generator.hpp +++ b/include/extractor/guidance/intersection_generator.hpp @@ -44,26 +44,6 @@ class IntersectionGenerator const std::vector &coordinates, const CompressedEdgeContainer &compressed_edge_container); - // For a source node `a` and a via edge `ab` creates an intersection at target `b`. - // - // a . . . b . . - // . - // . - // - IntersectionView operator()(const NodeID nid, const EdgeID via_eid) const; - - /* - * Compute the shape of an intersection, returning a set of connected roads, without any further - * concern for which of the entries are actually allowed. - * The shape also only comes with turn bearings, not with turn angles. All turn angles will be - * set to zero - */ - OSRM_ATTR_WARN_UNUSED - IntersectionShape - ComputeIntersectionShape(const NodeID center_node, - const boost::optional sorting_base = boost::none, - bool use_low_precision_angles = false) const; - // 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 @@ -75,49 +55,12 @@ class IntersectionGenerator IntersectionGenerationParameters SkipDegreeTwoNodes(const NodeID starting_node, const EdgeID via_edge) const; - // Allow access to the coordinate extractor for all owners - const CoordinateExtractor &GetCoordinateExtractor() const; - - // Check for restrictions/barriers and generate a list of valid and invalid turns present at - // the node reached from `from_node` via `via_eid`. The resulting candidates have to be analysed - // for their actual instructions later on. - // The switch for `use_low_precision_angles` enables a faster mode that will procude less - // accurate coordinates. It should be good enough to check order of turns, find straightmost - // turns. Even good enough to do some simple angle verifications. It is mostly available to - // allow for faster graph traversal in the extraction phase. - OSRM_ATTR_WARN_UNUSED - IntersectionView GetConnectedRoads(const NodeID from_node, - const EdgeID via_eid, - const bool use_low_precision_angles = false) const; - - /* - * To be used in the road network, we need to check for valid/restricted turns. These two - * functions transform a basic intersection / a normalised intersection into the - * correct view when entering via a given edge. - */ - OSRM_ATTR_WARN_UNUSED - IntersectionView - TransformIntersectionShapeIntoView(const NodeID previous_node, - const EdgeID entering_via_edge, - const IntersectionShape &intersection) const; - // version for normalised intersection - OSRM_ATTR_WARN_UNUSED - IntersectionView TransformIntersectionShapeIntoView( - const NodeID previous_node, - const EdgeID entering_via_edge, - const IntersectionShape &normalised_intersection, - const IntersectionShape &intersection, - const std::vector &merging_map) const; - private: const util::NodeBasedDynamicGraph &node_based_graph; const EdgeBasedNodeDataContainer &node_data_container; const RestrictionMap &restriction_map; const std::unordered_set &barrier_nodes; const std::vector &coordinates; - - // own state, used to find the correct coordinates along a road - const CoordinateExtractor coordinate_extractor; }; } // namespace guidance diff --git a/include/extractor/guidance/intersection_handler.hpp b/include/extractor/guidance/intersection_handler.hpp index 9c63825c9..31e0326c5 100644 --- a/include/extractor/guidance/intersection_handler.hpp +++ b/include/extractor/guidance/intersection_handler.hpp @@ -4,6 +4,7 @@ #include "extractor/guidance/intersection.hpp" #include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/node_based_graph_walker.hpp" +#include "extractor/intersection/intersection_analysis.hpp" #include "extractor/query_node.hpp" #include "extractor/suffix_table.hpp" @@ -34,7 +35,11 @@ class IntersectionHandler public: IntersectionHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, - const std::vector &coordinates, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table, const IntersectionGenerator &intersection_generator); @@ -52,7 +57,11 @@ class IntersectionHandler protected: const util::NodeBasedDynamicGraph &node_based_graph; const EdgeBasedNodeDataContainer &node_data_container; - const std::vector &coordinates; + const std::vector &node_coordinates; + const extractor::CompressedEdgeContainer &compressed_geometries; + const RestrictionMap &node_restriction_map; + const std::unordered_set &barrier_nodes; + const guidance::TurnLanesIndexedArray &turn_lanes_data; const util::NameTable &name_table; const SuffixTable &street_name_suffix_table; const IntersectionGenerator &intersection_generator; @@ -571,7 +580,15 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, node_at_intersection, intersection[0].eid); if (node_based_graph.GetTarget(parameters.via_eid) == node_at_intersection) return {}; - return intersection_generator.GetConnectedRoads(parameters.nid, parameters.via_eid); + + return intersection::getConnectedRoads(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, + {parameters.nid, parameters.via_eid}); }(); if (!previous_intersection.empty()) diff --git a/include/extractor/guidance/mergable_road_detector.hpp b/include/extractor/guidance/mergable_road_detector.hpp index fa428d5ed..f26c5acfd 100644 --- a/include/extractor/guidance/mergable_road_detector.hpp +++ b/include/extractor/guidance/mergable_road_detector.hpp @@ -1,7 +1,10 @@ #ifndef OSRM_EXTRACTOR_GUIDANCE_MERGEABLE_ROADS #define OSRM_EXTRACTOR_GUIDANCE_MERGEABLE_ROADS +#include "extractor/compressed_edge_container.hpp" #include "extractor/guidance/intersection.hpp" +#include "extractor/guidance/turn_lane_types.hpp" +#include "extractor/restriction_index.hpp" #include "util/coordinate.hpp" #include "util/node_based_graph.hpp" #include "util/typedefs.hpp" @@ -9,6 +12,7 @@ #include #include #include +#include #include namespace osrm @@ -39,6 +43,10 @@ class MergableRoadDetector MergableRoadDetector(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const IntersectionGenerator &intersection_generator, const CoordinateExtractor &coordinate_extractor, const util::NameTable &name_table, @@ -159,6 +167,10 @@ class MergableRoadDetector const util::NodeBasedDynamicGraph &node_based_graph; const EdgeBasedNodeDataContainer &node_data_container; const std::vector &node_coordinates; + const extractor::CompressedEdgeContainer &compressed_geometries; + const RestrictionMap &node_restriction_map; + const std::unordered_set &barrier_nodes; + const guidance::TurnLanesIndexedArray &turn_lanes_data; const IntersectionGenerator &intersection_generator; const CoordinateExtractor &coordinate_extractor; diff --git a/include/extractor/guidance/motorway_handler.hpp b/include/extractor/guidance/motorway_handler.hpp index 036395dd4..dcee8df55 100644 --- a/include/extractor/guidance/motorway_handler.hpp +++ b/include/extractor/guidance/motorway_handler.hpp @@ -26,6 +26,10 @@ class MotorwayHandler : public IntersectionHandler MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table, const IntersectionGenerator &intersection_generator); diff --git a/include/extractor/guidance/node_based_graph_walker.hpp b/include/extractor/guidance/node_based_graph_walker.hpp index 806e11329..708fd841f 100644 --- a/include/extractor/guidance/node_based_graph_walker.hpp +++ b/include/extractor/guidance/node_based_graph_walker.hpp @@ -2,7 +2,9 @@ #define OSRM_EXTRACTOR_GUIDANCE_NODE_BASED_GRAPH_WALKER #include "extractor/guidance/constants.hpp" -#include "extractor/guidance/intersection_generator.hpp" +#include "extractor/guidance/coordinate_extractor.hpp" +#include "extractor/guidance/turn_lane_data.hpp" +#include "extractor/intersection/intersection_analysis.hpp" #include "util/coordinate.hpp" #include "util/coordinate_calculation.hpp" #include "util/node_based_graph.hpp" @@ -29,7 +31,11 @@ class NodeBasedGraphWalker public: NodeBasedGraphWalker(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, - const IntersectionGenerator &intersection_generator); + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data); /* * the returned node-id, edge-id are either the last ones used, just prior accumulator @@ -48,7 +54,11 @@ class NodeBasedGraphWalker private: const util::NodeBasedDynamicGraph &node_based_graph; const EdgeBasedNodeDataContainer &node_data_container; - const IntersectionGenerator &intersection_generator; + const std::vector &node_coordinates; + const extractor::CompressedEdgeContainer &compressed_geometries; + const RestrictionMap &node_restriction_map; + const std::unordered_set &barrier_nodes; + const guidance::TurnLanesIndexedArray &turn_lanes_data; }; /* @@ -149,7 +159,13 @@ struct SelectStraightmostRoadByNameAndOnlyChoice struct IntersectionFinderAccumulator { IntersectionFinderAccumulator(const std::uint8_t hop_limit, - const IntersectionGenerator &intersection_generator); + const util::NodeBasedDynamicGraph &node_based_graph, + const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data); // true if the path has traversed enough distance bool terminate(); @@ -159,13 +175,19 @@ struct IntersectionFinderAccumulator std::uint8_t hops; const std::uint8_t hop_limit; - // we need to be able to look-up the intersection - const IntersectionGenerator &intersection_generator; - // the result we are looking for NodeID nid; EdgeID via_edge_id; IntersectionView intersection; + + private: + const util::NodeBasedDynamicGraph &node_based_graph; + const EdgeBasedNodeDataContainer &node_data_container; + const std::vector &node_coordinates; + const extractor::CompressedEdgeContainer &compressed_geometries; + const RestrictionMap &node_restriction_map; + const std::unordered_set &barrier_nodes; + const guidance::TurnLanesIndexedArray &turn_lanes_data; }; template @@ -199,9 +221,15 @@ NodeBasedGraphWalker::TraverseRoad(NodeID current_node_id, return {}; // look at the next intersection - const constexpr auto LOW_PRECISION = true; - const auto next_intersection = intersection_generator.GetConnectedRoads( - current_node_id, current_edge_id, LOW_PRECISION); + const auto next_intersection = + intersection::getConnectedRoads(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, + {current_node_id, current_edge_id}); // don't follow u-turns or go past our initial intersection if (next_intersection.size() <= 1) diff --git a/include/extractor/guidance/roundabout_handler.hpp b/include/extractor/guidance/roundabout_handler.hpp index 3387348cd..a419b7580 100644 --- a/include/extractor/guidance/roundabout_handler.hpp +++ b/include/extractor/guidance/roundabout_handler.hpp @@ -42,7 +42,10 @@ class RoundaboutHandler : public IntersectionHandler RoundaboutHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, - const CompressedEdgeContainer &compressed_edge_container, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table, const IntersectionGenerator &intersection_generator); @@ -80,7 +83,6 @@ class RoundaboutHandler : public IntersectionHandler bool qualifiesAsRoundaboutIntersection(const std::unordered_set &roundabout_nodes) const; - const CompressedEdgeContainer &compressed_edge_container; const CoordinateExtractor coordinate_extractor; }; diff --git a/include/extractor/guidance/sliproad_handler.hpp b/include/extractor/guidance/sliproad_handler.hpp index 8dfa5d3ea..5f8812a11 100644 --- a/include/extractor/guidance/sliproad_handler.hpp +++ b/include/extractor/guidance/sliproad_handler.hpp @@ -28,6 +28,10 @@ class SliproadHandler final : public IntersectionHandler const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table); @@ -78,6 +82,8 @@ class SliproadHandler final : public IntersectionHandler // The return value is guaranteed to not be larger than `threshold`. static double scaledThresholdByRoadClass(const double max_threshold, const RoadClassification &classification); + + const CoordinateExtractor coordinate_extractor; }; } // namespace guidance diff --git a/include/extractor/guidance/statistics_handler.hpp b/include/extractor/guidance/statistics_handler.hpp index 57c767175..bbfc944f6 100644 --- a/include/extractor/guidance/statistics_handler.hpp +++ b/include/extractor/guidance/statistics_handler.hpp @@ -31,11 +31,19 @@ class StatisticsHandler final : public IntersectionHandler const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table) : IntersectionHandler(node_based_graph, node_data_container, coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table, intersection_generator) diff --git a/include/extractor/guidance/suppress_mode_handler.hpp b/include/extractor/guidance/suppress_mode_handler.hpp index 7b3eb458c..b10993cbd 100644 --- a/include/extractor/guidance/suppress_mode_handler.hpp +++ b/include/extractor/guidance/suppress_mode_handler.hpp @@ -25,6 +25,10 @@ class SuppressModeHandler final : public IntersectionHandler const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table); diff --git a/include/extractor/guidance/turn_analysis.hpp b/include/extractor/guidance/turn_analysis.hpp index 4308c9ebd..aca49038a 100644 --- a/include/extractor/guidance/turn_analysis.hpp +++ b/include/extractor/guidance/turn_analysis.hpp @@ -42,10 +42,11 @@ class TurnAnalysis public: TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, - const std::vector &coordinates, + const std::vector &node_coordinates, + const CompressedEdgeContainer &compressed_edge_container, const RestrictionMap &restriction_map, const std::unordered_set &barrier_nodes, - const CompressedEdgeContainer &compressed_edge_container, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table); @@ -61,8 +62,6 @@ class TurnAnalysis const EdgeID via_eid, const IntersectionView &intersection) const; - const IntersectionGenerator &GetIntersectionGenerator() const; - private: const util::NodeBasedDynamicGraph &node_based_graph; const IntersectionGenerator intersection_generator; diff --git a/include/extractor/guidance/turn_discovery.hpp b/include/extractor/guidance/turn_discovery.hpp index ff8207c5f..e7588c19a 100644 --- a/include/extractor/guidance/turn_discovery.hpp +++ b/include/extractor/guidance/turn_discovery.hpp @@ -3,6 +3,7 @@ #include "extractor/guidance/intersection.hpp" #include "extractor/guidance/intersection_generator.hpp" +#include "extractor/guidance/turn_lane_data.hpp" #include "util/typedefs.hpp" namespace osrm @@ -21,8 +22,13 @@ bool findPreviousIntersection( const NodeID node, const EdgeID via_edge, const Intersection &intersection, - const IntersectionGenerator &intersection_generator, const util::NodeBasedDynamicGraph &node_based_graph, // query edge data + const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, // output parameters, will be in an arbitrary state on failure NodeID &result_node, EdgeID &result_via_edge, diff --git a/include/extractor/guidance/turn_handler.hpp b/include/extractor/guidance/turn_handler.hpp index b80edebad..427533730 100644 --- a/include/extractor/guidance/turn_handler.hpp +++ b/include/extractor/guidance/turn_handler.hpp @@ -30,6 +30,10 @@ class TurnHandler : public IntersectionHandler TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table, const IntersectionGenerator &intersection_generator); diff --git a/include/extractor/guidance/turn_lane_handler.hpp b/include/extractor/guidance/turn_lane_handler.hpp index 4f19e163b..c1e1fd760 100644 --- a/include/extractor/guidance/turn_lane_handler.hpp +++ b/include/extractor/guidance/turn_lane_handler.hpp @@ -74,6 +74,11 @@ class TurnLaneHandler TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, LaneDescriptionMap &lane_description_map, const TurnAnalysis &turn_analysis, util::guidance::LaneDataIdMap &id_map); @@ -90,6 +95,12 @@ class TurnLaneHandler // lanes for a turn const util::NodeBasedDynamicGraph &node_based_graph; const EdgeBasedNodeDataContainer &node_data_container; + const std::vector &node_coordinates; + const extractor::CompressedEdgeContainer &compressed_geometries; + const RestrictionMap &node_restriction_map; + const std::unordered_set &barrier_nodes; + const guidance::TurnLanesIndexedArray &turn_lanes_data; + std::vector turn_lane_offsets; std::vector turn_lane_masks; LaneDescriptionMap &lane_description_map; diff --git a/include/extractor/intersection/intersection_analysis.hpp b/include/extractor/intersection/intersection_analysis.hpp index 3711bd02e..6552e7d38 100644 --- a/include/extractor/intersection/intersection_analysis.hpp +++ b/include/extractor/intersection/intersection_analysis.hpp @@ -26,6 +26,19 @@ IntersectionEdges getIncomingEdges(const util::NodeBasedDynamicGraph &graph, IntersectionEdges getOutgoingEdges(const util::NodeBasedDynamicGraph &graph, const NodeID intersection); +bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph, + const EdgeBasedNodeDataContainer &node_data_container, + const RestrictionMap &restriction_map, + const std::unordered_set &barrier_nodes, + const IntersectionEdgeGeometries &geometries, + const guidance::TurnLanesIndexedArray &turn_lanes_data, + const IntersectionEdge &from, + const IntersectionEdge &to); + +double findEdgeBearing(const IntersectionEdgeGeometries &geometries, const EdgeID &edge); + +double findEdgeLength(const IntersectionEdgeGeometries &geometries, const EdgeID &edge); + std::pair> getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph, const extractor::CompressedEdgeContainer &compressed_geometries, @@ -44,18 +57,15 @@ convertToIntersectionView(const util::NodeBasedDynamicGraph &graph, const IntersectionEdges &outgoing_edges, const std::unordered_set &merged_edges); -bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph, - const EdgeBasedNodeDataContainer &node_data_container, - const RestrictionMap &restriction_map, - const std::unordered_set &barrier_nodes, - const IntersectionEdgeGeometries &geometries, - const guidance::TurnLanesIndexedArray &turn_lanes_data, - const IntersectionEdge &from, - const IntersectionEdge &to); - -double findEdgeBearing(const IntersectionEdgeGeometries &geometries, const EdgeID &edge); - -double findEdgeLength(const IntersectionEdgeGeometries &geometries, const EdgeID &edge); +guidance::IntersectionView +getConnectedRoads(const util::NodeBasedDynamicGraph &graph, + const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, + const IntersectionEdge &incoming_edge); } } } diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 296f0836d..2f16fca87 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -423,42 +423,57 @@ 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::IntersectionGenerator intersection_generator(m_node_based_graph, + m_edge_based_node_container, + node_restriction_map, + m_barrier_nodes, + m_coordinates, + m_compressed_edge_container); + guidance::MergableRoadDetector mergable_road_detector(m_node_based_graph, + m_edge_based_node_container, + m_coordinates, + m_compressed_edge_container, + node_restriction_map, + m_barrier_nodes, + turn_lanes_data, + intersection_generator, + coordinate_extractor, + name_table, + street_name_suffix_table); + // Loop over all turns and generate new set of edges. // Three nested loop look super-linear, but we are dealing with a (kind of) // linear number of turns only. - SuffixTable street_name_suffix_table(scripting_environment); guidance::TurnAnalysis turn_analysis(m_node_based_graph, m_edge_based_node_container, m_coordinates, + m_compressed_edge_container, node_restriction_map, m_barrier_nodes, - m_compressed_edge_container, + turn_lanes_data, name_table, street_name_suffix_table); util::guidance::LaneDataIdMap lane_data_map; guidance::lanes::TurnLaneHandler turn_lane_handler(m_node_based_graph, m_edge_based_node_container, + m_coordinates, + m_compressed_edge_container, + node_restriction_map, + m_barrier_nodes, + turn_lanes_data, lane_description_map, turn_analysis, lane_data_map); - // TODO: add a MergableRoadDetector instance, to be deleted later - 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, - turn_analysis.GetIntersectionGenerator(), - coordinate_extractor, - name_table, - street_name_suffix_table); - bearing_class_by_node_based_node.resize(m_node_based_graph.GetNumberOfNodes(), std::numeric_limits::max()); - const auto &turn_lanes_data = transformTurnLaneMapIntoArrays(lane_description_map); - // FIXME these need to be tuned in pre-allocated size std::vector turn_weight_penalties; std::vector turn_duration_penalties; diff --git a/src/extractor/guidance/driveway_handler.cpp b/src/extractor/guidance/driveway_handler.cpp index 3b1f0bac1..6c455eb07 100644 --- a/src/extractor/guidance/driveway_handler.cpp +++ b/src/extractor/guidance/driveway_handler.cpp @@ -15,12 +15,20 @@ namespace guidance DrivewayHandler::DrivewayHandler(const IntersectionGenerator &intersection_generator, const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, - const std::vector &coordinates, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table) : IntersectionHandler(node_based_graph, node_data_container, - coordinates, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table, intersection_generator) @@ -64,12 +72,12 @@ operator()(const NodeID nid, const EdgeID source_edge_id, Intersection intersect }); (void)nid; - OSRM_ASSERT(road != intersection.end(), coordinates[nid]); + OSRM_ASSERT(road != intersection.end(), node_coordinates[nid]); if (road->instruction == TurnInstruction::INVALID()) return intersection; - OSRM_ASSERT(road->instruction.type == TurnType::Turn, coordinates[nid]); + OSRM_ASSERT(road->instruction.type == TurnType::Turn, node_coordinates[nid]); road->instruction.type = isSameName(source_edge_id, road->eid) ? TurnType::NoTurn : TurnType::NewName; diff --git a/src/extractor/guidance/intersection_generator.cpp b/src/extractor/guidance/intersection_generator.cpp index d1d6e2075..17a7e8341 100644 --- a/src/extractor/guidance/intersection_generator.cpp +++ b/src/extractor/guidance/intersection_generator.cpp @@ -31,214 +31,17 @@ const constexpr bool USE_LOW_PRECISION_MODE = true; const constexpr bool USE_HIGH_PRECISION_MODE = !USE_LOW_PRECISION_MODE; } -IntersectionGenerator::IntersectionGenerator( - const util::NodeBasedDynamicGraph &node_based_graph, - const EdgeBasedNodeDataContainer &node_data_container, - const RestrictionMap &restriction_map, - const std::unordered_set &barrier_nodes, - const std::vector &coordinates, - const CompressedEdgeContainer &compressed_edge_container) +IntersectionGenerator::IntersectionGenerator(const util::NodeBasedDynamicGraph &node_based_graph, + const EdgeBasedNodeDataContainer &node_data_container, + const RestrictionMap &restriction_map, + const std::unordered_set &barrier_nodes, + const std::vector &coordinates, + const CompressedEdgeContainer &) : node_based_graph(node_based_graph), node_data_container(node_data_container), - restriction_map(restriction_map), barrier_nodes(barrier_nodes), coordinates(coordinates), - coordinate_extractor(node_based_graph, compressed_edge_container, coordinates) + restriction_map(restriction_map), barrier_nodes(barrier_nodes), coordinates(coordinates) { } -IntersectionView IntersectionGenerator::operator()(const NodeID from_node, - const EdgeID via_eid) const -{ - return GetConnectedRoads(from_node, via_eid, USE_HIGH_PRECISION_MODE); -} - -IntersectionShape -IntersectionGenerator::ComputeIntersectionShape(const NodeID node_at_center_of_intersection, - const boost::optional sorting_base, - const bool use_low_precision_angles) const -{ - const auto intersection_degree = node_based_graph.GetOutDegree(node_at_center_of_intersection); - const util::Coordinate turn_coordinate = coordinates[node_at_center_of_intersection]; - - // compute bearings in a relatively small circle to prevent wrong roads order with true bearings - struct RoadWithInitialBearing - { - double bearing; - IntersectionShapeData road; - }; - std::vector initial_roads_ordering; - // reserve enough items (+ the possibly missing u-turn edge) - initial_roads_ordering.reserve(intersection_degree); - - // number of lanes at the intersection changes how far we look down the road - const auto edge_range = node_based_graph.GetAdjacentEdgeRange(node_at_center_of_intersection); - const auto max_lanes_intersection = - std::accumulate(edge_range.begin(), - edge_range.end(), - std::uint8_t{0}, - [this](const auto current_max, const auto current_eid) { - return std::max(current_max, - node_based_graph.GetEdgeData(current_eid) - .flags.road_classification.GetNumberOfLanes()); - }); - - for (const EdgeID edge_connected_to_intersection : - node_based_graph.GetAdjacentEdgeRange(node_at_center_of_intersection)) - { - BOOST_ASSERT(edge_connected_to_intersection != SPECIAL_EDGEID); - const NodeID to_node = node_based_graph.GetTarget(edge_connected_to_intersection); - double bearing = 0.; - - auto coordinates = coordinate_extractor.GetCoordinatesAlongRoad( - node_at_center_of_intersection, edge_connected_to_intersection, !INVERT, to_node); - - const auto close_coordinate = - coordinate_extractor.ExtractCoordinateAtLength(2. /*m*/, coordinates); - const auto initial_bearing = - util::coordinate_calculation::bearing(turn_coordinate, close_coordinate); - - const auto segment_length = util::coordinate_calculation::getLength( - coordinates.begin(), - coordinates.end(), - util::coordinate_calculation::haversineDistance); - - const auto extract_coordinate = [&](const NodeID from_node, - const EdgeID via_eid, - const bool traversed_in_reverse, - const NodeID to_node) { - return (use_low_precision_angles || intersection_degree <= 2) - ? coordinate_extractor.GetCoordinateCloseToTurn( - from_node, via_eid, traversed_in_reverse, to_node) - : coordinate_extractor.ExtractRepresentativeCoordinate( - from_node, - via_eid, - traversed_in_reverse, - to_node, - max_lanes_intersection, - std::move(coordinates)); - }; - - // we have to look down the road a bit to get the correct turn - const auto coordinate_along_edge_leaving = extract_coordinate( - node_at_center_of_intersection, edge_connected_to_intersection, !INVERT, to_node); - - bearing = - util::coordinate_calculation::bearing(turn_coordinate, coordinate_along_edge_leaving); - - // OSM data sometimes contains duplicated nodes with identical coordinates, or - // because of coordinate precision rounding, end up at the same coordinate. - // It's impossible to calculate a bearing between these, so we log a warning - // that the data should be checked. - // The bearing calculation should return 0 in these cases, which may not be correct, - // but is at least not random. - if (turn_coordinate == coordinate_along_edge_leaving) - { - util::Log(logDEBUG) << "Zero length segment at " << coordinate_along_edge_leaving - << " could cause invalid intersection exit bearing."; - BOOST_ASSERT(std::abs(bearing) <= 0.1); - } - - initial_roads_ordering.push_back( - {initial_bearing, {edge_connected_to_intersection, bearing, segment_length}}); - } - - if (!initial_roads_ordering.empty()) - { - const auto base_initial_bearing = [&]() { - if (sorting_base) - { - const auto itr = std::find_if(initial_roads_ordering.begin(), - initial_roads_ordering.end(), - [&](const auto &data) { - return node_based_graph.GetTarget( - data.road.eid) == *sorting_base; - }); - if (itr != initial_roads_ordering.end()) - return util::bearing::reverse(itr->bearing); - } - return util::bearing::reverse(initial_roads_ordering.begin()->bearing); - }(); - - // sort roads with respect to the initial bearings, a tie-breaker for equal initial bearings - // is to order roads via final bearings to have roads in clockwise order - // - // rhs <---. lhs <----. - // / / - // lhs / rhs / - // - // lhs road is before rhs one rhs road is before lhs one - // bearing::angleBetween < 180 bearing::angleBetween > 180 - const auto initial_bearing_order = makeCompareShapeDataAngleToBearing(base_initial_bearing); - std::sort(initial_roads_ordering.begin(), - initial_roads_ordering.end(), - [&initial_bearing_order](const auto &lhs, const auto &rhs) { - return initial_bearing_order(lhs, rhs) || - (lhs.bearing == rhs.bearing && - util::bearing::angleBetween(lhs.road.bearing, rhs.road.bearing) < - 180); - }); - - // copy intersection data in the initial order - IntersectionShape intersection; - intersection.reserve(initial_roads_ordering.size()); - std::transform(initial_roads_ordering.begin(), - initial_roads_ordering.end(), - std::back_inserter(intersection), - [](const auto &entry) { return entry.road; }); - - if (intersection.size() > 2) - { // Check bearings ordering with respect to true bearings - const auto base_bearing = intersection.front().bearing; - const auto bearings_order = - makeCompareShapeDataAngleToBearing(util::bearing::reverse(base_bearing)); - for (auto curr = intersection.begin(), next = std::next(curr); - next != intersection.end(); - ++curr, ++next) - { - if (bearings_order(*next, *curr)) - { // If the true bearing is out of the initial order (next before current) then - // adjust the next bearing to keep the order. The adjustment angle is at most - // 0.5° or a half-angle between the current bearing and the base bearing. - // to prevent overlapping over base bearing + 360°. - const auto angle_adjustment = std::min( - .5, util::restrictAngleToValidRange(base_bearing - curr->bearing) / 2.); - next->bearing = - util::restrictAngleToValidRange(curr->bearing + angle_adjustment); - } - } - } - return intersection; - } - - return IntersectionShape{}; -} - -// a -// | -// | -// v -// For an intersection from_node --via_eid--> turn_node ----> c -// ^ -// | -// | -// b -// This functions returns _all_ turns as if the graph was undirected. -// That means we not only get (from_node, turn_node, c) in the above example -// but also (from_node, turn_node, a), (from_node, turn_node, b). These turns are -// marked as invalid and only needed for intersection classification. -IntersectionView IntersectionGenerator::GetConnectedRoads(const NodeID from_node, - const EdgeID via_eid, - const bool use_low_precision_angles) const -{ - // make sure the via-eid is valid - BOOST_ASSERT([this](const NodeID from_node, const EdgeID via_eid) { - const auto range = node_based_graph.GetAdjacentEdgeRange(from_node); - return range.front() <= via_eid && via_eid <= range.back(); - }(from_node, via_eid)); - - auto intersection = ComputeIntersectionShape( - node_based_graph.GetTarget(via_eid), boost::none, use_low_precision_angles); - return TransformIntersectionShapeIntoView(from_node, via_eid, std::move(intersection)); -} - IntersectionGenerationParameters IntersectionGenerator::SkipDegreeTwoNodes(const NodeID starting_node, const EdgeID via_edge) const { @@ -277,212 +80,6 @@ IntersectionGenerator::SkipDegreeTwoNodes(const NodeID starting_node, const Edge return {query_node, query_edge}; } -IntersectionView IntersectionGenerator::TransformIntersectionShapeIntoView( - const NodeID previous_node, - const EdgeID entering_via_edge, - const IntersectionShape &intersection_shape) const -{ - // requires a copy of the intersection - return TransformIntersectionShapeIntoView(previous_node, - entering_via_edge, - intersection_shape, // creates a copy - intersection_shape, // reference to local - {}); // empty vector of performed merges -} - -IntersectionView IntersectionGenerator::TransformIntersectionShapeIntoView( - const NodeID previous_node, - const EdgeID entering_via_edge, - const IntersectionShape &normalized_intersection, - const IntersectionShape &intersection, - const std::vector &performed_merges) const -{ - const auto node_at_intersection = node_based_graph.GetTarget(entering_via_edge); - - // request all turn restrictions - auto const restrictions = restriction_map.Restrictions(previous_node, node_at_intersection); - - // check turn restrictions to find a node that is the only allowed target when coming from a - // node to an intersection - // d - // | - // a - b - c and `only_straight_on ab | bc would return `c` for `a,b` - const auto find_only_valid_turn = [&]() -> boost::optional { - const auto itr = std::find_if(restrictions.first, restrictions.second, [](auto pair) { - return pair.second->is_only; - }); - if (itr != restrictions.second) - return itr->second->AsNodeRestriction().to; - else - return boost::none; - }; - - const auto only_valid_turn = find_only_valid_turn(); - - // barriers change our behaviour regarding u-turns - const bool is_barrier_node = barrier_nodes.find(node_at_intersection) != barrier_nodes.end(); - - const auto connect_to_previous_node = [this, previous_node](const IntersectionShapeData road) { - return node_based_graph.GetTarget(road.eid) == previous_node; - }; - - // check which of the edges is the u-turn edge - const auto uturn_edge_itr = - std::find_if(intersection.begin(), intersection.end(), connect_to_previous_node); - - // there needs to be a connection, otherwise stuff went seriously wrong. Note that this is not - // necessarily the same id as `entering_via_edge`. - // In cases where parallel edges are present, we only remember the minimal edge. Both share - // exactly the same coordinates, so the u-turn is still the best choice here. - BOOST_ASSERT(uturn_edge_itr != intersection.end()); - - const auto is_restricted = [&](const NodeID destination) { - // check if we have a dedicated destination - if (only_valid_turn) - return *only_valid_turn != destination; - - // check if explicitly forbidden - return restrictions.second != - std::find_if(restrictions.first, restrictions.second, [&](const auto &restriction) { - return restriction.second->AsNodeRestriction().to == destination; - }); - }; - - const auto is_allowed_turn = [&](const IntersectionShapeData &road) { - const auto &road_data = node_based_graph.GetEdgeData(road.eid); - const NodeID road_destination_node = node_based_graph.GetTarget(road.eid); - // reverse edges are never valid turns because the resulting turn would look like this: - // from_node --via_edge--> node_at_intersection <--onto_edge-- to_node - // however we need this for capture intersection shape for incoming one-ways - return !road_data.reversed && - // we are not turning over a barrier - (!is_barrier_node || road_destination_node == previous_node) && - // don't allow restricted turns - !is_restricted(road_destination_node); - - }; - - // due to merging of roads, the u-turn might actually not be part of the intersection anymore - // uturn is a pair of {edge id, bearing} - const auto uturn = [&]() { - const auto merge_entry = std::find_if( - performed_merges.begin(), performed_merges.end(), [&uturn_edge_itr](const auto entry) { - return entry.merged_eid == uturn_edge_itr->eid; - }); - if (merge_entry != performed_merges.end()) - { - const auto merged_into_id = merge_entry->into_eid; - const auto merged_u_turn = std::find_if( - normalized_intersection.begin(), - normalized_intersection.end(), - [&](const IntersectionShapeData &road) { return road.eid == merged_into_id; }); - BOOST_ASSERT(merged_u_turn != normalized_intersection.end()); - return std::make_pair(merged_u_turn->eid, - util::bearing::reverse(merged_u_turn->bearing)); - } - else - { - const auto uturn_edge_at_normalized_intersection_itr = - std::find_if(normalized_intersection.begin(), - normalized_intersection.end(), - connect_to_previous_node); - BOOST_ASSERT(uturn_edge_at_normalized_intersection_itr != - normalized_intersection.end()); - return std::make_pair( - uturn_edge_at_normalized_intersection_itr->eid, - util::bearing::reverse(uturn_edge_at_normalized_intersection_itr->bearing)); - } - }(); - - IntersectionView intersection_view; - intersection_view.reserve(normalized_intersection.size()); - std::transform(normalized_intersection.begin(), - normalized_intersection.end(), - std::back_inserter(intersection_view), - [&](const IntersectionShapeData &road) { - return IntersectionViewData( - road, - is_allowed_turn(road), - util::bearing::angleBetween(uturn.second, road.bearing)); - }); - - const auto uturn_edge_at_intersection_view_itr = - std::find_if(intersection_view.begin(), intersection_view.end(), connect_to_previous_node); - // number of found valid exit roads - const auto valid_count = - std::count_if(intersection_view.begin(), - intersection_view.end(), - [](const IntersectionViewData &road) { return road.entry_allowed; }); - // in general, we don't wan't to allow u-turns. If we don't look at a barrier, we have to check - // for dead end streets. These are the only ones that we allow uturns for, next to barriers - // (which are also kind of a dead end, but we don't have to check these again :)) - if (uturn_edge_at_intersection_view_itr != intersection_view.end() && - ((uturn_edge_at_intersection_view_itr->entry_allowed && !is_barrier_node && - valid_count != 1) || - valid_count == 0)) - { - const auto allow_uturn_at_dead_end = [&]() { - const auto &uturn_data = node_based_graph.GetEdgeData(uturn_edge_itr->eid); - - // we can't turn back onto oneway streets - if (uturn_data.reversed) - return false; - - // don't allow explicitly restricted turns - if (is_restricted(previous_node)) - return false; - - // we define dead ends as roads that can only be entered via the possible u-turn - const auto is_bidirectional = [&](const EdgeID entering_via_edge) { - const auto to_node = node_based_graph.GetTarget(entering_via_edge); - const auto reverse_edge = node_based_graph.FindEdge(to_node, node_at_intersection); - BOOST_ASSERT(reverse_edge != SPECIAL_EDGEID); - return !node_based_graph.GetEdgeData(reverse_edge).reversed; - }; - - const auto bidirectional_edges = [&]() { - std::uint32_t count = 0; - for (const auto eid : node_based_graph.GetAdjacentEdgeRange(node_at_intersection)) - if (is_bidirectional(eid)) - ++count; - return count; - }(); - - // Checking for dead-end streets is kind of difficult. There is obvious dead ends - // (single road connected) - return bidirectional_edges <= 1; - }(); - uturn_edge_at_intersection_view_itr->entry_allowed = allow_uturn_at_dead_end; - } - std::sort(std::begin(intersection_view), - std::end(intersection_view), - std::mem_fn(&IntersectionViewData::CompareByAngle)); - - // Move entering_via_edge to intersection front and place all roads prior entering_via_edge - // at the end of the intersection view with 360° angle - auto entering_via_it = std::find_if(intersection_view.begin(), - intersection_view.end(), - [&uturn](auto &road) { return road.eid == uturn.first; }); - - OSRM_ASSERT(entering_via_it != intersection_view.end() && entering_via_it->angle >= 0. && - entering_via_it->angle < std::numeric_limits::epsilon(), - coordinates[node_at_intersection]); - - if (entering_via_it != intersection_view.begin() && entering_via_it != intersection_view.end()) - { - std::for_each( - intersection_view.begin(), entering_via_it, [](auto &road) { road.angle = 360.; }); - std::rotate(intersection_view.begin(), entering_via_it, intersection_view.end()); - } - - return intersection_view; -} - -const CoordinateExtractor &IntersectionGenerator::GetCoordinateExtractor() const -{ - return coordinate_extractor; -} - } // namespace guidance } // namespace extractor } // namespace osrm diff --git a/src/extractor/guidance/intersection_handler.cpp b/src/extractor/guidance/intersection_handler.cpp index 756ee3217..96d6028e6 100644 --- a/src/extractor/guidance/intersection_handler.cpp +++ b/src/extractor/guidance/intersection_handler.cpp @@ -1,5 +1,6 @@ #include "extractor/guidance/intersection_handler.hpp" #include "extractor/guidance/constants.hpp" +#include "extractor/intersection/intersection_analysis.hpp" #include "util/coordinate_calculation.hpp" #include "util/guidance/name_announcements.hpp" @@ -45,17 +46,29 @@ inline bool requiresAnnouncement(const util::NodeBasedDynamicGraph &node_based_g } } // namespace detail -IntersectionHandler::IntersectionHandler(const util::NodeBasedDynamicGraph &node_based_graph, - const EdgeBasedNodeDataContainer &node_data_container, - const std::vector &coordinates, - const util::NameTable &name_table, - const SuffixTable &street_name_suffix_table, - const IntersectionGenerator &intersection_generator) +IntersectionHandler::IntersectionHandler( + const util::NodeBasedDynamicGraph &node_based_graph, + const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, + const util::NameTable &name_table, + const SuffixTable &street_name_suffix_table, + const IntersectionGenerator &intersection_generator) : node_based_graph(node_based_graph), node_data_container(node_data_container), - coordinates(coordinates), name_table(name_table), + node_coordinates(node_coordinates), compressed_geometries(compressed_geometries), + node_restriction_map(node_restriction_map), barrier_nodes(barrier_nodes), + turn_lanes_data(turn_lanes_data), name_table(name_table), street_name_suffix_table(street_name_suffix_table), - intersection_generator(intersection_generator), - graph_walker(node_based_graph, node_data_container, intersection_generator) + intersection_generator(intersection_generator), graph_walker(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data) { } @@ -162,8 +175,8 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t // or actually follow the full road. When 2399 lands, we can exchange here for a // precalculated distance value. const auto distance = util::coordinate_calculation::haversineDistance( - coordinates[node_based_graph.GetTarget(via_edge)], - coordinates[node_based_graph.GetTarget(road.eid)]); + node_coordinates[node_based_graph.GetTarget(via_edge)], + node_coordinates[node_based_graph.GetTarget(road.eid)]); return {TurnType::Turn, (angularDeviation(road.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE && @@ -470,8 +483,15 @@ IntersectionHandler::getNextIntersection(const NodeID at, const EdgeID via) cons return boost::none; } - auto intersection = - intersection_generator(intersection_parameters.nid, intersection_parameters.via_eid); + auto intersection = intersection::getConnectedRoads( + node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, + {intersection_parameters.nid, intersection_parameters.via_eid}); auto intersection_node = node_based_graph.GetTarget(intersection_parameters.via_eid); if (intersection.size() <= 2 || intersection.isTrafficSignalOrBarrier()) diff --git a/src/extractor/guidance/mergable_road_detector.cpp b/src/extractor/guidance/mergable_road_detector.cpp index 4773d631d..316d3fffb 100644 --- a/src/extractor/guidance/mergable_road_detector.cpp +++ b/src/extractor/guidance/mergable_road_detector.cpp @@ -3,6 +3,7 @@ #include "extractor/guidance/coordinate_extractor.hpp" #include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/node_based_graph_walker.hpp" +#include "extractor/intersection/intersection_analysis.hpp" #include "extractor/query_node.hpp" #include "extractor/suffix_table.hpp" @@ -52,15 +53,22 @@ inline auto makeCheckRoadForName(const NameID name_id, } } -MergableRoadDetector::MergableRoadDetector(const util::NodeBasedDynamicGraph &node_based_graph, - const EdgeBasedNodeDataContainer &node_data_container, - const std::vector &node_coordinates, - const IntersectionGenerator &intersection_generator, - const CoordinateExtractor &coordinate_extractor, - const util::NameTable &name_table, - const SuffixTable &street_name_suffix_table) +MergableRoadDetector::MergableRoadDetector( + const util::NodeBasedDynamicGraph &node_based_graph, + const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, + const IntersectionGenerator &intersection_generator, + 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), intersection_generator(intersection_generator), + node_coordinates(node_coordinates), compressed_geometries(compressed_geometries), + node_restriction_map(node_restriction_map), barrier_nodes(barrier_nodes), + turn_lanes_data(turn_lanes_data), intersection_generator(intersection_generator), coordinate_extractor(coordinate_extractor), name_table(name_table), street_name_suffix_table(street_name_suffix_table) { @@ -180,8 +188,22 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node, { // selection data to the right and left const auto constexpr SMALL_RANDOM_HOPLIMIT = 5; - IntersectionFinderAccumulator left_accumulator(SMALL_RANDOM_HOPLIMIT, intersection_generator), - right_accumulator(SMALL_RANDOM_HOPLIMIT, intersection_generator); + IntersectionFinderAccumulator left_accumulator(SMALL_RANDOM_HOPLIMIT, + node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data), + right_accumulator(SMALL_RANDOM_HOPLIMIT, + node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data); /* Standard following the straightmost road * Since both items have the same id, we can `select` based on any setup @@ -193,8 +215,13 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node, /*requires entry=*/false, false); - NodeBasedGraphWalker graph_walker( - node_based_graph, node_data_container, intersection_generator); + NodeBasedGraphWalker graph_walker(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data); graph_walker.TraverseRoad(intersection_node, lhs.eid, left_accumulator, selector); /* if the intersection does not have a right turn, we continue onto the next one once * (skipping over a single small side street) @@ -266,7 +293,13 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node, // check if both intersections are connected IntersectionFinderAccumulator connect_accumulator(SMALL_RANDOM_HOPLIMIT, - intersection_generator); + node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data); graph_walker.TraverseRoad(node_based_graph.GetTarget(left_accumulator.via_edge_id), connector_turn->eid, connect_accumulator, @@ -281,8 +314,13 @@ bool MergableRoadDetector::IsCircularShape(const NodeID intersection_node, const MergableRoadData &lhs, const MergableRoadData &rhs) const { - NodeBasedGraphWalker graph_walker( - node_based_graph, node_data_container, intersection_generator); + NodeBasedGraphWalker graph_walker(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data); const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length) { LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length); SelectStraightmostRoadByNameAndOnlyChoice selector( @@ -348,8 +386,13 @@ bool MergableRoadDetector::HaveSameDirection(const NodeID intersection_node, return false; // Find a coordinate following a road that is far away - NodeBasedGraphWalker graph_walker( - node_based_graph, node_data_container, intersection_generator); + NodeBasedGraphWalker graph_walker(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data); const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length) { LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length); SelectStraightmostRoadByNameAndOnlyChoice selector( @@ -517,8 +560,15 @@ bool MergableRoadDetector::IsLinkRoad(const NodeID intersection_node, { const auto next_intersection_parameters = intersection_generator.SkipDegreeTwoNodes(intersection_node, road.eid); - const auto next_intersection_along_road = intersection_generator.GetConnectedRoads( - next_intersection_parameters.nid, next_intersection_parameters.via_eid); + const auto next_intersection_along_road = intersection::getConnectedRoads( + node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, + {next_intersection_parameters.nid, next_intersection_parameters.via_eid}); const auto extract_name_id = [this](const MergableRoadData &road) { return node_data_container .GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data) diff --git a/src/extractor/guidance/motorway_handler.cpp b/src/extractor/guidance/motorway_handler.cpp index 95ff22507..d69d861d3 100644 --- a/src/extractor/guidance/motorway_handler.cpp +++ b/src/extractor/guidance/motorway_handler.cpp @@ -42,12 +42,20 @@ inline bool isRampClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_base MotorwayHandler::MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table, const IntersectionGenerator &intersection_generator) : IntersectionHandler(node_based_graph, node_data_container, coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table, intersection_generator) diff --git a/src/extractor/guidance/node_based_graph_walker.cpp b/src/extractor/guidance/node_based_graph_walker.cpp index a84a0b01c..529070271 100644 --- a/src/extractor/guidance/node_based_graph_walker.cpp +++ b/src/extractor/guidance/node_based_graph_walker.cpp @@ -1,4 +1,5 @@ #include "extractor/guidance/node_based_graph_walker.hpp" +#include "extractor/intersection/intersection_analysis.hpp" #include "util/bearing.hpp" #include "util/coordinate_calculation.hpp" @@ -14,11 +15,18 @@ namespace guidance { // --------------------------------------------------------------------------------- -NodeBasedGraphWalker::NodeBasedGraphWalker(const util::NodeBasedDynamicGraph &node_based_graph, - const EdgeBasedNodeDataContainer &node_data_container, - const IntersectionGenerator &intersection_generator) +NodeBasedGraphWalker::NodeBasedGraphWalker( + const util::NodeBasedDynamicGraph &node_based_graph, + const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data) : node_based_graph(node_based_graph), node_data_container(node_data_container), - intersection_generator(intersection_generator) + node_coordinates(node_coordinates), compressed_geometries(compressed_geometries), + node_restriction_map(node_restriction_map), barrier_nodes(barrier_nodes), + turn_lanes_data(turn_lanes_data) { } @@ -235,8 +243,18 @@ operator()(const NodeID /*nid*/, // --------------------------------------------------------------------------------- IntersectionFinderAccumulator::IntersectionFinderAccumulator( - const std::uint8_t hop_limit, const IntersectionGenerator &intersection_generator) - : hops(0), hop_limit(hop_limit), intersection_generator(intersection_generator) + const std::uint8_t hop_limit, + const util::NodeBasedDynamicGraph &node_based_graph, + const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data) + : hops(0), hop_limit(hop_limit), 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) { } @@ -261,7 +279,14 @@ void IntersectionFinderAccumulator::update(const NodeID from_node, nid = from_node; via_edge_id = via_edge; - intersection = intersection_generator.GetConnectedRoads(from_node, via_edge, true); + intersection = intersection::getConnectedRoads(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, + {from_node, via_edge}); } } // namespace guidance diff --git a/src/extractor/guidance/roundabout_handler.cpp b/src/extractor/guidance/roundabout_handler.cpp index a10e88fc1..87dc3436a 100644 --- a/src/extractor/guidance/roundabout_handler.cpp +++ b/src/extractor/guidance/roundabout_handler.cpp @@ -23,21 +23,28 @@ namespace extractor namespace guidance { -RoundaboutHandler::RoundaboutHandler(const util::NodeBasedDynamicGraph &node_based_graph, - const EdgeBasedNodeDataContainer &node_data_container, - const std::vector &coordinates, - const CompressedEdgeContainer &compressed_edge_container, - const util::NameTable &name_table, - const SuffixTable &street_name_suffix_table, - const IntersectionGenerator &intersection_generator) +RoundaboutHandler::RoundaboutHandler( + const util::NodeBasedDynamicGraph &node_based_graph, + const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, + const util::NameTable &name_table, + const SuffixTable &street_name_suffix_table, + const IntersectionGenerator &intersection_generator) : IntersectionHandler(node_based_graph, node_data_container, coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table, intersection_generator), - compressed_edge_container(compressed_edge_container), - coordinate_extractor(node_based_graph, compressed_edge_container, coordinates) + coordinate_extractor(node_based_graph, compressed_geometries, coordinates) { } @@ -143,7 +150,7 @@ bool RoundaboutHandler::qualifiesAsRoundaboutIntersection( continue; // there is a single non-roundabout edge - const auto src_coordinate = coordinates[node]; + const auto src_coordinate = node_coordinates[node]; const auto edge_range = node_based_graph.GetAdjacentEdgeRange(node); const auto number_of_lanes_at_intersection = std::accumulate( @@ -262,11 +269,11 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const const auto getEdgeLength = [&](const NodeID source_node, EdgeID eid) { double length = 0.; - auto last_coord = coordinates[source_node]; - const auto &edge_bucket = compressed_edge_container.GetBucketReference(eid); + auto last_coord = node_coordinates[source_node]; + const auto &edge_bucket = compressed_geometries.GetBucketReference(eid); for (const auto &compressed_edge : edge_bucket) { - const auto next_coord = coordinates[compressed_edge.node_id]; + const auto next_coord = node_coordinates[compressed_edge.node_id]; length += util::coordinate_calculation::haversineDistance(last_coord, next_coord); last_coord = next_coord; } diff --git a/src/extractor/guidance/sliproad_handler.cpp b/src/extractor/guidance/sliproad_handler.cpp index abdc72297..5f71e1f93 100644 --- a/src/extractor/guidance/sliproad_handler.cpp +++ b/src/extractor/guidance/sliproad_handler.cpp @@ -25,15 +25,24 @@ namespace guidance SliproadHandler::SliproadHandler(const IntersectionGenerator &intersection_generator, const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, - const std::vector &coordinates, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table) : IntersectionHandler(node_based_graph, node_data_container, - coordinates, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table, - intersection_generator) + intersection_generator), + coordinate_extractor(node_based_graph, compressed_geometries, node_coordinates) { } @@ -243,7 +252,14 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter // Starting out at the intersection and going onto the Sliproad we skip artificial // degree two intersections and limit the max hop count in doing so. - IntersectionFinderAccumulator intersection_finder{10, intersection_generator}; + IntersectionFinderAccumulator intersection_finder{10, + node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data}; const SkipTrafficSignalBarrierRoadSelector road_selector{}; (void)graph_walker.TraverseRoad(intersection_node_id, // start node sliproad_edge, // onto edge @@ -372,8 +388,6 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter // // Sliproad Not a Sliproad { - const auto &coordinate_extractor = intersection_generator.GetCoordinateExtractor(); - const NodeID start = intersection_node_id; // b const EdgeID edge = sliproad_edge; // bd @@ -424,8 +438,8 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter // Only check for curvature and ~90 degree when it makes sense to do so. const constexpr auto MIN_LENGTH = 3.; - const auto length = haversineDistance(coordinates[intersection_node_id], - coordinates[main_road_intersection->node]); + const auto length = haversineDistance(node_coordinates[intersection_node_id], + node_coordinates[main_road_intersection->node]); const double minimal_crossroad_angle_of_intersection = 40.; @@ -546,8 +560,15 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter } else { - const auto skip_traffic_light_intersection = intersection_generator( - node_based_graph.GetTarget(sliproad_edge), candidate_road.eid); + const auto skip_traffic_light_intersection = intersection::getConnectedRoads( + node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, + {node_based_graph.GetTarget(sliproad_edge), candidate_road.eid}); if (skip_traffic_light_intersection.isTrafficSignalOrBarrier() && node_based_graph.GetTarget(skip_traffic_light_intersection[1].eid) == main_road_intersection->node) @@ -656,8 +677,6 @@ bool SliproadHandler::nextIntersectionIsTooFarAway(const NodeID start, const Edg BOOST_ASSERT(start != SPECIAL_NODEID); BOOST_ASSERT(onto != SPECIAL_EDGEID); - const auto &coordinate_extractor = intersection_generator.GetCoordinateExtractor(); - // Base max distance threshold on the current road class we're on const auto &data = node_based_graph.GetEdgeData(onto).flags; const auto threshold = scaledThresholdByRoadClass(MAX_SLIPROAD_THRESHOLD, // <- scales down @@ -728,9 +747,9 @@ bool SliproadHandler::isValidSliproadArea(const double max_area, { using namespace util::coordinate_calculation; - const auto first = coordinates[a]; - const auto second = coordinates[b]; - const auto third = coordinates[c]; + const auto first = node_coordinates[a]; + const auto second = node_coordinates[b]; + const auto third = node_coordinates[c]; const auto length = haversineDistance(first, second); const auto heigth = haversineDistance(second, third); diff --git a/src/extractor/guidance/suppress_mode_handler.cpp b/src/extractor/guidance/suppress_mode_handler.cpp index 6a870ee98..0f41eed5d 100644 --- a/src/extractor/guidance/suppress_mode_handler.cpp +++ b/src/extractor/guidance/suppress_mode_handler.cpp @@ -11,15 +11,24 @@ namespace extractor namespace guidance { -SuppressModeHandler::SuppressModeHandler(const IntersectionGenerator &intersection_generator, - const util::NodeBasedDynamicGraph &node_based_graph, - const EdgeBasedNodeDataContainer &node_data_container, - const std::vector &coordinates, - const util::NameTable &name_table, - const SuffixTable &street_name_suffix_table) +SuppressModeHandler::SuppressModeHandler( + const IntersectionGenerator &intersection_generator, + const util::NodeBasedDynamicGraph &node_based_graph, + const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, + const util::NameTable &name_table, + const SuffixTable &street_name_suffix_table) : IntersectionHandler(node_based_graph, node_data_container, coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table, intersection_generator) diff --git a/src/extractor/guidance/turn_analysis.cpp b/src/extractor/guidance/turn_analysis.cpp index 76eca2047..32d6685d6 100644 --- a/src/extractor/guidance/turn_analysis.cpp +++ b/src/extractor/guidance/turn_analysis.cpp @@ -23,60 +23,87 @@ using EdgeData = util::NodeBasedDynamicGraph::EdgeData; TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, - const std::vector &coordinates, + const std::vector &node_coordinates, + const CompressedEdgeContainer &compressed_edge_container, const RestrictionMap &restriction_map, const std::unordered_set &barrier_nodes, - const CompressedEdgeContainer &compressed_edge_container, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table) : node_based_graph(node_based_graph), intersection_generator(node_based_graph, node_data_container, restriction_map, barrier_nodes, - coordinates, + node_coordinates, compressed_edge_container), roundabout_handler(node_based_graph, node_data_container, - coordinates, + node_coordinates, compressed_edge_container, + restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table, intersection_generator), motorway_handler(node_based_graph, node_data_container, - - coordinates, + node_coordinates, + compressed_edge_container, + restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table, intersection_generator), turn_handler(node_based_graph, node_data_container, - coordinates, + node_coordinates, + compressed_edge_container, + restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table, intersection_generator), sliproad_handler(intersection_generator, node_based_graph, node_data_container, - coordinates, + node_coordinates, + compressed_edge_container, + restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table), suppress_mode_handler(intersection_generator, node_based_graph, node_data_container, - coordinates, + node_coordinates, + compressed_edge_container, + restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table), driveway_handler(intersection_generator, node_based_graph, node_data_container, - coordinates, + node_coordinates, + compressed_edge_container, + restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table), statistics_handler(intersection_generator, node_based_graph, node_data_container, - coordinates, + node_coordinates, + compressed_edge_container, + restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table) { @@ -188,11 +215,6 @@ Intersection TurnAnalysis::setTurnTypes(const NodeID node_prior_to_intersection, return intersection; } -const IntersectionGenerator &TurnAnalysis::GetIntersectionGenerator() const -{ - return intersection_generator; -} - } // namespace guidance } // namespace extractor } // namespace osrm diff --git a/src/extractor/guidance/turn_discovery.cpp b/src/extractor/guidance/turn_discovery.cpp index fc8f868d9..aa6c8db4b 100644 --- a/src/extractor/guidance/turn_discovery.cpp +++ b/src/extractor/guidance/turn_discovery.cpp @@ -1,5 +1,6 @@ #include "extractor/guidance/turn_discovery.hpp" #include "extractor/guidance/constants.hpp" +#include "extractor/intersection/intersection_analysis.hpp" #include "util/bearing.hpp" #include "util/coordinate_calculation.hpp" @@ -14,16 +15,16 @@ namespace guidance namespace lanes { -namespace -{ -const constexpr bool USE_LOW_PRECISION_MODE = true; -} - bool findPreviousIntersection(const NodeID node_v, const EdgeID via_edge, const Intersection &intersection, - const IntersectionGenerator &intersection_generator, const util::NodeBasedDynamicGraph &node_based_graph, + const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, // output parameters NodeID &result_node, EdgeID &result_via_edge, @@ -43,7 +44,9 @@ bool findPreviousIntersection(const NodeID node_v, */ const constexpr double COMBINE_DISTANCE_CUTOFF = 30; - const auto coordinate_extractor = intersection_generator.GetCoordinateExtractor(); + const CoordinateExtractor coordinate_extractor( + node_based_graph, compressed_geometries, node_coordinates); + const auto coordinates_along_via_edge = coordinate_extractor.GetForwardCoordinatesAlongRoad(node_v, via_edge); const auto via_edge_length = @@ -71,7 +74,14 @@ bool findPreviousIntersection(const NodeID node_v, return false; const auto node_v_reverse_intersection = - intersection_generator.GetConnectedRoads(node_w, u_turn_at_node_w, USE_LOW_PRECISION_MODE); + intersection::getConnectedRoads(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, + {node_w, u_turn_at_node_w}); // Continue along the straightmost turn. If there is no straight turn, we cannot find a valid // previous intersection. const auto straightmost_at_v_in_reverse = @@ -83,8 +93,15 @@ bool findPreviousIntersection(const NodeID node_v, return false; const auto node_u = node_based_graph.GetTarget(straightmost_at_v_in_reverse->eid); - const auto node_u_reverse_intersection = intersection_generator.GetConnectedRoads( - node_v, straightmost_at_v_in_reverse->eid, USE_LOW_PRECISION_MODE); + const auto node_u_reverse_intersection = + intersection::getConnectedRoads(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, + {node_v, straightmost_at_v_in_reverse->eid}); // now check that the u-turn at the given intersection connects to via-edge // The u-turn at the now found intersection should, hopefully, represent the previous edge. @@ -102,7 +119,14 @@ bool findPreviousIntersection(const NodeID node_v, return false; } - result_intersection = intersection_generator(node_u, result_via_edge); + result_intersection = intersection::getConnectedRoads(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, + {node_u, result_via_edge}); const auto check_via_edge = result_intersection.end() != std::find_if(result_intersection.begin(), diff --git a/src/extractor/guidance/turn_handler.cpp b/src/extractor/guidance/turn_handler.cpp index a4be7ede6..aeb9f7843 100644 --- a/src/extractor/guidance/turn_handler.cpp +++ b/src/extractor/guidance/turn_handler.cpp @@ -113,12 +113,20 @@ std::size_t TurnHandler::Fork::getLeftIndex() const TurnHandler::TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table, const IntersectionGenerator &intersection_generator) : IntersectionHandler(node_based_graph, node_data_container, coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, name_table, street_name_suffix_table, intersection_generator) diff --git a/src/extractor/guidance/turn_lane_handler.cpp b/src/extractor/guidance/turn_lane_handler.cpp index 4f9f2ecec..b04b51293 100644 --- a/src/extractor/guidance/turn_lane_handler.cpp +++ b/src/extractor/guidance/turn_lane_handler.cpp @@ -3,6 +3,7 @@ #include "extractor/guidance/turn_discovery.hpp" #include "extractor/guidance/turn_lane_augmentation.hpp" #include "extractor/guidance/turn_lane_matcher.hpp" +#include "extractor/intersection/intersection_analysis.hpp" #include "util/bearing.hpp" #include "util/log.hpp" #include "util/typedefs.hpp" @@ -35,14 +36,21 @@ std::size_t getNumberOfTurns(const Intersection &intersection) TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, LaneDescriptionMap &lane_description_map, const TurnAnalysis &turn_analysis, util::guidance::LaneDataIdMap &id_map) : node_based_graph(node_based_graph), node_data_container(node_data_container), - lane_description_map(lane_description_map), turn_analysis(turn_analysis), id_map(id_map) + node_coordinates(node_coordinates), compressed_geometries(compressed_geometries), + node_restriction_map(node_restriction_map), barrier_nodes(barrier_nodes), + turn_lanes_data(turn_lanes_data), lane_description_map(lane_description_map), + turn_analysis(turn_analysis), id_map(id_map) { - std::tie(turn_lane_offsets, turn_lane_masks) = - transformTurnLaneMapIntoArrays(lane_description_map); + std::tie(turn_lane_offsets, turn_lane_masks) = turn_lanes_data; count_handled = count_called = 0; } @@ -205,8 +213,13 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at, if (findPreviousIntersection(at, via_edge, intersection, - turn_analysis.GetIntersectionGenerator(), node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, previous_node, previous_via_edge, previous_intersection_view)) @@ -559,8 +572,17 @@ std::pair TurnLaneHandler::partitionLaneData( // find out about the next intersection. To check for valid matches, we also need the turn // types. We can skip merging/angle adjustments, though - const auto next_intersection = turn_analysis.AssignTurnTypes( - at, straightmost->eid, turn_analysis.GetIntersectionGenerator()(at, straightmost->eid)); + const auto next_intersection = + turn_analysis.AssignTurnTypes(at, + straightmost->eid, + intersection::getConnectedRoads(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, + {at, straightmost->eid})); // check where we can match turn lanes std::size_t straightmost_tag_index = turn_lane_data.size(); diff --git a/src/extractor/intersection/intersection_analysis.cpp b/src/extractor/intersection/intersection_analysis.cpp index e5ebb2d26..8a7d19c87 100644 --- a/src/extractor/intersection/intersection_analysis.cpp +++ b/src/extractor/intersection/intersection_analysis.cpp @@ -658,7 +658,7 @@ bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph, return true; } -// TODO: the function adapts intersection geometry data to TurnAnalysis +// The function adapts intersection geometry data to TurnAnalysis guidance::IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &graph, const EdgeBasedNodeDataContainer &node_data_container, @@ -727,6 +727,62 @@ convertToIntersectionView(const util::NodeBasedDynamicGraph &graph, return intersection_view; } + +// a +// | +// | +// v +// For an intersection from_node --via_eid--> turn_node ----> c +// ^ +// | +// | +// b +// This functions returns _all_ turns as if the graph was undirected. +// That means we not only get (from_node, turn_node, c) in the above example +// but also (from_node, turn_node, a), (from_node, turn_node, b). These turns are +// marked as invalid and only needed for intersection classification. +guidance::IntersectionView +getConnectedRoads(const util::NodeBasedDynamicGraph &graph, + const EdgeBasedNodeDataContainer &node_data_container, + const std::vector &node_coordinates, + const extractor::CompressedEdgeContainer &compressed_geometries, + const RestrictionMap &node_restriction_map, + const std::unordered_set &barrier_nodes, + const guidance::TurnLanesIndexedArray &turn_lanes_data, + const IntersectionEdge &incoming_edge) +{ + const auto intersection_node = graph.GetTarget(incoming_edge.edge); + const auto &outgoing_edges = intersection::getOutgoingEdges(graph, intersection_node); + auto edge_geometries = getIntersectionOutgoingGeometries( + graph, compressed_geometries, node_coordinates, intersection_node); + + // Add incoming edges with reversed bearings + const auto edges_number = edge_geometries.size(); + edge_geometries.resize(2 * edges_number); + for (std::size_t index = 0; index < edges_number; ++index) + { + const auto &geometry = edge_geometries[index]; + const auto remote_node = graph.GetTarget(geometry.edge); + const auto incoming_edge = graph.FindEdge(remote_node, intersection_node); + edge_geometries[edges_number + index] = {incoming_edge, + util::bearing::reverse(geometry.initial_bearing), + util::bearing::reverse(geometry.perceived_bearing), + geometry.length}; + } + + // Enforce ordering of edges by IDs + std::sort(edge_geometries.begin(), edge_geometries.end()); + + return convertToIntersectionView(graph, + node_data_container, + node_restriction_map, + barrier_nodes, + edge_geometries, + turn_lanes_data, + incoming_edge, + outgoing_edges, + std::unordered_set()); +} } } }