diff --git a/platform/location.hpp b/platform/location.hpp index d4a620b0cb..d4432eea29 100644 --- a/platform/location.hpp +++ b/platform/location.hpp @@ -136,6 +136,8 @@ namespace location string m_distToTurn; string m_turnUnitsSuffix; routing::turns::TurnDirection m_turn; + /// Turn after m_turn. NoTurn if there-is no turns after. + routing::turns::TurnDirection m_nextTurn; uint32_t m_exitNum; //@} int m_time; diff --git a/routing/route.cpp b/routing/route.cpp index 783d4aaa9c..bed66be1a6 100644 --- a/routing/route.cpp +++ b/routing/route.cpp @@ -135,32 +135,44 @@ uint32_t Route::GetCurrentTimeToEndSec() const return (uint32_t)((GetTotalTimeSec() - (*it).second)); } +Route::TTurns::const_iterator Route::GetCurrentTurn() const +{ + ASSERT(!m_turns.empty(), ()); + + turns::TurnItem t; + t.m_index = static_cast(m_poly.GetCurrentIter().m_ind); + return upper_bound(m_turns.cbegin(), m_turns.cend(), t, + [](turns::TurnItem const & lhs, turns::TurnItem const & rhs) + { + return lhs.m_index < rhs.m_index; + }); +} + void Route::GetCurrentTurn(double & distanceToTurnMeters, turns::TurnItem & turn) const { - if (m_turns.empty()) + auto it = GetCurrentTurn(); + if (it == m_turns.end()) { - ASSERT(!m_turns.empty(), ()); + ASSERT(it != m_turns.end(), ()); distanceToTurnMeters = 0; turn = turns::TurnItem(); return; } - turns::TurnItem t; - t.m_index = static_cast(m_poly.GetCurrentIter().m_ind); - auto it = upper_bound(m_turns.begin(), m_turns.end(), t, - [](turns::TurnItem const & lhs, turns::TurnItem const & rhs) - { - return lhs.m_index < rhs.m_index; - }); - - ASSERT_GREATER_OR_EQUAL((*it).m_index, 0, ()); - size_t const segIdx = (*it).m_index; turn = (*it); distanceToTurnMeters = m_poly.GetDistanceM(m_poly.GetCurrentIter(), m_poly.GetIterToIndex(segIdx)); } +void Route::GetNextTurn(turns::TurnItem & turn) const +{ + auto it = GetCurrentTurn(); + ASSERT(it != m_turns.end(), ()); + ++it; + turn = it != m_turns.end() ? *it : turns::TurnItem(); +} + void Route::GetCurrentDirectionPoint(m2::PointD & pt) const { if (m_routingSettings.m_keepPedestrianInfo && m_simplifiedPoly.IsValid()) diff --git a/routing/route.hpp b/routing/route.hpp index 7f0cb3ed7b..138470d35e 100644 --- a/routing/route.hpp +++ b/routing/route.hpp @@ -73,6 +73,8 @@ public: double GetMercatorDistanceFromBegin() const; void GetCurrentTurn(double & distanceToTurnMeters, turns::TurnItem & turn) const; + /// Returns turn after current. + void GetNextTurn(turns::TurnItem & turn) const; void GetCurrentDirectionPoint(m2::PointD & pt) const; @@ -101,6 +103,7 @@ private: /// Call this fucnction when geometry have changed. void Update(); double GetPolySegAngle(size_t ind) const; + TTurns::const_iterator GetCurrentTurn() const; private: friend string DebugPrint(Route const & r); diff --git a/routing/routing_session.cpp b/routing/routing_session.cpp index a8b5642fdc..aaaa362940 100644 --- a/routing/routing_session.cpp +++ b/routing/routing_session.cpp @@ -202,10 +202,13 @@ void RoutingSession::GetRouteFollowingInfo(FollowingInfo & info) const double distanceToTurnMeters = 0.; turns::TurnItem turn; + turns::TurnItem nextTurn; m_route.GetCurrentTurn(distanceToTurnMeters, turn); + m_route.GetNextTurn(nextTurn); formatDistFn(distanceToTurnMeters, info.m_distToTurn, info.m_turnUnitsSuffix); info.m_turn = turn.m_turn; + info.m_nextTurn = nextTurn.m_turn; info.m_exitNum = turn.m_exitNum; info.m_time = m_route.GetCurrentTimeToEndSec(); info.m_sourceName = turn.m_sourceName;