// #include "extractor/intersection/intersection_analysis.hpp" #include "extractor/graph_compressor.hpp" #include "../common/range_tools.hpp" #include "../unit_tests/mocks/mock_scripting_environment.hpp" #include #include BOOST_AUTO_TEST_SUITE(intersection_analysis_tests) using namespace osrm; using namespace osrm::guidance; using namespace osrm::extractor; using namespace osrm::extractor::intersection; using InputEdge = util::NodeBasedDynamicGraph::InputEdge; using Graph = util::NodeBasedDynamicGraph; // BOOST_AUTO_TEST_CASE(simple_intersection_connectivity) // { // std::unordered_set barrier_nodes{6}; // std::unordered_set traffic_lights; // std::vector annotations{ // {EMPTY_NAMEID, 0, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}, // {EMPTY_NAMEID, 1, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}}; // std::vector restrictions{TurnRestriction{NodeRestriction{0, 2, 1}, false}}; // std::vector conditional_restrictions; // CompressedEdgeContainer container; // test::MockScriptingEnvironment scripting_environment; // std::vector maneuver_overrides; // TurnLanesIndexedArray turn_lanes_data{{0, 0, 3}, // {TurnLaneType::uturn | TurnLaneType::left, // TurnLaneType::straight, // TurnLaneType::straight | TurnLaneType::right}}; // // Graph with an additional turn restriction 0→2→1 and bollard at 6 // // 0→5↔6↔7 // // ↕ // // 1↔2←3 // // ↓ // // 4 // const auto unit_edge = // [](const NodeID from, const NodeID to, bool allowed, AnnotationID annotation) { // return InputEdge{from, // to, // 1, // 1, // GeometryID{0, false}, // !allowed, // NodeBasedEdgeClassification(), // annotation}; // }; // std::vector edges = {unit_edge(0, 2, true, 1), // unit_edge(0, 5, true, 0), // unit_edge(1, 2, true, 0), // unit_edge(2, 0, true, 0), // unit_edge(2, 1, true, 0), // unit_edge(2, 3, false, 0), // unit_edge(2, 4, true, 0), // unit_edge(3, 2, true, 0), // unit_edge(4, 2, false, 0), // unit_edge(5, 0, false, 0), // unit_edge(5, 6, true, 0), // unit_edge(6, 5, true, 0), // unit_edge(6, 7, true, 0), // unit_edge(7, 6, true, 0)}; // IntersectionEdgeGeometries edge_geometries{ // {0, 180, 180, 10.}, // 0→2 // {1, 90, 90, 10.}, // 0→5 // {2, 90, 90, 10.}, // 1→2 // {3, 0, 0, 10.}, // 2→0 // {4, 270, 270, 10.}, // 2→1 // {5, 90, 90, 10.}, // 2→3 // {6, 180, 180, 10.}, // 2→4 // {7, 270, 270, 10.}, // 3→2 // {8, 0, 0, 10.}, // 4→2 // {9, 270, 270, 10.}, // 5→0 // {10, 90, 90, 10.}, // 5→6 // {11, 270, 270, 10.}, // 6→5 // {12, 90, 90, 10.}, // 6→7 // {13, 270, 270, 10.} // 7→6 // }; // Graph graph(8, edges); // GraphCompressor().Compress(barrier_nodes, // traffic_lights, // scripting_environment, // restrictions, // conditional_restrictions, // maneuver_overrides, // graph, // annotations, // container); // REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 2), 3); // REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 2), 4); // EdgeBasedNodeDataContainer node_data_container( // std::vector(graph.GetNumberOfEdges()), annotations); // RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia()); // const auto connectivity_matrix = [&](NodeID node) { // std::vector result; // const auto incoming_edges = getIncomingEdges(graph, node); // const auto outgoing_edges = getOutgoingEdges(graph, node); // for (const auto incoming_edge : incoming_edges) // { // for (const auto outgoing_edge : outgoing_edges) // { // result.push_back(isTurnAllowed(graph, // node_data_container, // restriction_map, // barrier_nodes, // edge_geometries, // turn_lanes_data, // incoming_edge, // outgoing_edge)); // } // } // return result; // }; // CHECK_EQUAL_RANGE(connectivity_matrix(0), 1, 1); // from node 2 allowed U-turn and to node 5 // CHECK_EQUAL_RANGE(connectivity_matrix(1), 1); // from node 2 allowed U-turn // CHECK_EQUAL_RANGE(connectivity_matrix(2), // // clang-format off // 1, 0, 0, 1, // from node 0 to node 4 and a U-turn at 2 // 1, 0, 0, 1, // from node 1 to nodes 0 and 4 // 1, 1, 0, 1 // from node 3 to nodes 0, 1 and 4 // // clang-format on // ); // REQUIRE_SIZE_RANGE(connectivity_matrix(3), 0); // no incoming edges, empty matrix // CHECK_EQUAL_RANGE(connectivity_matrix(4), 0); // from node 2 not allowed U-turn // CHECK_EQUAL_RANGE(connectivity_matrix(5), // // clang-format off // 0, 1, // from node 0 to node 6 // 0, 1, // from node 6 a U-turn to node 6 // // clang-format on // ); // CHECK_EQUAL_RANGE(connectivity_matrix(6), // // clang-format off // 1, 0, // from node 5 a U-turn to node 5 // 0, 1, // from node 7 a U-turn to node 7 // // clang-format on // ); // } // BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity) // { // std::unordered_set barrier_nodes; // std::unordered_set traffic_lights; // std::vector annotations; // std::vector restrictions; // std::vector conditional_restrictions; // CompressedEdgeContainer container; // test::MockScriptingEnvironment scripting_environment; // std::vector maneuver_overrides; // TurnLanesIndexedArray turn_lanes_data; // // Graph with roundabout edges 5→0→2 // // 1 2 3 // // ↘ ↑ ↙ // // 0 // // ↙ ↑ ↘ // // 4 5 6 // const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed, bool roundabout) // { // return InputEdge{from, // to, // 1, // 1, // GeometryID{0, false}, // !allowed, // NodeBasedEdgeClassification{ // true, false, false, roundabout, false, false, false, {}, 0, 0}, // 0}; // }; // std::vector edges = {unit_edge(0, 1, false, false), // unit_edge(0, 2, true, true), // unit_edge(0, 3, false, false), // unit_edge(0, 4, true, false), // unit_edge(0, 5, false, true), // unit_edge(0, 6, true, false), // unit_edge(1, 0, true, false), // unit_edge(2, 0, false, true), // unit_edge(3, 0, true, false), // unit_edge(4, 0, false, false), // unit_edge(5, 0, true, true), // unit_edge(6, 0, false, false)}; // IntersectionEdgeGeometries edge_geometries{ // {0, 315, 315, 10}, // 0→1 // {1, 0, 0, 10}, // 0→2 // {2, 45, 45, 10}, // 0→3 // {3, 225, 225, 10}, // 0→4 // {4, 180, 180, 10}, // 0→5 // {5, 135, 135, 10}, // 0→6 // {6, 135, 135, 10}, // 1→0 // {7, 180, 180, 10}, // 2→0 // {8, 225, 225, 10}, // 3→0 // {9, 45, 45, 10}, // 4→0 // {10, 0, 0, 10}, // 5→0 // {11, 315, 315, 10} // 6→0 // }; // Graph graph(7, edges); // GraphCompressor().Compress(barrier_nodes, // traffic_lights, // scripting_environment, // restrictions, // conditional_restrictions, // maneuver_overrides, // graph, // annotations, // container); // REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 0), 3); // REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 0), 6); // EdgeBasedNodeDataContainer node_data_container( // std::vector(graph.GetNumberOfEdges()), annotations); // RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia()); // const auto connectivity_matrix = [&](NodeID node) { // std::vector result; // const auto incoming_edges = getIncomingEdges(graph, node); // const auto outgoing_edges = getOutgoingEdges(graph, node); // for (const auto incoming_edge : incoming_edges) // { // for (const auto outgoing_edge : outgoing_edges) // { // result.push_back(isTurnAllowed(graph, // node_data_container, // restriction_map, // barrier_nodes, // edge_geometries, // turn_lanes_data, // incoming_edge, // outgoing_edge)); // } // } // return result; // }; // CHECK_EQUAL_RANGE(connectivity_matrix(0), // // clang-format off // 0, 1, 0, 0, 0, 1, // from node 1 to nodes 2 and 6 // 0, 1, 0, 1, 0, 0, // from node 3 to nodes 2 and 4 // 0, 1, 0, 1, 0, 1 // from node 5 to nodes 2, 4 and 6 // // clang-format on // ); // } // 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; // std::vector maneuver_overrides; // 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, // maneuver_overrides, // 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()