Remove GetConnectedRoads from IntersectionGenerator
This commit is contained in:
		
							parent
							
								
									cc1a5ea78d
								
							
						
					
					
						commit
						db7c76d04d
					
				| @ -18,6 +18,10 @@ class DrivewayHandler final : public IntersectionHandler | |||||||
|                     const util::NodeBasedDynamicGraph &node_based_graph, |                     const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                     const EdgeBasedNodeDataContainer &node_data_container, |                     const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                     const std::vector<util::Coordinate> &coordinates, |                     const std::vector<util::Coordinate> &coordinates, | ||||||
|  |                     const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                     const RestrictionMap &node_restriction_map, | ||||||
|  |                     const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                     const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                     const util::NameTable &name_table, |                     const util::NameTable &name_table, | ||||||
|                     const SuffixTable &street_name_suffix_table); |                     const SuffixTable &street_name_suffix_table); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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) | inline auto makeCompareAngularDeviation(const double angle) | ||||||
| { | { | ||||||
|     return [angle](const auto &lhs, const auto &rhs) { |     return [angle](const auto &lhs, const auto &rhs) { | ||||||
|  | |||||||
| @ -44,26 +44,6 @@ class IntersectionGenerator | |||||||
|                           const std::vector<util::Coordinate> &coordinates, |                           const std::vector<util::Coordinate> &coordinates, | ||||||
|                           const CompressedEdgeContainer &compressed_edge_container); |                           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<NodeID> sorting_base = boost::none, |  | ||||||
|                              bool use_low_precision_angles = false) const; |  | ||||||
| 
 |  | ||||||
|     // Graph Compression cannot compress every setting. For example any barrier/traffic light cannot
 |     // 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
 |     // 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
 |     // 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, |     IntersectionGenerationParameters SkipDegreeTwoNodes(const NodeID starting_node, | ||||||
|                                                         const EdgeID via_edge) const; |                                                         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<IntersectionNormalizationOperation> &merging_map) const; |  | ||||||
| 
 |  | ||||||
|   private: |   private: | ||||||
|     const util::NodeBasedDynamicGraph &node_based_graph; |     const util::NodeBasedDynamicGraph &node_based_graph; | ||||||
|     const EdgeBasedNodeDataContainer &node_data_container; |     const EdgeBasedNodeDataContainer &node_data_container; | ||||||
|     const RestrictionMap &restriction_map; |     const RestrictionMap &restriction_map; | ||||||
|     const std::unordered_set<NodeID> &barrier_nodes; |     const std::unordered_set<NodeID> &barrier_nodes; | ||||||
|     const std::vector<util::Coordinate> &coordinates; |     const std::vector<util::Coordinate> &coordinates; | ||||||
| 
 |  | ||||||
|     // own state, used to find the correct coordinates along a road
 |  | ||||||
|     const CoordinateExtractor coordinate_extractor; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace guidance
 | } // namespace guidance
 | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ | |||||||
| #include "extractor/guidance/intersection.hpp" | #include "extractor/guidance/intersection.hpp" | ||||||
| #include "extractor/guidance/intersection_generator.hpp" | #include "extractor/guidance/intersection_generator.hpp" | ||||||
| #include "extractor/guidance/node_based_graph_walker.hpp" | #include "extractor/guidance/node_based_graph_walker.hpp" | ||||||
|  | #include "extractor/intersection/intersection_analysis.hpp" | ||||||
| #include "extractor/query_node.hpp" | #include "extractor/query_node.hpp" | ||||||
| #include "extractor/suffix_table.hpp" | #include "extractor/suffix_table.hpp" | ||||||
| 
 | 
 | ||||||
| @ -34,7 +35,11 @@ class IntersectionHandler | |||||||
|   public: |   public: | ||||||
|     IntersectionHandler(const util::NodeBasedDynamicGraph &node_based_graph, |     IntersectionHandler(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                         const EdgeBasedNodeDataContainer &node_data_container, |                         const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                         const std::vector<util::Coordinate> &coordinates, |                         const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |                         const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                         const RestrictionMap &node_restriction_map, | ||||||
|  |                         const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                         const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                         const util::NameTable &name_table, |                         const util::NameTable &name_table, | ||||||
|                         const SuffixTable &street_name_suffix_table, |                         const SuffixTable &street_name_suffix_table, | ||||||
|                         const IntersectionGenerator &intersection_generator); |                         const IntersectionGenerator &intersection_generator); | ||||||
| @ -52,7 +57,11 @@ class IntersectionHandler | |||||||
|   protected: |   protected: | ||||||
|     const util::NodeBasedDynamicGraph &node_based_graph; |     const util::NodeBasedDynamicGraph &node_based_graph; | ||||||
|     const EdgeBasedNodeDataContainer &node_data_container; |     const EdgeBasedNodeDataContainer &node_data_container; | ||||||
|     const std::vector<util::Coordinate> &coordinates; |     const std::vector<util::Coordinate> &node_coordinates; | ||||||
|  |     const extractor::CompressedEdgeContainer &compressed_geometries; | ||||||
|  |     const RestrictionMap &node_restriction_map; | ||||||
|  |     const std::unordered_set<NodeID> &barrier_nodes; | ||||||
|  |     const guidance::TurnLanesIndexedArray &turn_lanes_data; | ||||||
|     const util::NameTable &name_table; |     const util::NameTable &name_table; | ||||||
|     const SuffixTable &street_name_suffix_table; |     const SuffixTable &street_name_suffix_table; | ||||||
|     const IntersectionGenerator &intersection_generator; |     const IntersectionGenerator &intersection_generator; | ||||||
| @ -571,7 +580,15 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, | |||||||
|                     node_at_intersection, intersection[0].eid); |                     node_at_intersection, intersection[0].eid); | ||||||
|                 if (node_based_graph.GetTarget(parameters.via_eid) == node_at_intersection) |                 if (node_based_graph.GetTarget(parameters.via_eid) == node_at_intersection) | ||||||
|                     return {}; |                     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()) |             if (!previous_intersection.empty()) | ||||||
|  | |||||||
| @ -1,7 +1,10 @@ | |||||||
| #ifndef OSRM_EXTRACTOR_GUIDANCE_MERGEABLE_ROADS | #ifndef OSRM_EXTRACTOR_GUIDANCE_MERGEABLE_ROADS | ||||||
| #define 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/intersection.hpp" | ||||||
|  | #include "extractor/guidance/turn_lane_types.hpp" | ||||||
|  | #include "extractor/restriction_index.hpp" | ||||||
| #include "util/coordinate.hpp" | #include "util/coordinate.hpp" | ||||||
| #include "util/node_based_graph.hpp" | #include "util/node_based_graph.hpp" | ||||||
| #include "util/typedefs.hpp" | #include "util/typedefs.hpp" | ||||||
| @ -9,6 +12,7 @@ | |||||||
| #include <cstdint> | #include <cstdint> | ||||||
| #include <functional> | #include <functional> | ||||||
| #include <limits> | #include <limits> | ||||||
|  | #include <unordered_set> | ||||||
| #include <vector> | #include <vector> | ||||||
| 
 | 
 | ||||||
| namespace osrm | namespace osrm | ||||||
| @ -39,6 +43,10 @@ class MergableRoadDetector | |||||||
|     MergableRoadDetector(const util::NodeBasedDynamicGraph &node_based_graph, |     MergableRoadDetector(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                          const EdgeBasedNodeDataContainer &node_data_container, |                          const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                          const std::vector<util::Coordinate> &node_coordinates, |                          const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |                          const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                          const RestrictionMap &node_restriction_map, | ||||||
|  |                          const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                          const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                          const IntersectionGenerator &intersection_generator, |                          const IntersectionGenerator &intersection_generator, | ||||||
|                          const CoordinateExtractor &coordinate_extractor, |                          const CoordinateExtractor &coordinate_extractor, | ||||||
|                          const util::NameTable &name_table, |                          const util::NameTable &name_table, | ||||||
| @ -159,6 +167,10 @@ class MergableRoadDetector | |||||||
|     const util::NodeBasedDynamicGraph &node_based_graph; |     const util::NodeBasedDynamicGraph &node_based_graph; | ||||||
|     const EdgeBasedNodeDataContainer &node_data_container; |     const EdgeBasedNodeDataContainer &node_data_container; | ||||||
|     const std::vector<util::Coordinate> &node_coordinates; |     const std::vector<util::Coordinate> &node_coordinates; | ||||||
|  |     const extractor::CompressedEdgeContainer &compressed_geometries; | ||||||
|  |     const RestrictionMap &node_restriction_map; | ||||||
|  |     const std::unordered_set<NodeID> &barrier_nodes; | ||||||
|  |     const guidance::TurnLanesIndexedArray &turn_lanes_data; | ||||||
|     const IntersectionGenerator &intersection_generator; |     const IntersectionGenerator &intersection_generator; | ||||||
|     const CoordinateExtractor &coordinate_extractor; |     const CoordinateExtractor &coordinate_extractor; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -26,6 +26,10 @@ class MotorwayHandler : public IntersectionHandler | |||||||
|     MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph, |     MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                     const EdgeBasedNodeDataContainer &node_data_container, |                     const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                     const std::vector<util::Coordinate> &coordinates, |                     const std::vector<util::Coordinate> &coordinates, | ||||||
|  |                     const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                     const RestrictionMap &node_restriction_map, | ||||||
|  |                     const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                     const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                     const util::NameTable &name_table, |                     const util::NameTable &name_table, | ||||||
|                     const SuffixTable &street_name_suffix_table, |                     const SuffixTable &street_name_suffix_table, | ||||||
|                     const IntersectionGenerator &intersection_generator); |                     const IntersectionGenerator &intersection_generator); | ||||||
|  | |||||||
| @ -2,7 +2,9 @@ | |||||||
| #define OSRM_EXTRACTOR_GUIDANCE_NODE_BASED_GRAPH_WALKER | #define OSRM_EXTRACTOR_GUIDANCE_NODE_BASED_GRAPH_WALKER | ||||||
| 
 | 
 | ||||||
| #include "extractor/guidance/constants.hpp" | #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.hpp" | ||||||
| #include "util/coordinate_calculation.hpp" | #include "util/coordinate_calculation.hpp" | ||||||
| #include "util/node_based_graph.hpp" | #include "util/node_based_graph.hpp" | ||||||
| @ -29,7 +31,11 @@ class NodeBasedGraphWalker | |||||||
|   public: |   public: | ||||||
|     NodeBasedGraphWalker(const util::NodeBasedDynamicGraph &node_based_graph, |     NodeBasedGraphWalker(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                          const EdgeBasedNodeDataContainer &node_data_container, |                          const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                          const IntersectionGenerator &intersection_generator); |                          const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |                          const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                          const RestrictionMap &node_restriction_map, | ||||||
|  |                          const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                          const guidance::TurnLanesIndexedArray &turn_lanes_data); | ||||||
| 
 | 
 | ||||||
|     /*
 |     /*
 | ||||||
|      * the returned node-id, edge-id are either the last ones used, just prior accumulator |      * the returned node-id, edge-id are either the last ones used, just prior accumulator | ||||||
| @ -48,7 +54,11 @@ class NodeBasedGraphWalker | |||||||
|   private: |   private: | ||||||
|     const util::NodeBasedDynamicGraph &node_based_graph; |     const util::NodeBasedDynamicGraph &node_based_graph; | ||||||
|     const EdgeBasedNodeDataContainer &node_data_container; |     const EdgeBasedNodeDataContainer &node_data_container; | ||||||
|     const IntersectionGenerator &intersection_generator; |     const std::vector<util::Coordinate> &node_coordinates; | ||||||
|  |     const extractor::CompressedEdgeContainer &compressed_geometries; | ||||||
|  |     const RestrictionMap &node_restriction_map; | ||||||
|  |     const std::unordered_set<NodeID> &barrier_nodes; | ||||||
|  |     const guidance::TurnLanesIndexedArray &turn_lanes_data; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
| @ -149,7 +159,13 @@ struct SelectStraightmostRoadByNameAndOnlyChoice | |||||||
| struct IntersectionFinderAccumulator | struct IntersectionFinderAccumulator | ||||||
| { | { | ||||||
|     IntersectionFinderAccumulator(const std::uint8_t hop_limit, |     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<util::Coordinate> &node_coordinates, | ||||||
|  |                                   const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                                   const RestrictionMap &node_restriction_map, | ||||||
|  |                                   const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                                   const guidance::TurnLanesIndexedArray &turn_lanes_data); | ||||||
|     // true if the path has traversed enough distance
 |     // true if the path has traversed enough distance
 | ||||||
|     bool terminate(); |     bool terminate(); | ||||||
| 
 | 
 | ||||||
| @ -159,13 +175,19 @@ struct IntersectionFinderAccumulator | |||||||
|     std::uint8_t hops; |     std::uint8_t hops; | ||||||
|     const std::uint8_t hop_limit; |     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
 |     // the result we are looking for
 | ||||||
|     NodeID nid; |     NodeID nid; | ||||||
|     EdgeID via_edge_id; |     EdgeID via_edge_id; | ||||||
|     IntersectionView intersection; |     IntersectionView intersection; | ||||||
|  | 
 | ||||||
|  |   private: | ||||||
|  |     const util::NodeBasedDynamicGraph &node_based_graph; | ||||||
|  |     const EdgeBasedNodeDataContainer &node_data_container; | ||||||
|  |     const std::vector<util::Coordinate> &node_coordinates; | ||||||
|  |     const extractor::CompressedEdgeContainer &compressed_geometries; | ||||||
|  |     const RestrictionMap &node_restriction_map; | ||||||
|  |     const std::unordered_set<NodeID> &barrier_nodes; | ||||||
|  |     const guidance::TurnLanesIndexedArray &turn_lanes_data; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template <class accumulator_type, class selector_type> | template <class accumulator_type, class selector_type> | ||||||
| @ -199,9 +221,15 @@ NodeBasedGraphWalker::TraverseRoad(NodeID current_node_id, | |||||||
|             return {}; |             return {}; | ||||||
| 
 | 
 | ||||||
|         // look at the next intersection
 |         // look at the next intersection
 | ||||||
|         const constexpr auto LOW_PRECISION = true; |         const auto next_intersection = | ||||||
|         const auto next_intersection = intersection_generator.GetConnectedRoads( |             intersection::getConnectedRoads(node_based_graph, | ||||||
|             current_node_id, current_edge_id, LOW_PRECISION); |                                             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
 |         // don't follow u-turns or go past our initial intersection
 | ||||||
|         if (next_intersection.size() <= 1) |         if (next_intersection.size() <= 1) | ||||||
|  | |||||||
| @ -42,7 +42,10 @@ class RoundaboutHandler : public IntersectionHandler | |||||||
|     RoundaboutHandler(const util::NodeBasedDynamicGraph &node_based_graph, |     RoundaboutHandler(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                       const EdgeBasedNodeDataContainer &node_data_container, |                       const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                       const std::vector<util::Coordinate> &coordinates, |                       const std::vector<util::Coordinate> &coordinates, | ||||||
|                       const CompressedEdgeContainer &compressed_edge_container, |                       const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                       const RestrictionMap &node_restriction_map, | ||||||
|  |                       const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                       const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                       const util::NameTable &name_table, |                       const util::NameTable &name_table, | ||||||
|                       const SuffixTable &street_name_suffix_table, |                       const SuffixTable &street_name_suffix_table, | ||||||
|                       const IntersectionGenerator &intersection_generator); |                       const IntersectionGenerator &intersection_generator); | ||||||
| @ -80,7 +83,6 @@ class RoundaboutHandler : public IntersectionHandler | |||||||
|     bool |     bool | ||||||
|     qualifiesAsRoundaboutIntersection(const std::unordered_set<NodeID> &roundabout_nodes) const; |     qualifiesAsRoundaboutIntersection(const std::unordered_set<NodeID> &roundabout_nodes) const; | ||||||
| 
 | 
 | ||||||
|     const CompressedEdgeContainer &compressed_edge_container; |  | ||||||
|     const CoordinateExtractor coordinate_extractor; |     const CoordinateExtractor coordinate_extractor; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -28,6 +28,10 @@ class SliproadHandler final : public IntersectionHandler | |||||||
|                     const util::NodeBasedDynamicGraph &node_based_graph, |                     const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                     const EdgeBasedNodeDataContainer &node_data_container, |                     const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                     const std::vector<util::Coordinate> &coordinates, |                     const std::vector<util::Coordinate> &coordinates, | ||||||
|  |                     const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                     const RestrictionMap &node_restriction_map, | ||||||
|  |                     const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                     const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                     const util::NameTable &name_table, |                     const util::NameTable &name_table, | ||||||
|                     const SuffixTable &street_name_suffix_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`.
 |     // The return value is guaranteed to not be larger than `threshold`.
 | ||||||
|     static double scaledThresholdByRoadClass(const double max_threshold, |     static double scaledThresholdByRoadClass(const double max_threshold, | ||||||
|                                              const RoadClassification &classification); |                                              const RoadClassification &classification); | ||||||
|  | 
 | ||||||
|  |     const CoordinateExtractor coordinate_extractor; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace guidance
 | } // namespace guidance
 | ||||||
|  | |||||||
| @ -31,11 +31,19 @@ class StatisticsHandler final : public IntersectionHandler | |||||||
|                       const util::NodeBasedDynamicGraph &node_based_graph, |                       const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                       const EdgeBasedNodeDataContainer &node_data_container, |                       const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                       const std::vector<util::Coordinate> &coordinates, |                       const std::vector<util::Coordinate> &coordinates, | ||||||
|  |                       const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                       const RestrictionMap &node_restriction_map, | ||||||
|  |                       const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                       const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                       const util::NameTable &name_table, |                       const util::NameTable &name_table, | ||||||
|                       const SuffixTable &street_name_suffix_table) |                       const SuffixTable &street_name_suffix_table) | ||||||
|         : IntersectionHandler(node_based_graph, |         : IntersectionHandler(node_based_graph, | ||||||
|                               node_data_container, |                               node_data_container, | ||||||
|                               coordinates, |                               coordinates, | ||||||
|  |                               compressed_geometries, | ||||||
|  |                               node_restriction_map, | ||||||
|  |                               barrier_nodes, | ||||||
|  |                               turn_lanes_data, | ||||||
|                               name_table, |                               name_table, | ||||||
|                               street_name_suffix_table, |                               street_name_suffix_table, | ||||||
|                               intersection_generator) |                               intersection_generator) | ||||||
|  | |||||||
| @ -25,6 +25,10 @@ class SuppressModeHandler final : public IntersectionHandler | |||||||
|                         const util::NodeBasedDynamicGraph &node_based_graph, |                         const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                         const EdgeBasedNodeDataContainer &node_data_container, |                         const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                         const std::vector<util::Coordinate> &coordinates, |                         const std::vector<util::Coordinate> &coordinates, | ||||||
|  |                         const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                         const RestrictionMap &node_restriction_map, | ||||||
|  |                         const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                         const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                         const util::NameTable &name_table, |                         const util::NameTable &name_table, | ||||||
|                         const SuffixTable &street_name_suffix_table); |                         const SuffixTable &street_name_suffix_table); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -42,10 +42,11 @@ class TurnAnalysis | |||||||
|   public: |   public: | ||||||
|     TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph, |     TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                  const EdgeBasedNodeDataContainer &node_data_container, |                  const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                  const std::vector<util::Coordinate> &coordinates, |                  const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |                  const CompressedEdgeContainer &compressed_edge_container, | ||||||
|                  const RestrictionMap &restriction_map, |                  const RestrictionMap &restriction_map, | ||||||
|                  const std::unordered_set<NodeID> &barrier_nodes, |                  const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|                  const CompressedEdgeContainer &compressed_edge_container, |                  const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                  const util::NameTable &name_table, |                  const util::NameTable &name_table, | ||||||
|                  const SuffixTable &street_name_suffix_table); |                  const SuffixTable &street_name_suffix_table); | ||||||
| 
 | 
 | ||||||
| @ -61,8 +62,6 @@ class TurnAnalysis | |||||||
|                                  const EdgeID via_eid, |                                  const EdgeID via_eid, | ||||||
|                                  const IntersectionView &intersection) const; |                                  const IntersectionView &intersection) const; | ||||||
| 
 | 
 | ||||||
|     const IntersectionGenerator &GetIntersectionGenerator() const; |  | ||||||
| 
 |  | ||||||
|   private: |   private: | ||||||
|     const util::NodeBasedDynamicGraph &node_based_graph; |     const util::NodeBasedDynamicGraph &node_based_graph; | ||||||
|     const IntersectionGenerator intersection_generator; |     const IntersectionGenerator intersection_generator; | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| 
 | 
 | ||||||
| #include "extractor/guidance/intersection.hpp" | #include "extractor/guidance/intersection.hpp" | ||||||
| #include "extractor/guidance/intersection_generator.hpp" | #include "extractor/guidance/intersection_generator.hpp" | ||||||
|  | #include "extractor/guidance/turn_lane_data.hpp" | ||||||
| #include "util/typedefs.hpp" | #include "util/typedefs.hpp" | ||||||
| 
 | 
 | ||||||
| namespace osrm | namespace osrm | ||||||
| @ -21,8 +22,13 @@ bool findPreviousIntersection( | |||||||
|     const NodeID node, |     const NodeID node, | ||||||
|     const EdgeID via_edge, |     const EdgeID via_edge, | ||||||
|     const Intersection &intersection, |     const Intersection &intersection, | ||||||
|     const IntersectionGenerator &intersection_generator, |  | ||||||
|     const util::NodeBasedDynamicGraph &node_based_graph, // query edge data
 |     const util::NodeBasedDynamicGraph &node_based_graph, // query edge data
 | ||||||
|  |     const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|  |     const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |     const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |     const RestrictionMap &node_restriction_map, | ||||||
|  |     const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |     const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|     // output parameters, will be in an arbitrary state on failure
 |     // output parameters, will be in an arbitrary state on failure
 | ||||||
|     NodeID &result_node, |     NodeID &result_node, | ||||||
|     EdgeID &result_via_edge, |     EdgeID &result_via_edge, | ||||||
|  | |||||||
| @ -30,6 +30,10 @@ class TurnHandler : public IntersectionHandler | |||||||
|     TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph, |     TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                 const EdgeBasedNodeDataContainer &node_data_container, |                 const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                 const std::vector<util::Coordinate> &coordinates, |                 const std::vector<util::Coordinate> &coordinates, | ||||||
|  |                 const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                 const RestrictionMap &node_restriction_map, | ||||||
|  |                 const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                 const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                 const util::NameTable &name_table, |                 const util::NameTable &name_table, | ||||||
|                 const SuffixTable &street_name_suffix_table, |                 const SuffixTable &street_name_suffix_table, | ||||||
|                 const IntersectionGenerator &intersection_generator); |                 const IntersectionGenerator &intersection_generator); | ||||||
|  | |||||||
| @ -74,6 +74,11 @@ class TurnLaneHandler | |||||||
| 
 | 
 | ||||||
|     TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph, |     TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                     const EdgeBasedNodeDataContainer &node_data_container, |                     const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|  |                     const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |                     const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                     const RestrictionMap &node_restriction_map, | ||||||
|  |                     const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                     const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                     LaneDescriptionMap &lane_description_map, |                     LaneDescriptionMap &lane_description_map, | ||||||
|                     const TurnAnalysis &turn_analysis, |                     const TurnAnalysis &turn_analysis, | ||||||
|                     util::guidance::LaneDataIdMap &id_map); |                     util::guidance::LaneDataIdMap &id_map); | ||||||
| @ -90,6 +95,12 @@ class TurnLaneHandler | |||||||
|     // lanes for a turn
 |     // lanes for a turn
 | ||||||
|     const util::NodeBasedDynamicGraph &node_based_graph; |     const util::NodeBasedDynamicGraph &node_based_graph; | ||||||
|     const EdgeBasedNodeDataContainer &node_data_container; |     const EdgeBasedNodeDataContainer &node_data_container; | ||||||
|  |     const std::vector<util::Coordinate> &node_coordinates; | ||||||
|  |     const extractor::CompressedEdgeContainer &compressed_geometries; | ||||||
|  |     const RestrictionMap &node_restriction_map; | ||||||
|  |     const std::unordered_set<NodeID> &barrier_nodes; | ||||||
|  |     const guidance::TurnLanesIndexedArray &turn_lanes_data; | ||||||
|  | 
 | ||||||
|     std::vector<std::uint32_t> turn_lane_offsets; |     std::vector<std::uint32_t> turn_lane_offsets; | ||||||
|     std::vector<TurnLaneType::Mask> turn_lane_masks; |     std::vector<TurnLaneType::Mask> turn_lane_masks; | ||||||
|     LaneDescriptionMap &lane_description_map; |     LaneDescriptionMap &lane_description_map; | ||||||
|  | |||||||
| @ -26,6 +26,19 @@ IntersectionEdges getIncomingEdges(const util::NodeBasedDynamicGraph &graph, | |||||||
| IntersectionEdges getOutgoingEdges(const util::NodeBasedDynamicGraph &graph, | IntersectionEdges getOutgoingEdges(const util::NodeBasedDynamicGraph &graph, | ||||||
|                                    const NodeID intersection); |                                    const NodeID intersection); | ||||||
| 
 | 
 | ||||||
|  | bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph, | ||||||
|  |                    const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|  |                    const RestrictionMap &restriction_map, | ||||||
|  |                    const std::unordered_set<NodeID> &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<IntersectionEdgeGeometries, std::unordered_set<EdgeID>> | std::pair<IntersectionEdgeGeometries, std::unordered_set<EdgeID>> | ||||||
| getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph, | getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph, | ||||||
|                           const extractor::CompressedEdgeContainer &compressed_geometries, |                           const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
| @ -44,18 +57,15 @@ convertToIntersectionView(const util::NodeBasedDynamicGraph &graph, | |||||||
|                           const IntersectionEdges &outgoing_edges, |                           const IntersectionEdges &outgoing_edges, | ||||||
|                           const std::unordered_set<EdgeID> &merged_edges); |                           const std::unordered_set<EdgeID> &merged_edges); | ||||||
| 
 | 
 | ||||||
| bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph, | guidance::IntersectionView | ||||||
|                    const EdgeBasedNodeDataContainer &node_data_container, | getConnectedRoads(const util::NodeBasedDynamicGraph &graph, | ||||||
|                    const RestrictionMap &restriction_map, |                   const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                    const std::unordered_set<NodeID> &barrier_nodes, |                   const std::vector<util::Coordinate> &node_coordinates, | ||||||
|                    const IntersectionEdgeGeometries &geometries, |                   const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|                    const guidance::TurnLanesIndexedArray &turn_lanes_data, |                   const RestrictionMap &node_restriction_map, | ||||||
|                    const IntersectionEdge &from, |                   const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|                    const IntersectionEdge &to); |                   const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
| 
 |                   const IntersectionEdge &incoming_edge); | ||||||
| double findEdgeBearing(const IntersectionEdgeGeometries &geometries, const EdgeID &edge); |  | ||||||
| 
 |  | ||||||
| double findEdgeLength(const IntersectionEdgeGeometries &geometries, const EdgeID &edge); |  | ||||||
| } | } | ||||||
| } | } | ||||||
| } | } | ||||||
|  | |||||||
| @ -423,42 +423,57 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( | |||||||
| 
 | 
 | ||||||
|     TurnDataExternalContainer turn_data_container; |     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.
 |     // Loop over all turns and generate new set of edges.
 | ||||||
|     // Three nested loop look super-linear, but we are dealing with a (kind of)
 |     // Three nested loop look super-linear, but we are dealing with a (kind of)
 | ||||||
|     // linear number of turns only.
 |     // linear number of turns only.
 | ||||||
|     SuffixTable street_name_suffix_table(scripting_environment); |  | ||||||
|     guidance::TurnAnalysis turn_analysis(m_node_based_graph, |     guidance::TurnAnalysis turn_analysis(m_node_based_graph, | ||||||
|                                          m_edge_based_node_container, |                                          m_edge_based_node_container, | ||||||
|                                          m_coordinates, |                                          m_coordinates, | ||||||
|  |                                          m_compressed_edge_container, | ||||||
|                                          node_restriction_map, |                                          node_restriction_map, | ||||||
|                                          m_barrier_nodes, |                                          m_barrier_nodes, | ||||||
|                                          m_compressed_edge_container, |                                          turn_lanes_data, | ||||||
|                                          name_table, |                                          name_table, | ||||||
|                                          street_name_suffix_table); |                                          street_name_suffix_table); | ||||||
| 
 | 
 | ||||||
|     util::guidance::LaneDataIdMap lane_data_map; |     util::guidance::LaneDataIdMap lane_data_map; | ||||||
|     guidance::lanes::TurnLaneHandler turn_lane_handler(m_node_based_graph, |     guidance::lanes::TurnLaneHandler turn_lane_handler(m_node_based_graph, | ||||||
|                                                        m_edge_based_node_container, |                                                        m_edge_based_node_container, | ||||||
|  |                                                        m_coordinates, | ||||||
|  |                                                        m_compressed_edge_container, | ||||||
|  |                                                        node_restriction_map, | ||||||
|  |                                                        m_barrier_nodes, | ||||||
|  |                                                        turn_lanes_data, | ||||||
|                                                        lane_description_map, |                                                        lane_description_map, | ||||||
|                                                        turn_analysis, |                                                        turn_analysis, | ||||||
|                                                        lane_data_map); |                                                        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(), |     bearing_class_by_node_based_node.resize(m_node_based_graph.GetNumberOfNodes(), | ||||||
|                                             std::numeric_limits<std::uint32_t>::max()); |                                             std::numeric_limits<std::uint32_t>::max()); | ||||||
| 
 | 
 | ||||||
|     const auto &turn_lanes_data = transformTurnLaneMapIntoArrays(lane_description_map); |  | ||||||
| 
 |  | ||||||
|     // FIXME these need to be tuned in pre-allocated size
 |     // FIXME these need to be tuned in pre-allocated size
 | ||||||
|     std::vector<TurnPenalty> turn_weight_penalties; |     std::vector<TurnPenalty> turn_weight_penalties; | ||||||
|     std::vector<TurnPenalty> turn_duration_penalties; |     std::vector<TurnPenalty> turn_duration_penalties; | ||||||
|  | |||||||
| @ -15,12 +15,20 @@ namespace guidance | |||||||
| DrivewayHandler::DrivewayHandler(const IntersectionGenerator &intersection_generator, | DrivewayHandler::DrivewayHandler(const IntersectionGenerator &intersection_generator, | ||||||
|                                  const util::NodeBasedDynamicGraph &node_based_graph, |                                  const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                                  const EdgeBasedNodeDataContainer &node_data_container, |                                  const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                                  const std::vector<util::Coordinate> &coordinates, |                                  const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |                                  const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                                  const RestrictionMap &node_restriction_map, | ||||||
|  |                                  const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                                  const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                                  const util::NameTable &name_table, |                                  const util::NameTable &name_table, | ||||||
|                                  const SuffixTable &street_name_suffix_table) |                                  const SuffixTable &street_name_suffix_table) | ||||||
|     : IntersectionHandler(node_based_graph, |     : IntersectionHandler(node_based_graph, | ||||||
|                           node_data_container, |                           node_data_container, | ||||||
|                           coordinates, |                           node_coordinates, | ||||||
|  |                           compressed_geometries, | ||||||
|  |                           node_restriction_map, | ||||||
|  |                           barrier_nodes, | ||||||
|  |                           turn_lanes_data, | ||||||
|                           name_table, |                           name_table, | ||||||
|                           street_name_suffix_table, |                           street_name_suffix_table, | ||||||
|                           intersection_generator) |                           intersection_generator) | ||||||
| @ -64,12 +72,12 @@ operator()(const NodeID nid, const EdgeID source_edge_id, Intersection intersect | |||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|     (void)nid; |     (void)nid; | ||||||
|     OSRM_ASSERT(road != intersection.end(), coordinates[nid]); |     OSRM_ASSERT(road != intersection.end(), node_coordinates[nid]); | ||||||
| 
 | 
 | ||||||
|     if (road->instruction == TurnInstruction::INVALID()) |     if (road->instruction == TurnInstruction::INVALID()) | ||||||
|         return intersection; |         return intersection; | ||||||
| 
 | 
 | ||||||
|     OSRM_ASSERT(road->instruction.type == TurnType::Turn, coordinates[nid]); |     OSRM_ASSERT(road->instruction.type == TurnType::Turn, node_coordinates[nid]); | ||||||
| 
 | 
 | ||||||
|     road->instruction.type = |     road->instruction.type = | ||||||
|         isSameName(source_edge_id, road->eid) ? TurnType::NoTurn : TurnType::NewName; |         isSameName(source_edge_id, road->eid) ? TurnType::NoTurn : TurnType::NewName; | ||||||
|  | |||||||
| @ -31,214 +31,17 @@ const constexpr bool USE_LOW_PRECISION_MODE = true; | |||||||
| const constexpr bool USE_HIGH_PRECISION_MODE = !USE_LOW_PRECISION_MODE; | const constexpr bool USE_HIGH_PRECISION_MODE = !USE_LOW_PRECISION_MODE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| IntersectionGenerator::IntersectionGenerator( | IntersectionGenerator::IntersectionGenerator(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|     const util::NodeBasedDynamicGraph &node_based_graph, |                                              const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|     const EdgeBasedNodeDataContainer &node_data_container, |                                              const RestrictionMap &restriction_map, | ||||||
|     const RestrictionMap &restriction_map, |                                              const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|     const std::unordered_set<NodeID> &barrier_nodes, |                                              const std::vector<util::Coordinate> &coordinates, | ||||||
|     const std::vector<util::Coordinate> &coordinates, |                                              const CompressedEdgeContainer &) | ||||||
|     const CompressedEdgeContainer &compressed_edge_container) |  | ||||||
|     : node_based_graph(node_based_graph), node_data_container(node_data_container), |     : node_based_graph(node_based_graph), node_data_container(node_data_container), | ||||||
|       restriction_map(restriction_map), barrier_nodes(barrier_nodes), coordinates(coordinates), |       restriction_map(restriction_map), barrier_nodes(barrier_nodes), coordinates(coordinates) | ||||||
|       coordinate_extractor(node_based_graph, compressed_edge_container, 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<NodeID> 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<RoadWithInitialBearing> 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 | IntersectionGenerationParameters | ||||||
| IntersectionGenerator::SkipDegreeTwoNodes(const NodeID starting_node, const EdgeID via_edge) const | 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}; |     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<IntersectionNormalizationOperation> &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<NodeID> { |  | ||||||
|         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<double>::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 guidance
 | ||||||
| } // namespace extractor
 | } // namespace extractor
 | ||||||
| } // namespace osrm
 | } // namespace osrm
 | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| #include "extractor/guidance/intersection_handler.hpp" | #include "extractor/guidance/intersection_handler.hpp" | ||||||
| #include "extractor/guidance/constants.hpp" | #include "extractor/guidance/constants.hpp" | ||||||
|  | #include "extractor/intersection/intersection_analysis.hpp" | ||||||
| 
 | 
 | ||||||
| #include "util/coordinate_calculation.hpp" | #include "util/coordinate_calculation.hpp" | ||||||
| #include "util/guidance/name_announcements.hpp" | #include "util/guidance/name_announcements.hpp" | ||||||
| @ -45,17 +46,29 @@ inline bool requiresAnnouncement(const util::NodeBasedDynamicGraph &node_based_g | |||||||
| } | } | ||||||
| } // namespace detail
 | } // namespace detail
 | ||||||
| 
 | 
 | ||||||
| IntersectionHandler::IntersectionHandler(const util::NodeBasedDynamicGraph &node_based_graph, | IntersectionHandler::IntersectionHandler( | ||||||
|                                          const EdgeBasedNodeDataContainer &node_data_container, |     const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                                          const std::vector<util::Coordinate> &coordinates, |     const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                                          const util::NameTable &name_table, |     const std::vector<util::Coordinate> &node_coordinates, | ||||||
|                                          const SuffixTable &street_name_suffix_table, |     const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|                                          const IntersectionGenerator &intersection_generator) |     const RestrictionMap &node_restriction_map, | ||||||
|  |     const std::unordered_set<NodeID> &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), |     : 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), |       street_name_suffix_table(street_name_suffix_table), | ||||||
|       intersection_generator(intersection_generator), |       intersection_generator(intersection_generator), graph_walker(node_based_graph, | ||||||
|       graph_walker(node_based_graph, node_data_container, intersection_generator) |                                                                    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
 |                     // or actually follow the full road. When 2399 lands, we can exchange here for a
 | ||||||
|                     // precalculated distance value.
 |                     // precalculated distance value.
 | ||||||
|                     const auto distance = util::coordinate_calculation::haversineDistance( |                     const auto distance = util::coordinate_calculation::haversineDistance( | ||||||
|                         coordinates[node_based_graph.GetTarget(via_edge)], |                         node_coordinates[node_based_graph.GetTarget(via_edge)], | ||||||
|                         coordinates[node_based_graph.GetTarget(road.eid)]); |                         node_coordinates[node_based_graph.GetTarget(road.eid)]); | ||||||
| 
 | 
 | ||||||
|                     return {TurnType::Turn, |                     return {TurnType::Turn, | ||||||
|                             (angularDeviation(road.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE && |                             (angularDeviation(road.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE && | ||||||
| @ -470,8 +483,15 @@ IntersectionHandler::getNextIntersection(const NodeID at, const EdgeID via) cons | |||||||
|         return boost::none; |         return boost::none; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto intersection = |     auto intersection = intersection::getConnectedRoads( | ||||||
|         intersection_generator(intersection_parameters.nid, intersection_parameters.via_eid); |         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); |     auto intersection_node = node_based_graph.GetTarget(intersection_parameters.via_eid); | ||||||
| 
 | 
 | ||||||
|     if (intersection.size() <= 2 || intersection.isTrafficSignalOrBarrier()) |     if (intersection.size() <= 2 || intersection.isTrafficSignalOrBarrier()) | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| #include "extractor/guidance/coordinate_extractor.hpp" | #include "extractor/guidance/coordinate_extractor.hpp" | ||||||
| #include "extractor/guidance/intersection_generator.hpp" | #include "extractor/guidance/intersection_generator.hpp" | ||||||
| #include "extractor/guidance/node_based_graph_walker.hpp" | #include "extractor/guidance/node_based_graph_walker.hpp" | ||||||
|  | #include "extractor/intersection/intersection_analysis.hpp" | ||||||
| #include "extractor/query_node.hpp" | #include "extractor/query_node.hpp" | ||||||
| #include "extractor/suffix_table.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, | MergableRoadDetector::MergableRoadDetector( | ||||||
|                                            const EdgeBasedNodeDataContainer &node_data_container, |     const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                                            const std::vector<util::Coordinate> &node_coordinates, |     const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                                            const IntersectionGenerator &intersection_generator, |     const std::vector<util::Coordinate> &node_coordinates, | ||||||
|                                            const CoordinateExtractor &coordinate_extractor, |     const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|                                            const util::NameTable &name_table, |     const RestrictionMap &node_restriction_map, | ||||||
|                                            const SuffixTable &street_name_suffix_table) |     const std::unordered_set<NodeID> &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_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), |       coordinate_extractor(coordinate_extractor), name_table(name_table), | ||||||
|       street_name_suffix_table(street_name_suffix_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
 |     // selection data to the right and left
 | ||||||
|     const auto constexpr SMALL_RANDOM_HOPLIMIT = 5; |     const auto constexpr SMALL_RANDOM_HOPLIMIT = 5; | ||||||
|     IntersectionFinderAccumulator left_accumulator(SMALL_RANDOM_HOPLIMIT, intersection_generator), |     IntersectionFinderAccumulator left_accumulator(SMALL_RANDOM_HOPLIMIT, | ||||||
|         right_accumulator(SMALL_RANDOM_HOPLIMIT, intersection_generator); |                                                    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
 |     /* Standard following the straightmost road
 | ||||||
|      * Since both items have the same id, we can `select` based on any setup |      * 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, |         /*requires entry=*/false, | ||||||
|         false); |         false); | ||||||
| 
 | 
 | ||||||
|     NodeBasedGraphWalker graph_walker( |     NodeBasedGraphWalker graph_walker(node_based_graph, | ||||||
|         node_based_graph, node_data_container, intersection_generator); |                                       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); |     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
 |     /* if the intersection does not have a right turn, we continue onto the next one once
 | ||||||
|      * (skipping over a single small side street) |      * (skipping over a single small side street) | ||||||
| @ -266,7 +293,13 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node, | |||||||
| 
 | 
 | ||||||
|     // check if both intersections are connected
 |     // check if both intersections are connected
 | ||||||
|     IntersectionFinderAccumulator connect_accumulator(SMALL_RANDOM_HOPLIMIT, |     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), |     graph_walker.TraverseRoad(node_based_graph.GetTarget(left_accumulator.via_edge_id), | ||||||
|                               connector_turn->eid, |                               connector_turn->eid, | ||||||
|                               connect_accumulator, |                               connect_accumulator, | ||||||
| @ -281,8 +314,13 @@ bool MergableRoadDetector::IsCircularShape(const NodeID intersection_node, | |||||||
|                                            const MergableRoadData &lhs, |                                            const MergableRoadData &lhs, | ||||||
|                                            const MergableRoadData &rhs) const |                                            const MergableRoadData &rhs) const | ||||||
| { | { | ||||||
|     NodeBasedGraphWalker graph_walker( |     NodeBasedGraphWalker graph_walker(node_based_graph, | ||||||
|         node_based_graph, node_data_container, intersection_generator); |                                       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) { |     const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length) { | ||||||
|         LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length); |         LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length); | ||||||
|         SelectStraightmostRoadByNameAndOnlyChoice selector( |         SelectStraightmostRoadByNameAndOnlyChoice selector( | ||||||
| @ -348,8 +386,13 @@ bool MergableRoadDetector::HaveSameDirection(const NodeID intersection_node, | |||||||
|         return false; |         return false; | ||||||
| 
 | 
 | ||||||
|     // Find a coordinate following a road that is far away
 |     // Find a coordinate following a road that is far away
 | ||||||
|     NodeBasedGraphWalker graph_walker( |     NodeBasedGraphWalker graph_walker(node_based_graph, | ||||||
|         node_based_graph, node_data_container, intersection_generator); |                                       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) { |     const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length) { | ||||||
|         LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length); |         LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length); | ||||||
|         SelectStraightmostRoadByNameAndOnlyChoice selector( |         SelectStraightmostRoadByNameAndOnlyChoice selector( | ||||||
| @ -517,8 +560,15 @@ bool MergableRoadDetector::IsLinkRoad(const NodeID intersection_node, | |||||||
| { | { | ||||||
|     const auto next_intersection_parameters = |     const auto next_intersection_parameters = | ||||||
|         intersection_generator.SkipDegreeTwoNodes(intersection_node, road.eid); |         intersection_generator.SkipDegreeTwoNodes(intersection_node, road.eid); | ||||||
|     const auto next_intersection_along_road = intersection_generator.GetConnectedRoads( |     const auto next_intersection_along_road = intersection::getConnectedRoads( | ||||||
|         next_intersection_parameters.nid, next_intersection_parameters.via_eid); |         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) { |     const auto extract_name_id = [this](const MergableRoadData &road) { | ||||||
|         return node_data_container |         return node_data_container | ||||||
|             .GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data) |             .GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data) | ||||||
|  | |||||||
| @ -42,12 +42,20 @@ inline bool isRampClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_base | |||||||
| MotorwayHandler::MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph, | MotorwayHandler::MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                                  const EdgeBasedNodeDataContainer &node_data_container, |                                  const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                                  const std::vector<util::Coordinate> &coordinates, |                                  const std::vector<util::Coordinate> &coordinates, | ||||||
|  |                                  const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                                  const RestrictionMap &node_restriction_map, | ||||||
|  |                                  const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                                  const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                                  const util::NameTable &name_table, |                                  const util::NameTable &name_table, | ||||||
|                                  const SuffixTable &street_name_suffix_table, |                                  const SuffixTable &street_name_suffix_table, | ||||||
|                                  const IntersectionGenerator &intersection_generator) |                                  const IntersectionGenerator &intersection_generator) | ||||||
|     : IntersectionHandler(node_based_graph, |     : IntersectionHandler(node_based_graph, | ||||||
|                           node_data_container, |                           node_data_container, | ||||||
|                           coordinates, |                           coordinates, | ||||||
|  |                           compressed_geometries, | ||||||
|  |                           node_restriction_map, | ||||||
|  |                           barrier_nodes, | ||||||
|  |                           turn_lanes_data, | ||||||
|                           name_table, |                           name_table, | ||||||
|                           street_name_suffix_table, |                           street_name_suffix_table, | ||||||
|                           intersection_generator) |                           intersection_generator) | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| #include "extractor/guidance/node_based_graph_walker.hpp" | #include "extractor/guidance/node_based_graph_walker.hpp" | ||||||
|  | #include "extractor/intersection/intersection_analysis.hpp" | ||||||
| #include "util/bearing.hpp" | #include "util/bearing.hpp" | ||||||
| #include "util/coordinate_calculation.hpp" | #include "util/coordinate_calculation.hpp" | ||||||
| 
 | 
 | ||||||
| @ -14,11 +15,18 @@ namespace guidance | |||||||
| { | { | ||||||
| 
 | 
 | ||||||
| // ---------------------------------------------------------------------------------
 | // ---------------------------------------------------------------------------------
 | ||||||
| NodeBasedGraphWalker::NodeBasedGraphWalker(const util::NodeBasedDynamicGraph &node_based_graph, | NodeBasedGraphWalker::NodeBasedGraphWalker( | ||||||
|                                            const EdgeBasedNodeDataContainer &node_data_container, |     const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                                            const IntersectionGenerator &intersection_generator) |     const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|  |     const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |     const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |     const RestrictionMap &node_restriction_map, | ||||||
|  |     const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |     const guidance::TurnLanesIndexedArray &turn_lanes_data) | ||||||
|     : node_based_graph(node_based_graph), node_data_container(node_data_container), |     : 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( | IntersectionFinderAccumulator::IntersectionFinderAccumulator( | ||||||
|     const std::uint8_t hop_limit, const IntersectionGenerator &intersection_generator) |     const std::uint8_t hop_limit, | ||||||
|     : hops(0), hop_limit(hop_limit), intersection_generator(intersection_generator) |     const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|  |     const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|  |     const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |     const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |     const RestrictionMap &node_restriction_map, | ||||||
|  |     const std::unordered_set<NodeID> &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; |     nid = from_node; | ||||||
|     via_edge_id = via_edge; |     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
 | } // namespace guidance
 | ||||||
|  | |||||||
| @ -23,21 +23,28 @@ namespace extractor | |||||||
| namespace guidance | namespace guidance | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| RoundaboutHandler::RoundaboutHandler(const util::NodeBasedDynamicGraph &node_based_graph, | RoundaboutHandler::RoundaboutHandler( | ||||||
|                                      const EdgeBasedNodeDataContainer &node_data_container, |     const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                                      const std::vector<util::Coordinate> &coordinates, |     const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                                      const CompressedEdgeContainer &compressed_edge_container, |     const std::vector<util::Coordinate> &coordinates, | ||||||
|                                      const util::NameTable &name_table, |     const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|                                      const SuffixTable &street_name_suffix_table, |     const RestrictionMap &node_restriction_map, | ||||||
|                                      const IntersectionGenerator &intersection_generator) |     const std::unordered_set<NodeID> &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, |     : IntersectionHandler(node_based_graph, | ||||||
|                           node_data_container, |                           node_data_container, | ||||||
|                           coordinates, |                           coordinates, | ||||||
|  |                           compressed_geometries, | ||||||
|  |                           node_restriction_map, | ||||||
|  |                           barrier_nodes, | ||||||
|  |                           turn_lanes_data, | ||||||
|                           name_table, |                           name_table, | ||||||
|                           street_name_suffix_table, |                           street_name_suffix_table, | ||||||
|                           intersection_generator), |                           intersection_generator), | ||||||
|       compressed_edge_container(compressed_edge_container), |       coordinate_extractor(node_based_graph, compressed_geometries, coordinates) | ||||||
|       coordinate_extractor(node_based_graph, compressed_edge_container, coordinates) |  | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -143,7 +150,7 @@ bool RoundaboutHandler::qualifiesAsRoundaboutIntersection( | |||||||
|                     continue; |                     continue; | ||||||
| 
 | 
 | ||||||
|                 // there is a single non-roundabout edge
 |                 // 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 edge_range = node_based_graph.GetAdjacentEdgeRange(node); | ||||||
|                 const auto number_of_lanes_at_intersection = std::accumulate( |                 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) { |     const auto getEdgeLength = [&](const NodeID source_node, EdgeID eid) { | ||||||
|         double length = 0.; |         double length = 0.; | ||||||
|         auto last_coord = coordinates[source_node]; |         auto last_coord = node_coordinates[source_node]; | ||||||
|         const auto &edge_bucket = compressed_edge_container.GetBucketReference(eid); |         const auto &edge_bucket = compressed_geometries.GetBucketReference(eid); | ||||||
|         for (const auto &compressed_edge : edge_bucket) |         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); |             length += util::coordinate_calculation::haversineDistance(last_coord, next_coord); | ||||||
|             last_coord = next_coord; |             last_coord = next_coord; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -25,15 +25,24 @@ namespace guidance | |||||||
| SliproadHandler::SliproadHandler(const IntersectionGenerator &intersection_generator, | SliproadHandler::SliproadHandler(const IntersectionGenerator &intersection_generator, | ||||||
|                                  const util::NodeBasedDynamicGraph &node_based_graph, |                                  const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                                  const EdgeBasedNodeDataContainer &node_data_container, |                                  const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                                  const std::vector<util::Coordinate> &coordinates, |                                  const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |                                  const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                                  const RestrictionMap &node_restriction_map, | ||||||
|  |                                  const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                                  const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                                  const util::NameTable &name_table, |                                  const util::NameTable &name_table, | ||||||
|                                  const SuffixTable &street_name_suffix_table) |                                  const SuffixTable &street_name_suffix_table) | ||||||
|     : IntersectionHandler(node_based_graph, |     : IntersectionHandler(node_based_graph, | ||||||
|                           node_data_container, |                           node_data_container, | ||||||
|                           coordinates, |                           node_coordinates, | ||||||
|  |                           compressed_geometries, | ||||||
|  |                           node_restriction_map, | ||||||
|  |                           barrier_nodes, | ||||||
|  |                           turn_lanes_data, | ||||||
|                           name_table, |                           name_table, | ||||||
|                           street_name_suffix_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
 |         // 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.
 |         // 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{}; |         const SkipTrafficSignalBarrierRoadSelector road_selector{}; | ||||||
|         (void)graph_walker.TraverseRoad(intersection_node_id, // start node
 |         (void)graph_walker.TraverseRoad(intersection_node_id, // start node
 | ||||||
|                                         sliproad_edge,        // onto edge
 |                                         sliproad_edge,        // onto edge
 | ||||||
| @ -372,8 +388,6 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter | |||||||
|         //
 |         //
 | ||||||
|         //                    Sliproad           Not a Sliproad
 |         //                    Sliproad           Not a Sliproad
 | ||||||
|         { |         { | ||||||
|             const auto &coordinate_extractor = intersection_generator.GetCoordinateExtractor(); |  | ||||||
| 
 |  | ||||||
|             const NodeID start = intersection_node_id; // b
 |             const NodeID start = intersection_node_id; // b
 | ||||||
|             const EdgeID edge = sliproad_edge;         // bd
 |             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.
 |             // Only check for curvature and ~90 degree when it makes sense to do so.
 | ||||||
|             const constexpr auto MIN_LENGTH = 3.; |             const constexpr auto MIN_LENGTH = 3.; | ||||||
| 
 | 
 | ||||||
|             const auto length = haversineDistance(coordinates[intersection_node_id], |             const auto length = haversineDistance(node_coordinates[intersection_node_id], | ||||||
|                                                   coordinates[main_road_intersection->node]); |                                                   node_coordinates[main_road_intersection->node]); | ||||||
| 
 | 
 | ||||||
|             const double minimal_crossroad_angle_of_intersection = 40.; |             const double minimal_crossroad_angle_of_intersection = 40.; | ||||||
| 
 | 
 | ||||||
| @ -546,8 +560,15 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter | |||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 const auto skip_traffic_light_intersection = intersection_generator( |                 const auto skip_traffic_light_intersection = intersection::getConnectedRoads( | ||||||
|                     node_based_graph.GetTarget(sliproad_edge), candidate_road.eid); |                     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() && |                 if (skip_traffic_light_intersection.isTrafficSignalOrBarrier() && | ||||||
|                     node_based_graph.GetTarget(skip_traffic_light_intersection[1].eid) == |                     node_based_graph.GetTarget(skip_traffic_light_intersection[1].eid) == | ||||||
|                         main_road_intersection->node) |                         main_road_intersection->node) | ||||||
| @ -656,8 +677,6 @@ bool SliproadHandler::nextIntersectionIsTooFarAway(const NodeID start, const Edg | |||||||
|     BOOST_ASSERT(start != SPECIAL_NODEID); |     BOOST_ASSERT(start != SPECIAL_NODEID); | ||||||
|     BOOST_ASSERT(onto != SPECIAL_EDGEID); |     BOOST_ASSERT(onto != SPECIAL_EDGEID); | ||||||
| 
 | 
 | ||||||
|     const auto &coordinate_extractor = intersection_generator.GetCoordinateExtractor(); |  | ||||||
| 
 |  | ||||||
|     // Base max distance threshold on the current road class we're on
 |     // Base max distance threshold on the current road class we're on
 | ||||||
|     const auto &data = node_based_graph.GetEdgeData(onto).flags; |     const auto &data = node_based_graph.GetEdgeData(onto).flags; | ||||||
|     const auto threshold = scaledThresholdByRoadClass(MAX_SLIPROAD_THRESHOLD, // <- scales down
 |     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; |     using namespace util::coordinate_calculation; | ||||||
| 
 | 
 | ||||||
|     const auto first = coordinates[a]; |     const auto first = node_coordinates[a]; | ||||||
|     const auto second = coordinates[b]; |     const auto second = node_coordinates[b]; | ||||||
|     const auto third = coordinates[c]; |     const auto third = node_coordinates[c]; | ||||||
| 
 | 
 | ||||||
|     const auto length = haversineDistance(first, second); |     const auto length = haversineDistance(first, second); | ||||||
|     const auto heigth = haversineDistance(second, third); |     const auto heigth = haversineDistance(second, third); | ||||||
|  | |||||||
| @ -11,15 +11,24 @@ namespace extractor | |||||||
| namespace guidance | namespace guidance | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| SuppressModeHandler::SuppressModeHandler(const IntersectionGenerator &intersection_generator, | SuppressModeHandler::SuppressModeHandler( | ||||||
|                                          const util::NodeBasedDynamicGraph &node_based_graph, |     const IntersectionGenerator &intersection_generator, | ||||||
|                                          const EdgeBasedNodeDataContainer &node_data_container, |     const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                                          const std::vector<util::Coordinate> &coordinates, |     const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                                          const util::NameTable &name_table, |     const std::vector<util::Coordinate> &coordinates, | ||||||
|                                          const SuffixTable &street_name_suffix_table) |     const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |     const RestrictionMap &node_restriction_map, | ||||||
|  |     const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |     const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|  |     const util::NameTable &name_table, | ||||||
|  |     const SuffixTable &street_name_suffix_table) | ||||||
|     : IntersectionHandler(node_based_graph, |     : IntersectionHandler(node_based_graph, | ||||||
|                           node_data_container, |                           node_data_container, | ||||||
|                           coordinates, |                           coordinates, | ||||||
|  |                           compressed_geometries, | ||||||
|  |                           node_restriction_map, | ||||||
|  |                           barrier_nodes, | ||||||
|  |                           turn_lanes_data, | ||||||
|                           name_table, |                           name_table, | ||||||
|                           street_name_suffix_table, |                           street_name_suffix_table, | ||||||
|                           intersection_generator) |                           intersection_generator) | ||||||
|  | |||||||
| @ -23,60 +23,87 @@ using EdgeData = util::NodeBasedDynamicGraph::EdgeData; | |||||||
| 
 | 
 | ||||||
| TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph, | TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                            const EdgeBasedNodeDataContainer &node_data_container, |                            const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                            const std::vector<util::Coordinate> &coordinates, |                            const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |                            const CompressedEdgeContainer &compressed_edge_container, | ||||||
|                            const RestrictionMap &restriction_map, |                            const RestrictionMap &restriction_map, | ||||||
|                            const std::unordered_set<NodeID> &barrier_nodes, |                            const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|                            const CompressedEdgeContainer &compressed_edge_container, |                            const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                            const util::NameTable &name_table, |                            const util::NameTable &name_table, | ||||||
|                            const SuffixTable &street_name_suffix_table) |                            const SuffixTable &street_name_suffix_table) | ||||||
|     : node_based_graph(node_based_graph), intersection_generator(node_based_graph, |     : node_based_graph(node_based_graph), intersection_generator(node_based_graph, | ||||||
|                                                                  node_data_container, |                                                                  node_data_container, | ||||||
|                                                                  restriction_map, |                                                                  restriction_map, | ||||||
|                                                                  barrier_nodes, |                                                                  barrier_nodes, | ||||||
|                                                                  coordinates, |                                                                  node_coordinates, | ||||||
|                                                                  compressed_edge_container), |                                                                  compressed_edge_container), | ||||||
|       roundabout_handler(node_based_graph, |       roundabout_handler(node_based_graph, | ||||||
|                          node_data_container, |                          node_data_container, | ||||||
|                          coordinates, |                          node_coordinates, | ||||||
|                          compressed_edge_container, |                          compressed_edge_container, | ||||||
|  |                          restriction_map, | ||||||
|  |                          barrier_nodes, | ||||||
|  |                          turn_lanes_data, | ||||||
|                          name_table, |                          name_table, | ||||||
|                          street_name_suffix_table, |                          street_name_suffix_table, | ||||||
|                          intersection_generator), |                          intersection_generator), | ||||||
|       motorway_handler(node_based_graph, |       motorway_handler(node_based_graph, | ||||||
|                        node_data_container, |                        node_data_container, | ||||||
| 
 |                        node_coordinates, | ||||||
|                        coordinates, |                        compressed_edge_container, | ||||||
|  |                        restriction_map, | ||||||
|  |                        barrier_nodes, | ||||||
|  |                        turn_lanes_data, | ||||||
|                        name_table, |                        name_table, | ||||||
|                        street_name_suffix_table, |                        street_name_suffix_table, | ||||||
|                        intersection_generator), |                        intersection_generator), | ||||||
|       turn_handler(node_based_graph, |       turn_handler(node_based_graph, | ||||||
|                    node_data_container, |                    node_data_container, | ||||||
|                    coordinates, |                    node_coordinates, | ||||||
|  |                    compressed_edge_container, | ||||||
|  |                    restriction_map, | ||||||
|  |                    barrier_nodes, | ||||||
|  |                    turn_lanes_data, | ||||||
|                    name_table, |                    name_table, | ||||||
|                    street_name_suffix_table, |                    street_name_suffix_table, | ||||||
|                    intersection_generator), |                    intersection_generator), | ||||||
|       sliproad_handler(intersection_generator, |       sliproad_handler(intersection_generator, | ||||||
|                        node_based_graph, |                        node_based_graph, | ||||||
|                        node_data_container, |                        node_data_container, | ||||||
|                        coordinates, |                        node_coordinates, | ||||||
|  |                        compressed_edge_container, | ||||||
|  |                        restriction_map, | ||||||
|  |                        barrier_nodes, | ||||||
|  |                        turn_lanes_data, | ||||||
|                        name_table, |                        name_table, | ||||||
|                        street_name_suffix_table), |                        street_name_suffix_table), | ||||||
|       suppress_mode_handler(intersection_generator, |       suppress_mode_handler(intersection_generator, | ||||||
|                             node_based_graph, |                             node_based_graph, | ||||||
|                             node_data_container, |                             node_data_container, | ||||||
|                             coordinates, |                             node_coordinates, | ||||||
|  |                             compressed_edge_container, | ||||||
|  |                             restriction_map, | ||||||
|  |                             barrier_nodes, | ||||||
|  |                             turn_lanes_data, | ||||||
|                             name_table, |                             name_table, | ||||||
|                             street_name_suffix_table), |                             street_name_suffix_table), | ||||||
|       driveway_handler(intersection_generator, |       driveway_handler(intersection_generator, | ||||||
|                        node_based_graph, |                        node_based_graph, | ||||||
|                        node_data_container, |                        node_data_container, | ||||||
|                        coordinates, |                        node_coordinates, | ||||||
|  |                        compressed_edge_container, | ||||||
|  |                        restriction_map, | ||||||
|  |                        barrier_nodes, | ||||||
|  |                        turn_lanes_data, | ||||||
|                        name_table, |                        name_table, | ||||||
|                        street_name_suffix_table), |                        street_name_suffix_table), | ||||||
|       statistics_handler(intersection_generator, |       statistics_handler(intersection_generator, | ||||||
|                          node_based_graph, |                          node_based_graph, | ||||||
|                          node_data_container, |                          node_data_container, | ||||||
|                          coordinates, |                          node_coordinates, | ||||||
|  |                          compressed_edge_container, | ||||||
|  |                          restriction_map, | ||||||
|  |                          barrier_nodes, | ||||||
|  |                          turn_lanes_data, | ||||||
|                          name_table, |                          name_table, | ||||||
|                          street_name_suffix_table) |                          street_name_suffix_table) | ||||||
| { | { | ||||||
| @ -188,11 +215,6 @@ Intersection TurnAnalysis::setTurnTypes(const NodeID node_prior_to_intersection, | |||||||
|     return intersection; |     return intersection; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const IntersectionGenerator &TurnAnalysis::GetIntersectionGenerator() const |  | ||||||
| { |  | ||||||
|     return intersection_generator; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| } // namespace guidance
 | } // namespace guidance
 | ||||||
| } // namespace extractor
 | } // namespace extractor
 | ||||||
| } // namespace osrm
 | } // namespace osrm
 | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| #include "extractor/guidance/turn_discovery.hpp" | #include "extractor/guidance/turn_discovery.hpp" | ||||||
| #include "extractor/guidance/constants.hpp" | #include "extractor/guidance/constants.hpp" | ||||||
|  | #include "extractor/intersection/intersection_analysis.hpp" | ||||||
| #include "util/bearing.hpp" | #include "util/bearing.hpp" | ||||||
| #include "util/coordinate_calculation.hpp" | #include "util/coordinate_calculation.hpp" | ||||||
| 
 | 
 | ||||||
| @ -14,16 +15,16 @@ namespace guidance | |||||||
| namespace lanes | namespace lanes | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| namespace |  | ||||||
| { |  | ||||||
| const constexpr bool USE_LOW_PRECISION_MODE = true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool findPreviousIntersection(const NodeID node_v, | bool findPreviousIntersection(const NodeID node_v, | ||||||
|                               const EdgeID via_edge, |                               const EdgeID via_edge, | ||||||
|                               const Intersection &intersection, |                               const Intersection &intersection, | ||||||
|                               const IntersectionGenerator &intersection_generator, |  | ||||||
|                               const util::NodeBasedDynamicGraph &node_based_graph, |                               const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|  |                               const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|  |                               const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |                               const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                               const RestrictionMap &node_restriction_map, | ||||||
|  |                               const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                               const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                               // output parameters
 |                               // output parameters
 | ||||||
|                               NodeID &result_node, |                               NodeID &result_node, | ||||||
|                               EdgeID &result_via_edge, |                               EdgeID &result_via_edge, | ||||||
| @ -43,7 +44,9 @@ bool findPreviousIntersection(const NodeID node_v, | |||||||
|      */ |      */ | ||||||
|     const constexpr double COMBINE_DISTANCE_CUTOFF = 30; |     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 = |     const auto coordinates_along_via_edge = | ||||||
|         coordinate_extractor.GetForwardCoordinatesAlongRoad(node_v, via_edge); |         coordinate_extractor.GetForwardCoordinatesAlongRoad(node_v, via_edge); | ||||||
|     const auto via_edge_length = |     const auto via_edge_length = | ||||||
| @ -71,7 +74,14 @@ bool findPreviousIntersection(const NodeID node_v, | |||||||
|         return false; |         return false; | ||||||
| 
 | 
 | ||||||
|     const auto node_v_reverse_intersection = |     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
 |     // Continue along the straightmost turn. If there is no straight turn, we cannot find a valid
 | ||||||
|     // previous intersection.
 |     // previous intersection.
 | ||||||
|     const auto straightmost_at_v_in_reverse = |     const auto straightmost_at_v_in_reverse = | ||||||
| @ -83,8 +93,15 @@ bool findPreviousIntersection(const NodeID node_v, | |||||||
|         return false; |         return false; | ||||||
| 
 | 
 | ||||||
|     const auto node_u = node_based_graph.GetTarget(straightmost_at_v_in_reverse->eid); |     const auto node_u = node_based_graph.GetTarget(straightmost_at_v_in_reverse->eid); | ||||||
|     const auto node_u_reverse_intersection = intersection_generator.GetConnectedRoads( |     const auto node_u_reverse_intersection = | ||||||
|         node_v, straightmost_at_v_in_reverse->eid, 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_v, straightmost_at_v_in_reverse->eid}); | ||||||
| 
 | 
 | ||||||
|     // now check that the u-turn at the given intersection connects to via-edge
 |     // 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.
 |     // 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; |         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 = |     const auto check_via_edge = | ||||||
|         result_intersection.end() != |         result_intersection.end() != | ||||||
|         std::find_if(result_intersection.begin(), |         std::find_if(result_intersection.begin(), | ||||||
|  | |||||||
| @ -113,12 +113,20 @@ std::size_t TurnHandler::Fork::getLeftIndex() const | |||||||
| TurnHandler::TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph, | TurnHandler::TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                          const EdgeBasedNodeDataContainer &node_data_container, |                          const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|                          const std::vector<util::Coordinate> &coordinates, |                          const std::vector<util::Coordinate> &coordinates, | ||||||
|  |                          const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                          const RestrictionMap &node_restriction_map, | ||||||
|  |                          const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                          const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                          const util::NameTable &name_table, |                          const util::NameTable &name_table, | ||||||
|                          const SuffixTable &street_name_suffix_table, |                          const SuffixTable &street_name_suffix_table, | ||||||
|                          const IntersectionGenerator &intersection_generator) |                          const IntersectionGenerator &intersection_generator) | ||||||
|     : IntersectionHandler(node_based_graph, |     : IntersectionHandler(node_based_graph, | ||||||
|                           node_data_container, |                           node_data_container, | ||||||
|                           coordinates, |                           coordinates, | ||||||
|  |                           compressed_geometries, | ||||||
|  |                           node_restriction_map, | ||||||
|  |                           barrier_nodes, | ||||||
|  |                           turn_lanes_data, | ||||||
|                           name_table, |                           name_table, | ||||||
|                           street_name_suffix_table, |                           street_name_suffix_table, | ||||||
|                           intersection_generator) |                           intersection_generator) | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| #include "extractor/guidance/turn_discovery.hpp" | #include "extractor/guidance/turn_discovery.hpp" | ||||||
| #include "extractor/guidance/turn_lane_augmentation.hpp" | #include "extractor/guidance/turn_lane_augmentation.hpp" | ||||||
| #include "extractor/guidance/turn_lane_matcher.hpp" | #include "extractor/guidance/turn_lane_matcher.hpp" | ||||||
|  | #include "extractor/intersection/intersection_analysis.hpp" | ||||||
| #include "util/bearing.hpp" | #include "util/bearing.hpp" | ||||||
| #include "util/log.hpp" | #include "util/log.hpp" | ||||||
| #include "util/typedefs.hpp" | #include "util/typedefs.hpp" | ||||||
| @ -35,14 +36,21 @@ std::size_t getNumberOfTurns(const Intersection &intersection) | |||||||
| 
 | 
 | ||||||
| TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph, | TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph, | ||||||
|                                  const EdgeBasedNodeDataContainer &node_data_container, |                                  const EdgeBasedNodeDataContainer &node_data_container, | ||||||
|  |                                  const std::vector<util::Coordinate> &node_coordinates, | ||||||
|  |                                  const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                                  const RestrictionMap &node_restriction_map, | ||||||
|  |                                  const std::unordered_set<NodeID> &barrier_nodes, | ||||||
|  |                                  const guidance::TurnLanesIndexedArray &turn_lanes_data, | ||||||
|                                  LaneDescriptionMap &lane_description_map, |                                  LaneDescriptionMap &lane_description_map, | ||||||
|                                  const TurnAnalysis &turn_analysis, |                                  const TurnAnalysis &turn_analysis, | ||||||
|                                  util::guidance::LaneDataIdMap &id_map) |                                  util::guidance::LaneDataIdMap &id_map) | ||||||
|     : node_based_graph(node_based_graph), node_data_container(node_data_container), |     : 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) = |     std::tie(turn_lane_offsets, turn_lane_masks) = turn_lanes_data; | ||||||
|         transformTurnLaneMapIntoArrays(lane_description_map); |  | ||||||
|     count_handled = count_called = 0; |     count_handled = count_called = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -205,8 +213,13 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at, | |||||||
|     if (findPreviousIntersection(at, |     if (findPreviousIntersection(at, | ||||||
|                                  via_edge, |                                  via_edge, | ||||||
|                                  intersection, |                                  intersection, | ||||||
|                                  turn_analysis.GetIntersectionGenerator(), |  | ||||||
|                                  node_based_graph, |                                  node_based_graph, | ||||||
|  |                                  node_data_container, | ||||||
|  |                                  node_coordinates, | ||||||
|  |                                  compressed_geometries, | ||||||
|  |                                  node_restriction_map, | ||||||
|  |                                  barrier_nodes, | ||||||
|  |                                  turn_lanes_data, | ||||||
|                                  previous_node, |                                  previous_node, | ||||||
|                                  previous_via_edge, |                                  previous_via_edge, | ||||||
|                                  previous_intersection_view)) |                                  previous_intersection_view)) | ||||||
| @ -559,8 +572,17 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData( | |||||||
| 
 | 
 | ||||||
|     // find out about the next intersection. To check for valid matches, we also need the turn
 |     // find out about the next intersection. To check for valid matches, we also need the turn
 | ||||||
|     // types. We can skip merging/angle adjustments, though
 |     // types. We can skip merging/angle adjustments, though
 | ||||||
|     const auto next_intersection = turn_analysis.AssignTurnTypes( |     const auto next_intersection = | ||||||
|         at, straightmost->eid, turn_analysis.GetIntersectionGenerator()(at, straightmost->eid)); |         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
 |     // check where we can match turn lanes
 | ||||||
|     std::size_t straightmost_tag_index = turn_lane_data.size(); |     std::size_t straightmost_tag_index = turn_lane_data.size(); | ||||||
|  | |||||||
| @ -658,7 +658,7 @@ bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph, | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TODO: the function adapts intersection geometry data to TurnAnalysis
 | // The function adapts intersection geometry data to TurnAnalysis
 | ||||||
| guidance::IntersectionView | guidance::IntersectionView | ||||||
| convertToIntersectionView(const util::NodeBasedDynamicGraph &graph, | convertToIntersectionView(const util::NodeBasedDynamicGraph &graph, | ||||||
|                           const EdgeBasedNodeDataContainer &node_data_container, |                           const EdgeBasedNodeDataContainer &node_data_container, | ||||||
| @ -727,6 +727,62 @@ convertToIntersectionView(const util::NodeBasedDynamicGraph &graph, | |||||||
| 
 | 
 | ||||||
|     return intersection_view; |     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<util::Coordinate> &node_coordinates, | ||||||
|  |                   const extractor::CompressedEdgeContainer &compressed_geometries, | ||||||
|  |                   const RestrictionMap &node_restriction_map, | ||||||
|  |                   const std::unordered_set<NodeID> &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<EdgeID>()); | ||||||
|  | } | ||||||
| } | } | ||||||
| } | } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user