diff --git a/routing/index_graph_starter.cpp b/routing/index_graph_starter.cpp index c1eff6831f..ad6957b579 100644 --- a/routing/index_graph_starter.cpp +++ b/routing/index_graph_starter.cpp @@ -27,14 +27,14 @@ Junction CalcProjectionToSegment(Segment const & segment, m2::PointD const & poi m2::ProjectionToSection projection; projection.SetBounds(begin.GetPoint(), end.GetPoint()); auto projectedPoint = projection(point); - auto const distBeginToEnd = graph.GetEstimator().CalcLeapWeight(begin.GetPoint(), end.GetPoint()); + auto const distBeginToEnd = graph.CalcLeapWeight(begin.GetPoint(), end.GetPoint()).GetWeight(); double constexpr kEpsMeters = 2.0; if (my::AlmostEqualAbs(distBeginToEnd, 0.0, kEpsMeters)) return Junction(projectedPoint, begin.GetAltitude()); auto const distBeginToProjection = - graph.GetEstimator().CalcLeapWeight(begin.GetPoint(), projectedPoint); + graph.CalcLeapWeight(begin.GetPoint(), projectedPoint).GetWeight(); auto const altitude = begin.GetAltitude() + (end.GetAltitude() - begin.GetAltitude()) * distBeginToProjection / distBeginToEnd; return Junction(projectedPoint, altitude); @@ -285,19 +285,15 @@ RouteWeight IndexGraphStarter::CalcSegmentWeight(Segment const & segment) const { if (!IsFakeSegment(segment)) { - return RouteWeight( - m_graph.GetEstimator().CalcSegmentWeight( - segment, m_graph.GetRoadGeometry(segment.GetMwmId(), segment.GetFeatureId())), - 0 /* nontransitCross */); + return m_graph.CalcSegmentWeight(segment); } auto const fakeVertexIt = m_fake.m_segmentToVertex.find(segment); CHECK(fakeVertexIt != m_fake.m_segmentToVertex.end(), ("Requested junction for invalid fake segment.")); - return RouteWeight(m_graph.GetEstimator().CalcLeapWeight(fakeVertexIt->second.GetPointFrom(), - fakeVertexIt->second.GetPointTo()), - 0 /* nontransitCross */); + return m_graph.CalcLeapWeight(fakeVertexIt->second.GetPointFrom(), + fakeVertexIt->second.GetPointTo()); } RouteWeight IndexGraphStarter::CalcRouteSegmentWeight(vector const & route, @@ -320,7 +316,7 @@ bool IndexGraphStarter::IsLeap(NumMwmId mwmId) const return false; } - return m_graph.GetEstimator().LeapIsAllowed(mwmId); + return m_graph.LeapIsAllowed(mwmId); } void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding, FakeEnding const & otherEnding, @@ -361,10 +357,10 @@ void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding, FakeEnding cons if (it != otherSegments.end()) { auto const & otherJunction = it->second; - auto const distBackToThis = m_graph.GetEstimator().CalcLeapWeight( - backJunction.GetPoint(), projection.m_junction.GetPoint()); - auto const distBackToOther = - m_graph.GetEstimator().CalcLeapWeight(backJunction.GetPoint(), otherJunction.GetPoint()); + auto const distBackToThis = m_graph.CalcLeapWeight(backJunction.GetPoint(), + projection.m_junction.GetPoint()); + auto const distBackToOther = m_graph.CalcLeapWeight(backJunction.GetPoint(), + otherJunction.GetPoint()); if (distBackToThis < distBackToOther) frontJunction = otherJunction; else @@ -432,33 +428,7 @@ void IndexGraphStarter::AddStart(FakeEnding const & startEnding, FakeEnding cons void IndexGraphStarter::AddRealEdges(Segment const & segment, bool isOutgoing, std::vector & edges) const { - if (m_graph.GetMode() == WorldGraph::Mode::LeapsOnly && - m_fake.m_realToFake.find(segment) != m_fake.m_realToFake.end()) - { - ConnectLeapToTransitions(segment, isOutgoing, edges); - return; - } - - m_graph.GetEdgeList(segment, isOutgoing, IsLeap(segment.GetMwmId()), edges); + bool const isEnding = m_fake.m_realToFake.find(segment) != m_fake.m_realToFake.end(); + m_graph.GetEdgeList(segment, isOutgoing, IsLeap(segment.GetMwmId()), isEnding, edges); } - -void IndexGraphStarter::ConnectLeapToTransitions(Segment const & segment, bool isOutgoing, - vector & edges) const -{ - edges.clear(); - m2::PointD const & segmentPoint = GetPoint(segment, true /* front */); - - // Note. If |isOutgoing| == true it's necessary to add edges which connect the start with all - // exits of its mwm. So |isEnter| below should be set to false. - // If |isOutgoing| == false all enters of the finish mwm should be connected with the finish - // point. So |isEnter| below should be set to true. - m_graph.ForEachTransition( - segment.GetMwmId(), !isOutgoing /* isEnter */, [&](Segment const & transition) { - edges.emplace_back(transition, - RouteWeight(m_graph.GetEstimator().CalcLeapWeight( - segmentPoint, GetPoint(transition, isOutgoing)), - 0 /* nontransitCross */)); - }); -} - } // namespace routing diff --git a/routing/index_graph_starter.hpp b/routing/index_graph_starter.hpp index a0bca0963e..25d26a4f01 100644 --- a/routing/index_graph_starter.hpp +++ b/routing/index_graph_starter.hpp @@ -104,9 +104,8 @@ public: RouteWeight HeuristicCostEstimate(TVertexType const & from, TVertexType const & to) const { - return RouteWeight(m_graph.GetEstimator().CalcHeuristic(GetPoint(from, true /* front */), - GetPoint(to, true /* front */)), - 0 /* nontransitCross */); + return m_graph.HeuristicCostEstimate(GetPoint(from, true /* front */), + GetPoint(to, true /* front */)); } RouteWeight CalcSegmentWeight(Segment const & segment) const; @@ -208,12 +207,6 @@ private: // Adds real edges from m_graph void AddRealEdges(Segment const & segment, bool isOutgoing, std::vector & edges) const; - /// \brief If |isOutgoing| == true fills |edges| with SegmentEdge(s) which connects - /// |fakeVertex| with all exits of mwm. - /// \brief If |isOutgoing| == false fills |edges| with SegmentEdge(s) which connects - /// all enters to mwm with |fakeVertex|. - void ConnectLeapToTransitions(Segment const & segment, bool isOutgoing, - std::vector & edges) const; WorldGraph & m_graph; // Start segment id diff --git a/routing/index_router.cpp b/routing/index_router.cpp index c09a2e02d1..b2db2c5195 100644 --- a/routing/index_router.cpp +++ b/routing/index_router.cpp @@ -140,7 +140,7 @@ bool IsDeadEnd(Segment const & segment, bool isOutgoing, WorldGraph & worldGraph // 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); + graph.GetEdgeList(u, isOutgoing, false /* isLeap */, false /* isEnding */, edges); }; return !CheckGraphConnectivity(segment, kDeadEndTestLimit, worldGraph, diff --git a/routing/world_graph.cpp b/routing/world_graph.cpp index 4082c6e355..54cfd91093 100644 --- a/routing/world_graph.cpp +++ b/routing/world_graph.cpp @@ -13,8 +13,28 @@ WorldGraph::WorldGraph(unique_ptr crossMwmGraph, unique_ptr & edges) + bool isEnding, std::vector & edges) { + // If mode is LeapsOnly and |isEnding| == true we need to connect segment to transitions. + // If |isOutgoing| == true connects |segment| with all exits of mwm. + // If |isOutgoing| == false connects all enters to mwm with |segment|. + if (m_mode == Mode::LeapsOnly && isEnding) + { + edges.clear(); + m2::PointD const & segmentPoint = GetPoint(segment, true /* front */); + + // Note. If |isOutgoing| == true it's necessary to add edges which connect the start with all + // exits of its mwm. So |isEnter| below should be set to false. + // If |isOutgoing| == false all enters of the finish mwm should be connected with the finish + // point. So |isEnter| below should be set to true. + m_crossMwmGraph->ForEachTransition( + segment.GetMwmId(), !isOutgoing /* isEnter */, [&](Segment const & transition) { + edges.emplace_back(transition, CalcLeapWeight(segmentPoint, + GetPoint(transition, isOutgoing))); + }); + return; + } + if (m_mode != Mode::NoLeaps && (isLeap || m_mode == Mode::LeapsOnly)) { CHECK(m_crossMwmGraph, ()); @@ -51,22 +71,44 @@ RoadGeometry const & WorldGraph::GetRoadGeometry(NumMwmId mwmId, uint32_t featur void WorldGraph::GetOutgoingEdgesList(Segment const & segment, vector & edges) { edges.clear(); - GetEdgeList(segment, true /* isOutgoing */, false /* isLeap */, edges); + GetEdgeList(segment, true /* isOutgoing */, false /* isLeap */, false /* isEnding */, edges); } void WorldGraph::GetIngoingEdgesList(Segment const & segment, vector & edges) { edges.clear(); - GetEdgeList(segment, false /* isOutgoing */, false /* isLeap */, edges); + GetEdgeList(segment, false /* isOutgoing */, false /* isLeap */, false /* isEnding */, edges); } RouteWeight WorldGraph::HeuristicCostEstimate(Segment const & from, Segment const & to) +{ + return HeuristicCostEstimate(GetPoint(from, true /* front */), + GetPoint(to, true /* front */)); +} + +RouteWeight WorldGraph::HeuristicCostEstimate(m2::PointD const & from, m2::PointD const & to) +{ + return RouteWeight(m_estimator->CalcHeuristic(from, to), 0 /* nontransitCross */); +} + + +RouteWeight WorldGraph::CalcSegmentWeight(Segment const & segment) { return RouteWeight( - m_estimator->CalcHeuristic(GetPoint(from, true /* front */), GetPoint(to, true /* front */)), + m_estimator->CalcSegmentWeight(segment, GetRoadGeometry(segment.GetMwmId(), segment.GetFeatureId())), 0 /* nontransitCross */); } +RouteWeight WorldGraph::CalcLeapWeight(m2::PointD const & from, m2::PointD const & to) const +{ + return RouteWeight(m_estimator->CalcLeapWeight(from, to), 0 /* nontransitCross */); +} + +bool WorldGraph::LeapIsAllowed(NumMwmId mwmId) const +{ + return m_estimator->LeapIsAllowed(mwmId); +} + void WorldGraph::GetTwins(Segment const & segment, bool isOutgoing, vector & edges) { m_twins.clear(); diff --git a/routing/world_graph.hpp b/routing/world_graph.hpp index 090967581a..b372b15709 100644 --- a/routing/world_graph.hpp +++ b/routing/world_graph.hpp @@ -40,11 +40,12 @@ public: WorldGraph(std::unique_ptr crossMwmGraph, std::unique_ptr loader, std::shared_ptr estimator); + // |isEnding| == true iff |segment| is first or last segment of the route. Needed because first and + // last segments may need special processing. void GetEdgeList(Segment const & segment, bool isOutgoing, bool isLeap, - std::vector & edges); + bool isEnding, std::vector & edges); IndexGraph & GetIndexGraph(NumMwmId numMwmId) { return m_loader->GetIndexGraph(numMwmId); } - EdgeEstimator const & GetEstimator() const { return *m_estimator; } Junction const & GetJunction(Segment const & segment, bool front); m2::PointD const & GetPoint(Segment const & segment, bool front); @@ -58,18 +59,12 @@ public: // Interface for AStarAlgorithm: void GetOutgoingEdgesList(Segment const & segment, vector & edges); void GetIngoingEdgesList(Segment const & segment, vector & edges); + RouteWeight HeuristicCostEstimate(Segment const & from, Segment const & to); - - template - void ForEachTransition(NumMwmId numMwmId, bool isEnter, Fn && fn) - { - m_crossMwmGraph->ForEachTransition(numMwmId, isEnter, std::forward(fn)); - } - - bool IsTransition(Segment const & s, bool isOutgoing) - { - return m_crossMwmGraph->IsTransition(s, isOutgoing); - } + RouteWeight HeuristicCostEstimate(m2::PointD const & from, m2::PointD const & to); + RouteWeight CalcSegmentWeight(Segment const & segment); + RouteWeight CalcLeapWeight(m2::PointD const & from, m2::PointD const & to) const; + bool LeapIsAllowed(NumMwmId mwmId) const; private: void GetTwins(Segment const & s, bool isOutgoing, std::vector & edges);