diff --git a/routing/base/astar_algorithm.hpp b/routing/base/astar_algorithm.hpp index 85951b47bc..5c66820769 100644 --- a/routing/base/astar_algorithm.hpp +++ b/routing/base/astar_algorithm.hpp @@ -49,6 +49,7 @@ public: Result FindPath(TGraphType const & graph, TVertexType const & startVertex, TVertexType const & finalVertex, vector & path, + double & distance, my::Cancellable const & cancellable = my::Cancellable(), TOnVisitedVertexCallback onVisitedVertexCallback = nullptr) const; @@ -170,6 +171,7 @@ typename AStarAlgorithm::Result AStarAlgorithm::FindPath( TGraphType const & graph, TVertexType const & startVertex, TVertexType const & finalVertex, vector & path, + double & distance, my::Cancellable const & cancellable, TOnVisitedVertexCallback onVisitedVertexCallback) const { @@ -205,6 +207,7 @@ typename AStarAlgorithm::Result AStarAlgorithm::FindPath( if (stateV.vertex == finalVertex) { ReconstructPath(stateV.vertex, parent, path); + distance = stateV.distance; return Result::OK; } diff --git a/routing/cross_mwm_router.cpp b/routing/cross_mwm_router.cpp index 4da5761af7..c54e486843 100644 --- a/routing/cross_mwm_router.cpp +++ b/routing/cross_mwm_router.cpp @@ -11,7 +11,7 @@ namespace /// Function to run AStar Algorithm from the base. IRouter::ResultCode CalculateRoute(BorderCross const & startPos, BorderCross const & finalPos, CrossMwmGraph const & roadGraph, vector & route, - RouterDelegate const & delegate) + double & cost, RouterDelegate const & delegate) { using TAlgorithm = AStarAlgorithm; @@ -23,7 +23,7 @@ IRouter::ResultCode CalculateRoute(BorderCross const & startPos, BorderCross con my::HighResTimer timer(true); TAlgorithm::Result const result = - TAlgorithm().FindPath(roadGraph, startPos, finalPos, route, delegate, onVisitedVertex); + TAlgorithm().FindPath(roadGraph, startPos, finalPos, route, cost, delegate, onVisitedVertex); LOG(LINFO, ("Duration of the cross MWM path finding", timer.ElapsedNano())); switch (result) { @@ -43,6 +43,7 @@ IRouter::ResultCode CalculateRoute(BorderCross const & startPos, BorderCross con IRouter::ResultCode CalculateCrossMwmPath(TRoutingNodes const & startGraphNodes, TRoutingNodes const & finalGraphNodes, RoutingIndexManager & indexManager, + double & cost, RouterDelegate const & delegate, TCheckedPath & route) { CrossMwmGraph roadGraph(indexManager); @@ -88,7 +89,7 @@ IRouter::ResultCode CalculateCrossMwmPath(TRoutingNodes const & startGraphNodes, // Finding path through maps. vector tempRoad; - code = CalculateRoute({startNode, startNode}, {finalNode, finalNode}, roadGraph, tempRoad, + code = CalculateRoute({startNode, startNode}, {finalNode, finalNode}, roadGraph, tempRoad, cost, delegate); if (code != IRouter::NoError) return code; diff --git a/routing/cross_mwm_router.hpp b/routing/cross_mwm_router.hpp index 4fcebf8c16..abc5f0baf8 100644 --- a/routing/cross_mwm_router.hpp +++ b/routing/cross_mwm_router.hpp @@ -34,11 +34,12 @@ using TCheckedPath = vector; * \param finalGraphNodes The vector of final routing graph nodes. * \param route Storage for the result records about crossing maps. * \param indexManager Manager for getting indexes of new countries. + * \param cost Found path cost. * \param RoutingVisualizerFn Debug visualization function. * \return NoError if the path exists, error code otherwise. */ IRouter::ResultCode CalculateCrossMwmPath(TRoutingNodes const & startGraphNodes, TRoutingNodes const & finalGraphNodes, - RoutingIndexManager & indexManager, + RoutingIndexManager & indexManager, double & cost, RouterDelegate const & delegate, TCheckedPath & route); } // namespace routing diff --git a/routing/osrm_router.cpp b/routing/osrm_router.cpp index b39c15059f..b758c58964 100644 --- a/routing/osrm_router.cpp +++ b/routing/osrm_router.cpp @@ -294,6 +294,8 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRoute(m2::PointD const & startPoint, // 4. Find route. RawRoutingResult routingResult; + double crossCost = 0; + TCheckedPath finalPath; // Manually load facade to avoid unmaping files we routing on. startMapping->LoadFacade(); @@ -306,11 +308,32 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRoute(m2::PointD const & startPoint, { indexPair.second->FreeCrossContext(); }); + ResultCode crossCode = CalculateCrossMwmPath(startTask, m_cachedTargets, m_indexManager, crossCost, + delegate, finalPath); + LOG(LINFO, ("Found cross path", timer.ElapsedNano())); if (!FindRouteFromCases(startTask, m_cachedTargets, startMapping->m_dataFacade, routingResult)) { + if (crossCode == NoError) + { + LOG(LINFO, ("Found only cross path.")); + auto code = MakeRouteFromCrossesPath(finalPath, delegate, route); + LOG(LINFO, ("Make final route", timer.ElapsedNano())); + return code; + } return RouteNotFound; } + INTERRUPT_WHEN_CANCELLED(delegate); + + if (crossCode == NoError && crossCost < routingResult.shortestPathLength) + { + LOG(LINFO, ("Cross mwm path shorter. Cross cost:", crossCost, "single cost:", routingResult.shortestPathLength)); + auto code = MakeRouteFromCrossesPath(finalPath, delegate, route); + LOG(LINFO, ("Make final route", timer.ElapsedNano())); + timer.Reset(); + return code; + } + INTERRUPT_WHEN_CANCELLED(delegate); delegate.OnProgress(kPathFoundProgress); @@ -335,9 +358,8 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRoute(m2::PointD const & startPoint, else //4.2 Multiple mwm case { LOG(LINFO, ("Multiple mwm routing case")); - TCheckedPath finalPath; - ResultCode code = CalculateCrossMwmPath(startTask, m_cachedTargets, m_indexManager, delegate, - finalPath); + ResultCode code = CalculateCrossMwmPath(startTask, m_cachedTargets, m_indexManager, crossCost, + delegate, finalPath); timer.Reset(); INTERRUPT_WHEN_CANCELLED(delegate); delegate.OnProgress(kCrossPathFoundProgress); diff --git a/routing/routing_algorithm.cpp b/routing/routing_algorithm.cpp index 43806ebfa3..a07dec1fe6 100644 --- a/routing/routing_algorithm.cpp +++ b/routing/routing_algorithm.cpp @@ -145,8 +145,9 @@ IRoutingAlgorithm::Result AStarRoutingAlgorithm::CalculateRoute(IRoadGraph const my::Cancellable const & cancellable = delegate; progress.Initialize(startPos.GetPoint(), finalPos.GetPoint()); + double cost = 0; TAlgorithmImpl::Result const res = TAlgorithmImpl().FindPath( - RoadGraph(graph), startPos, finalPos, path, cancellable, onVisitJunctionFn); + RoadGraph(graph), startPos, finalPos, path, cost, cancellable, onVisitJunctionFn); return Convert(res); } diff --git a/routing/routing_tests/astar_algorithm_test.cpp b/routing/routing_tests/astar_algorithm_test.cpp index adba0c5c89..0ab46e5e7f 100644 --- a/routing/routing_tests/astar_algorithm_test.cpp +++ b/routing/routing_tests/astar_algorithm_test.cpp @@ -62,9 +62,10 @@ void TestAStar(UndirectedGraph const & graph, vector const & expectedR using TAlgorithm = AStarAlgorithm; TAlgorithm algo; + double cost = 0; vector actualRoute; - TEST_EQUAL(TAlgorithm::Result::OK, algo.FindPath(graph, 0u, 4u, actualRoute), ()); + TEST_EQUAL(TAlgorithm::Result::OK, algo.FindPath(graph, 0u, 4u, actualRoute, cost), ()); TEST_EQUAL(expectedRoute, actualRoute, ()); actualRoute.clear();