| 263 | } |
| 264 | |
| 265 | SessionState RoutingSession::OnLocationPositionChanged(GpsInfo const & info) |
| 266 | { |
| 267 | CHECK_THREAD_CHECKER(m_threadChecker, ()); |
| 268 | ASSERT_NOT_EQUAL(m_state, SessionState::NoValidRoute, ()); |
| 269 | ASSERT(m_router, ()); |
| 270 | |
| 271 | if (m_state == SessionState::RouteFinished || m_state == SessionState::RouteBuilding || |
| 272 | m_state == SessionState::RouteNoFollowing || m_state == SessionState::NoValidRoute) |
| 273 | { |
| 274 | return m_state; |
| 275 | } |
| 276 | |
| 277 | CHECK(m_route, (m_state)); |
| 278 | // Note. The route may not be valid here. It happens in case when while the first route |
| 279 | // build is cancelled because of traffic jam were downloaded. After that route rebuilding |
| 280 | // happens. While the rebuilding may be called OnLocationPositionChanged(...) |
| 281 | if (!m_route->IsValid()) |
| 282 | return m_state; |
| 283 | |
| 284 | m_turnNotificationsMgr.SetSpeedMetersPerSecond(info.m_speed); |
| 285 | |
| 286 | auto const formerIter = m_route->GetCurrentIteratorTurn(); |
| 287 | if (m_route->MoveIterator(info)) |
| 288 | { |
| 289 | m_moveAwayCounter = 0; |
| 290 | m_lastDistance = 0.0; |
| 291 | |
| 292 | PassCheckpoints(); |
| 293 | |
| 294 | if (m_checkpoints.IsFinished()) |
| 295 | { |
| 296 | m_passedDistanceOnRouteMeters += m_route->GetTotalDistanceMeters(); |
| 297 | SetState(SessionState::RouteFinished); |
| 298 | } |
| 299 | else |
| 300 | { |
| 301 | SetState(SessionState::OnRoute); |
| 302 | m_speedCameraManager.OnLocationPositionChanged(info); |
| 303 | } |
| 304 | |
| 305 | if (m_userCurrentPositionValid) |
| 306 | m_lastGoodPosition = m_userCurrentPosition; |
| 307 | |
| 308 | auto const curIter = m_route->GetCurrentIteratorTurn(); |
| 309 | // If we are moving to the next segment after passing the turn |
| 310 | // it means the turn is changed. So the |m_onNewTurn| should be called. |
| 311 | if (formerIter && curIter && IsNormalTurn(*formerIter) && formerIter->m_index < curIter->m_index && m_onNewTurn) |
| 312 | m_onNewTurn(); |
| 313 | |
| 314 | return m_state; |
| 315 | } |
| 316 | |
| 317 | if (m_state != SessionState::RouteNeedsRebuild && m_state != SessionState::RouteRebuilding) |
| 318 | { |
| 319 | // Distance from the last known projection on route |
| 320 | // (check if we are moving far from the last known projection). |
| 321 | auto const & lastGoodPoint = m_route->GetFollowedPolyline().GetCurrentIter().m_pt; |
| 322 | double const dist = |