diff --git a/routing/index_graph_starter.hpp b/routing/index_graph_starter.hpp index e4caaef534..93e1edc6e4 100644 --- a/routing/index_graph_starter.hpp +++ b/routing/index_graph_starter.hpp @@ -17,33 +17,37 @@ class IndexGraphStarter final { public: // AStarAlgorithm types aliases: - using TVertexType = Segment; - using TEdgeType = SegmentEdge; + using TVertexType = WorldGraph::Vertex; + using TEdgeType = WorldGraph::Edge; class FakeVertex final { public: - FakeVertex(Segment const & segment, m2::PointD const & point) - : m_segment(segment), m_point(point) - { - } FakeVertex(NumMwmId mwmId, uint32_t featureId, uint32_t segmentIdx, m2::PointD const & point) : m_segment(mwmId, featureId, segmentIdx, true /* forward */), m_point(point) { } + FakeVertex(Segment const & segment, m2::PointD const & point) + : m_segment(segment), m_point(point) + { + } + NumMwmId GetMwmId() const { return m_segment.GetMwmId(); } uint32_t GetFeatureId() const { return m_segment.GetFeatureId(); } m2::PointD const & GetPoint() const { return m_point; } Segment GetSegmentWithDirection(bool forward) const { - return Segment(m_segment.GetMwmId(), m_segment.GetFeatureId(), m_segment.GetSegmentIdx(), forward); + return Segment(m_segment.GetMwmId(), m_segment.GetFeatureId(), m_segment.GetSegmentIdx(), + forward); } bool Fits(Segment const & segment) const { - return segment.GetMwmId() == m_segment.GetMwmId() && segment.GetFeatureId() == m_segment.GetFeatureId() && + // Note. Comparing |segment| and |m_segment| without field |Segment::m_forward|. + return segment.GetMwmId() == m_segment.GetMwmId() && + segment.GetFeatureId() == m_segment.GetFeatureId() && segment.GetSegmentIdx() == m_segment.GetSegmentIdx(); } diff --git a/routing/index_router.cpp b/routing/index_router.cpp index 34a49a6927..4ad1f2f411 100644 --- a/routing/index_router.cpp +++ b/routing/index_router.cpp @@ -36,22 +36,21 @@ size_t constexpr kMaxRoadCandidates = 6; float constexpr kProgressInterval = 2; uint32_t constexpr kDrawPointsPeriod = 10; -bool IsDeadEnd(Segment const & segment, bool fromPoint, WorldGraph & worldGraph) +bool IsDeadEnd(Segment const & segment, bool isOutgoing, WorldGraph & worldGraph) { size_t constexpr kDeadEndTestLimit = 50; - auto const getVertexByEdgeFn = [](SegmentEdge const & edge){ - return edge.GetTarget(); + auto const getVertexByEdgeFn = [](SegmentEdge const & edge) { return edge.GetTarget(); }; + + // Note. If |isOutgoing| == true outgoing edges are looked for. + // If |isOutgoing| == false it's the finish. So ingoing edges are looked for. + auto const getOutgoingEdgesFn = [isOutgoing](WorldGraph & graph, Segment const & u, + vector & edges) { + graph.GetEdgeList(u, isOutgoing, false /* isLeap */, edges); }; - // Note. If |fromPoint| == true outgoing edges are looked for. - // If |fromPoint| == false it's the finish. So ingoing edges are looked for. - auto const getOutgoingEdgesFn = [fromPoint](WorldGraph & graph, Segment const & u, vector & edges){ - graph.GetEdgeList(u, fromPoint, false /* isLeap */, edges); - }; - - return !CheckGraphConnectivity(worldGraph, segment, kDeadEndTestLimit, - getVertexByEdgeFn, getOutgoingEdgesFn); + return !CheckGraphConnectivity(segment, kDeadEndTestLimit, worldGraph, + getVertexByEdgeFn, getOutgoingEdgesFn); } } // namespace @@ -137,25 +136,27 @@ IRouter::ResultCode IndexRouter::DoCalculateRoute(string const & startCountry, TrafficStash::Guard guard(*m_trafficStash); WorldGraph graph( - make_unique(m_numMwmIds, m_numMwmTree, m_vehicleModelFactory, m_countryRectFn, - m_index, m_indexManager), - IndexGraphLoader::Create(m_numMwmIds, m_vehicleModelFactory, m_estimator, m_index), - m_estimator); + make_unique(m_numMwmIds, m_numMwmTree, m_vehicleModelFactory, m_countryRectFn, + m_index, m_indexManager), + IndexGraphLoader::Create(m_numMwmIds, m_vehicleModelFactory, m_estimator, m_index), + m_estimator); Edge startEdge; - if (!FindClosestEdge(graph, startFile, startPoint, true /* fromPoint */, startEdge)) + if (!FindClosestEdge(startFile, startPoint, true /* isOutgoing */, graph, startEdge)) return IRouter::StartPointNotFound; Edge finishEdge; - if (!FindClosestEdge(graph, finishFile, finalPoint, false /* fromPoint */, finishEdge)) + if (!FindClosestEdge(finishFile, finalPoint, false /* isOutgoing */, graph, finishEdge)) return IRouter::EndPointNotFound; - IndexGraphStarter::FakeVertex const start(Segment(m_numMwmIds->GetId(startFile), - startEdge.GetFeatureId().m_index, startEdge.GetSegId(), true /* forward */), - startPoint); - IndexGraphStarter::FakeVertex const finish(Segment(m_numMwmIds->GetId(finishFile), - finishEdge.GetFeatureId().m_index, - finishEdge.GetSegId(), true /* forward */), finalPoint); + IndexGraphStarter::FakeVertex const start( + Segment(m_numMwmIds->GetId(startFile), startEdge.GetFeatureId().m_index, startEdge.GetSegId(), + true /* forward */), + startPoint); + IndexGraphStarter::FakeVertex const finish( + Segment(m_numMwmIds->GetId(finishFile), finishEdge.GetFeatureId().m_index, + finishEdge.GetSegId(), true /* forward */), + finalPoint); WorldGraph::Mode mode = WorldGraph::Mode::SingleMwm; if (forSingleMwm) @@ -213,10 +214,8 @@ IRouter::ResultCode IndexRouter::DoCalculateRoute(string const & startCountry, } } -bool IndexRouter::FindClosestEdge(WorldGraph & worldGraph, - platform::CountryFile const & file, - m2::PointD const & point, - bool fromPoint, +bool IndexRouter::FindClosestEdge(platform::CountryFile const & file, m2::PointD const & point, + bool isOutgoing, WorldGraph & worldGraph, Edge & closestEdge) const { MwmSet::MwmHandle handle = m_index.GetMwmHandleByCountryFile(file); @@ -236,7 +235,7 @@ bool IndexRouter::FindClosestEdge(WorldGraph & worldGraph, { Edge const & edge = candidates[i].first; Segment const segment(numMwmId, edge.GetFeatureId().m_index, edge.GetSegId(), edge.IsForward()); - if (edge.GetFeatureId().m_mwmId != mwmId || IsDeadEnd(segment, fromPoint, worldGraph)) + if (edge.GetFeatureId().m_mwmId != mwmId || IsDeadEnd(segment, isOutgoing, worldGraph)) continue; m2::DistanceToLineSquare squaredDistance; diff --git a/routing/index_router.hpp b/routing/index_router.hpp index 1bb8c00b40..43875f9352 100644 --- a/routing/index_router.hpp +++ b/routing/index_router.hpp @@ -71,13 +71,10 @@ private: RouterDelegate const & delegate, Route & route); /// \brief Finds closest edges which may be considered as start of finish of the route. - /// \param fromPoint == true is |point| is considered as the start of the route. - /// fromPoint == false is |point| is considered as the finish of the route. - bool FindClosestEdge(WorldGraph & worldGraph, - platform::CountryFile const & file, - m2::PointD const & point, - bool fromPoint, - Edge & closestEdge) const; + /// \param isOutgoing == true is |point| is considered as the start of the route. + /// isOutgoing == false is |point| is considered as the finish of the route. + bool FindClosestEdge(platform::CountryFile const & file, m2::PointD const & point, + bool isOutgoing, WorldGraph & worldGraph, Edge & closestEdge) const; // Input route may contains 'leaps': shortcut edges from mwm border enter to exit. // ProcessLeaps replaces each leap with calculated route through mwm. IRouter::ResultCode ProcessLeaps(vector const & input, RouterDelegate const & delegate, diff --git a/routing/road_graph.hpp b/routing/road_graph.hpp index 6fcc21a6c9..ccd0bff734 100644 --- a/routing/road_graph.hpp +++ b/routing/road_graph.hpp @@ -123,7 +123,9 @@ public: class IRoadGraph : public RoadGraphBase { public: - typedef vector TJunctionVector; + // CheckGraphConnectivity() types aliases: + using Vertex = Junction; + using Edge = routing::Edge; enum class Mode { diff --git a/routing/road_graph_router.cpp b/routing/road_graph_router.cpp index bcf8784ec9..52f059d7f3 100644 --- a/routing/road_graph_router.cpp +++ b/routing/road_graph_router.cpp @@ -81,15 +81,12 @@ void FindClosestEdges(IRoadGraph const & graph, m2::PointD const & point, for (auto const & candidate : candidates) { auto const & edge = candidate.first; - auto const getVertexByEdgeFn = [](Edge const & edge){ - return edge.GetEndJunction(); - }; - auto const getOutgoingEdgesFn = [](IRoadGraph const & graph, Junction const & u, vector & edges){ - graph.GetOutgoingEdges(u, edges); - }; + auto const getVertexByEdgeFn = [](Edge const & edge) { return edge.GetEndJunction(); }; + auto const getOutgoingEdgesFn = [](IRoadGraph const & graph, Junction const & u, + vector & edges) { graph.GetOutgoingEdges(u, edges); }; - if (CheckGraphConnectivity(graph, edge.GetEndJunction(), kTestConnectivityVisitJunctionsLimit, - getVertexByEdgeFn, getOutgoingEdgesFn)) + if (CheckGraphConnectivity(edge.GetEndJunction(), kTestConnectivityVisitJunctionsLimit, + graph, getVertexByEdgeFn, getOutgoingEdgesFn)) { vicinity.emplace_back(candidate); diff --git a/routing/routing_helpers.hpp b/routing/routing_helpers.hpp index d8af77d25e..2633dd2ba7 100644 --- a/routing/routing_helpers.hpp +++ b/routing/routing_helpers.hpp @@ -33,37 +33,39 @@ void ReconstructRoute(IDirectionsEngine & engine, RoadGraphBase const & graph, shared_ptr const & trafficStash, my::Cancellable const & cancellable, vector & path, Route & route); -/// \brief Checks is edge connected with world graph. Function does BFS while it finds some number of edges, -/// if graph ends before this number is reached then junction is assumed as not connected to the world graph. -template -bool CheckGraphConnectivity(Graph & graph, GraphVertex const & vertex, size_t limit, +/// \brief Checks is edge connected with world graph. Function does BFS while it finds some number +/// of edges, +/// if graph ends before this number is reached then junction is assumed as not connected to the +/// world graph. +template +bool CheckGraphConnectivity(typename Graph::Vertex const & start, size_t limit, Graph & graph, GetVertexByEdgeFn && getVertexByEdgeFn, GetOutgoingEdgesFn && getOutgoingEdgesFn) { - queue q; - q.push(vertex); + queue q; + q.push(start); - set visited; - visited.insert(vertex); + set marked; + marked.insert(start); - vector edges; - while (!q.empty() && visited.size() < limit) + vector edges; + while (!q.empty() && marked.size() < limit) { - GraphVertex const u = q.front(); + auto const u = q.front(); q.pop(); edges.clear(); getOutgoingEdgesFn(graph, u, edges); - for (GraphEdge const edge : edges) + for (auto const & edge : edges) { - GraphVertex const & v = getVertexByEdgeFn(edge); - if (visited.count(v) == 0) + auto const & v = getVertexByEdgeFn(edge); + if (marked.count(v) == 0) { q.push(v); - visited.insert(v); + marked.insert(v); } } } - return visited.size() >= limit; + return marked.size() >= limit; } } // namespace rouing diff --git a/routing/routing_tests/index_graph_test.cpp b/routing/routing_tests/index_graph_test.cpp index 828ba533ec..e027dcf29f 100644 --- a/routing/routing_tests/index_graph_test.cpp +++ b/routing/routing_tests/index_graph_test.cpp @@ -218,7 +218,8 @@ UNIT_TEST(FindPathCross) uint32_t expectedLength = 0; if (start.GetFeatureId() == finish.GetFeatureId()) { - expectedLength = AbsDelta(start.GetSegmentIdxForTesting(), finish.GetSegmentIdxForTesting()) + 1; + expectedLength = + AbsDelta(start.GetSegmentIdxForTesting(), finish.GetSegmentIdxForTesting()) + 1; } else { @@ -303,7 +304,8 @@ UNIT_TEST(FindPathManhattan) if (start.GetFeatureId() < kCitySize == finish.GetFeatureId() < kCitySize) { - uint32_t segDelta = AbsDelta(start.GetSegmentIdxForTesting(), finish.GetSegmentIdxForTesting()); + uint32_t segDelta = + AbsDelta(start.GetSegmentIdxForTesting(), finish.GetSegmentIdxForTesting()); if (segDelta == 0 && start.GetFeatureId() != finish.GetFeatureId()) segDelta = 1; expectedLength += segDelta; diff --git a/routing/world_graph.hpp b/routing/world_graph.hpp index 984cafe1f5..3846238154 100644 --- a/routing/world_graph.hpp +++ b/routing/world_graph.hpp @@ -17,6 +17,10 @@ namespace routing class WorldGraph final { public: + // CheckGraphConnectivity() types aliases: + using Vertex = Segment; + using Edge = SegmentEdge; + enum class Mode { SingleMwm, // Mode for building a route within single mwm.