If the route goes along the rightmost or the leftmost way among available ones: 1. RightmostDirection or LeftmostDirection is selected 2. If the turn direction is |CarDirection::GoStraight| and there's another not sharp enough turn GoStraight is corrected to TurnSlightRight/TurnSlightLeft to avoid ambiguity for GoStraight direction: 2 or more almost straight turns.
| 378 | // GoStraight is corrected to TurnSlightRight/TurnSlightLeft |
| 379 | // to avoid ambiguity for GoStraight direction: 2 or more almost straight turns. |
| 380 | void CorrectRightmostAndLeftmost(vector<TurnCandidate> const & turnCandidates, Segment const & firstOutgoingSeg, |
| 381 | double const turnAngle, TurnItem & turn) |
| 382 | { |
| 383 | // turnCandidates are sorted by angle from leftmost to rightmost. |
| 384 | // Normally no duplicates should be found. But if they are present we can't identify the leftmost/rightmost by order. |
| 385 | if (adjacent_find(turnCandidates.begin(), turnCandidates.end(), base::EqualsBy(&TurnCandidate::m_angle)) != |
| 386 | turnCandidates.end()) |
| 387 | { |
| 388 | LOG(LWARNING, ("nodes.candidates are not expected to have same m_angle.")); |
| 389 | return; |
| 390 | } |
| 391 | |
| 392 | double constexpr kMaxAbsAngleConsideredLeftOrRightMost = 90; |
| 393 | |
| 394 | // Go from left to right to findout if the route goes through the leftmost candidate and fixes can be applied. |
| 395 | // Other candidates which are sharper than kMaxAbsAngleConsideredLeftOrRightMost are ignored. |
| 396 | for (auto candidate = turnCandidates.begin(); candidate != turnCandidates.end(); ++candidate) |
| 397 | { |
| 398 | if (candidate->m_segment == firstOutgoingSeg && candidate + 1 != turnCandidates.end()) |
| 399 | { |
| 400 | // The route goes along the leftmost candidate. |
| 401 | turn.m_turn = LeftmostDirection(turnAngle); |
| 402 | if (IntermediateDirection(turnAngle) != turn.m_turn) |
| 403 | LOG(LDEBUG, ("Turn: ", turn.m_index, " LeftmostDirection correction.")); |
| 404 | // Compare with the next candidate to the right. |
| 405 | CorrectGoStraight(*(candidate + 1), candidate->m_angle, CarDirection::TurnSlightLeft, turn); |
| 406 | break; |
| 407 | } |
| 408 | // Check if this candidate is considered as leftmost as not too sharp. |
| 409 | // If yes - this candidate is leftmost, not route's one. |
| 410 | if (candidate->m_angle > -kMaxAbsAngleConsideredLeftOrRightMost) |
| 411 | break; |
| 412 | } |
| 413 | // Go from right to left to findout if the route goes through the rightmost candidate anf fixes can be applied. |
| 414 | // Other candidates which are sharper than kMaxAbsAngleConsideredLeftOrRightMost are ignored. |
| 415 | for (auto candidate = turnCandidates.rbegin(); candidate != turnCandidates.rend(); ++candidate) |
| 416 | { |
| 417 | if (candidate->m_segment == firstOutgoingSeg && candidate + 1 != turnCandidates.rend()) |
| 418 | { |
| 419 | // The route goes along the rightmost candidate. |
| 420 | turn.m_turn = RightmostDirection(turnAngle); |
| 421 | if (IntermediateDirection(turnAngle) != turn.m_turn) |
| 422 | LOG(LDEBUG, ("Turn: ", turn.m_index, " RighmostDirection correction.")); |
| 423 | // Compare with the next candidate to the left. |
| 424 | CorrectGoStraight(*(candidate + 1), candidate->m_angle, CarDirection::TurnSlightRight, turn); |
| 425 | break; |
| 426 | } |
| 427 | // Check if this candidate is considered as rightmost as not too sharp. |
| 428 | // If yes - this candidate is rightmost, not route's one. |
| 429 | if (candidate->m_angle < kMaxAbsAngleConsideredLeftOrRightMost) |
| 430 | break; |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | void GetTurnDirectionBasic(IRoutingResult const & result, size_t const outgoingSegmentIndex, |
| 435 | NumMwmIds const & numMwmIds, RoutingSettings const & vehicleSettings, TurnItem & turn) |
no test coverage detected