From 66a203752aab620575c06791fe8454a798c4ac52 Mon Sep 17 00:00:00 2001 From: Vladimir Byko-Ianko Date: Fri, 25 Sep 2020 11:16:39 +0300 Subject: [PATCH] [routing] Adding a callback on change turn. --- routing/route.cpp | 26 ++++++++++++++++++-------- routing/route.hpp | 9 +++++++++ routing/routing_callbacks.hpp | 3 +++ routing/routing_session.cpp | 16 ++++++++++++++++ routing/routing_session.hpp | 2 ++ 5 files changed, 48 insertions(+), 8 deletions(-) diff --git a/routing/route.cpp b/routing/route.cpp index 196604c2dc..905383e5a5 100644 --- a/routing/route.cpp +++ b/routing/route.cpp @@ -30,14 +30,6 @@ namespace { double constexpr kOnEndToleranceM = 10.0; double constexpr kSteetNameLinkMeters = 400.; - -bool IsNormalTurn(TurnItem const & turn) -{ - CHECK_NOT_EQUAL(turn.m_turn, CarDirection::Count, ()); - CHECK_NOT_EQUAL(turn.m_pedestrianTurn, PedestrianDirection::Count, ()); - - return !turn.IsTurnNone(); -} } // namespace Route::Route(string const & router, vector const & points, uint64_t routeId, @@ -189,6 +181,16 @@ void Route::GetCurrentTurn(double & distanceToTurnMeters, TurnItem & turn) const m_poly.GetIterToIndex(turn.m_index)); } +optional Route::GetCurrentIteratorTurn() const +{ + auto const & iter = m_poly.GetCurrentIter(); + if (!iter.IsValid()) + return nullopt; + + CHECK_LESS(iter.m_ind, m_routeSegments.size(), ()); + return m_routeSegments[iter.m_ind].GetTurn(); +} + bool Route::GetNextTurn(double & distanceToTurnMeters, TurnItem & nextTurn) const { TurnItem curTurn; @@ -427,6 +429,14 @@ double Route::GetETAToLastPassedPointSec() const return curIter.m_ind == 0 ? 0.0 : m_routeSegments[curIter.m_ind - 1].GetTimeFromBeginningSec(); } +bool IsNormalTurn(TurnItem const & turn) +{ + CHECK_NOT_EQUAL(turn.m_turn, CarDirection::Count, ()); + CHECK_NOT_EQUAL(turn.m_pedestrianTurn, PedestrianDirection::Count, ()); + + return !turn.IsTurnNone(); +} + string DebugPrint(Route const & r) { return DebugPrint(r.m_poly.GetPolyline()); diff --git a/routing/route.hpp b/routing/route.hpp index 250c0a9500..82a7a00f4d 100644 --- a/routing/route.hpp +++ b/routing/route.hpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -297,6 +298,11 @@ public: /// \param turn is information about the nearest turn. void GetCurrentTurn(double & distanceToTurnMeters, turns::TurnItem & turn) const; + /// \brief Extracts information about turn RouteSegment according to current iterator + /// set with MoveIterator() method. + /// \returns true if |turn| is filled correctly and false otherwise. + std::optional GetCurrentIteratorTurn() const; + /// \brief Returns a name of a street where the user rides at this moment. void GetCurrentStreetName(std::string & name) const; @@ -415,4 +421,7 @@ private: // Mwms which are crossed by the route where speed cameras are prohibited. std::vector m_speedCamPartlyProhibitedMwms; }; + +/// \returns true if |turn| is equal to turns::CarDirection::None or |turns::PedestrianDirection::None|. +bool IsNormalTurn(turns::TurnItem const & turn); } // namespace routing diff --git a/routing/routing_callbacks.hpp b/routing/routing_callbacks.hpp index 22a1f7f80b..2354cc3c7d 100644 --- a/routing/routing_callbacks.hpp +++ b/routing/routing_callbacks.hpp @@ -1,5 +1,7 @@ #pragma once +#include "routing/turns.hpp" + #include "geometry/latlon.hpp" #include "geometry/point2d.hpp" @@ -82,6 +84,7 @@ using ChangeSessionStateCallback = std::function const &)>; using SpeedCameraShowCallback = std::function; using SpeedCameraClearCallback = std::function; +using OnNewTurn = std::function; inline std::string ToString(RouterResultCode code) { diff --git a/routing/routing_session.cpp b/routing/routing_session.cpp index 0971e7c14c..575149dc91 100644 --- a/routing/routing_session.cpp +++ b/routing/routing_session.cpp @@ -290,6 +290,7 @@ SessionState RoutingSession::OnLocationPositionChanged(GpsInfo const & info) m_turnNotificationsMgr.SetSpeedMetersPerSecond(info.m_speedMpS); + auto const formerCurIter = m_route->GetCurrentIteratorTurn(); if (m_route->MoveIterator(info)) { m_moveAwayCounter = 0; @@ -316,6 +317,15 @@ SessionState RoutingSession::OnLocationPositionChanged(GpsInfo const & info) if (m_userCurrentPositionValid) m_lastGoodPosition = m_userCurrentPosition; + auto const curIter = m_route->GetCurrentIteratorTurn(); + // If we are moving to the next segment after passing the turn + // it means the turn is changed. So the |m_onNewTurn| should be called. + if (formerCurIter && curIter && IsNormalTurn(*formerCurIter) && + formerCurIter->m_index < curIter->m_index && m_onNewTurn) + { + m_onNewTurn(); + } + return m_state; } @@ -664,6 +674,12 @@ void RoutingSession::SetChangeSessionStateCallback( m_changeSessionStateCallback = changeSessionStateCallback; } +void RoutingSession::SetOnNewTurnCallback(OnNewTurn const & onNewTurn) +{ + CHECK_THREAD_CHECKER(m_threadChecker, ()); + m_onNewTurn = onNewTurn; +} + void RoutingSession::SetUserCurrentPosition(m2::PointD const & position) { CHECK_THREAD_CHECKER(m_threadChecker, ()); diff --git a/routing/routing_session.hpp b/routing/routing_session.hpp index e1a45372c8..e0010e2462 100644 --- a/routing/routing_session.hpp +++ b/routing/routing_session.hpp @@ -130,6 +130,7 @@ public: void SetCheckpointCallback(CheckpointCallback const & checkpointCallback); /// \brief Sets a callback which is called every time when RoutingSession::m_state is changed. void SetChangeSessionStateCallback(ChangeSessionStateCallback const & changeSessionStateCallback); + void SetOnNewTurnCallback(OnNewTurn const & onNewTurn); void SetSpeedCamShowCallback(SpeedCameraShowCallback && callback); void SetSpeedCamClearCallback(SpeedCameraClearCallback && callback); @@ -221,6 +222,7 @@ private: ProgressCallback m_progressCallback; CheckpointCallback m_checkpointCallback; ChangeSessionStateCallback m_changeSessionStateCallback; + OnNewTurn m_onNewTurn; // Statistics parameters // Passed distance on route including reroutes