handle service roads next to roundabouts - ambiguous exit... :(

This commit is contained in:
Moritz Kobitzsch 2016-11-24 14:11:59 +01:00
parent e343f71541
commit 186cc8340a
4 changed files with 104 additions and 30 deletions

View File

@ -0,0 +1,59 @@
@routing @guidance @left-handed
Feature: Basic Roundabout
Background:
Given a grid size of 10 meters
Given the profile file
"""
require 'car'
properties.left_hand_driving = true
"""
Scenario: Roundabout exit counting for left sided driving
And a grid size of 10 meters
And the node map
"""
a
b
h g c d
e
f
"""
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bcegb | roundabout |
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout turn left exit-1,arrive |
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive |
| a,h | ab,gh,gh | depart,roundabout turn right exit-3,arrive |
Scenario: Mixed Entry and Exit
And a grid size of 10 meters
And the node map
"""
c a
j b f
k e
l h d
g i
"""
And the ways
| nodes | junction | oneway |
| cba | | yes |
| fed | | yes |
| ihg | | yes |
| lkj | | yes |
| behkb | roundabout | yes |
When I route I should get
| waypoints | route | turns |
| c,a | cba,cba,cba | depart,roundabout-exit-1,arrive |
| l,a | lkj,cba,cba | depart,roundabout-exit-2,arrive |
| i,a | ihg,cba,cba | depart,roundabout-exit-3,arrive |

View File

@ -38,6 +38,30 @@ Feature: Basic Roundabout
| h,c | gh,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| h,e | gh,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
Scenario: Roundabout With Service
Given the node map
"""
a h
bg
d c
e
f
"""
And the ways
| nodes | junction | highway |
| ab | | primary |
| cd | | primary |
| ef | | service |
| gh | | primary |
| bcegb | roundabout | primary |
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout-exit-1,arrive |
| a,h | ab,gh,gh | depart,roundabout-exit-2,arrive |
| a,f | ab,ef,ef | depart,roundabout-exit-2,arrive |
#2927
Scenario: Only Roundabout
Given the node map

View File

@ -83,28 +83,3 @@ Feature: Testbot - side bias
| a,d | ab,cd,cd | depart,roundabout turn left exit-1,arrive |
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive |
| a,h | ab,gh,gh | depart,roundabout turn right exit-3,arrive |
Scenario: Mixed Entry and Exit
And a grid size of 10 meters
And the node map
"""
c a
j b f
k e
l h d
g i
"""
And the ways
| nodes | junction | oneway |
| cba | | yes |
| fed | | yes |
| ihg | | yes |
| lkj | | yes |
| behkb | roundabout | yes |
When I route I should get
| waypoints | route | turns |
| c,a | cba,cba,cba | depart,roundabout-exit-1,arrive |
| l,a | lkj,cba,cba | depart,roundabout-exit-2,arrive |
| i,a | ihg,cba,cba | depart,roundabout-exit-3,arrive |

View File

@ -360,8 +360,7 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
const bool can_exit_roundabout_separately,
Intersection intersection) const
{
// detect via radius (get via circle through three vertices)
NodeID node_v = node_based_graph.GetTarget(via_eid);
NodeID node_at_center_of_intersection = node_based_graph.GetTarget(via_eid);
const bool lhs = profile_properties.left_hand_driving;
const int step = lhs ? -1 : 1;
@ -380,7 +379,7 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
if (out_data.roundabout)
{
// TODO can forks happen in roundabouts? E.g. required lane changes
if (1 == node_based_graph.GetDirectedOutDegree(node_v))
if (1 == node_based_graph.GetDirectedOutDegree(node_at_center_of_intersection))
{
// No turn possible.
if (intersection.size() == 2)
@ -394,8 +393,25 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
}
else
{
turn.instruction = TurnInstruction::REMAIN_ROUNDABOUT(
roundabout_type, getTurnDirection(turn.angle));
// check if there is a non-service exit
const auto has_non_ignorable_exit = [&]() {
for (const auto eid :
node_based_graph.GetAdjacentEdgeRange(node_at_center_of_intersection))
{
const auto &data_of_leaving_edge = node_based_graph.GetEdgeData(eid);
if (!data_of_leaving_edge.reversed &&
!data_of_leaving_edge.roundabout &&
!data_of_leaving_edge.road_classification.IsLowPriorityRoadClass())
return true;
}
return false;
}();
if (has_non_ignorable_exit)
turn.instruction = TurnInstruction::REMAIN_ROUNDABOUT(
roundabout_type, getTurnDirection(turn.angle));
else
turn.instruction = {TurnType::Suppressed, getTurnDirection(turn.angle)};
}
}
else