diff --git a/integration_tests/osrm_route_test.cpp b/integration_tests/osrm_route_test.cpp index 57742d09c9..c83b6474f4 100644 --- a/integration_tests/osrm_route_test.cpp +++ b/integration_tests/osrm_route_test.cpp @@ -83,10 +83,26 @@ namespace {18.54269, -36.09501}, 17873000.); }*/ + UNIT_TEST(MoroccoToSahrawiCrossMwmTest) + { + integration::CalculateRouteAndTestRouteLength( + integration::GetAllMaps(), MercatorBounds::FromLatLon(27.15587, -13.23059), {0., 0.}, + MercatorBounds::FromLatLon(27.94049, -12.88800), 100864); + integration::CalculateRouteAndTestRouteLength( + integration::GetAllMaps(), MercatorBounds::FromLatLon(27.94049, -12.88800), {0., 0.}, + MercatorBounds::FromLatLon(27.15587, -13.23059), 100864); + } + + UNIT_TEST(ArbatBaliCrimeanForwardCrossMwmTest) + { + integration::CalculateRouteAndTestRouteLength( + integration::GetAllMaps(), MercatorBounds::FromLatLon(46.152324, 34.804955), {0., 0.}, + MercatorBounds::FromLatLon(45.35697, 35.369712), 105000.); + } + // TODO In these two tests below the following ASSERT is reproduced // ASSERT_LESS(node_index, m_nodeIds.size(), ()); in OsrmFtSegBackwardIndex::GetNodeIdByFid() // It should be fixed. - // UNIT_TEST(ArbatBaliCrimeanForwardCrossMwmTest) // { // integration::CalculateRouteAndTestRouteLength( diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index 49c5de2c76..6e56f60078 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -1,4 +1,5 @@ #include "cross_mwm_road_graph.hpp" +#include "cross_mwm_router.hpp" #include "geometry/distance_on_sphere.hpp" @@ -183,4 +184,31 @@ double CrossMwmGraph::HeuristicCostEstimate(BorderCross const & v, BorderCross c return 0; } +void ConvertToSingleRouterTasks(vector const & graphCrosses, + FeatureGraphNode const & startGraphNode, + FeatureGraphNode const & finalGraphNode, + TCheckedPath & route) +{ + route.clear(); + for (size_t i = 0; i < graphCrosses.size() - 1; ++i) + { + route.emplace_back(graphCrosses[i].toNode.node, graphCrosses[i + 1].fromNode.node, + graphCrosses[i].toNode.mwmName); + } + + if (!route.empty()) + { + //Start virtual node always will be becase they are not compaired in A* algo. + route.front().startNode = startGraphNode; + + // Stop point lays on out edge, and we have no virtual edge to unpack. + if (route.back().startNode.mwmName != finalGraphNode.mwmName) + route.emplace_back(RoutePathCross(graphCrosses.back().toNode.node, + graphCrosses.back().toNode.node, + graphCrosses.back().toNode.mwmName)); + + route.back().finalNode = finalGraphNode; + } +} + } // namespace routing diff --git a/routing/cross_mwm_road_graph.hpp b/routing/cross_mwm_road_graph.hpp index 120bbb072c..025c21e580 100644 --- a/routing/cross_mwm_road_graph.hpp +++ b/routing/cross_mwm_road_graph.hpp @@ -113,4 +113,12 @@ private: mutable RoutingIndexManager m_indexManager; mutable unordered_map m_cachedNextNodes; }; + +// Helper functions. +/// Convertor from CrossMwmGraph to cross mwm route task. +void ConvertToSingleRouterTasks(vector const & graphCrosses, + FeatureGraphNode const & startGraphNode, + FeatureGraphNode const & finalGraphNode, + TCheckedPath & route); + } // namespace routing diff --git a/routing/cross_mwm_router.cpp b/routing/cross_mwm_router.cpp index 316358aec9..14934f9918 100644 --- a/routing/cross_mwm_router.cpp +++ b/routing/cross_mwm_router.cpp @@ -92,24 +92,12 @@ IRouter::ResultCode CalculateCrossMwmPath(TRoutingNodes const & startGraphNodes, return code; // Final path conversion to output type. - for (size_t i = 0; i < tempRoad.size() - 1; ++i) - { - route.emplace_back(tempRoad[i].toNode.node, tempRoad[i + 1].fromNode.node, - tempRoad[i].toNode.mwmName); - } + ConvertToSingleRouterTasks(tempRoad, startGraphNode, finalGraphNode, route); - if (!route.empty()) - { - route.front().startNode = startGraphNode; + if (route.empty()) + return IRouter::RouteNotFound; - // Stop point lays on out edge, and we have no virtual edge to unpack. - if (route.back().startNode.mwmName != finalGraphNode.mwmName) - route.emplace_back(RoutePathCross(tempRoad.back().toNode.node, tempRoad.back().toNode.node, tempRoad.back().toNode.mwmName)); - - route.back().finalNode = finalGraphNode; - return IRouter::NoError; - } - return IRouter::RouteNotFound; + return IRouter::NoError; } } // namespace routing diff --git a/routing/routing_tests/cross_routing_tests.cpp b/routing/routing_tests/cross_routing_tests.cpp index 5e31f496dd..0f63555df2 100644 --- a/routing/routing_tests/cross_routing_tests.cpp +++ b/routing/routing_tests/cross_routing_tests.cpp @@ -1,12 +1,67 @@ #include "testing/testing.hpp" #include "routing/cross_routing_context.hpp" +#include "routing/cross_mwm_road_graph.hpp" +#include "routing/cross_mwm_router.hpp" + #include "coding/reader.hpp" #include "coding/writer.hpp" +using namespace routing; namespace { +// Graph to convertions. +UNIT_TEST(TestCrossRouteConverter) +{ + vector graphCrosses; + CrossNode a(1, "aMap", {0,0}), b(2, "aMap", {2, 2}); + CrossNode c(3, "bMap", {3,3}), d(3, "bMap", {4, 4}); + graphCrosses.emplace_back(BorderCross(a, b)); + graphCrosses.emplace_back(BorderCross(b, c)); + graphCrosses.emplace_back(BorderCross(c, d)); + FeatureGraphNode startGraphNode; + startGraphNode.node.forward_node_id = 5; + startGraphNode.mwmName = "aMap"; + FeatureGraphNode finalGraphNode; + finalGraphNode.node.reverse_node_id = 6; + finalGraphNode.mwmName = "bMap"; + TCheckedPath route; + ConvertToSingleRouterTasks(graphCrosses, startGraphNode, finalGraphNode, route); + TEST_EQUAL(route.size(), 2, ("We have 2 maps aMap and bMap.")); + for (auto const & r : route) + TEST_EQUAL(r.startNode.mwmName, r.finalNode.mwmName, ()); + TEST_EQUAL(route.front().startNode.node, startGraphNode.node, + ("Start node must be replaced by origin.")); + TEST_EQUAL(route.back().finalNode.node, finalGraphNode.node, + ("End node must be replaced by origin.")); +} + +UNIT_TEST(TestCrossRouteConverterEdgeCase) +{ + vector graphCrosses; + CrossNode a(1, "aMap", {0,0}), b(2, "aMap", {2, 2}); + CrossNode c(3, "bMap", {3,3}); + graphCrosses.emplace_back(BorderCross(a, b)); + graphCrosses.emplace_back(BorderCross(b, c)); + FeatureGraphNode startGraphNode; + startGraphNode.node.forward_node_id = 5; + startGraphNode.mwmName = "aMap"; + FeatureGraphNode finalGraphNode; + finalGraphNode.node.reverse_node_id = 6; + finalGraphNode.mwmName = "bMap"; + TCheckedPath route; + ConvertToSingleRouterTasks(graphCrosses, startGraphNode, finalGraphNode, route); + TEST_EQUAL(route.size(), 2, ("We have 2 maps aMap and bMap.")); + for (auto const & r : route) + TEST_EQUAL(r.startNode.mwmName, r.finalNode.mwmName, ()); + TEST_EQUAL(route.front().startNode.node, startGraphNode.node, + ("Start node must be replaced by origin.")); + TEST_EQUAL(route.back().finalNode.node, finalGraphNode.node, + ("End node must be replaced by origin.")); +} + +// Cross routing context tests. UNIT_TEST(TestContextSerialization) { routing::CrossRoutingContextWriter context;