emit turn-straight for obvious turns where the main road continues
This commit is contained in:
parent
1e8a92ccb4
commit
a9f674497a
@ -1,5 +1,5 @@
|
||||
# 5.2
|
||||
Changes from 5.1
|
||||
# 5.2.0
|
||||
Changes from 5.1.0
|
||||
|
||||
- API:
|
||||
- new parameter `annotate` for `route` and `match` requests. Returns additional data about each
|
||||
@ -11,6 +11,9 @@
|
||||
- Infrastructure:
|
||||
- Open sockets with SO_REUSEPORT to allow multiple servers connecting to the same port
|
||||
|
||||
- Guidance:
|
||||
- improved detection of turning streets, not reporting new-name in wrong situations
|
||||
|
||||
# 5.1.0
|
||||
Changes with regard to 5.0.0
|
||||
|
||||
|
@ -344,4 +344,4 @@ Feature: Collapse
|
||||
| waypoints | route | turns |
|
||||
| a,d | first,first,first,first | depart,continue left,continue right,arrive |
|
||||
| a,e | first,second,second | depart,turn left,arrive |
|
||||
| a,f | first,third,third | depart,new name straight,arrive |
|
||||
| a,f | first,third,third | depart,turn straight,arrive |
|
||||
|
@ -16,9 +16,9 @@ Feature: Continue Instructions
|
||||
| bd | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | abc,abc,abc | depart,continue left,arrive |
|
||||
| a,d | abc,bd,bd | depart,new name straight,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | abc,abc,abc | depart,continue left,arrive |
|
||||
| a,d | abc,bd,bd | depart,turn straight,arrive |
|
||||
|
||||
Scenario: Road turning right
|
||||
Given the node map
|
||||
@ -31,9 +31,9 @@ Feature: Continue Instructions
|
||||
| bd | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | abc,abc,abc | depart,continue right,arrive |
|
||||
| a,d | abc,bd,bd | depart,new name straight,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | abc,abc,abc | depart,continue right,arrive |
|
||||
| a,d | abc,bd,bd | depart,turn straight,arrive |
|
||||
|
||||
Scenario: Road turning slight left
|
||||
Given the node map
|
||||
|
@ -323,8 +323,14 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
||||
return angularDeviation(bearing_in, bearing_out) > 170;
|
||||
};
|
||||
|
||||
const auto isCollapsableInstruction = [](const TurnInstruction instruction) {
|
||||
return instruction.type == TurnType::NewName ||
|
||||
(instruction.type == TurnType::Turn &&
|
||||
instruction.direction_modifier == DirectionModifier::Straight);
|
||||
};
|
||||
|
||||
// Very Short New Name
|
||||
if (TurnType::NewName == one_back_step.maneuver.instruction.type)
|
||||
if (isCollapsableInstruction(one_back_step.maneuver.instruction))
|
||||
{
|
||||
BOOST_ASSERT(two_back_index < steps.size());
|
||||
if (one_back_step.mode == steps[two_back_index].mode)
|
||||
@ -339,7 +345,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
||||
}
|
||||
}
|
||||
// very short segment after turn
|
||||
else if (TurnType::NewName == current_step.maneuver.instruction.type)
|
||||
else if (isCollapsableInstruction(current_step.maneuver.instruction))
|
||||
{
|
||||
if (one_back_step.mode == current_step.mode)
|
||||
{
|
||||
@ -365,7 +371,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
||||
// additionall collapse a name-change as well
|
||||
const bool continues_with_name_change =
|
||||
(step_index + 1 < steps.size()) &&
|
||||
(TurnType::NewName == steps[step_index + 1].maneuver.instruction.type);
|
||||
isCollapsableInstruction(steps[step_index + 1].maneuver.instruction);
|
||||
const bool u_turn_with_name_change =
|
||||
collapsable(current_step) && continues_with_name_change &&
|
||||
steps[step_index + 1].name == steps[two_back_index].name;
|
||||
@ -533,6 +539,11 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
||||
invalidateStep(steps[1]);
|
||||
}
|
||||
}
|
||||
const auto isCollapsableInstruction = [](const TurnInstruction instruction) {
|
||||
return instruction.type == TurnType::NewName ||
|
||||
(instruction.type == TurnType::Turn &&
|
||||
instruction.direction_modifier == DirectionModifier::Straight);
|
||||
};
|
||||
|
||||
// first and last instructions are waypoints that cannot be collapsed
|
||||
for (std::size_t step_index = 2; step_index < steps.size(); ++step_index)
|
||||
@ -551,7 +562,7 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
||||
|
||||
// Due to empty segments, we can get name-changes from A->A
|
||||
// These have to be handled in post-processing
|
||||
if (TurnType::NewName == current_step.maneuver.instruction.type &&
|
||||
if (isCollapsableInstruction(current_step.maneuver.instruction) &&
|
||||
current_step.name == steps[one_back_index].name)
|
||||
{
|
||||
steps[one_back_index] = elongate(std::move(steps[one_back_index]), steps[step_index]);
|
||||
@ -560,8 +571,8 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
||||
// If we look at two consecutive name changes, we can check for a name oszillation.
|
||||
// A name oszillation changes from name A shortly to name B and back to A.
|
||||
// In these cases, the name change will be suppressed.
|
||||
else if (TurnType::NewName == current_step.maneuver.instruction.type &&
|
||||
TurnType::NewName == one_back_step.maneuver.instruction.type)
|
||||
else if (isCollapsableInstruction(current_step.maneuver.instruction) &&
|
||||
isCollapsableInstruction(one_back_step.maneuver.instruction))
|
||||
{
|
||||
// valid due to step_index starting at 2
|
||||
const auto &coming_from_name = steps[two_back_index].name;
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
#include "extractor/guidance/turn_handler.hpp"
|
||||
|
||||
#include "util/simple_logger.hpp"
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
|
||||
#include <limits>
|
||||
@ -78,6 +77,9 @@ Intersection TurnHandler::handleTwoWayTurn(const EdgeID via_edge, Intersection i
|
||||
|
||||
Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection intersection) const
|
||||
{
|
||||
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
||||
const auto &first_data = node_based_graph.GetEdgeData(intersection[1].turn.eid);
|
||||
const auto &second_data = node_based_graph.GetEdgeData(intersection[2].turn.eid);
|
||||
BOOST_ASSERT(intersection[0].turn.angle < 0.001);
|
||||
const auto isObviousOfTwo = [this](const ConnectedRoad road, const ConnectedRoad other) {
|
||||
const auto first_class =
|
||||
@ -134,14 +136,16 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
|
||||
{
|
||||
assignFork(via_edge, intersection[2], intersection[1]);
|
||||
}
|
||||
else if (isObviousOfTwo(intersection[1], intersection[2]))
|
||||
else if (isObviousOfTwo(intersection[1], intersection[2]) &&
|
||||
second_data.name_id != in_data.name_id)
|
||||
{
|
||||
intersection[1].turn.instruction =
|
||||
getInstructionForObvious(intersection.size(), via_edge, false, intersection[1]);
|
||||
intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]),
|
||||
DirectionModifier::SlightLeft};
|
||||
}
|
||||
else if (isObviousOfTwo(intersection[2], intersection[1]))
|
||||
else if (isObviousOfTwo(intersection[2], intersection[1]) &&
|
||||
first_data.name_id != in_data.name_id)
|
||||
{
|
||||
intersection[2].turn.instruction =
|
||||
getInstructionForObvious(intersection.size(), via_edge, false, intersection[2]);
|
||||
@ -193,7 +197,8 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isObviousOfTwo(intersection[1], intersection[2]))
|
||||
if (isObviousOfTwo(intersection[1], intersection[2]) &&
|
||||
in_data.name_id != second_data.name_id)
|
||||
{
|
||||
intersection[1].turn.instruction = getInstructionForObvious(
|
||||
3, via_edge, isThroughStreet(1, intersection), intersection[1]);
|
||||
@ -204,7 +209,8 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
|
||||
getTurnDirection(intersection[1].turn.angle)};
|
||||
}
|
||||
|
||||
if (isObviousOfTwo(intersection[2], intersection[1]))
|
||||
if (isObviousOfTwo(intersection[2], intersection[1]) &&
|
||||
in_data.name_id != first_data.name_id)
|
||||
{
|
||||
intersection[2].turn.instruction = getInstructionForObvious(
|
||||
3, via_edge, isThroughStreet(2, intersection), intersection[2]);
|
||||
@ -234,12 +240,44 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection
|
||||
}
|
||||
}
|
||||
|
||||
// check whether there is a turn of the same name
|
||||
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
||||
|
||||
const bool has_same_name_turn = [&]() {
|
||||
for (std::size_t i = 1; i < intersection.size(); ++i)
|
||||
{
|
||||
if (node_based_graph.GetEdgeData(intersection[i].turn.eid).name_id == in_data.name_id)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
|
||||
// check whether the obvious choice is actually a through street
|
||||
if (obvious_index != 0)
|
||||
{
|
||||
intersection[obvious_index].turn.instruction = getInstructionForObvious(
|
||||
intersection.size(), via_edge, isThroughStreet(obvious_index, intersection),
|
||||
intersection[obvious_index]);
|
||||
if (has_same_name_turn &&
|
||||
node_based_graph.GetEdgeData(intersection[obvious_index].turn.eid).name_id !=
|
||||
in_data.name_id &&
|
||||
intersection[obvious_index].turn.instruction.type == TurnType::NewName)
|
||||
{
|
||||
// this is a special case that is necessary to correctly handle obvious turns on
|
||||
// continuing streets. Right now osrm does not know about right of way. If a street
|
||||
// turns to the left just like:
|
||||
//
|
||||
// a
|
||||
// a
|
||||
// aaaaaaa b b
|
||||
//
|
||||
// And another road exits here, we don't want to call it a new name, even though the
|
||||
// turn is obvious and does not require steering. To correctly handle these situations
|
||||
// in turn collapsing, we use the turn + straight combination here
|
||||
intersection[obvious_index].turn.instruction.type = TurnType::Turn;
|
||||
intersection[obvious_index].turn.instruction.direction_modifier =
|
||||
DirectionModifier::Straight;
|
||||
}
|
||||
|
||||
// assign left/right turns
|
||||
intersection = assignLeftTurns(via_edge, std::move(intersection), obvious_index + 1);
|
||||
@ -302,7 +340,7 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection
|
||||
}
|
||||
else
|
||||
{
|
||||
assignTrivialTurns(via_edge,intersection,1,intersection.size());
|
||||
assignTrivialTurns(via_edge, intersection, 1, intersection.size());
|
||||
}
|
||||
return intersection;
|
||||
}
|
||||
@ -394,8 +432,7 @@ Intersection TurnHandler::assignLeftTurns(const EdgeID via_edge,
|
||||
const std::size_t starting_at) const
|
||||
{
|
||||
BOOST_ASSERT(starting_at <= intersection.size());
|
||||
const auto switch_left_and_right = []( Intersection &intersection )
|
||||
{
|
||||
const auto switch_left_and_right = [](Intersection &intersection) {
|
||||
BOOST_ASSERT(!intersection.empty());
|
||||
|
||||
for (auto &road : intersection)
|
||||
@ -410,7 +447,6 @@ Intersection TurnHandler::assignLeftTurns(const EdgeID via_edge,
|
||||
intersection = assignRightTurns(via_edge, std::move(intersection), count);
|
||||
switch_left_and_right(intersection);
|
||||
|
||||
|
||||
return intersection;
|
||||
}
|
||||
|
||||
@ -537,18 +573,6 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
|
||||
}
|
||||
else
|
||||
{
|
||||
util::SimpleLogger().Write(logWARNING)
|
||||
<< "Reached fallback for right turns, size 3 "
|
||||
<< " Valids: " << (intersection[1].entry_allowed + intersection[2].entry_allowed +
|
||||
intersection[3].entry_allowed);
|
||||
for (const auto road : intersection)
|
||||
{
|
||||
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
|
||||
util::SimpleLogger().Write(logWARNING)
|
||||
<< "\troad: " << toString(road) << " Name: " << out_data.name_id
|
||||
<< " Road Class: " << (int)out_data.road_classification.road_class;
|
||||
}
|
||||
|
||||
assignTrivialTurns(via_edge, intersection, 1, up_to);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user