Compare commits

...

6 Commits

Author SHA1 Message Date
Daniel Patterson
356bab9fcb
Prepare for alpha release. 2017-08-17 17:38:50 -07:00
Moritz Kobitzsch
314bf51465
format 2017-08-17 17:10:00 -07:00
Moritz Kobitzsch
5dc31252ef
remove debug output 2017-08-17 17:10:00 -07:00
Moritz Kobitzsch
8ec3c83d82
emit exit roundabout on turns only when mode changes 2017-08-17 17:09:58 -07:00
Moritz Kobitzsch
8319a96aed
format 2017-08-17 17:09:28 -07:00
Moritz Kobitzsch
28ddd983b3
use enter + exit for roundabout instructions 2017-08-17 17:09:26 -07:00
22 changed files with 610 additions and 1233 deletions

View File

@ -1,4 +1,5 @@
# UNRELEASED # UNRELEASED
- Adds new instruction types at the exit of roundabouts and rotaries `exit roundabout` and `exit rotary`.
# 5.11.0 # 5.11.0
- Changes from 5.10: - Changes from 5.10:

View File

@ -123,5 +123,5 @@ Feature: Car - Mode flag
When I route I should get When I route I should get
| from | to | route | turns | classes | | from | to | route | turns | classes |
| a | f | ab,df,df | depart,roundabout-exit-2,arrive | [()],[(),(motorway),(toll,motorway)],[()] | | a | f | ab,df,df,df | depart,roundabout-exit-2,exit roundabout slight right,arrive | [()],[(),(motorway)],[(toll,motorway)],[()] |

View File

@ -47,32 +47,3 @@ Feature: Testbot - side bias
| d | a | bd,ab,ab | 27s +-1 | | d | a | bd,ab,ab | 27s +-1 |
# should be inverse of left hand bias # should be inverse of left hand bias
| d | c | bd,bc,bc | 24s +-1 | | d | c | bd,bc,bc | 24s +-1 |
Scenario: Roundabout exit counting for left sided driving
Given the profile file "testbot" initialized with
"""
profile.left_hand_driving = true
profile.turn_bias = 1/1.075
"""
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 |

View File

@ -554,7 +554,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,h | ab,gh,gh | depart,roundabout-exit-5,arrive | ,;;;;;, | | a,h | ab,gh,gh,gh | depart,roundabout-exit-5,exit roundabout right,arrive | ,;;;;,, |
@anticipate @anticipate
Scenario: No Lanes for Roundabouts, see #2626 Scenario: No Lanes for Roundabouts, see #2626
@ -569,16 +569,16 @@ Feature: Turn Lane Guidance
| nodes | turn:lanes:forward | highway | junction | name | | nodes | turn:lanes:forward | highway | junction | name |
| xb | slight_right\|slight_right | primary | | xb | | xb | slight_right\|slight_right | primary | | xb |
| dy | | primary | | dy | | dy | | primary | | dy |
| ab | | primary | roundabout | roundabout | | ab | | primary | roundabout | rotary |
| bc | | primary | roundabout | roundabout | | bc | | primary | roundabout | rotary |
| cd | left\|slight_right | primary | roundabout | roundabout | | cd | left\|slight_right | primary | roundabout | rotary |
| da | | primary | roundabout | roundabout | | da | | primary | roundabout | rotary |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,;, | | x,y | xb,dy,dy,dy | depart,rotary-exit-1,exit rotary right,arrive | ,,, |
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, | | x,c | xb,rotary,rotary | depart,rotary-exit-undefined,arrive | ,, |
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,;, | | x,a | xb,rotary,rotary | depart,rotary-exit-undefined,arrive | ,;, |
@anticipate @anticipate
Scenario: No Lanes for Roundabouts, see #2626 Scenario: No Lanes for Roundabouts, see #2626
@ -615,7 +615,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,h | ab,ch,ch | depart,roundabout-exit-5,arrive | ,;;;;;, | | a,h | ab,ch,ch,ch | depart,roundabout-exit-5,exit roundabout left,arrive | ,;;;;,, |
@anticipate @anticipate
Scenario: No Lanes for Roundabouts, see #2626 Scenario: No Lanes for Roundabouts, see #2626
@ -635,16 +635,16 @@ Feature: Turn Lane Guidance
| nodes | turn:lanes:forward | highway | junction | name | | nodes | turn:lanes:forward | highway | junction | name |
| xb | slight_right\|slight_right | primary | | xb | | xb | slight_right\|slight_right | primary | | xb |
| dy | | primary | | dy | | dy | | primary | | dy |
| ab | | primary | roundabout | roundabout | | ab | | primary | roundabout | rotary |
| bc | | primary | roundabout | roundabout | | bc | | primary | roundabout | rotary |
| cd | left\|slight_right | primary | roundabout | roundabout | | cd | left\|slight_right | primary | roundabout | rotary |
| da | | primary | roundabout | roundabout | | da | | primary | roundabout | rotary |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,;, | | x,y | xb,dy,dy,dy | depart,rotary-exit-1,exit rotary right,arrive | ,,, |
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, | | x,c | xb,rotary,rotary | depart,rotary-exit-undefined,arrive | ,, |
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,;, | | x,a | xb,rotary,rotary | depart,rotary-exit-undefined,arrive | ,;, |
@anticipate @todo @2032 @anticipate @todo @2032
Scenario: No Lanes for Roundabouts, see #2626 Scenario: No Lanes for Roundabouts, see #2626

View File

@ -1,5 +1,8 @@
@routing @guidance @routing @guidance
Feature: Rotary Feature: Circular
# Circular tags are treated just as rotaries. We can rely on the rotary tests for their handling on special cases.
# Here we only ensure that the `circular` tag is handled and assigned a rotary type
Background: Background:
Given the profile "car" Given the profile "car"
@ -25,258 +28,15 @@ Feature: Rotary
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,d | ab,cd,cd | depart,bgecb-exit-3,arrive | | a,d | ab,cd,cd,cd | depart,bgecb-exit-3,exit rotary right,arrive |
| a,f | ab,ef,ef | depart,bgecb-exit-2,arrive | | a,f | ab,ef,ef,ef | depart,bgecb-exit-2,exit rotary right,arrive |
| a,h | ab,gh,gh | depart,bgecb-exit-1,arrive | | a,h | ab,gh,gh,gh | depart,bgecb-exit-1,exit rotary right,arrive |
| d,f | cd,ef,ef | depart,bgecb-exit-3,arrive | | d,f | cd,ef,ef,ef | depart,bgecb-exit-3,exit rotary right,arrive |
| d,h | cd,gh,gh | depart,bgecb-exit-2,arrive | | d,h | cd,gh,gh,gh | depart,bgecb-exit-2,exit rotary right,arrive |
| d,a | cd,ab,ab | depart,bgecb-exit-1,arrive | | d,a | cd,ab,ab,ab | depart,bgecb-exit-1,exit rotary right,arrive |
| f,h | ef,gh,gh | depart,bgecb-exit-3,arrive | | f,h | ef,gh,gh,gh | depart,bgecb-exit-3,exit rotary right,arrive |
| f,a | ef,ab,ab | depart,bgecb-exit-2,arrive | | f,a | ef,ab,ab,ab | depart,bgecb-exit-2,exit rotary right,arrive |
| f,d | ef,cd,cd | depart,bgecb-exit-1,arrive | | f,d | ef,cd,cd,cd | depart,bgecb-exit-1,exit rotary right,arrive |
| h,a | gh,ab,ab | depart,bgecb-exit-3,arrive | | h,a | gh,ab,ab,ab | depart,bgecb-exit-3,exit rotary right,arrive |
| h,d | gh,cd,cd | depart,bgecb-exit-2,arrive | | h,d | gh,cd,cd,cd | depart,bgecb-exit-2,exit rotary right,arrive |
| h,f | gh,ef,ef | depart,bgecb-exit-1,arrive | | h,f | gh,ef,ef,ef | depart,bgecb-exit-1,exit rotary right,arrive |
Scenario: Only Enter
Given the node map
"""
a
b
d c g h
e
f
"""
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bcegb | circular |
When I route I should get
| waypoints | route | turns |
| a,c | ab,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| a,e | ab,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| a,g | ab,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| d,e | cd,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| d,g | cd,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| d,b | cd,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| f,g | ef,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| f,b | ef,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| f,c | ef,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| h,b | gh,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| h,c | gh,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| h,e | gh,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
Scenario: Only Exit
Given the node map
"""
a
b
d c g h
e
f
"""
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bcegb | circular |
When I route I should get
| waypoints | route | turns |
| b,d | bcegb,cd,cd | depart,bcegb-exit-1,arrive |
| b,f | bcegb,ef,ef | depart,bcegb-exit-2,arrive |
| b,h | bcegb,gh,gh | depart,bcegb-exit-3,arrive |
| c,f | bcegb,ef,ef | depart,bcegb-exit-1,arrive |
| c,h | bcegb,gh,gh | depart,bcegb-exit-2,arrive |
| c,a | bcegb,ab,ab | depart,bcegb-exit-3,arrive |
| e,h | bcegb,gh,gh | depart,bcegb-exit-1,arrive |
| e,a | bcegb,ab,ab | depart,bcegb-exit-2,arrive |
| e,d | bcegb,cd,cd | depart,bcegb-exit-3,arrive |
| g,a | bcegb,ab,ab | depart,bcegb-exit-1,arrive |
| g,d | bcegb,cd,cd | depart,bcegb-exit-2,arrive |
| g,f | bcegb,ef,ef | depart,bcegb-exit-3,arrive |
#phantom node snapping can result in a full round-trip here, therefore we cannot test b->a and the other direct exits
Scenario: Drive Around
Given the node map
"""
a
b
d c g h
e
f
"""
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bcegb | circular |
When I route I should get
| waypoints | route | turns |
| b,c | bcegb,bcegb | depart,arrive |
| b,e | bcegb,bcegb | depart,arrive |
| b,g | bcegb,bcegb | depart,arrive |
| c,e | bcegb,bcegb | depart,arrive |
| c,g | bcegb,bcegb | depart,arrive |
| c,b | bcegb,bcegb | depart,arrive |
| e,g | bcegb,bcegb | depart,arrive |
| e,b | bcegb,bcegb | depart,arrive |
| e,c | bcegb,bcegb | depart,arrive |
| g,b | bcegb,bcegb | depart,arrive |
| g,c | bcegb,bcegb | depart,arrive |
| g,e | bcegb,bcegb | depart,arrive |
#needs to be adjusted when name-discovery works for entrys
Scenario: Mixed Entry and Exit
Given the node map
"""
c a
j b f
k e
l h d
g i
"""
And the ways
| nodes | junction | oneway |
| abc | | yes |
| def | | yes |
| ghi | | yes |
| jkl | | yes |
| bkheb | circular | yes |
When I route I should get
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,rotary-exit-1,arrive |
| a,l | abc,jkl,jkl | depart,bkheb-exit-2,arrive |
| a,i | abc,ghi,ghi | depart,bkheb-exit-3,arrive |
| a,f | abc,def,def | depart,bkheb-exit-4,arrive |
| d,f | def,def,def | depart,rotary-exit-1,arrive |
| d,c | def,abc,abc | depart,bkheb-exit-2,arrive |
| d,l | def,jkl,jkl | depart,bkheb-exit-3,arrive |
| d,i | def,ghi,ghi | depart,bkheb-exit-4,arrive |
| g,i | ghi,ghi,ghi | depart,rotary-exit-1,arrive |
| g,f | ghi,def,def | depart,bkheb-exit-2,arrive |
| g,c | ghi,abc,abc | depart,bkheb-exit-3,arrive |
| g,l | ghi,jkl,jkl | depart,bkheb-exit-4,arrive |
| j,l | jkl,jkl,jkl | depart,rotary-exit-1,arrive |
| j,i | jkl,ghi,ghi | depart,bkheb-exit-2,arrive |
| j,f | jkl,def,def | depart,bkheb-exit-3,arrive |
| j,c | jkl,abc,abc | depart,bkheb-exit-4,arrive |
Scenario: Collinear in X,Y
Given the node map
"""
a
b
c d f
e
"""
And the ways
| nodes | junction |
| ab | |
| bcdb | circular |
| ce | |
| df | |
When I route I should get
| waypoints | route | turns |
| a,e | ab,ce,ce | depart,bcdb-exit-1,arrive |
| a,f | ab,df,df | depart,bcdb-exit-2,arrive |
Scenario: Collinear in X,Y
Given the node map
"""
a
d
b c f
e
"""
And the ways
| nodes | junction |
| ad | |
| bcdb | circular |
| be | |
| cf | |
When I route I should get
| waypoints | route | turns |
| a,e | ad,be,be | depart,bcdb-exit-1,arrive |
| a,f | ad,cf,cf | depart,bcdb-exit-2,arrive |
Scenario: Collinear in X,Y
Given the node map
"""
a
c
d b f
e
"""
And the ways
| nodes | junction |
| ac | |
| bcdb | circular |
| de | |
| bf | |
When I route I should get
| waypoints | route | turns |
| a,e | ac,de,de | depart,bcdb-exit-1,arrive |
| a,f | ac,bf,bf | depart,bcdb-exit-2,arrive |
Scenario: Collinear in X,Y
Given the node map
"""
f
d c e
b
a
"""
And the ways
| nodes | junction |
| ab | |
| bcdb | circular |
| ce | |
| df | |
When I route I should get
| waypoints | route | turns |
| a,e | ab,ce,ce | depart,bcdb-exit-1,arrive |
| a,f | ab,df,df | depart,bcdb-exit-2,arrive |
Scenario: Collinear in X,Y
Given the node map
"""
f
d c e
b
a
"""
And the ways
| nodes | junction |
| ab | |
| bcdb | circular |
| ce | |
| df | |
When I route I should get
| waypoints | route | turns |
| a,e | ab,ce,ce | depart,bcdb-exit-1,arrive |
| a,f | ab,df,df | depart,bcdb-exit-2,arrive |

View File

@ -906,7 +906,7 @@ Feature: Slipways and Dedicated Turn Lanes
When I route I should get When I route I should get
| waypoints | route | turns | locations | | waypoints | route | turns | locations |
| z,t | through,,out,out | depart,off ramp slight right,round-exit-3,arrive | z,s,c,t | | z,t | through,,out,out,out | depart,off ramp slight right,round-exit-3,exit rotary right,arrive | z,s,c,e,t |
Scenario: Sliproad before a roundabout Scenario: Sliproad before a roundabout
Given the node map Given the node map

View File

@ -140,9 +140,9 @@ Feature: Intersections Data
When I route I should get When I route I should get
| waypoints | route | intersections | | waypoints | route | intersections |
| e,f | ea,fb,fb | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 | | e,f | ea,fb,fb,fb | true:180;false:0 false:150 true:210;false:30 true:150 true:270;true:90 |
| e,g | ea,gc,gc | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0 | | e,g | ea,gc,gc,gc | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:30 true:180 false:330;true:0 |
| e,h | ea,hd,hd | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330,true:90 false:210 true:330;true:270 | | e,h | ea,hd,hd,hd | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:90 false:210 true:330;true:270 |
| e,2 | ea,abcda,abcda | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1 | | e,2 | ea,abcda,abcda | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1 |
| 1,g | abcda,gc,gc | true:214;false:30 true:150 true:270,true:30 true:180 false:330;true:0 | | 1,g | abcda,gc,gc | true:214,false:30 true:150 true:270;true:30 true:180 false:330;true:0 |
| 1,3 | abcda,abcda | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214 | | 1,3 | abcda,abcda | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214 |

View File

@ -1,177 +0,0 @@
@routing @guidance
Feature: Rotary
Background:
Given the profile "bicycle"
Given a grid size of 30 meters
Scenario: Enter and Exit
Given the node map
"""
a
b
h g c d
e
f
"""
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bgecb | roundabout |
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,bgecb-exit-3,arrive |
| a,f | ab,ef,ef | depart,bgecb-exit-2,arrive |
| a,h | ab,gh,gh | depart,bgecb-exit-1,arrive |
| d,f | cd,ef,ef | depart,bgecb-exit-3,arrive |
| d,h | cd,gh,gh | depart,bgecb-exit-2,arrive |
| d,a | cd,ab,ab | depart,bgecb-exit-1,arrive |
| f,h | ef,gh,gh | depart,bgecb-exit-3,arrive |
| f,a | ef,ab,ab | depart,bgecb-exit-2,arrive |
| f,d | ef,cd,cd | depart,bgecb-exit-1,arrive |
| h,a | gh,ab,ab | depart,bgecb-exit-3,arrive |
| h,d | gh,cd,cd | depart,bgecb-exit-2,arrive |
| h,f | gh,ef,ef | depart,bgecb-exit-1,arrive |
Scenario: Only Enter
Given the node map
"""
a
b
d c g h
e
f
"""
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bcegb | roundabout |
When I route I should get
| waypoints | route | turns |
| a,c | ab,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| a,e | ab,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| a,g | ab,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| d,e | cd,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| d,g | cd,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| d,b | cd,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| f,g | ef,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| f,b | ef,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| f,c | ef,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| h,b | gh,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| h,c | gh,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
| h,e | gh,bcegb,bcegb | depart,bcegb-exit-undefined,arrive |
Scenario: Only Exit
Given the node map
"""
a
b
d c g h
e
f
"""
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bcegb | roundabout |
When I route I should get
| waypoints | route | turns |
| b,d | bcegb,cd,cd | depart,bcegb-exit-1,arrive |
| b,f | bcegb,ef,ef | depart,bcegb-exit-2,arrive |
| b,h | bcegb,gh,gh | depart,bcegb-exit-3,arrive |
| c,f | bcegb,ef,ef | depart,bcegb-exit-1,arrive |
| c,h | bcegb,gh,gh | depart,bcegb-exit-2,arrive |
| c,a | bcegb,ab,ab | depart,bcegb-exit-3,arrive |
| e,h | bcegb,gh,gh | depart,bcegb-exit-1,arrive |
| e,a | bcegb,ab,ab | depart,bcegb-exit-2,arrive |
| e,d | bcegb,cd,cd | depart,bcegb-exit-3,arrive |
| g,a | bcegb,ab,ab | depart,bcegb-exit-1,arrive |
| g,d | bcegb,cd,cd | depart,bcegb-exit-2,arrive |
| g,f | bcegb,ef,ef | depart,bcegb-exit-3,arrive |
#phantom node snapping can result in a full round-trip here, therefore we cannot test b->a and the other direct exits
Scenario: Drive Around
Given the node map
"""
a
b
d c g h
e
f
"""
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bcegb | roundabout |
When I route I should get
| waypoints | route | turns |
| b,c | bcegb,bcegb | depart,arrive |
| b,e | bcegb,bcegb | depart,arrive |
| b,g | bcegb,bcegb | depart,arrive |
| c,e | bcegb,bcegb | depart,arrive |
| c,g | bcegb,bcegb | depart,arrive |
| c,b | bcegb,bcegb | depart,arrive |
| e,g | bcegb,bcegb | depart,arrive |
| e,b | bcegb,bcegb | depart,arrive |
| e,c | bcegb,bcegb | depart,arrive |
| g,b | bcegb,bcegb | depart,arrive |
| g,c | bcegb,bcegb | depart,arrive |
| g,e | bcegb,bcegb | depart,arrive |
#needs to be adjusted when name-discovery works for entrys
Scenario: Mixed Entry and Exit
Given the node map
"""
c a
j b f
k e
l h d
g i
"""
And the ways
| nodes | junction | oneway |
| abc | | yes |
| def | | yes |
| ghi | | yes |
| jkl | | yes |
| bkheb | roundabout | yes |
When I route I should get
| waypoints | route | turns |
| a,c | abc,abc,abc | depart,rotary-exit-1,arrive |
| a,l | abc,jkl,jkl | depart,bkheb-exit-2,arrive |
| a,i | abc,ghi,ghi | depart,bkheb-exit-3,arrive |
| a,f | abc,def,def | depart,bkheb-exit-4,arrive |
| d,f | def,def,def | depart,rotary-exit-1,arrive |
| d,c | def,abc,abc | depart,bkheb-exit-2,arrive |
| d,l | def,jkl,jkl | depart,bkheb-exit-3,arrive |
| d,i | def,ghi,ghi | depart,bkheb-exit-4,arrive |
| g,i | ghi,ghi,ghi | depart,rotary-exit-1,arrive |
| g,f | ghi,def,def | depart,bkheb-exit-2,arrive |
| g,c | ghi,abc,abc | depart,bkheb-exit-3,arrive |
| g,l | ghi,jkl,jkl | depart,bkheb-exit-4,arrive |
| j,l | jkl,jkl,jkl | depart,rotary-exit-1,arrive |
| j,i | jkl,ghi,ghi | depart,bkheb-exit-2,arrive |
| j,f | jkl,def,def | depart,bkheb-exit-3,arrive |
| j,c | jkl,abc,abc | depart,bkheb-exit-4,arrive |

View File

@ -25,18 +25,18 @@ Feature: Rotary
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,d | ab,cd,cd | depart,bgecb-exit-3,arrive | | a,d | ab,cd,cd,cd | depart,bgecb-exit-3,exit rotary right,arrive |
| a,f | ab,ef,ef | depart,bgecb-exit-2,arrive | | a,f | ab,ef,ef,ef | depart,bgecb-exit-2,exit rotary right,arrive |
| a,h | ab,gh,gh | depart,bgecb-exit-1,arrive | | a,h | ab,gh,gh,gh | depart,bgecb-exit-1,exit rotary right,arrive |
| d,f | cd,ef,ef | depart,bgecb-exit-3,arrive | | d,f | cd,ef,ef,ef | depart,bgecb-exit-3,exit rotary right,arrive |
| d,h | cd,gh,gh | depart,bgecb-exit-2,arrive | | d,h | cd,gh,gh,gh | depart,bgecb-exit-2,exit rotary right,arrive |
| d,a | cd,ab,ab | depart,bgecb-exit-1,arrive | | d,a | cd,ab,ab,ab | depart,bgecb-exit-1,exit rotary right,arrive |
| f,h | ef,gh,gh | depart,bgecb-exit-3,arrive | | f,h | ef,gh,gh,gh | depart,bgecb-exit-3,exit rotary right,arrive |
| f,a | ef,ab,ab | depart,bgecb-exit-2,arrive | | f,a | ef,ab,ab,ab | depart,bgecb-exit-2,exit rotary right,arrive |
| f,d | ef,cd,cd | depart,bgecb-exit-1,arrive | | f,d | ef,cd,cd,cd | depart,bgecb-exit-1,exit rotary right,arrive |
| h,a | gh,ab,ab | depart,bgecb-exit-3,arrive | | h,a | gh,ab,ab,ab | depart,bgecb-exit-3,exit rotary right,arrive |
| h,d | gh,cd,cd | depart,bgecb-exit-2,arrive | | h,d | gh,cd,cd,cd | depart,bgecb-exit-2,exit rotary right,arrive |
| h,f | gh,ef,ef | depart,bgecb-exit-1,arrive | | h,f | gh,ef,ef,ef | depart,bgecb-exit-1,exit rotary right,arrive |
Scenario: Only Enter Scenario: Only Enter
Given the node map Given the node map
@ -91,18 +91,18 @@ Feature: Rotary
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| b,d | bcegb,cd,cd | depart,bcegb-exit-1,arrive | | b,d | bcegb,cd,cd | depart,exit rotary right,arrive |
| b,f | bcegb,ef,ef | depart,bcegb-exit-2,arrive | | b,f | bcegb,ef,ef | depart,exit rotary right,arrive |
| b,h | bcegb,gh,gh | depart,bcegb-exit-3,arrive | | b,h | bcegb,gh,gh | depart,exit rotary right,arrive |
| c,f | bcegb,ef,ef | depart,bcegb-exit-1,arrive | | c,f | bcegb,ef,ef | depart,exit rotary right,arrive |
| c,h | bcegb,gh,gh | depart,bcegb-exit-2,arrive | | c,h | bcegb,gh,gh | depart,exit rotary right,arrive |
| c,a | bcegb,ab,ab | depart,bcegb-exit-3,arrive | | c,a | bcegb,ab,ab | depart,exit rotary right,arrive |
| e,h | bcegb,gh,gh | depart,bcegb-exit-1,arrive | | e,h | bcegb,gh,gh | depart,exit rotary right,arrive |
| e,a | bcegb,ab,ab | depart,bcegb-exit-2,arrive | | e,a | bcegb,ab,ab | depart,exit rotary right,arrive |
| e,d | bcegb,cd,cd | depart,bcegb-exit-3,arrive | | e,d | bcegb,cd,cd | depart,exit rotary right,arrive |
| g,a | bcegb,ab,ab | depart,bcegb-exit-1,arrive | | g,a | bcegb,ab,ab | depart,exit rotary right,arrive |
| g,d | bcegb,cd,cd | depart,bcegb-exit-2,arrive | | g,d | bcegb,cd,cd | depart,exit rotary right,arrive |
| g,f | bcegb,ef,ef | depart,bcegb-exit-3,arrive | | g,f | bcegb,ef,ef | depart,exit rotary right,arrive |
#phantom node snapping can result in a full round-trip here, therefore we cannot test b->a and the other direct exits #phantom node snapping can result in a full round-trip here, therefore we cannot test b->a and the other direct exits
Scenario: Drive Around Scenario: Drive Around
@ -159,22 +159,22 @@ Feature: Rotary
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,c | abc,abc,abc | depart,rotary-exit-1,arrive | | a,c | abc,abc,abc | depart,exit rotary right,arrive |
| a,l | abc,jkl,jkl | depart,bkheb-exit-2,arrive | | a,l | abc,jkl,jkl,jkl | depart,bkheb-exit-2,exit rotary straight,arrive |
| a,i | abc,ghi,ghi | depart,bkheb-exit-3,arrive | | a,i | abc,ghi,ghi,ghi | depart,bkheb-exit-3,exit rotary straight,arrive |
| a,f | abc,def,def | depart,bkheb-exit-4,arrive | | a,f | abc,def,def,def | depart,bkheb-exit-4,exit rotary straight,arrive |
| d,f | def,def,def | depart,rotary-exit-1,arrive | | d,f | def,def,def | depart,exit rotary right,arrive |
| d,c | def,abc,abc | depart,bkheb-exit-2,arrive | | d,c | def,abc,abc,abc | depart,bkheb-exit-2,exit rotary straight,arrive |
| d,l | def,jkl,jkl | depart,bkheb-exit-3,arrive | | d,l | def,jkl,jkl,jkl | depart,bkheb-exit-3,exit rotary straight,arrive |
| d,i | def,ghi,ghi | depart,bkheb-exit-4,arrive | | d,i | def,ghi,ghi,ghi | depart,bkheb-exit-4,exit rotary straight,arrive |
| g,i | ghi,ghi,ghi | depart,rotary-exit-1,arrive | | g,i | ghi,ghi,ghi | depart,exit rotary right,arrive |
| g,f | ghi,def,def | depart,bkheb-exit-2,arrive | | g,f | ghi,def,def,def | depart,bkheb-exit-2,exit rotary straight,arrive |
| g,c | ghi,abc,abc | depart,bkheb-exit-3,arrive | | g,c | ghi,abc,abc,abc | depart,bkheb-exit-3,exit rotary straight,arrive |
| g,l | ghi,jkl,jkl | depart,bkheb-exit-4,arrive | | g,l | ghi,jkl,jkl,jkl | depart,bkheb-exit-4,exit rotary straight,arrive |
| j,l | jkl,jkl,jkl | depart,rotary-exit-1,arrive | | j,l | jkl,jkl,jkl | depart,exit rotary right,arrive |
| j,i | jkl,ghi,ghi | depart,bkheb-exit-2,arrive | | j,i | jkl,ghi,ghi,ghi | depart,bkheb-exit-2,exit rotary straight,arrive |
| j,f | jkl,def,def | depart,bkheb-exit-3,arrive | | j,f | jkl,def,def,def | depart,bkheb-exit-3,exit rotary straight,arrive |
| j,c | jkl,abc,abc | depart,bkheb-exit-4,arrive | | j,c | jkl,abc,abc,abc | depart,bkheb-exit-4,exit rotary straight,arrive |
Scenario: Collinear in X,Y Scenario: Collinear in X,Y
Given the node map Given the node map
@ -194,8 +194,8 @@ Feature: Rotary
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,e | ab,ce,ce | depart,bcdb-exit-1,arrive | | a,e | ab,ce,ce,ce | depart,bcdb-exit-1,exit rotary straight,arrive |
| a,f | ab,df,df | depart,bcdb-exit-2,arrive | | a,f | ab,df,df,df | depart,bcdb-exit-2,exit rotary straight,arrive |
Scenario: Collinear in X,Y Scenario: Collinear in X,Y
Given the node map Given the node map
@ -215,8 +215,8 @@ Feature: Rotary
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,e | ad,be,be | depart,bcdb-exit-1,arrive | | a,e | ad,be,be,be | depart,bcdb-exit-1,exit rotary straight,arrive |
| a,f | ad,cf,cf | depart,bcdb-exit-2,arrive | | a,f | ad,cf,cf,cf | depart,bcdb-exit-2,exit rotary straight,arrive |
Scenario: Collinear in X,Y Scenario: Collinear in X,Y
Given the node map Given the node map
@ -236,8 +236,8 @@ Feature: Rotary
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,e | ac,de,de | depart,bcdb-exit-1,arrive | | a,e | ac,de,de,de | depart,bcdb-exit-1,exit rotary straight,arrive |
| a,f | ac,bf,bf | depart,bcdb-exit-2,arrive | | a,f | ac,bf,bf,bf | depart,bcdb-exit-2,exit rotary straight,arrive |
Scenario: Collinear in X,Y Scenario: Collinear in X,Y
Given the node map Given the node map
@ -257,8 +257,8 @@ Feature: Rotary
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,e | ab,ce,ce | depart,bcdb-exit-1,arrive | | a,e | ab,ce,ce,ce | depart,bcdb-exit-1,exit rotary right,arrive |
| a,f | ab,df,df | depart,bcdb-exit-2,arrive | | a,f | ab,df,df,df | depart,bcdb-exit-2,exit rotary right,arrive |
Scenario: Collinear in X,Y Scenario: Collinear in X,Y
Given the node map Given the node map
@ -278,5 +278,5 @@ Feature: Rotary
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,e | ab,ce,ce | depart,bcdb-exit-1,arrive | | a,e | ab,ce,ce,ce | depart,bcdb-exit-1,exit rotary right,arrive |
| a,f | ab,df,df | depart,bcdb-exit-2,arrive | | a,f | ab,df,df,df | depart,bcdb-exit-2,exit rotary right,arrive |

View File

@ -5,39 +5,6 @@ Feature: Basic Roundabout
Given the profile "bicycle" Given the profile "bicycle"
Given a grid size of 10 meters Given a grid size of 10 meters
Scenario: Only Enter
Given the node map
"""
a
b
d c g h
e
f
"""
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bcegb | roundabout |
When I route I should get
| waypoints | route | turns |
| a,c | ab,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| a,e | ab,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| a,g | ab,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| d,e | cd,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| d,g | cd,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| d,b | cd,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| f,g | ef,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| f,b | ef,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| f,c | ef,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| h,b | gh,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| h,c | gh,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
| h,e | gh,bcegb,bcegb | depart,roundabout-exit-undefined,arrive |
Scenario: Only Exit Scenario: Only Exit
Given the node map Given the node map
""" """
@ -58,53 +25,20 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| b,d | bcegb,cd,cd | depart,roundabout-exit-1,arrive | | b,d | bcegb,cd,cd | depart,exit roundabout right,arrive |
| b,f | bcegb,ef,ef | depart,roundabout-exit-2,arrive | | b,f | bcegb,ef,ef | depart,exit roundabout right,arrive |
| b,h | bcegb,gh,gh | depart,roundabout-exit-3,arrive | | b,h | bcegb,gh,gh | depart,exit roundabout right,arrive |
| c,f | bcegb,ef,ef | depart,roundabout-exit-1,arrive | | c,f | bcegb,ef,ef | depart,exit roundabout right,arrive |
| c,h | bcegb,gh,gh | depart,roundabout-exit-2,arrive | | c,h | bcegb,gh,gh | depart,exit roundabout right,arrive |
| c,a | bcegb,ab,ab | depart,roundabout-exit-3,arrive | | c,a | bcegb,ab,ab | depart,exit roundabout right,arrive |
| e,h | bcegb,gh,gh | depart,roundabout-exit-1,arrive | | e,h | bcegb,gh,gh | depart,exit roundabout right,arrive |
| e,a | bcegb,ab,ab | depart,roundabout-exit-2,arrive | | e,a | bcegb,ab,ab | depart,exit roundabout right,arrive |
| e,d | bcegb,cd,cd | depart,roundabout-exit-3,arrive | | e,d | bcegb,cd,cd | depart,exit roundabout right,arrive |
| g,a | bcegb,ab,ab | depart,roundabout-exit-1,arrive | | g,a | bcegb,ab,ab | depart,exit roundabout right,arrive |
| g,d | bcegb,cd,cd | depart,roundabout-exit-2,arrive | | g,d | bcegb,cd,cd | depart,exit roundabout right,arrive |
| g,f | bcegb,ef,ef | depart,roundabout-exit-3,arrive | | g,f | bcegb,ef,ef | depart,exit roundabout right,arrive |
#phantom node snapping can result in a full round-trip here, therefore we cannot test b->a and the other direct exits #phantom node snapping can result in a full round-trip here, therefore we cannot test b->a and the other direct exits
Scenario: Drive Around
Given the node map
"""
a
b
d c g h
e
f
"""
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bcegb | roundabout |
When I route I should get
| waypoints | route | turns |
| b,c | bcegb,bcegb | depart,arrive |
| b,e | bcegb,bcegb | depart,arrive |
| b,g | bcegb,bcegb | depart,arrive |
| c,e | bcegb,bcegb | depart,arrive |
| c,g | bcegb,bcegb | depart,arrive |
| c,b | bcegb,bcegb | depart,arrive |
| e,g | bcegb,bcegb | depart,arrive |
| e,b | bcegb,bcegb | depart,arrive |
| e,c | bcegb,bcegb | depart,arrive |
| g,b | bcegb,bcegb | depart,arrive |
| g,c | bcegb,bcegb | depart,arrive |
| g,e | bcegb,bcegb | depart,arrive |
Scenario: Mixed Entry and Exit Scenario: Mixed Entry and Exit
Given the node map Given the node map
""" """
@ -125,19 +59,19 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,c | abc,abc,abc | depart,roundabout-exit-1,arrive | | a,c | abc,abc,abc | depart,exit roundabout right,arrive |
| a,l | abc,jkl,jkl | depart,roundabout-exit-2,arrive | | a,l | abc,jkl,jkl,jkl | depart,roundabout-exit-2,exit roundabout straight,arrive |
| a,i | abc,ghi,ghi | depart,roundabout-exit-3,arrive | | a,i | abc,ghi,ghi,ghi | depart,roundabout-exit-3,exit roundabout straight,arrive |
| a,f | abc,def,def | depart,roundabout-exit-4,arrive | | a,f | abc,def,def,def | depart,roundabout-exit-4,exit roundabout straight,arrive |
| d,f | def,def,def | depart,roundabout-exit-1,arrive | | d,f | def,def,def | depart,exit roundabout right,arrive |
| d,c | def,abc,abc | depart,roundabout-exit-2,arrive | | d,c | def,abc,abc,abc | depart,roundabout-exit-2,exit roundabout straight,arrive |
| d,l | def,jkl,jkl | depart,roundabout-exit-3,arrive | | d,l | def,jkl,jkl,jkl | depart,roundabout-exit-3,exit roundabout straight,arrive |
| d,i | def,ghi,ghi | depart,roundabout-exit-4,arrive | | d,i | def,ghi,ghi,ghi | depart,roundabout-exit-4,exit roundabout straight,arrive |
| g,i | ghi,ghi,ghi | depart,roundabout-exit-1,arrive | | g,i | ghi,ghi,ghi | depart,exit roundabout right,arrive |
| g,f | ghi,def,def | depart,roundabout-exit-2,arrive | | g,f | ghi,def,def,def | depart,roundabout-exit-2,exit roundabout straight,arrive |
| g,c | ghi,abc,abc | depart,roundabout-exit-3,arrive | | g,c | ghi,abc,abc,abc | depart,roundabout-exit-3,exit roundabout straight,arrive |
| g,l | ghi,jkl,jkl | depart,roundabout-exit-4,arrive | | g,l | ghi,jkl,jkl,jkl | depart,roundabout-exit-4,exit roundabout straight,arrive |
| j,l | jkl,jkl,jkl | depart,roundabout-exit-1,arrive | | j,l | jkl,jkl,jkl | depart,exit roundabout right,arrive |
| j,i | jkl,ghi,ghi | depart,roundabout-exit-2,arrive | | j,i | jkl,ghi,ghi,ghi | depart,roundabout-exit-2,exit roundabout straight,arrive |
| j,f | jkl,def,def | depart,roundabout-exit-3,arrive | | j,f | jkl,def,def,def | depart,roundabout-exit-3,exit roundabout straight,arrive |
| j,c | jkl,abc,abc | depart,roundabout-exit-4,arrive | | j,c | jkl,abc,abc,abc | depart,roundabout-exit-4,exit roundabout straight,arrive |

View File

@ -53,6 +53,6 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| c,a | cba,cba,cba | depart,roundabout-exit-1,arrive | | c,a | cba,cba,cba | depart,exit roundabout left,arrive |
| l,a | lkj,cba,cba | depart,roundabout-exit-2,arrive | | l,a | lkj,cba,cba,cba | depart,roundabout-exit-2,exit roundabout straight,arrive |
| i,a | ihg,cba,cba | depart,roundabout-exit-3,arrive | | i,a | ihg,cba,cba,cba | depart,roundabout-exit-3,exit roundabout straight,arrive |

View File

@ -5,39 +5,6 @@ Feature: Basic Roundabout
Given the profile "bicycle" Given the profile "bicycle"
Given a grid size of 10 meters Given a grid size of 10 meters
Scenario: Enter and Exit
Given the node map
"""
a
b
h g c d
e
f
"""
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bgecb | roundabout |
When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout turn left exit-3,arrive |
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive |
| a,h | ab,gh,gh | depart,roundabout turn right exit-1,arrive |
| d,f | cd,ef,ef | depart,roundabout turn left exit-3,arrive |
| d,h | cd,gh,gh | depart,roundabout turn straight exit-2,arrive |
| d,a | cd,ab,ab | depart,roundabout turn right exit-1,arrive |
| f,h | ef,gh,gh | depart,roundabout turn left exit-3,arrive |
| f,a | ef,ab,ab | depart,roundabout turn straight exit-2,arrive |
| f,d | ef,cd,cd | depart,roundabout turn right exit-1,arrive |
| h,a | gh,ab,ab | depart,roundabout turn left exit-3,arrive |
| h,d | gh,cd,cd | depart,roundabout turn straight exit-2,arrive |
| h,f | gh,ef,ef | depart,roundabout turn right exit-1,arrive |
# https://www.openstreetmap.org/way/223225602 # https://www.openstreetmap.org/way/223225602
Scenario: Enter and Exit with changing mode Scenario: Enter and Exit with changing mode
Given the node map Given the node map
@ -60,14 +27,14 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout turn left exit-1,arrive | | a,d | ab,cd,cd | depart,roundabout turn left exit-1,arrive |
| a,f | ab,ef,ef,ef | depart,roundabout turn left exit-1,notification right,arrive | | a,f | ab,ef,ef,ef | depart,roundabout turn straight exit-1,exit roundabout right,arrive |
| a,h | ab,bgecb,gh,gh | depart,roundabout turn right exit-1,notification right,arrive | | a,h | ab,gh,gh,gh | depart,roundabout turn right exit-1,exit roundabout right,arrive |
| d,f | cd,ef,ef,ef | depart,roundabout turn sharp left exit-2,notification right,arrive | | d,f | cd,ef,ef,ef | depart,roundabout turn left exit-2,exit roundabout right,arrive |
| d,h | cd,gh,gh,gh | depart,roundabout turn left exit-2,notification right,arrive | | d,h | cd,gh,gh,gh | depart,roundabout turn straight exit-2,exit roundabout right,arrive |
| d,a | cd,ab,ab | depart,roundabout turn right exit-1,arrive | | d,a | cd,ab,ab | depart,roundabout turn right exit-1,arrive |
| f,h | ef,gh,gh,gh | depart,roundabout turn sharp left exit-3,notification right,arrive | | f,h | ef,gh,gh,gh | depart,roundabout turn left exit-3,exit roundabout right,arrive |
| f,a | ef,ab,ab | depart,roundabout turn straight exit-2,arrive | | f,a | ef,ab,ab | depart,roundabout turn straight exit-2,arrive |
| f,d | ef,cd,cd | depart,roundabout turn right exit-1,arrive | | f,d | ef,cd,cd | depart,roundabout turn right exit-1,arrive |
| h,a | gh,ab,ab | depart,roundabout turn left exit-2,arrive | | h,a | gh,ab,ab | depart,roundabout turn left exit-2,arrive |
| h,d | gh,cd,cd | depart,roundabout turn straight exit-1,arrive | | h,d | gh,cd,cd | depart,roundabout turn straight exit-1,arrive |
| h,f | gh,bgecb,ef,ef | depart,roundabout turn right exit-1,notification right,arrive | | h,f | gh,ef,ef,ef | depart,roundabout turn right exit-1,exit roundabout right,arrive |

View File

@ -123,18 +123,18 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| b,d | bcegb,cd,cd | depart,roundabout-exit-1,arrive | | b,d | bcegb,cd,cd | depart,exit roundabout right,arrive |
| b,f | bcegb,ef,ef | depart,roundabout-exit-2,arrive | | b,f | bcegb,ef,ef | depart,exit roundabout right,arrive |
| b,h | bcegb,gh,gh | depart,roundabout-exit-3,arrive | | b,h | bcegb,gh,gh | depart,exit roundabout right,arrive |
| c,f | bcegb,ef,ef | depart,roundabout-exit-1,arrive | | c,f | bcegb,ef,ef | depart,exit roundabout right,arrive |
| c,h | bcegb,gh,gh | depart,roundabout-exit-2,arrive | | c,h | bcegb,gh,gh | depart,exit roundabout right,arrive |
| c,a | bcegb,ab,ab | depart,roundabout-exit-3,arrive | | c,a | bcegb,ab,ab | depart,exit roundabout right,arrive |
| e,h | bcegb,gh,gh | depart,roundabout-exit-1,arrive | | e,h | bcegb,gh,gh | depart,exit roundabout right,arrive |
| e,a | bcegb,ab,ab | depart,roundabout-exit-2,arrive | | e,a | bcegb,ab,ab | depart,exit roundabout right,arrive |
| e,d | bcegb,cd,cd | depart,roundabout-exit-3,arrive | | e,d | bcegb,cd,cd | depart,exit roundabout right,arrive |
| g,a | bcegb,ab,ab | depart,roundabout-exit-1,arrive | | g,a | bcegb,ab,ab | depart,exit roundabout right,arrive |
| g,d | bcegb,cd,cd | depart,roundabout-exit-2,arrive | | g,d | bcegb,cd,cd | depart,exit roundabout right,arrive |
| g,f | bcegb,ef,ef | depart,roundabout-exit-3,arrive | | g,f | bcegb,ef,ef | depart,exit roundabout right,arrive |
#phantom node snapping can result in a full round-trip here, therefore we cannot test b->a and the other direct exits #phantom node snapping can result in a full round-trip here, therefore we cannot test b->a and the other direct exits
Scenario: Drive Around Scenario: Drive Around
@ -190,22 +190,22 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,c | abc,abc,abc | depart,roundabout-exit-1,arrive | | a,c | abc,abc,abc | depart,exit roundabout right,arrive |
| a,l | abc,jkl,jkl | depart,roundabout-exit-2,arrive | | a,l | abc,jkl,jkl,jkl | depart,roundabout-exit-2,exit roundabout straight,arrive |
| a,i | abc,ghi,ghi | depart,roundabout-exit-3,arrive | | a,i | abc,ghi,ghi,ghi | depart,roundabout-exit-3,exit roundabout straight,arrive |
| a,f | abc,def,def | depart,roundabout-exit-4,arrive | | a,f | abc,def,def,def | depart,roundabout-exit-4,exit roundabout straight,arrive |
| d,f | def,def,def | depart,roundabout-exit-1,arrive | | d,f | def,def,def | depart,exit roundabout right,arrive |
| d,c | def,abc,abc | depart,roundabout-exit-2,arrive | | d,c | def,abc,abc,abc | depart,roundabout-exit-2,exit roundabout straight,arrive |
| d,l | def,jkl,jkl | depart,roundabout-exit-3,arrive | | d,l | def,jkl,jkl,jkl | depart,roundabout-exit-3,exit roundabout straight,arrive |
| d,i | def,ghi,ghi | depart,roundabout-exit-4,arrive | | d,i | def,ghi,ghi,ghi | depart,roundabout-exit-4,exit roundabout straight,arrive |
| g,i | ghi,ghi,ghi | depart,roundabout-exit-1,arrive | | g,i | ghi,ghi,ghi | depart,exit roundabout right,arrive |
| g,f | ghi,def,def | depart,roundabout-exit-2,arrive | | g,f | ghi,def,def,def | depart,roundabout-exit-2,exit roundabout straight,arrive |
| g,c | ghi,abc,abc | depart,roundabout-exit-3,arrive | | g,c | ghi,abc,abc,abc | depart,roundabout-exit-3,exit roundabout straight,arrive |
| g,l | ghi,jkl,jkl | depart,roundabout-exit-4,arrive | | g,l | ghi,jkl,jkl,jkl | depart,roundabout-exit-4,exit roundabout straight,arrive |
| j,l | jkl,jkl,jkl | depart,roundabout-exit-1,arrive | | j,l | jkl,jkl,jkl | depart,exit roundabout right,arrive |
| j,i | jkl,ghi,ghi | depart,roundabout-exit-2,arrive | | j,i | jkl,ghi,ghi,ghi | depart,roundabout-exit-2,exit roundabout straight,arrive |
| j,f | jkl,def,def | depart,roundabout-exit-3,arrive | | j,f | jkl,def,def,def | depart,roundabout-exit-3,exit roundabout straight,arrive |
| j,c | jkl,abc,abc | depart,roundabout-exit-4,arrive | | j,c | jkl,abc,abc,abc | depart,roundabout-exit-4,exit roundabout straight,arrive |
Scenario: Segregated roads - Not an intersection Scenario: Segregated roads - Not an intersection
Given the node map Given the node map
@ -227,22 +227,22 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,c | abc,abc,abc | depart,roundabout-exit-4,arrive | | a,c | abc,abc,abc,abc | depart,roundabout-exit-4,exit roundabout right,arrive |
| a,l | abc,jkl,jkl | depart,roundabout-exit-1,arrive | | a,l | abc,jkl,jkl,jkl | depart,roundabout-exit-1,exit roundabout right,arrive |
| a,i | abc,ghi,ghi | depart,roundabout-exit-2,arrive | | a,i | abc,ghi,ghi,ghi | depart,roundabout-exit-2,exit roundabout right,arrive |
| a,f | abc,def,def | depart,roundabout-exit-3,arrive | | a,f | abc,def,def,def | depart,roundabout-exit-3,exit roundabout right,arrive |
| d,f | def,def,def | depart,roundabout-exit-4,arrive | | d,f | def,def,def,def | depart,roundabout-exit-4,exit roundabout right,arrive |
| d,c | def,abc,abc | depart,roundabout-exit-1,arrive | | d,c | def,abc,abc,abc | depart,roundabout-exit-1,exit roundabout right,arrive |
| d,l | def,jkl,jkl | depart,roundabout-exit-2,arrive | | d,l | def,jkl,jkl,jkl | depart,roundabout-exit-2,exit roundabout right,arrive |
| d,i | def,ghi,ghi | depart,roundabout-exit-3,arrive | | d,i | def,ghi,ghi,ghi | depart,roundabout-exit-3,exit roundabout right,arrive |
| g,i | ghi,ghi,ghi | depart,roundabout-exit-4,arrive | | g,i | ghi,ghi,ghi,ghi | depart,roundabout-exit-4,exit roundabout right,arrive |
| g,f | ghi,def,def | depart,roundabout-exit-1,arrive | | g,f | ghi,def,def,def | depart,roundabout-exit-1,exit roundabout right,arrive |
| g,c | ghi,abc,abc | depart,roundabout-exit-2,arrive | | g,c | ghi,abc,abc,abc | depart,roundabout-exit-2,exit roundabout right,arrive |
| g,l | ghi,jkl,jkl | depart,roundabout-exit-3,arrive | | g,l | ghi,jkl,jkl,jkl | depart,roundabout-exit-3,exit roundabout right,arrive |
| j,l | jkl,jkl,jkl | depart,roundabout-exit-4,arrive | | j,l | jkl,jkl,jkl,jkl | depart,roundabout-exit-4,exit roundabout right,arrive |
| j,i | jkl,ghi,ghi | depart,roundabout-exit-1,arrive | | j,i | jkl,ghi,ghi,ghi | depart,roundabout-exit-1,exit roundabout right,arrive |
| j,f | jkl,def,def | depart,roundabout-exit-2,arrive | | j,f | jkl,def,def,def | depart,roundabout-exit-2,exit roundabout right,arrive |
| j,c | jkl,abc,abc | depart,roundabout-exit-3,arrive | | j,c | jkl,abc,abc,abc | depart,roundabout-exit-3,exit roundabout right,arrive |
Scenario: Collinear in X Scenario: Collinear in X
Given the node map Given the node map
@ -369,18 +369,18 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout-exit-4,arrive | | a,d | ab,cd,cd,cd | depart,roundabout-exit-4,exit roundabout right,arrive |
| a,f | ab,ef,ef | depart,roundabout-exit-3,arrive | | a,f | ab,ef,ef,ef | depart,roundabout-exit-3,exit roundabout right,arrive |
| a,h | ab,gh,gh | depart,roundabout-exit-2,arrive | | a,h | ab,gh,gh,gh | depart,roundabout-exit-2,exit roundabout right,arrive |
| d,f | cd,ef,ef | depart,roundabout-exit-4,arrive | | d,f | cd,ef,ef,ef | depart,roundabout-exit-4,exit roundabout right,arrive |
| d,h | cd,gh,gh | depart,roundabout-exit-3,arrive | | d,h | cd,gh,gh,gh | depart,roundabout-exit-3,exit roundabout right,arrive |
| d,a | cd,ab,ab | depart,roundabout-exit-1,arrive | | d,a | cd,ab,ab,ab | depart,roundabout-exit-1,exit roundabout right,arrive |
| f,h | ef,gh,gh | depart,roundabout-exit-4,arrive | | f,h | ef,gh,gh,gh | depart,roundabout-exit-4,exit roundabout right,arrive |
| f,a | ef,ab,ab | depart,roundabout-exit-2,arrive | | f,a | ef,ab,ab,ab | depart,roundabout-exit-2,exit roundabout right,arrive |
| f,d | ef,cd,cd | depart,roundabout-exit-1,arrive | | f,d | ef,cd,cd,cd | depart,roundabout-exit-1,exit roundabout right,arrive |
| h,a | gh,ab,ab | depart,roundabout-exit-3,arrive | | h,a | gh,ab,ab,ab | depart,roundabout-exit-3,exit roundabout right,arrive |
| h,d | gh,cd,cd | depart,roundabout-exit-2,arrive | | h,d | gh,cd,cd,cd | depart,roundabout-exit-2,exit roundabout right,arrive |
| h,f | gh,ef,ef | depart,roundabout-exit-1,arrive | | h,f | gh,ef,ef,ef | depart,roundabout-exit-1,exit roundabout right,arrive |
Scenario: Enter and Exit -- Non-Distinct Scenario: Enter and Exit -- Non-Distinct
Given the node map Given the node map
@ -402,18 +402,18 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout-exit-3,arrive | | a,d | ab,cd,cd,cd | depart,roundabout-exit-3,exit roundabout right,arrive |
| a,f | ab,ef,ef | depart,roundabout-exit-2,arrive | | a,f | ab,ef,ef,ef | depart,roundabout-exit-2,exit roundabout right,arrive |
| a,h | ab,gh,gh | depart,roundabout-exit-1,arrive | | a,h | ab,gh,gh,gh | depart,roundabout-exit-1,exit roundabout straight,arrive |
| d,f | cd,ef,ef | depart,roundabout-exit-3,arrive | | d,f | cd,ef,ef,ef | depart,roundabout-exit-3,exit roundabout right,arrive |
| d,h | cd,gh,gh | depart,roundabout-exit-2,arrive | | d,h | cd,gh,gh,gh | depart,roundabout-exit-2,exit roundabout straight,arrive |
| d,a | cd,ab,ab | depart,roundabout-exit-1,arrive | | d,a | cd,ab,ab,ab | depart,roundabout-exit-1,exit roundabout right,arrive |
| f,h | ef,gh,gh | depart,roundabout-exit-3,arrive | | f,h | ef,gh,gh,gh | depart,roundabout-exit-3,exit roundabout straight,arrive |
| f,a | ef,ab,ab | depart,roundabout-exit-2,arrive | | f,a | ef,ab,ab,ab | depart,roundabout-exit-2,exit roundabout right,arrive |
| f,d | ef,cd,cd | depart,roundabout-exit-1,arrive | | f,d | ef,cd,cd,cd | depart,roundabout-exit-1,exit roundabout right,arrive |
| h,a | gh,ab,ab | depart,roundabout-exit-3,arrive | | h,a | gh,ab,ab,ab | depart,roundabout-exit-3,exit roundabout right,arrive |
| h,d | gh,cd,cd | depart,roundabout-exit-2,arrive | | h,d | gh,cd,cd,cd | depart,roundabout-exit-2,exit roundabout right,arrive |
| h,f | gh,ef,ef | depart,roundabout-exit-1,arrive | | h,f | gh,ef,ef,ef | depart,roundabout-exit-1,exit roundabout right,arrive |
Scenario: Enter and Exit -- Bearing Scenario: Enter and Exit -- Bearing
Given the node map Given the node map

View File

@ -58,9 +58,9 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,d | ab,cd,cd | depart,roundabout-exit-1,arrive | | a,d | ab,cd,cd,cd | depart,roundabout-exit-1,exit roundabout right,arrive |
| a,h | ab,gh,gh | depart,roundabout-exit-2,arrive | | a,h | ab,gh,gh,gh | depart,roundabout-exit-2,exit roundabout straight,arrive |
| a,f | ab,ef,ef | depart,roundabout-exit-2,arrive | | a,f | ab,ef,ef,ef | depart,roundabout-exit-2,exit roundabout right,arrive |
#2927 #2927
Scenario: Only Roundabout Scenario: Only Roundabout
@ -99,18 +99,18 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| b,d | bcegb,cd,cd | depart,roundabout-exit-1,arrive | | b,d | bcegb,cd,cd | depart,exit roundabout right,arrive |
| b,f | bcegb,ef,ef | depart,roundabout-exit-2,arrive | | b,f | bcegb,ef,ef | depart,exit roundabout right,arrive |
| b,h | bcegb,gh,gh | depart,roundabout-exit-3,arrive | | b,h | bcegb,gh,gh | depart,exit roundabout right,arrive |
| c,f | bcegb,ef,ef | depart,roundabout-exit-1,arrive | | c,f | bcegb,ef,ef | depart,exit roundabout right,arrive |
| c,h | bcegb,gh,gh | depart,roundabout-exit-2,arrive | | c,h | bcegb,gh,gh | depart,exit roundabout right,arrive |
| c,a | bcegb,ab,ab | depart,roundabout-exit-3,arrive | | c,a | bcegb,ab,ab | depart,exit roundabout right,arrive |
| e,h | bcegb,gh,gh | depart,roundabout-exit-1,arrive | | e,h | bcegb,gh,gh | depart,exit roundabout right,arrive |
| e,a | bcegb,ab,ab | depart,roundabout-exit-2,arrive | | e,a | bcegb,ab,ab | depart,exit roundabout right,arrive |
| e,d | bcegb,cd,cd | depart,roundabout-exit-3,arrive | | e,d | bcegb,cd,cd | depart,exit roundabout right,arrive |
| g,a | bcegb,ab,ab | depart,roundabout-exit-1,arrive | | g,a | bcegb,ab,ab | depart,exit roundabout right,arrive |
| g,d | bcegb,cd,cd | depart,roundabout-exit-2,arrive | | g,d | bcegb,cd,cd | depart,exit roundabout right,arrive |
| g,f | bcegb,ef,ef | depart,roundabout-exit-3,arrive | | g,f | bcegb,ef,ef | depart,exit roundabout right,arrive |
#phantom node snapping can result in a full round-trip here, therefore we cannot test b->a and the other direct exits #phantom node snapping can result in a full round-trip here, therefore we cannot test b->a and the other direct exits
Scenario: Drive Around Scenario: Drive Around
@ -166,22 +166,22 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,c | abc,abc,abc | depart,roundabout-exit-1,arrive | | a,c | abc,abc,abc | depart,exit roundabout right,arrive |
| a,l | abc,jkl,jkl | depart,roundabout-exit-2,arrive | | a,l | abc,jkl,jkl,jkl | depart,roundabout-exit-2,exit roundabout straight,arrive |
| a,i | abc,ghi,ghi | depart,roundabout-exit-3,arrive | | a,i | abc,ghi,ghi,ghi | depart,roundabout-exit-3,exit roundabout straight,arrive |
| a,f | abc,def,def | depart,roundabout-exit-4,arrive | | a,f | abc,def,def,def | depart,roundabout-exit-4,exit roundabout straight,arrive |
| d,f | def,def,def | depart,roundabout-exit-1,arrive | | d,f | def,def,def | depart,exit roundabout right,arrive |
| d,c | def,abc,abc | depart,roundabout-exit-2,arrive | | d,c | def,abc,abc,abc | depart,roundabout-exit-2,exit roundabout straight,arrive |
| d,l | def,jkl,jkl | depart,roundabout-exit-3,arrive | | d,l | def,jkl,jkl,jkl | depart,roundabout-exit-3,exit roundabout straight,arrive |
| d,i | def,ghi,ghi | depart,roundabout-exit-4,arrive | | d,i | def,ghi,ghi,ghi | depart,roundabout-exit-4,exit roundabout straight,arrive |
| g,i | ghi,ghi,ghi | depart,roundabout-exit-1,arrive | | g,i | ghi,ghi,ghi | depart,exit roundabout right,arrive |
| g,f | ghi,def,def | depart,roundabout-exit-2,arrive | | g,f | ghi,def,def,def | depart,roundabout-exit-2,exit roundabout straight,arrive |
| g,c | ghi,abc,abc | depart,roundabout-exit-3,arrive | | g,c | ghi,abc,abc,abc | depart,roundabout-exit-3,exit roundabout straight,arrive |
| g,l | ghi,jkl,jkl | depart,roundabout-exit-4,arrive | | g,l | ghi,jkl,jkl,jkl | depart,roundabout-exit-4,exit roundabout straight,arrive |
| j,l | jkl,jkl,jkl | depart,roundabout-exit-1,arrive | | j,l | jkl,jkl,jkl | depart,exit roundabout right,arrive |
| j,i | jkl,ghi,ghi | depart,roundabout-exit-2,arrive | | j,i | jkl,ghi,ghi,ghi | depart,roundabout-exit-2,exit roundabout straight,arrive |
| j,f | jkl,def,def | depart,roundabout-exit-3,arrive | | j,f | jkl,def,def,def | depart,roundabout-exit-3,exit roundabout straight,arrive |
| j,c | jkl,abc,abc | depart,roundabout-exit-4,arrive | | j,c | jkl,abc,abc,abc | depart,roundabout-exit-4,exit roundabout straight,arrive |
Scenario: Mixed Entry and Exit - segregated roads Scenario: Mixed Entry and Exit - segregated roads
Given the node map Given the node map
@ -205,22 +205,22 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,c | abc,abc,abc | depart,roundabout-exit-4,arrive | | a,c | abc,abc,abc,abc | depart,roundabout-exit-4,exit roundabout right,arrive |
| a,l | abc,jkl,jkl | depart,roundabout-exit-1,arrive | | a,l | abc,jkl,jkl,jkl | depart,roundabout-exit-1,exit roundabout right,arrive |
| a,i | abc,ghi,ghi | depart,roundabout-exit-2,arrive | | a,i | abc,ghi,ghi,ghi | depart,roundabout-exit-2,exit roundabout right,arrive |
| a,f | abc,def,def | depart,roundabout-exit-3,arrive | | a,f | abc,def,def,def | depart,roundabout-exit-3,exit roundabout right,arrive |
| d,f | def,def,def | depart,roundabout-exit-4,arrive | | d,f | def,def,def,def | depart,roundabout-exit-4,exit roundabout right,arrive |
| d,c | def,abc,abc | depart,roundabout-exit-1,arrive | | d,c | def,abc,abc,abc | depart,roundabout-exit-1,exit roundabout right,arrive |
| d,l | def,jkl,jkl | depart,roundabout-exit-2,arrive | | d,l | def,jkl,jkl,jkl | depart,roundabout-exit-2,exit roundabout right,arrive |
| d,i | def,ghi,ghi | depart,roundabout-exit-3,arrive | | d,i | def,ghi,ghi,ghi | depart,roundabout-exit-3,exit roundabout right,arrive |
| g,i | ghi,ghi,ghi | depart,roundabout-exit-4,arrive | | g,i | ghi,ghi,ghi,ghi | depart,roundabout-exit-4,exit roundabout right,arrive |
| g,f | ghi,def,def | depart,roundabout-exit-1,arrive | | g,f | ghi,def,def,def | depart,roundabout-exit-1,exit roundabout right,arrive |
| g,c | ghi,abc,abc | depart,roundabout-exit-2,arrive | | g,c | ghi,abc,abc,abc | depart,roundabout-exit-2,exit roundabout right,arrive |
| g,l | ghi,jkl,jkl | depart,roundabout-exit-3,arrive | | g,l | ghi,jkl,jkl,jkl | depart,roundabout-exit-3,exit roundabout right,arrive |
| j,l | jkl,jkl,jkl | depart,roundabout-exit-4,arrive | | j,l | jkl,jkl,jkl,jkl | depart,roundabout-exit-4,exit roundabout right,arrive |
| j,i | jkl,ghi,ghi | depart,roundabout-exit-1,arrive | | j,i | jkl,ghi,ghi,ghi | depart,roundabout-exit-1,exit roundabout right,arrive |
| j,f | jkl,def,def | depart,roundabout-exit-2,arrive | | j,f | jkl,def,def,def | depart,roundabout-exit-2,exit roundabout right,arrive |
| j,c | jkl,abc,abc | depart,roundabout-exit-3,arrive | | j,c | jkl,abc,abc,abc | depart,roundabout-exit-3,exit roundabout right,arrive |
Scenario: Mixed Entry and Exit - clockwise order Scenario: Mixed Entry and Exit - clockwise order
Given the node map Given the node map
@ -242,22 +242,22 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,c | abc,abc,abc | depart,roundabout-exit-4,arrive | | a,c | abc,abc,abc,abc | depart,roundabout-exit-4,exit roundabout left,arrive |
| a,l | abc,jkl,jkl | depart,roundabout-exit-3,arrive | | a,l | abc,jkl,jkl,jkl | depart,roundabout-exit-3,exit roundabout left,arrive |
| a,i | abc,ghi,ghi | depart,roundabout-exit-2,arrive | | a,i | abc,ghi,ghi,ghi | depart,roundabout-exit-2,exit roundabout left,arrive |
| a,f | abc,def,def | depart,roundabout-exit-1,arrive | | a,f | abc,def,def,def | depart,roundabout-exit-1,exit roundabout left,arrive |
| d,f | def,def,def | depart,roundabout-exit-4,arrive | | d,f | def,def,def,def | depart,roundabout-exit-4,exit roundabout left,arrive |
| d,c | def,abc,abc | depart,roundabout-exit-3,arrive | | d,c | def,abc,abc,abc | depart,roundabout-exit-3,exit roundabout left,arrive |
| d,l | def,jkl,jkl | depart,roundabout-exit-2,arrive | | d,l | def,jkl,jkl,jkl | depart,roundabout-exit-2,exit roundabout left,arrive |
| d,i | def,ghi,ghi | depart,roundabout-exit-1,arrive | | d,i | def,ghi,ghi,ghi | depart,roundabout-exit-1,exit roundabout left,arrive |
| g,i | ghi,ghi,ghi | depart,roundabout-exit-4,arrive | | g,i | ghi,ghi,ghi,ghi | depart,roundabout-exit-4,exit roundabout left,arrive |
| g,f | ghi,def,def | depart,roundabout-exit-3,arrive | | g,f | ghi,def,def,def | depart,roundabout-exit-3,exit roundabout left,arrive |
| g,c | ghi,abc,abc | depart,roundabout-exit-2,arrive | | g,c | ghi,abc,abc,abc | depart,roundabout-exit-2,exit roundabout left,arrive |
| g,l | ghi,jkl,jkl | depart,roundabout-exit-1,arrive | | g,l | ghi,jkl,jkl,jkl | depart,roundabout-exit-1,exit roundabout left,arrive |
| j,l | jkl,jkl,jkl | depart,roundabout-exit-4,arrive | | j,l | jkl,jkl,jkl,jkl | depart,roundabout-exit-4,exit roundabout left,arrive |
| j,i | jkl,ghi,ghi | depart,roundabout-exit-3,arrive | | j,i | jkl,ghi,ghi,ghi | depart,roundabout-exit-3,exit roundabout left,arrive |
| j,f | jkl,def,def | depart,roundabout-exit-2,arrive | | j,f | jkl,def,def,def | depart,roundabout-exit-2,exit roundabout left,arrive |
| j,c | jkl,abc,abc | depart,roundabout-exit-1,arrive | | j,c | jkl,abc,abc,abc | depart,roundabout-exit-1,exit roundabout left,arrive |
Scenario: Mixed Entry and Exit - segregated roads, different names Scenario: Mixed Entry and Exit - segregated roads, different names
Given the node map Given the node map
@ -285,22 +285,22 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,c | ab,bc,bc | depart,roundabout-exit-4,arrive | | a,c | ab,bc,bc,bc | depart,roundabout-exit-4,exit roundabout right,arrive |
| a,l | ab,kl,kl | depart,roundabout-exit-1,arrive | | a,l | ab,kl,kl,kl | depart,roundabout-exit-1,exit roundabout right,arrive |
| a,i | ab,hi,hi | depart,roundabout-exit-2,arrive | | a,i | ab,hi,hi,hi | depart,roundabout-exit-2,exit roundabout right,arrive |
| a,f | ab,ef,ef | depart,roundabout-exit-3,arrive | | a,f | ab,ef,ef,ef | depart,roundabout-exit-3,exit roundabout right,arrive |
| d,f | de,ef,ef | depart,roundabout-exit-4,arrive | | d,f | de,ef,ef,ef | depart,roundabout-exit-4,exit roundabout right,arrive |
| d,c | de,bc,bc | depart,roundabout-exit-1,arrive | | d,c | de,bc,bc,bc | depart,roundabout-exit-1,exit roundabout right,arrive |
| d,l | de,kl,kl | depart,roundabout-exit-2,arrive | | d,l | de,kl,kl,kl | depart,roundabout-exit-2,exit roundabout right,arrive |
| d,i | de,hi,hi | depart,roundabout-exit-3,arrive | | d,i | de,hi,hi,hi | depart,roundabout-exit-3,exit roundabout right,arrive |
| g,i | gh,hi,hi | depart,roundabout-exit-4,arrive | | g,i | gh,hi,hi,hi | depart,roundabout-exit-4,exit roundabout right,arrive |
| g,f | gh,ef,ef | depart,roundabout-exit-1,arrive | | g,f | gh,ef,ef,ef | depart,roundabout-exit-1,exit roundabout right,arrive |
| g,c | gh,bc,bc | depart,roundabout-exit-2,arrive | | g,c | gh,bc,bc,bc | depart,roundabout-exit-2,exit roundabout right,arrive |
| g,l | gh,kl,kl | depart,roundabout-exit-3,arrive | | g,l | gh,kl,kl,kl | depart,roundabout-exit-3,exit roundabout right,arrive |
| j,l | jk,kl,kl | depart,roundabout-exit-4,arrive | | j,l | jk,kl,kl,kl | depart,roundabout-exit-4,exit roundabout right,arrive |
| j,i | jk,hi,hi | depart,roundabout-exit-1,arrive | | j,i | jk,hi,hi,hi | depart,roundabout-exit-1,exit roundabout right,arrive |
| j,f | jk,ef,ef | depart,roundabout-exit-2,arrive | | j,f | jk,ef,ef,ef | depart,roundabout-exit-2,exit roundabout right,arrive |
| j,c | jk,bc,bc | depart,roundabout-exit-3,arrive | | j,c | jk,bc,bc,bc | depart,roundabout-exit-3,exit roundabout right,arrive |
Scenario: Motorway Roundabout Scenario: Motorway Roundabout
#See 39.933742 -75.082345 #See 39.933742 -75.082345
@ -339,10 +339,9 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | ref | | waypoints | route | turns | ref |
| a,e | crescent,crescent,crescent | depart,roundabout-exit-3,arrive | US 130,US 130,US 130 | | a,e | crescent,crescent,crescent,crescent | depart,roundabout-exit-3,exit roundabout straight,arrive | US 130,US 130,US 130,US 130 |
| j,l | ,, | depart,roundabout-exit-2,arrive | NJ 38,NJ 38,NJ 38 | | j,l | ,,, | depart,roundabout-exit-2,exit roundabout straight,arrive | NJ 38,NJ 38,NJ 38,NJ 38 |
@todo
# this test previously only passed by accident. We need to handle throughabouts correctly, since staying on massachusetts is actually # this test previously only passed by accident. We need to handle throughabouts correctly, since staying on massachusetts is actually
# the desired setting. Rotary instructions here are not wanted but rather no instruction at all to go through the roundabout (or add # the desired setting. Rotary instructions here are not wanted but rather no instruction at all to go through the roundabout (or add
# a throughabout instruction) # a throughabout instruction)
@ -390,7 +389,7 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,k | massachusetts,massachusetts,massachusetts,massachusetts | depart,sheridan circle-exit-2,rotary-exit-1,arrive | | a,k | massachusetts,massachusetts,massachusetts,massachusetts | depart,sheridan circle-exit-2,exit rotary right,arrive |
#2856 - http://www.openstreetmap.org/#map=19/47.23318/-1.56563 #2856 - http://www.openstreetmap.org/#map=19/47.23318/-1.56563
Scenario: Linked Roundabouts Scenario: Linked Roundabouts
@ -478,7 +477,7 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| 1,h | roundabout,right-bot-out,right-bot-out | depart,roundabout-exit-1,arrive | | 1,h | roundabout,right-bot-out,right-bot-out | depart,exit rotary straight,arrive |
@3254 @3254
Scenario: Driving up to and through a roundabout Scenario: Driving up to and through a roundabout
@ -495,7 +494,7 @@ Feature: Basic Roundabout
And the ways And the ways
| nodes | junction | name | highway | | nodes | junction | name | highway |
| abcda | roundabout | roundabout | residential | | abcda | roundabout | rotary | residential |
| gfi | | side | residential | | gfi | | side | residential |
| efb | | left | residential | | efb | | left | residential |
| dh | | right | residential | | dh | | right | residential |
@ -503,7 +502,7 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| e,h | left,right,right | depart,roundabout-exit-2,arrive | | e,h | left,right,right,right | depart,rotary-exit-2,exit rotary right,arrive |
@3254 @3254
Scenario: Driving up to and through a roundabout Scenario: Driving up to and through a roundabout
@ -520,7 +519,7 @@ Feature: Basic Roundabout
And the ways And the ways
| nodes | junction | name | highway | | nodes | junction | name | highway |
| abcda | roundabout | roundabout | residential | | abcda | roundabout | rotary | residential |
| gfi | | side | residential | | gfi | | side | residential |
| efb | | left | residential | | efb | | left | residential |
| dh | | right | residential | | dh | | right | residential |
@ -528,7 +527,7 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| e,h | left,right,right | depart,roundabout-exit-2,arrive | | e,h | left,right,right,right | depart,rotary-exit-2,exit rotary right,arrive |
@3361 @3361
Scenario: Bersarinplatz (Not a Roundabout) Scenario: Bersarinplatz (Not a Roundabout)
@ -566,12 +565,12 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,g | Petersburger Strasse,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-2,arrive | | a,g | Petersburger Strasse,Petersburger Strasse,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-2,exit rotary straight,arrive |
| d,g | Weidenweg,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-1,arrive | | d,g | Weidenweg,Petersburger Strasse,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-1,exit rotary straight,arrive |
| i,k | Petersburger Strasse,Rigaer Strasse,Rigaer Strasse | depart,Bersarinplatz-exit-1,arrive | | i,k | Petersburger Strasse,Rigaer Strasse,Rigaer Strasse,Rigaer Strasse | depart,Bersarinplatz-exit-1,exit rotary right,arrive |
| i,n | Petersburger Strasse,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-2,arrive | | i,n | Petersburger Strasse,Petersburger Strasse,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-2,exit rotary straight,arrive |
| i,d | Petersburger Strasse,Weidenweg,Weidenweg | depart,Bersarinplatz-exit-3,arrive | | i,d | Petersburger Strasse,Weidenweg,Weidenweg,Weidenweg | depart,Bersarinplatz-exit-3,exit rotary right,arrive |
| i,g | Petersburger Strasse,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-4,arrive | | i,g | Petersburger Strasse,Petersburger Strasse,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-4,exit rotary straight,arrive |
@turboroundabout @turboroundabout
# http://www.openstreetmap.org/?mlat=48.782118&mlon=8.194456&zoom=16#map=19/48.78216/8.19457 # http://www.openstreetmap.org/?mlat=48.782118&mlon=8.194456&zoom=16#map=19/48.78216/8.19457
@ -607,10 +606,10 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,d | ,Europastrasse,Europastrasse | depart,Europaplatz-exit-1,arrive | | a,d | ,Europastrasse,Europastrasse,Europastrasse | depart,Europaplatz-exit-1,exit rotary right,arrive |
| a,h | ,Allee Cite,Allee Cite | depart,Europaplatz-exit-2,arrive | | a,h | ,Allee Cite,Allee Cite,Allee Cite | depart,Europaplatz-exit-2,exit rotary right,arrive |
| a,l | ,Europastrasse,Europastrasse | depart,Europaplatz-exit-3,arrive | | a,l | ,Europastrasse,Europastrasse,Europastrasse | depart,Europaplatz-exit-3,exit rotary right,arrive |
| a,p | ,, | depart,Europaplatz-exit-4,arrive | | a,p | ,,, | depart,Europaplatz-exit-4,exit rotary right,arrive |
@turboroundabout @turboroundabout
# http://www.openstreetmap.org/?mlat=50.180039&mlon=8.474939&zoom=16#map=19/50.17999/8.47506 # http://www.openstreetmap.org/?mlat=50.180039&mlon=8.474939&zoom=16#map=19/50.17999/8.47506
@ -660,11 +659,11 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,w | Le-Cannet-Rocheville-Strasse,, | depart,roundabout-exit-undefined,arrive | | a,w | Le-Cannet-Rocheville-Strasse,, | depart,roundabout-exit-undefined,arrive |
| a,r | Le-Cannet-Rocheville-Strasse,, | depart,roundabout-exit-4,arrive | | a,r | Le-Cannet-Rocheville-Strasse,,, | depart,roundabout-exit-4,exit roundabout right,arrive |
| a,f | Le-Cannet-Rocheville-Strasse,Frankfurter Strasse,Frankfurter Strasse | depart,roundabout-exit-1,arrive | | a,f | Le-Cannet-Rocheville-Strasse,Frankfurter Strasse,Frankfurter Strasse,Frankfurter Strasse | depart,roundabout-exit-1,exit roundabout right,arrive |
| a,h | Le-Cannet-Rocheville-Strasse,Bischof-Kaller-Strasse,Bischof-Kaller-Strasse | depart,roundabout-exit-2,arrive | | a,h | Le-Cannet-Rocheville-Strasse,Bischof-Kaller-Strasse,Bischof-Kaller-Strasse,Bischof-Kaller-Strasse | depart,roundabout-exit-2,exit roundabout right,arrive |
| u,r | ,, | depart,roundabout-exit-5,arrive | | u,r | ,,, | depart,roundabout-exit-5,exit roundabout right,arrive |
| j,h | Bischof-Kaller-Strasse,Bischof-Kaller-Strasse,Bischof-Kaller-Strasse | depart,roundabout-exit-5,arrive | | j,h | Bischof-Kaller-Strasse,Bischof-Kaller-Strasse,Bischof-Kaller-Strasse,Bischof-Kaller-Strasse | depart,roundabout-exit-5,exit roundabout right,arrive |
| n,m | , | depart,arrive | | n,m | , | depart,arrive |
@turboroundabout @turboroundabout
@ -709,16 +708,15 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| w,r | wk,ar,ar | depart,roundabout-exit-1,arrive | | w,r | wk,ar,ar,ar | depart,roundabout-exit-1,exit roundabout slight right,arrive |
| w,s | wk,ds,ds | depart,roundabout-exit-2,arrive | | w,s | wk,ds,ds,ds | depart,roundabout-exit-2,exit roundabout right,arrive |
| w,t | wk,ft,ft | depart,roundabout-exit-3,arrive | | w,t | wk,ft,ft,ft | depart,roundabout-exit-3,exit roundabout right,arrive |
| w,v | wk,hv,hv | depart,roundabout-exit-4,arrive | | w,v | wk,hv,hv,hv | depart,roundabout-exit-4,exit roundabout straight,arrive |
| u,v | ug,hv,hv | depart,roundabout-exit-1,arrive | | u,v | ug,hv,hv,hv | depart,roundabout-exit-1,exit roundabout straight,arrive |
| u,w | ug,jw,jw | depart,roundabout-exit-2,arrive | | u,w | ug,jw,jw,jw | depart,roundabout-exit-2,exit roundabout slight right,arrive |
| u,r | ug,ar,ar | depart,roundabout-exit-3,arrive | | u,r | ug,ar,ar,ar | depart,roundabout-exit-3,exit roundabout slight right,arrive |
| u,s | ug,ds,ds | depart,roundabout-exit-4,arrive | | u,s | ug,ds,ds,ds | depart,roundabout-exit-4,exit roundabout right,arrive |
| u,t | ug,ft,ft | depart,roundabout-exit-5,arrive | | u,t | ug,ft,ft,ft | depart,roundabout-exit-5,exit roundabout right,arrive |
@3762 @3762
Scenario: Only Enter Scenario: Only Enter
@ -743,7 +741,7 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,h | ab,ef,ef,fh,fh | depart,roundabout-exit-4,notification slight right,notification straight,arrive | | a,h | ab,ef,ef,fh,fh | depart,roundabout-exit-4,exit roundabout slight right,notification straight,arrive |
Scenario: Drive through roundabout Scenario: Drive through roundabout
@ -764,10 +762,10 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| waypoints | bearings | route | turns | | waypoints | bearings | route | turns |
| e,f | 90 90 | edf,edf | depart,arrive | | e,f | 90 90 | edf,edf | depart,arrive |
| e,h | 90 135 | edf,gch,gch | depart,roundabout-exit-2,arrive | | e,h | 90 135 | edf,gch,gch,gch | depart,roundabout-exit-2,exit roundabout straight,arrive |
| g,f | 45 90 | gch,edf,edf | depart,roundabout-exit-2,arrive | | g,f | 45 90 | gch,edf,edf,edf | depart,roundabout-exit-2,exit roundabout right,arrive |
| g,h | 45 135 | gch,gch,gch | depart,roundabout-exit-1,arrive | | g,h | 45 135 | gch,gch,gch | depart,exit roundabout right,arrive |
| e,e | 90 270 | edf,edf,edf | depart,roundabout-exit-3,arrive | | e,e | 90 270 | edf,edf,edf,edf | depart,roundabout-exit-3,exit roundabout sharp left,arrive |
Scenario: CCW and CW roundabouts with overlaps Scenario: CCW and CW roundabouts with overlaps
Given the node map Given the node map
@ -787,12 +785,13 @@ Feature: Basic Roundabout
| kg | tertiary | | | kg | tertiary | |
| hl | tertiary | | | hl | tertiary | |
# the turn angles here are quite strange, so we do get uturns for exiting
When I route I should get When I route I should get
| from | to | route | turns | distance | | from | to | route | turns | distance |
| e | f | ed,af,af | depart,roundabout-exit-1,arrive | 80.1m | | e | f | ed,af,af,af | depart,roundabout-exit-1,exit roundabout left,arrive | 80.1m |
| f | e | af,ed,ed | depart,roundabout-exit-1,arrive | 120.1m | | f | e | af,ed,ed,ed | depart,roundabout-exit-1,exit roundabout uturn,arrive | 120.1m |
| k | l | kg,hl,hl | depart,roundabout-exit-1,arrive | 80.1m | | k | l | kg,hl,hl,hl | depart,roundabout-exit-1,exit roundabout right,arrive | 80.1m |
| l | k | hl,kg,kg | depart,roundabout-exit-1,arrive | 120.1m | | l | k | hl,kg,kg,kg | depart,roundabout-exit-1,exit roundabout uturn,arrive | 120.1m |
@4030 @4075 @4030 @4075
Scenario: Service roundabout with service exits Scenario: Service roundabout with service exits
@ -812,10 +811,10 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| from | to | route | turns | | from | to | route | turns |
| 1 | e | abcda,ce,ce | depart,roundabout-exit-1,arrive | | 1 | e | abcda,ce,ce | depart,exit roundabout straight,arrive |
| 1 | f | abcda,df,df | depart,roundabout-exit-2,arrive | | 1 | f | abcda,df,df | depart,exit roundabout right,arrive |
| 1 | g | abcda,ag,ag | depart,roundabout-exit-3,arrive | | 1 | g | abcda,ag,ag | depart,exit roundabout straight,arrive |
| 1 | h | abcda,bh,bh | depart,roundabout-exit-4,arrive | | 1 | h | abcda,bh,bh | depart,exit roundabout right,arrive |
Scenario: Collapsing a sliproad step after roundabouts Scenario: Collapsing a sliproad step after roundabouts
Given the node map Given the node map
@ -844,5 +843,5 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| from | to | route | turns | distance | | from | to | route | turns | distance |
| e | k | ebds,ufghl,jhik,jhik | depart,rstur-exit-2,turn right,arrive | 189.1m | | e | k | ebds,ufghl,ufghl,jhik,jhik | depart,rstur-exit-2,exit rotary right,turn right,arrive | 189.1m |
| 1 | k | ebds,ufghl,jhik,jhik | depart,rstur-exit-2,turn right,arrive | 159.1m | | 1 | k | ebds,ufghl,ufghl,jhik,jhik | depart,rstur-exit-2,exit rotary right,turn right,arrive | 159.1m |

View File

@ -167,7 +167,7 @@ Feature: Approach parameter
| s | e | unrestricted curb | | | s | e | unrestricted curb | |
Scenario: UTurn test, router can found a route because he can use the roundabout Scenario: UTurn test, router can find a route because he can use the roundabout
Given the node map Given the node map
""" """
h h

View File

@ -167,12 +167,12 @@ class RouteAPI : public BaseAPI
* the overall response consistent. * the overall response consistent.
* *
* CAUTION: order of post-processing steps is important * CAUTION: order of post-processing steps is important
* - postProcess must be called before collapseTurnInstructions that expects * - handleRoundabouts must be called before collapseTurnInstructions that
* post-processed roundabouts without Exit instructions * expects post-processed roundabouts
*/ */
guidance::trimShortSegments(steps, leg_geometry); guidance::trimShortSegments(steps, leg_geometry);
leg.steps = guidance::postProcess(std::move(steps)); leg.steps = guidance::handleRoundabouts(std::move(steps));
leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps)); leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps));
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps)); leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
leg.steps = guidance::buildIntersections(std::move(leg.steps)); leg.steps = guidance::buildIntersections(std::move(leg.steps));

View File

@ -17,7 +17,7 @@ namespace guidance
// passed as none-reference to modify in-place and move out again // passed as none-reference to modify in-place and move out again
OSRM_ATTR_WARN_UNUSED OSRM_ATTR_WARN_UNUSED
std::vector<RouteStep> postProcess(std::vector<RouteStep> steps); std::vector<RouteStep> handleRoundabouts(std::vector<RouteStep> steps);
// trim initial/final segment of very short length. // trim initial/final segment of very short length.
// This function uses in/out parameter passing to modify both steps and geometry in place. // This function uses in/out parameter passing to modify both steps and geometry in place.

View File

@ -199,7 +199,10 @@ inline bool leavesRoundabout(const extractor::guidance::TurnInstruction instruct
inline bool staysOnRoundabout(const extractor::guidance::TurnInstruction instruction) inline bool staysOnRoundabout(const extractor::guidance::TurnInstruction instruction)
{ {
return instruction.type == extractor::guidance::TurnType::StayOnRoundabout; return instruction.type == extractor::guidance::TurnType::StayOnRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutAtExit ||
instruction.type == extractor::guidance::TurnType::EnterRotaryAtExit ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutIntersectionAtExit;
} }
// Silent Turn Instructions are not to be mentioned to the outside world but // Silent Turn Instructions are not to be mentioned to the outside world but

View File

@ -1,6 +1,6 @@
{ {
"name": "osrm", "name": "osrm",
"version": "5.12.0-latest.1", "version": "5.12.0-roundaboutexits.1",
"private": false, "private": false,
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.", "description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
"dependencies": { "dependencies": {

View File

@ -44,12 +44,13 @@ const constexpr char *modifier_names[] = {"uturn",
// translations of TurnTypes. Not all types are exposed to the outside world. // translations of TurnTypes. Not all types are exposed to the outside world.
// invalid types should never be returned as part of the API // invalid types should never be returned as part of the API
const constexpr char *turn_type_names[] = { const constexpr char *turn_type_names[] = {
"invalid", "new name", "continue", "turn", "merge", "invalid", "new name", "continue", "turn",
"on ramp", "off ramp", "fork", "end of road", "notification", "merge", "on ramp", "off ramp", "fork",
"roundabout", "roundabout", "rotary", "rotary", "roundabout turn", "end of road", "notification", "roundabout", "exit roundabout",
"roundabout turn", "use lane", "invalid", "invalid", "invalid", "rotary", "exit rotary", "roundabout turn", "roundabout turn",
"invalid", "invalid", "invalid", "invalid", "invalid", "use lane", "invalid", "invalid", "roundabout",
"invalid", "invalid"}; "exit roundabout", "rotary", "exit rotary", "roundabout turn",
"exit roundabout", "invalid", "invalid"};
const constexpr char *waypoint_type_names[] = {"invalid", "arrive", "depart"}; const constexpr char *waypoint_type_names[] = {"invalid", "arrive", "depart"};
@ -68,7 +69,7 @@ inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection
std::string instructionTypeToString(const TurnType::Enum type) std::string instructionTypeToString(const TurnType::Enum type)
{ {
static_assert(sizeof(turn_type_names) / sizeof(turn_type_names[0]) >= TurnType::MaxTurnType, static_assert(sizeof(turn_type_names) / sizeof(turn_type_names[0]) >= TurnType::MaxTurnType,
"Some turn types has not string representation."); "Some turn types doesn't have a string representation.");
return turn_type_names[static_cast<std::size_t>(type)]; return turn_type_names[static_cast<std::size_t>(type)];
} }

View File

@ -7,6 +7,7 @@
#include "engine/guidance/collapsing_utility.hpp" #include "engine/guidance/collapsing_utility.hpp"
#include "util/bearing.hpp" #include "util/bearing.hpp"
#include "util/group_by.hpp"
#include "util/guidance/name_announcements.hpp" #include "util/guidance/name_announcements.hpp"
#include "util/guidance/turn_lanes.hpp" #include "util/guidance/turn_lanes.hpp"
@ -14,6 +15,8 @@
#include <boost/numeric/conversion/cast.hpp> #include <boost/numeric/conversion/cast.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range.hpp>
#include "engine/guidance/collapsing_utility.hpp"
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <cstddef> #include <cstddef>
@ -26,6 +29,8 @@ using osrm::extractor::guidance::hasRampType;
using osrm::extractor::guidance::mirrorDirectionModifier; using osrm::extractor::guidance::mirrorDirectionModifier;
using osrm::extractor::guidance::bearingToDirectionModifier; using osrm::extractor::guidance::bearingToDirectionModifier;
using RouteStepIterator = std::vector<osrm::engine::guidance::RouteStep>::iterator;
namespace osrm namespace osrm
{ {
namespace engine namespace engine
@ -36,207 +41,136 @@ namespace guidance
namespace namespace
{ {
void fixFinalRoundabout(std::vector<RouteStep> &steps) // Ensure that after we are done with the roundabout, only the roundabout instructions themselves
// remain
void compressRange(const RouteStepIterator begin, const RouteStepIterator end)
{ {
for (std::size_t propagation_index = steps.size() - 1; propagation_index > 0; if (begin == end)
--propagation_index) return;
for (auto itr = begin + 1; itr != end; ++itr)
{ {
auto &propagation_step = steps[propagation_index]; // ensure not to invalidate the final arrive
propagation_step.maneuver.exit = 0; if (!hasWaypointType(*itr))
if (entersRoundabout(propagation_step.maneuver.instruction))
{ {
// remember the current name as rotary name in tha case we end in a rotary begin->ElongateBy(*itr);
if (propagation_step.maneuver.instruction.type == TurnType::EnterRotary || itr->Invalidate();
propagation_step.maneuver.instruction.type == TurnType::EnterRotaryAtExit)
{
propagation_step.rotary_name = propagation_step.name;
propagation_step.rotary_pronunciation = propagation_step.pronunciation;
} }
else if (propagation_step.maneuver.instruction.type == }
TurnType::EnterRoundaboutIntersection || }
propagation_step.maneuver.instruction.type ==
TurnType::EnterRoundaboutIntersectionAtExit) // this function handles a single roundabout between enter (which might be missing) to exit (which
// might be missing as well)
void processRoundaboutExits(const RouteStepIterator begin, const RouteStepIterator end)
{
auto const last = end - 1;
// If we do not exit the roundabout, there is no exit to report. All good here
if (!leavesRoundabout(last->maneuver.instruction))
{ {
propagation_step.maneuver.instruction.type = TurnType::EnterRoundabout; // first we do some clean-up
if (begin->maneuver.instruction.type == TurnType::EnterRotary ||
begin->maneuver.instruction.type == TurnType::EnterRotaryAtExit)
{
begin->rotary_name = begin->name;
begin->rotary_pronunciation = begin->pronunciation;
}
// roundabout turns don't make sense without an exit, update the type
else if (entersRoundabout(begin->maneuver.instruction) &&
(begin->maneuver.instruction.type == TurnType::EnterRoundaboutIntersection ||
begin->maneuver.instruction.type == TurnType::EnterRoundaboutIntersectionAtExit))
{
begin->maneuver.instruction.type = TurnType::EnterRoundabout;
} }
// We are doing a roundtrip on the roundabout, Nothing to do here but to remove the
// instructions
compressRange(begin, end);
return; return;
} }
// accumulate turn data into the enter instructions
else if (propagation_step.maneuver.instruction.type == TurnType::StayOnRoundabout)
{
// TODO this operates on the data that is in the instructions.
// We are missing out on the final segment after the last stay-on-roundabout
// instruction though. it is not contained somewhere until now
steps[propagation_index - 1].ElongateBy(propagation_step);
steps[propagation_index - 1].maneuver.exit = propagation_step.maneuver.exit;
propagation_step.Invalidate();
}
}
}
bool setUpRoundabout(RouteStep &step) const auto passes_exit_or_leaves_roundabout = [](auto const &step) {
{ return staysOnRoundabout(step.maneuver.instruction) ||
// basic entry into a roundabout leavesRoundabout(step.maneuver.instruction);
// Special case handling, if an entry is directly tied to an exit
const auto instruction = step.maneuver.instruction;
if (instruction.type == TurnType::EnterRotaryAtExit ||
instruction.type == TurnType::EnterRoundaboutAtExit ||
instruction.type == TurnType::EnterRoundaboutIntersectionAtExit)
{
// Here we consider an actual entry, not an exit. We simply have to count the additional
// exit
step.maneuver.exit = 1;
// prevent futher special case handling of these two.
if (instruction.type == TurnType::EnterRotaryAtExit)
step.maneuver.instruction.type = TurnType::EnterRotary;
else if (instruction.type == TurnType::EnterRoundaboutAtExit)
step.maneuver.instruction.type = TurnType::EnterRoundabout;
else
step.maneuver.instruction.type = TurnType::EnterRoundaboutIntersection;
}
if (leavesRoundabout(instruction))
{
// This set-up, even though it looks the same, is actually looking at entering AND exiting
step.maneuver.exit = 1; // count the otherwise missing exit
// prevent futher special case handling of these two.
if (instruction.type == TurnType::EnterAndExitRotary)
step.maneuver.instruction.type = TurnType::EnterRotary;
else if (instruction.type == TurnType::EnterAndExitRoundabout)
step.maneuver.instruction.type = TurnType::EnterRoundabout;
else
step.maneuver.instruction.type = TurnType::EnterRoundaboutIntersection;
return false;
}
else
{
return true;
}
}
void closeOffRoundabout(const bool on_roundabout,
std::vector<RouteStep> &steps,
std::size_t step_index)
{
auto &step = steps[step_index];
step.maneuver.exit += 1;
if (!on_roundabout)
{
BOOST_ASSERT(steps.size() >= 2);
// We reached a special case that requires the addition of a special route step in the
// beginning. We started in a roundabout, so to announce the exit, we move use the exit
// instruction and move it right to the beginning to make sure to immediately announce the
// exit.
BOOST_ASSERT(leavesRoundabout(steps[1].maneuver.instruction) ||
steps[1].maneuver.instruction.type == TurnType::StayOnRoundabout ||
steps[1].maneuver.instruction.type == TurnType::Suppressed ||
steps[1].maneuver.instruction.type == TurnType::NoTurn);
steps[0].geometry_end = 1;
steps[1].geometry_begin = 0;
steps[1].AddInFront(steps[0]);
steps[1].intersections.erase(steps[1].intersections.begin()); // otherwise we copy the
// source
if (leavesRoundabout(steps[1].maneuver.instruction))
steps[1].maneuver.exit = 1;
steps[0].duration = 0;
steps[0].distance = 0;
const auto exitToEnter = [](const TurnType::Enum type) {
if (TurnType::ExitRotary == type)
return TurnType::EnterRotary;
// if we do not enter the roundabout Intersection, we cannot treat the full traversal as
// a turn. So we switch it up to the roundabout type
else if (type == TurnType::ExitRoundaboutIntersection)
return TurnType::EnterRoundabout;
else
return TurnType::EnterRoundabout;
}; };
steps[1].maneuver.instruction.type = exitToEnter(step.maneuver.instruction.type);
if (steps[1].maneuver.instruction.type == TurnType::EnterRotary)
{
steps[1].rotary_name = steps[0].name;
steps[1].rotary_pronunciation = steps[0].pronunciation;
}
}
if (step_index > 1) // exit count
{ const auto exit = std::count_if(begin, end, passes_exit_or_leaves_roundabout);
auto &exit_step = steps[step_index];
auto &prev_step = steps[step_index - 1];
// In case the step with the roundabout exit instruction cannot be merged with the
// previous step we change the instruction to a normal turn
if (!guidance::haveSameMode(exit_step, prev_step))
{
BOOST_ASSERT(leavesRoundabout(exit_step.maneuver.instruction));
if (!entersRoundabout(prev_step.maneuver.instruction))
{
prev_step.maneuver.instruction = exit_step.maneuver.instruction;
}
prev_step.maneuver.exit = exit_step.maneuver.exit;
exit_step.maneuver.instruction.type = TurnType::Notification;
step_index--;
}
}
// Normal exit from the roundabout, or exit from a previously fixed roundabout. Propagate the // removes all intermediate instructions, assigns names and exit numbers
// index back to the entering location and prepare the current silent set of instructions for BOOST_ASSERT(leavesRoundabout(last->maneuver.instruction));
// removal. BOOST_ASSERT(std::distance(begin, end) >= 1);
std::vector<std::size_t> intermediate_steps; last->maneuver.exit = exit;
BOOST_ASSERT(!steps[step_index].intersections.empty());
// the very first intersection in the steps represents the location of the turn. Following // when we actually have an enter instruction, we can store all the information on it that we
// intersections are locations passed along the way // need, otherwise we only provide the exit instruciton. In case of re-routing on the
const auto exit_intersection = steps[step_index].intersections.front(); // roundabout, this might result in strange behaviour, but this way we are more resiliant and we
// do provide exit after all
if (entersRoundabout(begin->maneuver.instruction))
{
begin->maneuver.exit = exit;
// special handling for rotaries: remember the name (legacy feature, due to
// adapt-step-signage)
if (begin->maneuver.instruction.type == TurnType::EnterRotary ||
begin->maneuver.instruction.type == TurnType::EnterRotaryAtExit)
{
begin->rotary_name = begin->name;
begin->rotary_pronunciation = begin->pronunciation;
}
// compute the total direction modifier for roundabout turns
else if (begin->maneuver.instruction.type == TurnType::EnterRoundaboutIntersection ||
begin->maneuver.instruction.type == TurnType::EnterRoundaboutIntersectionAtExit)
{
const auto entry_intersection = begin->intersections.front();
const auto exit_intersection = last->intersections.front();
const auto exit_bearing = exit_intersection.bearings[exit_intersection.out]; const auto exit_bearing = exit_intersection.bearings[exit_intersection.out];
const auto destination_copy = step;
if (step_index > 1) BOOST_ASSERT(!begin->intersections.empty());
{
// The very first route-step is head, so we cannot iterate past that one
for (std::size_t propagation_index = step_index - 1; propagation_index > 0;
--propagation_index)
{
auto &propagation_step = steps[propagation_index];
auto &next_step = steps[propagation_index + 1];
if (guidance::haveSameMode(propagation_step, next_step))
{
propagation_step.ElongateBy(next_step);
propagation_step.maneuver.exit = next_step.maneuver.exit;
next_step.Invalidate();
}
if (entersRoundabout(propagation_step.maneuver.instruction))
{
const auto entry_intersection = propagation_step.intersections.front();
// remember rotary name
if (propagation_step.maneuver.instruction.type == TurnType::EnterRotary ||
propagation_step.maneuver.instruction.type == TurnType::EnterRotaryAtExit)
{
propagation_step.rotary_name = propagation_step.name;
propagation_step.rotary_pronunciation = propagation_step.pronunciation;
}
else if (propagation_step.maneuver.instruction.type ==
TurnType::EnterRoundaboutIntersection ||
propagation_step.maneuver.instruction.type ==
TurnType::EnterRoundaboutIntersectionAtExit)
{
BOOST_ASSERT(!propagation_step.intersections.empty());
const double angle = util::bearing::angleBetween( const double angle = util::bearing::angleBetween(
util::bearing::reverse(entry_intersection.bearings[entry_intersection.in]), util::bearing::reverse(entry_intersection.bearings[entry_intersection.in]),
exit_bearing); exit_bearing);
auto bearings = propagation_step.intersections.front().bearings; begin->maneuver.instruction.direction_modifier = getTurnDirection(angle);
propagation_step.maneuver.instruction.direction_modifier = }
getTurnDirection(angle); begin->AdaptStepSignage(*last);
} }
propagation_step.AdaptStepSignage(destination_copy); // in case of a roundabout turn, we do not emit an exit as long as the mode remains the same
break; if ((begin->maneuver.instruction.type == TurnType::EnterRoundaboutIntersection ||
begin->maneuver.instruction.type == TurnType::EnterRoundaboutIntersectionAtExit) &&
begin->mode == last->mode)
{
compressRange(begin, end);
} }
else
{
// do not remove last (the exit instruction)
compressRange(begin, last);
}
}
// roundabout groups are a sequence of roundabout instructions. This can contain enter/exit
// instructions in between
void processRoundaboutGroups(const std::pair<RouteStepIterator, RouteStepIterator> &range)
{
const auto leaves_roundabout = [](auto const &step) {
return leavesRoundabout(step.maneuver.instruction);
};
auto itr = range.first;
while (itr != range.second)
{
auto exit = std::find_if(itr, range.second, leaves_roundabout);
if (exit == range.second)
{
processRoundaboutExits(itr, exit);
itr = exit;
}
else
{
processRoundaboutExits(itr, exit + 1);
itr = exit + 1;
} }
// remove exit
} }
} }
@ -248,64 +182,49 @@ void closeOffRoundabout(const bool on_roundabout,
// They are required for maintenance purposes. We can calculate the number // They are required for maintenance purposes. We can calculate the number
// of exits to pass in a roundabout and the number of intersections // of exits to pass in a roundabout and the number of intersections
// that we come across. // that we come across.
std::vector<RouteStep> postProcess(std::vector<RouteStep> steps) std::vector<RouteStep> handleRoundabouts(std::vector<RouteStep> steps)
{ {
// the steps should always include the first/last step in form of a location // check if a step has roundabout type
BOOST_ASSERT(steps.size() >= 2); const auto has_roundabout_type = [](auto const &step) {
if (steps.size() == 2) return hasRoundaboutType(step.maneuver.instruction);
};
const auto first_roundabout_type =
std::find_if(steps.begin(), steps.end(), has_roundabout_type);
// no roundabout to process?
if (first_roundabout_type == steps.end())
return steps; return steps;
// Count Street Exits forward // unless the first instruction enters the roundabout, we are currently on a roundabout. This is
bool on_roundabout = false; // a special case that happens if the route starts on a roundabout. It is a border case, but
bool has_entered_roundabout = false; // could happen during re-routing. In the case of re-routing, exit counting might be confusing,
// but it is the best we can do
bool currently_on_roundabout = !entersRoundabout(first_roundabout_type->maneuver.instruction);
// count the exits forward. if enter/exit roundabout happen both, no further treatment is // this group by paradigm does might contain intermediate roundabout instructions, when they are
// required. We might end up with only one of them (e.g. starting within a roundabout) // directly connected. Otherwise it will be a sequence containing everything from enter to exit.
// or having a via-point in the roundabout. // If we already start on the roundabout, the first valid place will be steps.begin().
// In this case, exits are numbered from the start of the leg. const auto is_on_roundabout = [&currently_on_roundabout](const auto &step) {
for (std::size_t step_index = 0; step_index < steps.size(); ++step_index) if (currently_on_roundabout)
{ {
const auto next_step_index = step_index + 1; if (leavesRoundabout(step.maneuver.instruction))
auto &step = steps[step_index]; currently_on_roundabout = false;
const auto instruction = step.maneuver.instruction;
if (entersRoundabout(instruction))
{
has_entered_roundabout = setUpRoundabout(step);
if (has_entered_roundabout && next_step_index < steps.size()) return true;
steps[next_step_index].maneuver.exit = step.maneuver.exit;
} }
else if (instruction.type == TurnType::StayOnRoundabout) else
{ {
on_roundabout = true; currently_on_roundabout = entersRoundabout(step.maneuver.instruction);
// increase the exit number we require passing the exit auto result = currently_on_roundabout;
step.maneuver.exit += 1; // cases that immediately exit the roundabout
if (next_step_index < steps.size()) if (currently_on_roundabout)
steps[next_step_index].maneuver.exit = step.maneuver.exit; currently_on_roundabout = !leavesRoundabout(step.maneuver.instruction);
} return result;
else if (leavesRoundabout(instruction))
{
// if (!has_entered_roundabout)
// in case the we are not on a roundabout, the very first instruction
// after the depart will be transformed into a roundabout and become
// the first valid instruction
closeOffRoundabout(has_entered_roundabout, steps, step_index);
has_entered_roundabout = false;
on_roundabout = false;
}
else if (on_roundabout && next_step_index < steps.size())
{
steps[next_step_index].maneuver.exit = step.maneuver.exit;
}
} }
};
// unterminated roundabout // for each range of instructions between begin/end of a roundabout assign
// Move backwards through the instructions until the start and remove the exit number util::group_by(steps.begin(), steps.end(), is_on_roundabout, processRoundaboutGroups);
// A roundabout without exit translates to enter-roundabout
if (has_entered_roundabout || on_roundabout)
{
fixFinalRoundabout(steps);
}
BOOST_ASSERT(steps.front().intersections.size() >= 1); BOOST_ASSERT(steps.front().intersections.size() >= 1);
BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1); BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1);
@ -333,8 +252,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
return; return;
// if phantom node is located at the connection of two segments, either one can be selected // if phantom node is located at the connection of two segments, either one can be selected
// as // as turn
// turn
// //
// a --- b // a --- b
// | // |