[routing] Remove unnecessary "keep left/right" directions from the route #2397
|
@ -129,7 +129,7 @@ bool GetTurnHighwayClasses(TurnCandidates const & possibleTurns, TurnInfo const
|
|||
if (t.m_segment == firstOutgoingSegment || t.m_segment == inversedLastIngoingSegment)
|
||||
continue;
|
||||
ftypes::HighwayClass const highwayClass = t.m_highwayClass;
|
||||
// Note. The bigger road the less HighwayClass value.
|
||||
// @note The bigger is the road, the lesser is HighwayClass value.
|
||||
if (static_cast<int>(highwayClass) < static_cast<int>(turnHighwayClasses.m_biggestPossibleTurnRoadClass))
|
||||
turnHighwayClasses.m_biggestPossibleTurnRoadClass = highwayClass;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ bool GetTurnHighwayClasses(TurnCandidates const & possibleTurns, TurnInfo const
|
|||
if (turnHighwayClasses.m_biggestPossibleTurnRoadClass == ftypes::HighwayClass::Count)
|
||||
return false; // No outgoing segments except for the route.
|
||||
|
||||
// Note. The bigger road the less HighwayClass value.
|
||||
// @note The bigger is the road, the lesser is HighwayClass value.
|
||||
turnHighwayClasses.m_smallestRouteRoadClass =
|
||||
static_cast<ftypes::HighwayClass>(max(static_cast<int>(turnInfo.m_ingoing.m_highwayClass),
|
||||
static_cast<int>(turnInfo.m_outgoing.m_highwayClass)));
|
||||
|
@ -162,16 +162,16 @@ bool GetTurnHighwayClasses(TurnCandidates const & possibleTurns, TurnInfo const
|
|||
return true;
|
||||
}
|
||||
|
||||
/// * \returns false when
|
||||
/// * \returns true when
|
||||
/// * - the route leads from one big road to another one;
|
||||
/// * - and the other possible turns lead to small roads;
|
||||
/// * Returns true otherwise.
|
||||
/// * Returns false otherwise.
|
||||
/// \param possibleTurns is all possible ways out from a junction.
|
||||
/// \param turnInfo is information about ingoing and outgoing segments of the route.
|
||||
/// \param carDirection is a direction about the current turn if it's available.
|
||||
/// If not, CarDirection::None should be passed.
|
||||
bool KeepTurnByHighwayClass(TurnCandidates const & possibleTurns, TurnInfo const & turnInfo,
|
||||
NumMwmIds const & numMwmIds, CarDirection carDirection)
|
||||
bool DiscardTurnByHighwayClass(TurnCandidates const & possibleTurns, TurnInfo const & turnInfo,
|
||||
NumMwmIds const & numMwmIds, CarDirection carDirection)
|
||||
{
|
||||
// Maximum difference between HighwayClasses of the route segments and
|
||||
// the possible way segments to keep the junction as a turn.
|
||||
|
@ -180,8 +180,9 @@ bool KeepTurnByHighwayClass(TurnCandidates const & possibleTurns, TurnInfo const
|
|||
int constexpr kMaxHighwayClassDiffForService = 1;
|
||||
|
||||
TurnHighwayClasses turnHighwayClasses;
|
||||
// Looks like a bug. If no info received turn should not be discarded
|
||||
if (!GetTurnHighwayClasses(possibleTurns, turnInfo, numMwmIds, turnHighwayClasses))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
int const diff =
|
||||
static_cast<int>(turnHighwayClasses.m_biggestPossibleTurnRoadClass) - static_cast<int>(turnHighwayClasses.m_smallestRouteRoadClass);
|
||||
|
@ -190,7 +191,64 @@ bool KeepTurnByHighwayClass(TurnCandidates const & possibleTurns, TurnInfo const
|
|||
(diff >= kMaxHighwayClassDiffForService && turnHighwayClasses.m_biggestPossibleTurnRoadClass == ftypes::HighwayClass::Service))
|
||||
{
|
||||
// The turn shall be removed if the route goes near small roads.
|
||||
return true;
|
||||
![]() да. завершил. да. завершил.
![]() ок. поправил еще в 2 местах откуда скопировал ок. поправил еще в 2 местах откуда скопировал
![]() ок ок
![]() ок ок
![]() ок ок
![]() непонятно непонятно
![]()
```
foo(int x,
int y)
```
![]()
```suggestion
bool KeepTurnByAlignedAlternatives(TurnCandidates const & possibleTurns, TurnInfo const & turnInfo,
NumMwmIds const & numMwmIds)
```
![]() спасибо. понял. спасибо. понял.
![]() done done
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// * \returns false when
|
||||
/// * - any alternative turn to a bigger road
|
||||
/// * - or any alternative turn to a similar road if the turn's angle is less than kMaxAbsAngleSameRoadClass degrees (wider than SlightTurn)
|
||||
/// * - or any alternative turn to a smaller road if it's GoStraight or SlightTurn.
|
||||
/// * Returns true otherwise.
|
||||
/// \param possibleTurns is all possible ways out from a junction.
|
||||
/// \param turnInfo is information about ingoing and outgoing segments of the route.
|
||||
/// it is supposed that current turn is GoStraight or SlightTurn
|
||||
bool DiscardTurnByNoAlignedAlternatives(TurnCandidates const & possibleTurns, TurnInfo const & turnInfo,
|
||||
NumMwmIds const & numMwmIds)
|
||||
{
|
||||
double constexpr kMaxAbsAngleSameRoadClass = 70.0;
|
||||
|
||||
ftypes::HighwayClass outgoingRouteRoadClass = turnInfo.m_outgoing.m_highwayClass;
|
||||
|
||||
// The turn should be kept if there's no any information about feature id of outgoing segment
|
||||
// just to be on the safe side. It may happen in case of outgoing segment is a finish segment.
|
||||
Segment firstOutgoingSegment;
|
||||
if (!turnInfo.m_outgoing.m_segmentRange.GetFirstSegment(numMwmIds, firstOutgoingSegment))
|
||||
return false;
|
||||
|
||||
Segment inversedLastIngoingSegment;
|
||||
if (!turnInfo.m_ingoing.m_segmentRange.GetLastSegment(numMwmIds, inversedLastIngoingSegment))
|
||||
return false;
|
||||
![]() Момент, если false исправлено на true, то коммент надо дополнить. Момент, если false исправлено на true, то коммент надо дополнить.
// Previous version was returning false and it looked like a bug. If no info received turn should not be discarded.
![]() Я не исправлял логику. Я не исправлял логику.
False исправлено на True, потому что функция была инверсно переименована, и все return были инвертированы.
|
||||
inversedLastIngoingSegment.Inverse();
|
||||
|
||||
for (auto const & t : possibleTurns.candidates)
|
||||
{
|
||||
// Let's consider all outgoing segments except for
|
||||
// (1) route outgoing segment
|
||||
// (2) a U-turn segment (inversedLastIngoingSegment)
|
||||
if (t.m_segment == firstOutgoingSegment || t.m_segment == inversedLastIngoingSegment)
|
||||
continue;
|
||||
ftypes::HighwayClass const highwayClass = t.m_highwayClass;
|
||||
// @note The bigger is the road, the lesser is HighwayClass value.
|
||||
if (static_cast<int>(highwayClass) < static_cast<int>(outgoingRouteRoadClass))
|
||||
{
|
||||
// Any alternative turn to a bigger road keeps the turn direction.
|
||||
return false;
|
||||
}
|
||||
else if (highwayClass == outgoingRouteRoadClass)
|
||||
{
|
||||
// Any alternative turn to a similar road keeps the turn direction if the turn's angle is less than
|
||||
// kMaxAbsAngleSameRoadClass degrees (wider than SlightTurn).
|
||||
if (fabs(t.m_angle) < kMaxAbsAngleSameRoadClass)
|
||||
return false;
|
||||
}
|
||||
else // static_cast<int>(highwayClass) > static_cast<int>(outgoingRouteRoadClass)
|
||||
{
|
||||
// Any alternative turn to a smaller road keeps the turn direction if it's GoStraight or SlightTurn.
|
||||
if (IsGoStraightOrSlightTurn(IntermediateDirection(t.m_angle)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -488,7 +546,7 @@ bool GetNextCrossSegmentRoutePoint(IRoutingResult const & result, RoutePointInde
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!KeepTurnByHighwayClass(possibleTurns, turnInfo, numMwmIds, CarDirection::None))
|
||||
if (DiscardTurnByHighwayClass(possibleTurns, turnInfo, numMwmIds, CarDirection::None))
|
||||
{
|
||||
// Taking the next point of the next segment.
|
||||
nextIndex = {index.m_segmentIndex + 1, 1 /* m_pathIndex */};
|
||||
|
@ -1140,15 +1198,18 @@ void GetTurnDirection(IRoutingResult const & result, size_t outgoingSegmentIndex
|
|||
}
|
||||
|
||||
// Note 1. If the road significantly changes its direction this turn shall be kept here.
|
||||
// Note 2. If there's only one exit from this junction (nodes.candidates.size() != 1)
|
||||
// this turn should be kept.
|
||||
// Note 2. If there's only one exit from this junction (nodes.candidates.size() == 1)
|
||||
// this turn should be kept (because it was kept by previous logic as an exception).
|
||||
// Note 3. Keeping a turn at this point means that the decision to keep this turn or not
|
||||
// will be made after.
|
||||
if (!turn.m_keepAnyway && IsGoStraightOrSlightTurn(turn.m_turn) && nodes.candidates.size() != 1 &&
|
||||
!KeepTurnByHighwayClass(nodes, turnInfo, numMwmIds, turn.m_turn))
|
||||
if (!turn.m_keepAnyway && IsGoStraightOrSlightTurn(turn.m_turn) && nodes.candidates.size() != 1)
|
||||
{
|
||||
![]()
1. Для чего проверка `nodes.candidates.size() != 1` ?
2. candidates.size() не может быть 0?
![]()
1. Хороший вопрос.
Просто скопировал как в KeepTurnByHighwayClass.
Я не вижу проблем с `nodes.candidates.size() == 1`.
2. Предположительно, не может.
@vng
![]() Не может, тут все хорошо и да по аналогии с предидущим сравнением. Не может, тут все хорошо и да по аналогии с предидущим сравнением.
Эквивалентно nodes.candidates.size() > 1, проверяем когда больше одной альтернативы
![]() Тогда надо не копипастить, а сделать так:
Тогда надо не копипастить, а сделать так:
```C++
if (!turn.m_keepAnyway && IsGoStraightOrSlightTurn(turn.m_turn) && nodes.candidates.size() != 1)
{
if (!KeepTurnByHighwayClass(nodes, turnInfo, numMwmIds, turn.m_turn) ||
!KeepTurnByAlignedAlternatives(nodes, turnInfo, numMwmIds))
{
turn.m_turn = CarDirection::None;
return;
}
}
```
![]() вопросы к @vng :
вопросы к @vng :
```
Note 2. If there's only one exit from this junction (nodes.candidates.size() != 1)
// this turn should be kept.
```
- если выезд только один, то nodes.candidates.size() == 1, а не наоборот?
- если выезд только один - то почему именно в этом случае нужно оставить поворот? Если этого условия не будет, то оба KeepTurnBy... превратят SlightTurn в None. По идее, он и так уже должен быть таким к этому моменту. А если например кандидата 2: вперед и назад - то почему поворот не обязательно оставлять?
![]() Я эти комменты не писал :) но предполагаю что:
Я эти комменты не писал :) но предполагаю что:
- Для одного exit когда nodes.candidates.size() == 1, мы НЕ заходим в KeepTurnByHighwayClass и turn точно сохраняется. Можете переписать этот коммент на понятный :)
- Вероятно он остается, потому что вычисляется по какому-то другому жесткому условию раньше (например это может быть пересадка на паром), тут не скажу точно. Пусть так и остается, пока не увидим явный косяк
![]() Меняю, если нет возражений, на
Меняю, если нет возражений, на
```
// Note 2. If there's only one exit from this junction (nodes.candidates.size() == 1)
// this turn should be kept (because if was kept by previous logic as an exception).
```
![]() После перехода на
Стала понятна немного некорректная логика в названиях функций.
те если ни одной причины нет, чтобы сохранить поворот - то мы его удаляем. Предлагаю инвертировать функции на DiscardTurnByHighwayClass и DiscardTurnByNoAlignedAlternatives.
После перехода на
```
if (!KeepTurnByHighwayClass(nodes, turnInfo, numMwmIds, turn.m_turn) ||
!KeepTurnByAlignedAlternatives(nodes, turnInfo, numMwmIds))
```
Стала понятна немного некорректная логика в названиях функций.
Исходя из названия, должно быть так
```
if (! (KeepTurnByHighwayClass(nodes, turnInfo, numMwmIds, turn.m_turn) ||
KeepTurnByAlignedAlternatives(nodes, turnInfo, numMwmIds)))
```
те если ни одной причины нет, чтобы сохранить поворот - то мы его удаляем.
а у нас получается, что если причины 1 нет - удаляем, если причины 2 нет - удаляем.
Предлагаю инвертировать функции на DiscardTurnByHighwayClass и DiscardTurnByNoAlignedAlternatives.
Тогда получится:
```
if (DiscardTurnByHighwayClass(nodes, turnInfo, numMwmIds, turn.m_turn) ||
DiscardTurnByNoAlignedAlternatives(nodes, turnInfo, numMwmIds))
```
![]() Согласен на переименовать. Тогда надо аккуратно внутри них инвертировать true/false и проверить актуальность комментов к ним. Согласен на переименовать. Тогда надо аккуратно внутри них инвертировать true/false и проверить актуальность комментов к ним.
![]() в процессе переименования обратил внимание на
в процессе переименования обратил внимание на
```
bool KeepTurnByHighwayClass()
...
if (!GetTurnHighwayClasses(possibleTurns, turnInfo, numMwmIds, turnHighwayClasses))
return false;
```
![]() Исходя из описания GetTurnHighwayClasses() Исходя из описания GetTurnHighwayClasses()
// If it's possible fills |turnHighwayClasses| and returns true, and returns false otherwise.
это выглядит ошибкой: если данные не получили - то вернуть false и удалить поворот.
должно быть наоборот? если данные не получили - то не трогать поворот на всякий случай.
![]() Есть подозрение, что Есть подозрение, что
GetTurnHighwayClasses()
не совсем соответствует описанию в отношении возвращаемого значения.
![]() Оставил старую логику (инвертировав true на false), добавив комент:
Оставил старую логику (инвертировав true на false), добавив комент:
```
bool DiscardTurnByHighwayClass(TurnCandidates const & possibleTurns, TurnInfo const & turnInfo,
NumMwmIds const & numMwmIds, CarDirection carDirection)
...
// Looks like a bug. If no info received turn should not be discarded
if (!GetTurnHighwayClasses(possibleTurns, turnInfo, numMwmIds, turnHighwayClasses))
return true;
```
|
||||
turn.m_turn = CarDirection::None;
|
||||
return;
|
||||
if (DiscardTurnByHighwayClass(nodes, turnInfo, numMwmIds, turn.m_turn) ||
|
||||
DiscardTurnByNoAlignedAlternatives(nodes, turnInfo, numMwmIds))
|
||||
{
|
||||
turn.m_turn = CarDirection::None;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsGoStraightOrSlightTurn(turn.m_turn))
|
||||
|
|
Незавершённое предложение?
Можно выровнять после скобки.