diff --git a/CHANGELOG.md b/CHANGELOG.md index b23daf6f895..8d444e2054e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ # UNRELEASED + - Changes from 5.14 + - Internals + - Guidance refactoring step to decouple intersection connectivity analysis and turn instructions generation # 5.14.1 - Changes from 5.14.0 diff --git a/include/extractor/geojson_debug_policies.hpp b/include/extractor/geojson_debug_policies.hpp index 4ba1f447491..693214e0d92 100644 --- a/include/extractor/geojson_debug_policies.hpp +++ b/include/extractor/geojson_debug_policies.hpp @@ -60,7 +60,7 @@ operator()(const NodeID intersection_node, const boost::optional &way_style) const { // request the number of lanes. This process needs to be in sync with what happens over at - // intersection_generator + // intersection analysis const auto intersection_lanes = intersection.FindMaximum(guidance::makeExtractLanesForRoad(node_based_graph)); diff --git a/include/extractor/guidance/driveway_handler.hpp b/include/extractor/guidance/driveway_handler.hpp index ec434cc212c..be43e7bc89c 100644 --- a/include/extractor/guidance/driveway_handler.hpp +++ b/include/extractor/guidance/driveway_handler.hpp @@ -14,8 +14,7 @@ namespace guidance class DrivewayHandler final : public IntersectionHandler { public: - DrivewayHandler(const IntersectionGenerator &intersection_generator, - const util::NodeBasedDynamicGraph &node_based_graph, + DrivewayHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, const extractor::CompressedEdgeContainer &compressed_geometries, diff --git a/include/extractor/guidance/intersection_generator.hpp b/include/extractor/guidance/intersection_generator.hpp deleted file mode 100644 index 039302876dd..00000000000 --- a/include/extractor/guidance/intersection_generator.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_GENERATOR_HPP_ -#define OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_GENERATOR_HPP_ - -#include "extractor/compressed_edge_container.hpp" -#include "extractor/guidance/coordinate_extractor.hpp" -#include "extractor/guidance/intersection.hpp" -#include "extractor/guidance/intersection_normalization_operation.hpp" -#include "extractor/query_node.hpp" -#include "extractor/restriction_index.hpp" -#include "util/attributes.hpp" -#include "util/node_based_graph.hpp" -#include "util/typedefs.hpp" - -#include -#include -#include - -#include - -namespace osrm -{ -namespace extractor -{ -namespace guidance -{ - -struct IntersectionGenerationParameters -{ - NodeID nid; - EdgeID via_eid; -}; - -// The Intersection Generator is given a turn location and generates an intersection representation -// from it. For this all turn possibilities are analysed. -// We consider turn restrictions to indicate possible turns. U-turns are generated based on profile -// decisions. -class IntersectionGenerator -{ - public: - IntersectionGenerator(const util::NodeBasedDynamicGraph &node_based_graph, - const EdgeBasedNodeDataContainer &node_data_container, - const RestrictionMap &restriction_map, - const std::unordered_set &barrier_nodes, - const std::vector &coordinates, - const CompressedEdgeContainer &compressed_edge_container); - - // Graph Compression cannot compress every setting. For example any barrier/traffic light cannot - // be compressed. As a result, a simple road of the form `a ----- b` might end up as having an - // intermediate intersection, if there is a traffic light in between. If we want to look farther - // down a road, finding the next actual decision requires the look at multiple intersections. - // Here we follow the road until we either reach a dead end or find the next intersection with - // more than a single next road. This function skips over degree two nodes to find coorect input - // for GetConnectedRoads. - OSRM_ATTR_WARN_UNUSED - IntersectionGenerationParameters SkipDegreeTwoNodes(const NodeID starting_node, - const EdgeID via_edge) const; - - private: - const util::NodeBasedDynamicGraph &node_based_graph; - const EdgeBasedNodeDataContainer &node_data_container; - const RestrictionMap &restriction_map; - const std::unordered_set &barrier_nodes; - const std::vector &coordinates; -}; - -} // namespace guidance -} // namespace extractor -} // namespace osrm - -#endif /* OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_GENERATOR_HPP_ */ diff --git a/include/extractor/guidance/intersection_handler.hpp b/include/extractor/guidance/intersection_handler.hpp index 31e0326c539..6a91a205adc 100644 --- a/include/extractor/guidance/intersection_handler.hpp +++ b/include/extractor/guidance/intersection_handler.hpp @@ -2,7 +2,6 @@ #define OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_HANDLER_HPP_ #include "extractor/guidance/intersection.hpp" -#include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/node_based_graph_walker.hpp" #include "extractor/intersection/intersection_analysis.hpp" #include "extractor/query_node.hpp" @@ -41,8 +40,7 @@ class IntersectionHandler const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, - const SuffixTable &street_name_suffix_table, - const IntersectionGenerator &intersection_generator); + const SuffixTable &street_name_suffix_table); virtual ~IntersectionHandler() = default; @@ -64,7 +62,6 @@ class IntersectionHandler const guidance::TurnLanesIndexedArray &turn_lanes_data; const util::NameTable &name_table; const SuffixTable &street_name_suffix_table; - const IntersectionGenerator &intersection_generator; const NodeBasedGraphWalker graph_walker; // for skipping traffic signal, distances etc. // Decide on a basic turn types @@ -576,9 +573,9 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, // try to find whether there is a turn going to the opposite direction of our obvious // turn, this should be alright. const auto previous_intersection = [&]() -> IntersectionView { - const auto parameters = intersection_generator.SkipDegreeTwoNodes( - node_at_intersection, intersection[0].eid); - if (node_based_graph.GetTarget(parameters.via_eid) == node_at_intersection) + const auto parameters = intersection::skipDegreeTwoNodes( + node_based_graph, {node_at_intersection, intersection[0].eid}); + if (node_based_graph.GetTarget(parameters.edge) == node_at_intersection) return {}; return intersection::getConnectedRoads(node_based_graph, @@ -588,7 +585,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, node_restriction_map, barrier_nodes, turn_lanes_data, - {parameters.nid, parameters.via_eid}); + parameters); }(); if (!previous_intersection.empty()) diff --git a/include/extractor/guidance/intersection_normalization_operation.hpp b/include/extractor/guidance/intersection_normalization_operation.hpp deleted file mode 100644 index 57750d262e8..00000000000 --- a/include/extractor/guidance/intersection_normalization_operation.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_NORMALIZATION_OPERATION_HPP_ -#define OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_NORMALIZATION_OPERATION_HPP_ - -#include "util/typedefs.hpp" - -namespace osrm -{ -namespace extractor -{ -namespace guidance -{ - -struct IntersectionNormalizationOperation -{ - // the source of the merge, not part of the intersection after the merge is performed. - EdgeID merged_eid; - // the edge that is covering the `merged_eid` - EdgeID into_eid; -}; - -} // namespace guidance -} // namespace extractor -} // namespace osrm - -#endif /*OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_NORMALIZATION_OPERATION_HPP_*/ diff --git a/include/extractor/guidance/mergable_road_detector.hpp b/include/extractor/guidance/mergable_road_detector.hpp index f26c5acfd0b..524d192b359 100644 --- a/include/extractor/guidance/mergable_road_detector.hpp +++ b/include/extractor/guidance/mergable_road_detector.hpp @@ -47,7 +47,6 @@ class MergableRoadDetector const RestrictionMap &node_restriction_map, const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, - const IntersectionGenerator &intersection_generator, const CoordinateExtractor &coordinate_extractor, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table); @@ -171,7 +170,6 @@ class MergableRoadDetector const RestrictionMap &node_restriction_map; const std::unordered_set &barrier_nodes; const guidance::TurnLanesIndexedArray &turn_lanes_data; - const IntersectionGenerator &intersection_generator; const CoordinateExtractor &coordinate_extractor; // name detection diff --git a/include/extractor/guidance/motorway_handler.hpp b/include/extractor/guidance/motorway_handler.hpp index dcee8df55cc..edf62de2682 100644 --- a/include/extractor/guidance/motorway_handler.hpp +++ b/include/extractor/guidance/motorway_handler.hpp @@ -2,7 +2,6 @@ #define OSRM_EXTRACTOR_GUIDANCE_MOTORWAY_HANDLER_HPP_ #include "extractor/guidance/intersection.hpp" -#include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/intersection_handler.hpp" #include "extractor/query_node.hpp" @@ -31,8 +30,7 @@ class MotorwayHandler : public IntersectionHandler const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, - const SuffixTable &street_name_suffix_table, - const IntersectionGenerator &intersection_generator); + const SuffixTable &street_name_suffix_table); ~MotorwayHandler() override final = default; diff --git a/include/extractor/guidance/roundabout_handler.hpp b/include/extractor/guidance/roundabout_handler.hpp index a419b758047..b40c12fad4d 100644 --- a/include/extractor/guidance/roundabout_handler.hpp +++ b/include/extractor/guidance/roundabout_handler.hpp @@ -4,7 +4,6 @@ #include "extractor/compressed_edge_container.hpp" #include "extractor/guidance/coordinate_extractor.hpp" #include "extractor/guidance/intersection.hpp" -#include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/intersection_handler.hpp" #include "extractor/guidance/roundabout_type.hpp" #include "extractor/query_node.hpp" @@ -47,8 +46,7 @@ class RoundaboutHandler : public IntersectionHandler const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, - const SuffixTable &street_name_suffix_table, - const IntersectionGenerator &intersection_generator); + const SuffixTable &street_name_suffix_table); ~RoundaboutHandler() override final = default; diff --git a/include/extractor/guidance/sliproad_handler.hpp b/include/extractor/guidance/sliproad_handler.hpp index 5f8812a1124..8fb710b7b84 100644 --- a/include/extractor/guidance/sliproad_handler.hpp +++ b/include/extractor/guidance/sliproad_handler.hpp @@ -2,7 +2,6 @@ #define OSRM_EXTRACTOR_GUIDANCE_SLIPROAD_HANDLER_HPP_ #include "extractor/guidance/intersection.hpp" -#include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/intersection_handler.hpp" #include "extractor/query_node.hpp" @@ -24,8 +23,7 @@ namespace guidance class SliproadHandler final : public IntersectionHandler { public: - SliproadHandler(const IntersectionGenerator &intersection_generator, - const util::NodeBasedDynamicGraph &node_based_graph, + SliproadHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, const extractor::CompressedEdgeContainer &compressed_geometries, diff --git a/include/extractor/guidance/statistics_handler.hpp b/include/extractor/guidance/statistics_handler.hpp index bbfc944f6ec..735f53ad52b 100644 --- a/include/extractor/guidance/statistics_handler.hpp +++ b/include/extractor/guidance/statistics_handler.hpp @@ -27,8 +27,7 @@ namespace guidance class StatisticsHandler final : public IntersectionHandler { public: - StatisticsHandler(const IntersectionGenerator &intersection_generator, - const util::NodeBasedDynamicGraph &node_based_graph, + StatisticsHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, const extractor::CompressedEdgeContainer &compressed_geometries, @@ -45,8 +44,7 @@ class StatisticsHandler final : public IntersectionHandler barrier_nodes, turn_lanes_data, name_table, - street_name_suffix_table, - intersection_generator) + street_name_suffix_table) { } diff --git a/include/extractor/guidance/suppress_mode_handler.hpp b/include/extractor/guidance/suppress_mode_handler.hpp index b10993cbdbd..a99061c793c 100644 --- a/include/extractor/guidance/suppress_mode_handler.hpp +++ b/include/extractor/guidance/suppress_mode_handler.hpp @@ -3,7 +3,6 @@ #include "extractor/guidance/constants.hpp" #include "extractor/guidance/intersection.hpp" -#include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/intersection_handler.hpp" #include "extractor/travel_mode.hpp" #include "util/node_based_graph.hpp" @@ -21,8 +20,7 @@ namespace guidance class SuppressModeHandler final : public IntersectionHandler { public: - SuppressModeHandler(const IntersectionGenerator &intersection_generator, - const util::NodeBasedDynamicGraph &node_based_graph, + SuppressModeHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, const extractor::CompressedEdgeContainer &compressed_geometries, diff --git a/include/extractor/guidance/turn_analysis.hpp b/include/extractor/guidance/turn_analysis.hpp index aca49038ae2..e9c637cba18 100644 --- a/include/extractor/guidance/turn_analysis.hpp +++ b/include/extractor/guidance/turn_analysis.hpp @@ -4,8 +4,6 @@ #include "extractor/compressed_edge_container.hpp" #include "extractor/guidance/driveway_handler.hpp" #include "extractor/guidance/intersection.hpp" -#include "extractor/guidance/intersection_generator.hpp" -#include "extractor/guidance/intersection_normalization_operation.hpp" #include "extractor/guidance/motorway_handler.hpp" #include "extractor/guidance/roundabout_handler.hpp" #include "extractor/guidance/sliproad_handler.hpp" @@ -64,7 +62,6 @@ class TurnAnalysis private: const util::NodeBasedDynamicGraph &node_based_graph; - const IntersectionGenerator intersection_generator; const RoundaboutHandler roundabout_handler; const MotorwayHandler motorway_handler; const TurnHandler turn_handler; diff --git a/include/extractor/guidance/turn_discovery.hpp b/include/extractor/guidance/turn_discovery.hpp index e7588c19ad9..92cfe20c8a7 100644 --- a/include/extractor/guidance/turn_discovery.hpp +++ b/include/extractor/guidance/turn_discovery.hpp @@ -2,16 +2,27 @@ #define OSRM_EXTRACTOR_GUIDANCE_TURN_DISCOVERY_HPP_ #include "extractor/guidance/intersection.hpp" -#include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/turn_lane_data.hpp" +#include "extractor/restriction_index.hpp" #include "util/typedefs.hpp" +#include + namespace osrm { +namespace util +{ +class Coordinate; +} + namespace extractor { + +class CompressedEdgeContainer; + namespace guidance { + namespace lanes { diff --git a/include/extractor/guidance/turn_handler.hpp b/include/extractor/guidance/turn_handler.hpp index 42753373047..b8d5a227ee4 100644 --- a/include/extractor/guidance/turn_handler.hpp +++ b/include/extractor/guidance/turn_handler.hpp @@ -2,7 +2,6 @@ #define OSRM_EXTRACTOR_GUIDANCE_TURN_HANDLER_HPP_ #include "extractor/guidance/intersection.hpp" -#include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/intersection_handler.hpp" #include "extractor/query_node.hpp" @@ -35,8 +34,7 @@ class TurnHandler : public IntersectionHandler const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, - const SuffixTable &street_name_suffix_table, - const IntersectionGenerator &intersection_generator); + const SuffixTable &street_name_suffix_table); ~TurnHandler() override final = default; diff --git a/include/extractor/intersection/intersection_analysis.hpp b/include/extractor/intersection/intersection_analysis.hpp index 6552e7d385e..07503a52448 100644 --- a/include/extractor/intersection/intersection_analysis.hpp +++ b/include/extractor/intersection/intersection_analysis.hpp @@ -66,6 +66,9 @@ getConnectedRoads(const util::NodeBasedDynamicGraph &graph, const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, const IntersectionEdge &incoming_edge); + +IntersectionEdge skipDegreeTwoNodes(const util::NodeBasedDynamicGraph &graph, + IntersectionEdge road); } } } diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index bbe1326319d..af5f890d115 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -426,12 +426,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( 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, @@ -439,7 +433,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( node_restriction_map, m_barrier_nodes, turn_lanes_data, - intersection_generator, coordinate_extractor, name_table, street_name_suffix_table); diff --git a/src/extractor/guidance/driveway_handler.cpp b/src/extractor/guidance/driveway_handler.cpp index 6c455eb07ed..75d0642560f 100644 --- a/src/extractor/guidance/driveway_handler.cpp +++ b/src/extractor/guidance/driveway_handler.cpp @@ -12,8 +12,7 @@ namespace extractor namespace guidance { -DrivewayHandler::DrivewayHandler(const IntersectionGenerator &intersection_generator, - const util::NodeBasedDynamicGraph &node_based_graph, +DrivewayHandler::DrivewayHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &node_coordinates, const extractor::CompressedEdgeContainer &compressed_geometries, @@ -30,8 +29,7 @@ DrivewayHandler::DrivewayHandler(const IntersectionGenerator &intersection_gener barrier_nodes, turn_lanes_data, name_table, - street_name_suffix_table, - intersection_generator) + street_name_suffix_table) { } diff --git a/src/extractor/guidance/intersection_generator.cpp b/src/extractor/guidance/intersection_generator.cpp deleted file mode 100644 index 17a7e834160..00000000000 --- a/src/extractor/guidance/intersection_generator.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "extractor/guidance/intersection_generator.hpp" - -#include "extractor/geojson_debug_policies.hpp" - -#include "util/geojson_debug_logger.hpp" - -#include "util/assert.hpp" -#include "util/bearing.hpp" -#include "util/coordinate_calculation.hpp" -#include "util/log.hpp" - -#include -#include -#include // mem_fn -#include -#include -#include - -#include - -namespace osrm -{ -namespace extractor -{ -namespace guidance -{ -namespace -{ -const constexpr bool USE_LOW_PRECISION_MODE = true; -// the inverse of use low precision mode -const constexpr bool USE_HIGH_PRECISION_MODE = !USE_LOW_PRECISION_MODE; -} - -IntersectionGenerator::IntersectionGenerator(const util::NodeBasedDynamicGraph &node_based_graph, - const EdgeBasedNodeDataContainer &node_data_container, - const RestrictionMap &restriction_map, - const std::unordered_set &barrier_nodes, - const std::vector &coordinates, - const CompressedEdgeContainer &) - : node_based_graph(node_based_graph), node_data_container(node_data_container), - restriction_map(restriction_map), barrier_nodes(barrier_nodes), coordinates(coordinates) -{ -} - -IntersectionGenerationParameters -IntersectionGenerator::SkipDegreeTwoNodes(const NodeID starting_node, const EdgeID via_edge) const -{ - NodeID query_node = starting_node; - EdgeID query_edge = via_edge; - - const auto get_next_edge = [this](const NodeID from, const EdgeID via) { - const NodeID new_node = node_based_graph.GetTarget(via); - BOOST_ASSERT(node_based_graph.GetOutDegree(new_node) == 2); - const EdgeID begin_edges_new_node = node_based_graph.BeginEdges(new_node); - return (node_based_graph.GetTarget(begin_edges_new_node) == from) ? begin_edges_new_node + 1 - : begin_edges_new_node; - }; - - std::unordered_set visited_nodes; - // skip trivial nodes without generating the intersection in between, stop at the very first - // intersection of degree > 2 - while (0 == visited_nodes.count(query_node) && - 2 == node_based_graph.GetOutDegree(node_based_graph.GetTarget(query_edge))) - { - visited_nodes.insert(query_node); - const auto next_node = node_based_graph.GetTarget(query_edge); - const auto next_edge = get_next_edge(query_node, query_edge); - - query_node = next_node; - query_edge = next_edge; - - // check if there is a relevant change in the graph - if (!CanBeCompressed(node_based_graph.GetEdgeData(query_edge), - node_based_graph.GetEdgeData(next_edge), - node_data_container) || - (node_based_graph.GetTarget(next_edge) == starting_node)) - break; - } - - return {query_node, query_edge}; -} - -} // namespace guidance -} // namespace extractor -} // namespace osrm diff --git a/src/extractor/guidance/intersection_handler.cpp b/src/extractor/guidance/intersection_handler.cpp index 71b874a3534..a2dc5d41831 100644 --- a/src/extractor/guidance/intersection_handler.cpp +++ b/src/extractor/guidance/intersection_handler.cpp @@ -55,20 +55,18 @@ IntersectionHandler::IntersectionHandler( const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, - const SuffixTable &street_name_suffix_table, - const IntersectionGenerator &intersection_generator) + const SuffixTable &street_name_suffix_table) : node_based_graph(node_based_graph), node_data_container(node_data_container), node_coordinates(node_coordinates), compressed_geometries(compressed_geometries), node_restriction_map(node_restriction_map), barrier_nodes(barrier_nodes), turn_lanes_data(turn_lanes_data), name_table(name_table), - street_name_suffix_table(street_name_suffix_table), - intersection_generator(intersection_generator), graph_walker(node_based_graph, - node_data_container, - node_coordinates, - compressed_geometries, - node_restriction_map, - barrier_nodes, - turn_lanes_data) + street_name_suffix_table(street_name_suffix_table), graph_walker(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data) { } @@ -473,24 +471,24 @@ IntersectionHandler::getNextIntersection(const NodeID at, const EdgeID via) cons // Starting at node `a` via edge `e0` the intersection generator returns the intersection at `c` // writing `tl` (traffic signal) node and the edge `e1` which has the intersection as target. - const auto intersection_parameters = intersection_generator.SkipDegreeTwoNodes(at, via); + const auto intersection_parameters = + intersection::skipDegreeTwoNodes(node_based_graph, {at, via}); // This should never happen, guard against nevertheless - if (intersection_parameters.nid == SPECIAL_NODEID || - intersection_parameters.via_eid == SPECIAL_EDGEID) + if (intersection_parameters.node == SPECIAL_NODEID || + intersection_parameters.edge == SPECIAL_EDGEID) { return boost::none; } - auto intersection = intersection::getConnectedRoads( - node_based_graph, - node_data_container, - node_coordinates, - compressed_geometries, - node_restriction_map, - barrier_nodes, - turn_lanes_data, - {intersection_parameters.nid, intersection_parameters.via_eid}); - auto intersection_node = node_based_graph.GetTarget(intersection_parameters.via_eid); + auto intersection = intersection::getConnectedRoads(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, + intersection_parameters); + auto intersection_node = node_based_graph.GetTarget(intersection_parameters.edge); if (intersection.size() <= 2 || intersection.isTrafficSignalOrBarrier()) { diff --git a/src/extractor/guidance/mergable_road_detector.cpp b/src/extractor/guidance/mergable_road_detector.cpp index 5c2c705dd73..9c67a3f6d96 100644 --- a/src/extractor/guidance/mergable_road_detector.cpp +++ b/src/extractor/guidance/mergable_road_detector.cpp @@ -1,7 +1,6 @@ #include "extractor/guidance/mergable_road_detector.hpp" #include "extractor/guidance/constants.hpp" #include "extractor/guidance/coordinate_extractor.hpp" -#include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/node_based_graph_walker.hpp" #include "extractor/intersection/intersection_analysis.hpp" #include "extractor/query_node.hpp" @@ -56,16 +55,14 @@ MergableRoadDetector::MergableRoadDetector( const RestrictionMap &node_restriction_map, const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, - const IntersectionGenerator &intersection_generator, const CoordinateExtractor &coordinate_extractor, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table) : node_based_graph(node_based_graph), node_data_container(node_data_container), node_coordinates(node_coordinates), compressed_geometries(compressed_geometries), node_restriction_map(node_restriction_map), barrier_nodes(barrier_nodes), - turn_lanes_data(turn_lanes_data), intersection_generator(intersection_generator), - coordinate_extractor(coordinate_extractor), name_table(name_table), - street_name_suffix_table(street_name_suffix_table) + turn_lanes_data(turn_lanes_data), coordinate_extractor(coordinate_extractor), + name_table(name_table), street_name_suffix_table(street_name_suffix_table) { } @@ -173,8 +170,9 @@ bool MergableRoadDetector::EdgeDataSupportsMerge( bool MergableRoadDetector::IsTrafficLoop(const NodeID intersection_node, const MergableRoadData &road) const { - const auto connection = intersection_generator.SkipDegreeTwoNodes(intersection_node, road.eid); - return intersection_node == node_based_graph.GetTarget(connection.via_eid); + const auto connection = + intersection::skipDegreeTwoNodes(node_based_graph, {intersection_node, road.eid}); + return intersection_node == node_based_graph.GetTarget(connection.edge); } bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node, @@ -481,12 +479,12 @@ bool MergableRoadDetector::IsTrafficIsland(const NodeID intersection_node, * location with the same name repeatet at least three times */ const auto left_connection = - intersection_generator.SkipDegreeTwoNodes(intersection_node, lhs.eid); + intersection::skipDegreeTwoNodes(node_based_graph, {intersection_node, lhs.eid}); const auto right_connection = - intersection_generator.SkipDegreeTwoNodes(intersection_node, rhs.eid); + intersection::skipDegreeTwoNodes(node_based_graph, {intersection_node, rhs.eid}); - const auto left_candidate = node_based_graph.GetTarget(left_connection.via_eid); - const auto right_candidate = node_based_graph.GetTarget(right_connection.via_eid); + const auto left_candidate = node_based_graph.GetTarget(left_connection.edge); + const auto right_candidate = node_based_graph.GetTarget(right_connection.edge); const auto candidate_is_valid = left_candidate == right_candidate && left_candidate != intersection_node; @@ -552,16 +550,16 @@ bool MergableRoadDetector::IsLinkRoad(const NodeID intersection_node, const MergableRoadData &road) const { const auto next_intersection_parameters = - intersection_generator.SkipDegreeTwoNodes(intersection_node, road.eid); - const auto next_intersection_along_road = intersection::getConnectedRoads( - node_based_graph, - node_data_container, - node_coordinates, - compressed_geometries, - node_restriction_map, - barrier_nodes, - turn_lanes_data, - {next_intersection_parameters.nid, next_intersection_parameters.via_eid}); + intersection::skipDegreeTwoNodes(node_based_graph, {intersection_node, road.eid}); + const auto next_intersection_along_road = + intersection::getConnectedRoads(node_based_graph, + node_data_container, + node_coordinates, + compressed_geometries, + node_restriction_map, + barrier_nodes, + turn_lanes_data, + next_intersection_parameters); const auto extract_name_id = [this](const MergableRoadData &road) { return node_data_container .GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data) @@ -586,7 +584,7 @@ bool MergableRoadDetector::IsLinkRoad(const NodeID intersection_node, // we cannot be looking at the same road we came from if (node_based_graph.GetTarget(opposite_of_next_road_along_path->eid) == - next_intersection_parameters.nid) + next_intersection_parameters.node) return false; /* check if the opposite of the next road decision was sane. It could have been just as well our diff --git a/src/extractor/guidance/motorway_handler.cpp b/src/extractor/guidance/motorway_handler.cpp index 52aaa54afa9..39614ba2bd8 100644 --- a/src/extractor/guidance/motorway_handler.cpp +++ b/src/extractor/guidance/motorway_handler.cpp @@ -47,8 +47,7 @@ MotorwayHandler::MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_g const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, - const SuffixTable &street_name_suffix_table, - const IntersectionGenerator &intersection_generator) + const SuffixTable &street_name_suffix_table) : IntersectionHandler(node_based_graph, node_data_container, coordinates, @@ -57,8 +56,7 @@ MotorwayHandler::MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_g barrier_nodes, turn_lanes_data, name_table, - street_name_suffix_table, - intersection_generator) + street_name_suffix_table) { } diff --git a/src/extractor/guidance/roundabout_handler.cpp b/src/extractor/guidance/roundabout_handler.cpp index 7fd1d501a4f..bb8630e1db8 100644 --- a/src/extractor/guidance/roundabout_handler.cpp +++ b/src/extractor/guidance/roundabout_handler.cpp @@ -32,8 +32,7 @@ RoundaboutHandler::RoundaboutHandler( const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, - const SuffixTable &street_name_suffix_table, - const IntersectionGenerator &intersection_generator) + const SuffixTable &street_name_suffix_table) : IntersectionHandler(node_based_graph, node_data_container, coordinates, @@ -42,8 +41,7 @@ RoundaboutHandler::RoundaboutHandler( barrier_nodes, turn_lanes_data, name_table, - street_name_suffix_table, - intersection_generator), + street_name_suffix_table), coordinate_extractor(node_based_graph, compressed_geometries, coordinates) { } diff --git a/src/extractor/guidance/sliproad_handler.cpp b/src/extractor/guidance/sliproad_handler.cpp index 59620f26d96..6f656f9e5bb 100644 --- a/src/extractor/guidance/sliproad_handler.cpp +++ b/src/extractor/guidance/sliproad_handler.cpp @@ -21,8 +21,7 @@ namespace extractor namespace guidance { -SliproadHandler::SliproadHandler(const IntersectionGenerator &intersection_generator, - const util::NodeBasedDynamicGraph &node_based_graph, +SliproadHandler::SliproadHandler(const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &node_coordinates, const extractor::CompressedEdgeContainer &compressed_geometries, @@ -39,8 +38,7 @@ SliproadHandler::SliproadHandler(const IntersectionGenerator &intersection_gener barrier_nodes, turn_lanes_data, name_table, - street_name_suffix_table, - intersection_generator), + street_name_suffix_table), coordinate_extractor(node_based_graph, compressed_geometries, node_coordinates) { } diff --git a/src/extractor/guidance/suppress_mode_handler.cpp b/src/extractor/guidance/suppress_mode_handler.cpp index 0f41eed5d04..09b33629184 100644 --- a/src/extractor/guidance/suppress_mode_handler.cpp +++ b/src/extractor/guidance/suppress_mode_handler.cpp @@ -12,7 +12,6 @@ namespace guidance { SuppressModeHandler::SuppressModeHandler( - const IntersectionGenerator &intersection_generator, const util::NodeBasedDynamicGraph &node_based_graph, const EdgeBasedNodeDataContainer &node_data_container, const std::vector &coordinates, @@ -30,8 +29,7 @@ SuppressModeHandler::SuppressModeHandler( barrier_nodes, turn_lanes_data, name_table, - street_name_suffix_table, - intersection_generator) + street_name_suffix_table) { } diff --git a/src/extractor/guidance/turn_analysis.cpp b/src/extractor/guidance/turn_analysis.cpp index 32d6685d658..8d1cb066929 100644 --- a/src/extractor/guidance/turn_analysis.cpp +++ b/src/extractor/guidance/turn_analysis.cpp @@ -30,22 +30,15 @@ TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph, const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, const SuffixTable &street_name_suffix_table) - : node_based_graph(node_based_graph), intersection_generator(node_based_graph, - node_data_container, - restriction_map, - barrier_nodes, - node_coordinates, - compressed_edge_container), - roundabout_handler(node_based_graph, - node_data_container, - node_coordinates, - compressed_edge_container, - restriction_map, - barrier_nodes, - turn_lanes_data, - name_table, - street_name_suffix_table, - intersection_generator), + : node_based_graph(node_based_graph), roundabout_handler(node_based_graph, + node_data_container, + node_coordinates, + compressed_edge_container, + restriction_map, + barrier_nodes, + turn_lanes_data, + name_table, + street_name_suffix_table), motorway_handler(node_based_graph, node_data_container, node_coordinates, @@ -54,8 +47,7 @@ TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph, barrier_nodes, turn_lanes_data, name_table, - street_name_suffix_table, - intersection_generator), + street_name_suffix_table), turn_handler(node_based_graph, node_data_container, node_coordinates, @@ -64,10 +56,8 @@ TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph, barrier_nodes, turn_lanes_data, name_table, - street_name_suffix_table, - intersection_generator), - sliproad_handler(intersection_generator, - node_based_graph, + street_name_suffix_table), + sliproad_handler(node_based_graph, node_data_container, node_coordinates, compressed_edge_container, @@ -76,8 +66,7 @@ TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph, turn_lanes_data, name_table, street_name_suffix_table), - suppress_mode_handler(intersection_generator, - node_based_graph, + suppress_mode_handler(node_based_graph, node_data_container, node_coordinates, compressed_edge_container, @@ -86,8 +75,7 @@ TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph, turn_lanes_data, name_table, street_name_suffix_table), - driveway_handler(intersection_generator, - node_based_graph, + driveway_handler(node_based_graph, node_data_container, node_coordinates, compressed_edge_container, @@ -96,8 +84,7 @@ TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph, turn_lanes_data, name_table, street_name_suffix_table), - statistics_handler(intersection_generator, - node_based_graph, + statistics_handler(node_based_graph, node_data_container, node_coordinates, compressed_edge_container, diff --git a/src/extractor/guidance/turn_discovery.cpp b/src/extractor/guidance/turn_discovery.cpp index aa6c8db4b50..6af5ebe7d0e 100644 --- a/src/extractor/guidance/turn_discovery.cpp +++ b/src/extractor/guidance/turn_discovery.cpp @@ -1,5 +1,6 @@ #include "extractor/guidance/turn_discovery.hpp" #include "extractor/guidance/constants.hpp" +#include "extractor/guidance/coordinate_extractor.hpp" #include "extractor/intersection/intersection_analysis.hpp" #include "util/bearing.hpp" #include "util/coordinate_calculation.hpp" diff --git a/src/extractor/guidance/turn_handler.cpp b/src/extractor/guidance/turn_handler.cpp index dd79318f1b7..c6d367040dc 100644 --- a/src/extractor/guidance/turn_handler.cpp +++ b/src/extractor/guidance/turn_handler.cpp @@ -118,8 +118,7 @@ TurnHandler::TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph, const std::unordered_set &barrier_nodes, const guidance::TurnLanesIndexedArray &turn_lanes_data, const util::NameTable &name_table, - const SuffixTable &street_name_suffix_table, - const IntersectionGenerator &intersection_generator) + const SuffixTable &street_name_suffix_table) : IntersectionHandler(node_based_graph, node_data_container, coordinates, @@ -128,8 +127,7 @@ TurnHandler::TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph, barrier_nodes, turn_lanes_data, name_table, - street_name_suffix_table, - intersection_generator) + street_name_suffix_table) { } diff --git a/src/extractor/intersection/intersection_analysis.cpp b/src/extractor/intersection/intersection_analysis.cpp index 404dec72e7b..ada9549acf2 100644 --- a/src/extractor/intersection/intersection_analysis.cpp +++ b/src/extractor/intersection/intersection_analysis.cpp @@ -782,6 +782,27 @@ getConnectedRoads(const util::NodeBasedDynamicGraph &graph, outgoing_edges, std::unordered_set()); } + +IntersectionEdge skipDegreeTwoNodes(const util::NodeBasedDynamicGraph &graph, IntersectionEdge road) +{ + std::unordered_set visited_nodes; + (void)visited_nodes; + + // Skip trivial nodes without generating the intersection in between, stop at the very first + // intersection of degree > 2 + const auto starting_node = road.node; + auto next_node = graph.GetTarget(road.edge); + while (graph.GetOutDegree(next_node) == 2 && next_node != starting_node) + { + BOOST_ASSERT(visited_nodes.insert(next_node).second); + const auto next_edge = graph.BeginEdges(next_node); + road.edge = graph.GetTarget(next_edge) == road.node ? next_edge + 1 : next_edge; + road.node = next_node; + next_node = graph.GetTarget(road.edge); + } + + return road; +} } } } diff --git a/unit_tests/extractor/intersection_analysis_tests.cpp b/unit_tests/extractor/intersection_analysis_tests.cpp index cd7ca619f54..1692a1cc4e0 100644 --- a/unit_tests/extractor/intersection_analysis_tests.cpp +++ b/unit_tests/extractor/intersection_analysis_tests.cpp @@ -252,4 +252,64 @@ BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity) ); } +BOOST_AUTO_TEST_CASE(skip_degree_two_nodes) +{ + std::unordered_set barrier_nodes{1}; + std::unordered_set traffic_lights{2}; + std::vector annotations(1); + std::vector restrictions; + std::vector conditional_restrictions; + CompressedEdgeContainer container; + test::MockScriptingEnvironment scripting_environment; + + TurnLanesIndexedArray turn_lanes_data; + + // Graph + // + // 0↔1→2↔3↔4→5 7 + // ↑ ↕ ↕ + // 6 8 ↔ 9 + // + const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed) { + return InputEdge{ + from, to, 1, 1, GeometryID{0, false}, !allowed, NodeBasedEdgeClassification{}, 0}; + }; + std::vector edges = {unit_edge(0, 1, true), // 0 + unit_edge(1, 0, true), + unit_edge(1, 2, true), + unit_edge(2, 1, false), + unit_edge(2, 3, true), + unit_edge(3, 2, true), // 5 + unit_edge(3, 4, true), + unit_edge(4, 3, true), + unit_edge(4, 5, true), + unit_edge(4, 6, false), + unit_edge(5, 4, false), // 10 + unit_edge(6, 4, true), + // Circle + unit_edge(7, 8, true), // 12 + unit_edge(7, 9, true), + unit_edge(8, 7, true), + unit_edge(8, 9, true), + unit_edge(9, 7, true), + unit_edge(9, 8, true)}; + + Graph graph(10, edges); + + GraphCompressor().Compress(barrier_nodes, + traffic_lights, + scripting_environment, + restrictions, + conditional_restrictions, + graph, + annotations, + container); + + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {0, 0}).edge), 4); + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {4, 7}).edge), 0); + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {5, 10}).edge), 4); + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {6, 11}).edge), 4); + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {7, 12}).edge), 7); +} + BOOST_AUTO_TEST_SUITE_END()