From c2dc7e9cd0052e5a5dc7fc4b5de8b858c8e8f571 Mon Sep 17 00:00:00 2001 From: Moritz Kobitzsch Date: Tue, 5 Sep 2017 21:30:34 +0200 Subject: [PATCH] use enter + exit for roundabout instructions (#4358) * Expose roundabout/rotary exit instructions as a new instruction type. --- CHANGELOG.md | 2 +- docs/http.md | 2 + features/car/classes.feature | 4 +- features/car/side_bias.feature | 29 -- features/guidance/anticipate-lanes.feature | 40 +- features/guidance/circular.feature | 274 +------------ .../guidance/dedicated-turn-roads.feature | 10 +- features/guidance/intersections.feature | 8 +- features/guidance/rotary-bike.feature | 177 --------- features/guidance/rotary.feature | 116 +++--- features/guidance/roundabout-bike.feature | 126 ++---- .../guidance/roundabout-left-sided.feature | 8 +- .../guidance/roundabout-turn-bike.feature | 59 +-- features/guidance/roundabout-turn.feature | 172 ++++---- features/guidance/roundabout.feature | 301 +++++++------- features/guidance/turn-angles.feature | 12 +- features/testbot/approaches.feature | 2 +- include/engine/api/route_api.hpp | 6 +- include/engine/guidance/post_processing.hpp | 2 +- .../extractor/guidance/turn_instruction.hpp | 5 +- package.json | 2 +- src/engine/api/json_factory.cpp | 20 +- src/engine/guidance/post_processing.cpp | 372 +++++++----------- test/nodejs/constants.js | 2 +- 24 files changed, 564 insertions(+), 1187 deletions(-) delete mode 100644 features/guidance/rotary-bike.feature diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d573ed5f..86260eb6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # UNRELEASED - - Changes from 5.11: - Guidance - now announcing turning onto oneways at the end of a road (e.g. onto dual carriageways) + - Adds new instruction types at the exit of roundabouts and rotaries `exit roundabout` and `exit rotary`. - HTTP: - New query parameter for route/table/match/trip plugings: `exclude=` that can be used to exclude certain classes (e.g. exclude=motorway, exclude=toll). diff --git a/docs/http.md b/docs/http.md index 53135080d..9dd4b1204 100644 --- a/docs/http.md +++ b/docs/http.md @@ -668,6 +668,8 @@ step. | `rotary` | a traffic circle. While very similar to a larger version of a roundabout, it does not necessarily follow roundabout rules for right of way. It can offer `rotary_name` and/or `rotary_pronunciation` parameters (located in the RouteStep object) in addition to the `exit` parameter (located on the StepManeuver object). | | `roundabout turn`| Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. | | `notification` | not an actual turn but a change in the driving conditions. For example the travel mode or classes. If the road takes a turn itself, the `modifier` describes the direction | +| `exit roundabout`| Describes a maneuver exiting a roundabout (usually preceeded by a `roundabout` instruction) | +| `exit rotary` | Describes the maneuver exiting a rotary (large named roundabout) | Please note that even though there are `new name` and `notification` instructions, the `mode` and `name` can change between all instructions. They only offer a fallback in case nothing else is to report. diff --git a/features/car/classes.feature b/features/car/classes.feature index 343b556f1..e8ad41785 100644 --- a/features/car/classes.feature +++ b/features/car/classes.feature @@ -122,6 +122,6 @@ Feature: Car - Mode flag | df | yes | motorway| | yes | When I route I should get - | from | to | route | turns | classes | - | a | f | ab,df,df | depart,roundabout-exit-2,arrive | [()],[(),(motorway),(toll,motorway)],[()] | + | from | to | route | turns | classes | + | a | f | ab,df,df,df | depart,roundabout-exit-2,exit roundabout slight right,arrive | [()],[(),(motorway)],[(toll,motorway)],[()] | diff --git a/features/car/side_bias.feature b/features/car/side_bias.feature index 155a6f49b..2547ef21a 100644 --- a/features/car/side_bias.feature +++ b/features/car/side_bias.feature @@ -47,32 +47,3 @@ Feature: Testbot - side bias | d | a | bd,ab,ab | 27s +-1 | # should be inverse of left hand bias | 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 | diff --git a/features/guidance/anticipate-lanes.feature b/features/guidance/anticipate-lanes.feature index 95894763b..c082dc3c1 100644 --- a/features/guidance/anticipate-lanes.feature +++ b/features/guidance/anticipate-lanes.feature @@ -553,8 +553,8 @@ Feature: Turn Lane Guidance | fy | | primary | | When I route I should get - | waypoints | route | turns | lanes | - | a,h | ab,gh,gh | depart,roundabout-exit-5,arrive | ,;;;;;, | + | waypoints | route | turns | lanes | + | a,h | ab,gh,gh,gh | depart,roundabout-exit-5,exit roundabout right,arrive | ,;;;;,, | @anticipate Scenario: No Lanes for Roundabouts, see #2626 @@ -569,16 +569,16 @@ Feature: Turn Lane Guidance | nodes | turn:lanes:forward | highway | junction | name | | xb | slight_right\|slight_right | primary | | xb | | dy | | primary | | dy | - | ab | | primary | roundabout | roundabout | - | bc | | primary | roundabout | roundabout | - | cd | left\|slight_right | primary | roundabout | roundabout | - | da | | primary | roundabout | roundabout | + | ab | | primary | roundabout | rotary | + | bc | | primary | roundabout | rotary | + | cd | left\|slight_right | primary | roundabout | rotary | + | da | | primary | roundabout | rotary | When I route I should get - | waypoints | route | turns | lanes | - | x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,;, | - | x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, | - | x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,;, | + | waypoints | route | turns | lanes | + | x,y | xb,dy,dy,dy | depart,rotary-exit-1,exit rotary right,arrive | ,,, | + | x,c | xb,rotary,rotary | depart,rotary-exit-undefined,arrive | ,, | + | x,a | xb,rotary,rotary | depart,rotary-exit-undefined,arrive | ,;, | @anticipate Scenario: No Lanes for Roundabouts, see #2626 @@ -614,8 +614,8 @@ Feature: Turn Lane Guidance | fy | | primary | | When I route I should get - | waypoints | route | turns | lanes | - | a,h | ab,ch,ch | depart,roundabout-exit-5,arrive | ,;;;;;, | + | waypoints | route | turns | lanes | + | a,h | ab,ch,ch,ch | depart,roundabout-exit-5,exit roundabout left,arrive | ,;;;;,, | @anticipate Scenario: No Lanes for Roundabouts, see #2626 @@ -635,16 +635,16 @@ Feature: Turn Lane Guidance | nodes | turn:lanes:forward | highway | junction | name | | xb | slight_right\|slight_right | primary | | xb | | dy | | primary | | dy | - | ab | | primary | roundabout | roundabout | - | bc | | primary | roundabout | roundabout | - | cd | left\|slight_right | primary | roundabout | roundabout | - | da | | primary | roundabout | roundabout | + | ab | | primary | roundabout | rotary | + | bc | | primary | roundabout | rotary | + | cd | left\|slight_right | primary | roundabout | rotary | + | da | | primary | roundabout | rotary | When I route I should get - | waypoints | route | turns | lanes | - | x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,;, | - | x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,, | - | x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,;, | + | waypoints | route | turns | lanes | + | x,y | xb,dy,dy,dy | depart,rotary-exit-1,exit rotary right,arrive | ,,, | + | x,c | xb,rotary,rotary | depart,rotary-exit-undefined,arrive | ,, | + | x,a | xb,rotary,rotary | depart,rotary-exit-undefined,arrive | ,;, | @anticipate @todo @2032 Scenario: No Lanes for Roundabouts, see #2626 diff --git a/features/guidance/circular.feature b/features/guidance/circular.feature index 82a414d95..94e0b8023 100644 --- a/features/guidance/circular.feature +++ b/features/guidance/circular.feature @@ -1,5 +1,8 @@ @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: Given the profile "car" @@ -24,259 +27,16 @@ Feature: Rotary | bgecb | circular | 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 | 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 | + | waypoints | route | turns | + | a,d | ab,cd,cd,cd | depart,bgecb-exit-3,exit rotary right,arrive | + | a,f | ab,ef,ef,ef | depart,bgecb-exit-2,exit rotary right,arrive | + | a,h | ab,gh,gh,gh | depart,bgecb-exit-1,exit rotary right,arrive | + | d,f | cd,ef,ef,ef | depart,bgecb-exit-3,exit rotary right,arrive | + | d,h | cd,gh,gh,gh | depart,bgecb-exit-2,exit rotary right,arrive | + | d,a | cd,ab,ab,ab | depart,bgecb-exit-1,exit rotary right,arrive | + | f,h | ef,gh,gh,gh | depart,bgecb-exit-3,exit rotary right,arrive | + | f,a | ef,ab,ab,ab | depart,bgecb-exit-2,exit rotary right,arrive | + | f,d | ef,cd,cd,cd | depart,bgecb-exit-1,exit rotary right,arrive | + | h,a | gh,ab,ab,ab | depart,bgecb-exit-3,exit rotary right,arrive | + | h,d | gh,cd,cd,cd | depart,bgecb-exit-2,exit rotary right,arrive | + | h,f | gh,ef,ef,ef | depart,bgecb-exit-1,exit rotary right,arrive | diff --git a/features/guidance/dedicated-turn-roads.feature b/features/guidance/dedicated-turn-roads.feature index 4e57ee8a5..c062c8369 100644 --- a/features/guidance/dedicated-turn-roads.feature +++ b/features/guidance/dedicated-turn-roads.feature @@ -905,8 +905,8 @@ Feature: Slipways and Dedicated Turn Lanes | restriction | yb | be | b | only_straight | When I route I should get - | waypoints | route | turns | locations | - | z,t | through,,out,out | depart,off ramp slight right,round-exit-3,arrive | z,s,c,t | + | waypoints | route | turns | locations | + | 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 Given the node map @@ -942,8 +942,8 @@ Feature: Slipways and Dedicated Turn Lanes | restriction | bc | cd | c | only_straight | When I route I should get - | waypoints | route | turns | locations | - | a,k | road,,, | depart,turn right,roundabout turn right exit-1,arrive | a,b,h,k | + | waypoints | route | turns | locations | + | a,k | road,,, | depart,turn right,roundabout turn right exit-1,arrive | a,b,h,k | @sliproads Scenario: Sliproad with 4 roads at target @@ -995,4 +995,4 @@ Feature: Slipways and Dedicated Turn Lanes When I route I should get | waypoints | route | turns | locations | - | s,f | sabc,dbef,dbef | depart,turn right,arrive | s,a,f | + | s,f | sabc,dbef,dbef | depart,turn right,arrive | s,a,f | \ No newline at end of file diff --git a/features/guidance/intersections.feature b/features/guidance/intersections.feature index 56bc2cab2..bc66cd7ab 100644 --- a/features/guidance/intersections.feature +++ b/features/guidance/intersections.feature @@ -140,9 +140,9 @@ Feature: Intersections Data When I route I should get | 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,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,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,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,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,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 | - | 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 | diff --git a/features/guidance/rotary-bike.feature b/features/guidance/rotary-bike.feature deleted file mode 100644 index bc55e5de4..000000000 --- a/features/guidance/rotary-bike.feature +++ /dev/null @@ -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 | diff --git a/features/guidance/rotary.feature b/features/guidance/rotary.feature index 9a685be80..64e78b3ef 100644 --- a/features/guidance/rotary.feature +++ b/features/guidance/rotary.feature @@ -24,19 +24,19 @@ Feature: Rotary | 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 | + | waypoints | route | turns | + | a,d | ab,cd,cd,cd | depart,bgecb-exit-3,exit rotary right,arrive | + | a,f | ab,ef,ef,ef | depart,bgecb-exit-2,exit rotary right,arrive | + | a,h | ab,gh,gh,gh | depart,bgecb-exit-1,exit rotary right,arrive | + | d,f | cd,ef,ef,ef | depart,bgecb-exit-3,exit rotary right,arrive | + | d,h | cd,gh,gh,gh | depart,bgecb-exit-2,exit rotary right,arrive | + | d,a | cd,ab,ab,ab | depart,bgecb-exit-1,exit rotary right,arrive | + | f,h | ef,gh,gh,gh | depart,bgecb-exit-3,exit rotary right,arrive | + | f,a | ef,ab,ab,ab | depart,bgecb-exit-2,exit rotary right,arrive | + | f,d | ef,cd,cd,cd | depart,bgecb-exit-1,exit rotary right,arrive | + | h,a | gh,ab,ab,ab | depart,bgecb-exit-3,exit rotary right,arrive | + | h,d | gh,cd,cd,cd | depart,bgecb-exit-2,exit rotary right,arrive | + | h,f | gh,ef,ef,ef | depart,bgecb-exit-1,exit rotary right,arrive | Scenario: Only Enter Given the node map @@ -90,19 +90,19 @@ Feature: Rotary | 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 | + | waypoints | route | turns | + | b,d | bcegb,cd,cd | depart,exit rotary right,arrive | + | b,f | bcegb,ef,ef | depart,exit rotary right,arrive | + | b,h | bcegb,gh,gh | depart,exit rotary right,arrive | + | c,f | bcegb,ef,ef | depart,exit rotary right,arrive | + | c,h | bcegb,gh,gh | depart,exit rotary right,arrive | + | c,a | bcegb,ab,ab | depart,exit rotary right,arrive | + | e,h | bcegb,gh,gh | depart,exit rotary right,arrive | + | e,a | bcegb,ab,ab | depart,exit rotary right,arrive | + | e,d | bcegb,cd,cd | depart,exit rotary right,arrive | + | g,a | bcegb,ab,ab | depart,exit rotary right,arrive | + | g,d | bcegb,cd,cd | depart,exit rotary right,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 Scenario: Drive Around @@ -158,23 +158,23 @@ Feature: Rotary | 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 | + | waypoints | route | turns | + | a,c | abc,abc,abc | depart,exit rotary right,arrive | + | a,l | abc,jkl,jkl,jkl | depart,bkheb-exit-2,exit rotary straight,arrive | + | a,i | abc,ghi,ghi,ghi | depart,bkheb-exit-3,exit rotary straight,arrive | + | a,f | abc,def,def,def | depart,bkheb-exit-4,exit rotary straight,arrive | + | d,f | def,def,def | depart,exit rotary right,arrive | + | d,c | def,abc,abc,abc | depart,bkheb-exit-2,exit rotary straight,arrive | + | d,l | def,jkl,jkl,jkl | depart,bkheb-exit-3,exit rotary straight,arrive | + | d,i | def,ghi,ghi,ghi | depart,bkheb-exit-4,exit rotary straight,arrive | + | g,i | ghi,ghi,ghi | depart,exit rotary right,arrive | + | g,f | ghi,def,def,def | depart,bkheb-exit-2,exit rotary straight,arrive | + | g,c | ghi,abc,abc,abc | depart,bkheb-exit-3,exit rotary straight,arrive | + | g,l | ghi,jkl,jkl,jkl | depart,bkheb-exit-4,exit rotary straight,arrive | + | j,l | jkl,jkl,jkl | depart,exit rotary right,arrive | + | j,i | jkl,ghi,ghi,ghi | depart,bkheb-exit-2,exit rotary straight,arrive | + | j,f | jkl,def,def,def | depart,bkheb-exit-3,exit rotary straight,arrive | + | j,c | jkl,abc,abc,abc | depart,bkheb-exit-4,exit rotary straight,arrive | Scenario: Collinear in X,Y Given the node map @@ -193,9 +193,9 @@ Feature: Rotary | 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 | + | waypoints | route | turns | + | a,e | ab,ce,ce,ce | depart,bcdb-exit-1,exit rotary straight,arrive | + | a,f | ab,df,df,df | depart,bcdb-exit-2,exit rotary straight,arrive | Scenario: Collinear in X,Y Given the node map @@ -214,9 +214,9 @@ Feature: Rotary | 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 | + | waypoints | route | turns | + | a,e | ad,be,be,be | depart,bcdb-exit-1,exit rotary straight,arrive | + | a,f | ad,cf,cf,cf | depart,bcdb-exit-2,exit rotary straight,arrive | Scenario: Collinear in X,Y Given the node map @@ -235,9 +235,9 @@ Feature: Rotary | 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 | + | waypoints | route | turns | + | a,e | ac,de,de,de | depart,bcdb-exit-1,exit rotary straight,arrive | + | a,f | ac,bf,bf,bf | depart,bcdb-exit-2,exit rotary straight,arrive | Scenario: Collinear in X,Y Given the node map @@ -256,9 +256,9 @@ Feature: Rotary | 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 | + | waypoints | route | turns | + | a,e | ab,ce,ce,ce | depart,bcdb-exit-1,exit rotary right,arrive | + | a,f | ab,df,df,df | depart,bcdb-exit-2,exit rotary right,arrive | Scenario: Collinear in X,Y Given the node map @@ -277,6 +277,6 @@ Feature: Rotary | 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 | + | waypoints | route | turns | + | a,e | ab,ce,ce,ce | depart,bcdb-exit-1,exit rotary right,arrive | + | a,f | ab,df,df,df | depart,bcdb-exit-2,exit rotary right,arrive | diff --git a/features/guidance/roundabout-bike.feature b/features/guidance/roundabout-bike.feature index 9d9389eac..2f7bc823e 100644 --- a/features/guidance/roundabout-bike.feature +++ b/features/guidance/roundabout-bike.feature @@ -5,39 +5,6 @@ Feature: Basic Roundabout Given the profile "bicycle" 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 Given the node map """ @@ -57,54 +24,21 @@ Feature: Basic Roundabout | bcegb | roundabout | When I route I should get - | waypoints | route | turns | - | b,d | bcegb,cd,cd | depart,roundabout-exit-1,arrive | - | b,f | bcegb,ef,ef | depart,roundabout-exit-2,arrive | - | b,h | bcegb,gh,gh | depart,roundabout-exit-3,arrive | - | c,f | bcegb,ef,ef | depart,roundabout-exit-1,arrive | - | c,h | bcegb,gh,gh | depart,roundabout-exit-2,arrive | - | c,a | bcegb,ab,ab | depart,roundabout-exit-3,arrive | - | e,h | bcegb,gh,gh | depart,roundabout-exit-1,arrive | - | e,a | bcegb,ab,ab | depart,roundabout-exit-2,arrive | - | e,d | bcegb,cd,cd | depart,roundabout-exit-3,arrive | - | g,a | bcegb,ab,ab | depart,roundabout-exit-1,arrive | - | g,d | bcegb,cd,cd | depart,roundabout-exit-2,arrive | - | g,f | bcegb,ef,ef | depart,roundabout-exit-3,arrive | + | waypoints | route | turns | + | b,d | bcegb,cd,cd | depart,exit roundabout right,arrive | + | b,f | bcegb,ef,ef | depart,exit roundabout right,arrive | + | b,h | bcegb,gh,gh | depart,exit roundabout right,arrive | + | c,f | bcegb,ef,ef | depart,exit roundabout right,arrive | + | c,h | bcegb,gh,gh | depart,exit roundabout right,arrive | + | c,a | bcegb,ab,ab | depart,exit roundabout right,arrive | + | e,h | bcegb,gh,gh | depart,exit roundabout right,arrive | + | e,a | bcegb,ab,ab | depart,exit roundabout right,arrive | + | e,d | bcegb,cd,cd | depart,exit roundabout right,arrive | + | g,a | bcegb,ab,ab | depart,exit roundabout right,arrive | + | g,d | bcegb,cd,cd | depart,exit roundabout right,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 - 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 Given the node map """ @@ -124,20 +58,20 @@ Feature: Basic Roundabout | bkheb | roundabout | yes | When I route I should get - | waypoints | route | turns | - | a,c | abc,abc,abc | depart,roundabout-exit-1,arrive | - | a,l | abc,jkl,jkl | depart,roundabout-exit-2,arrive | - | a,i | abc,ghi,ghi | depart,roundabout-exit-3,arrive | - | a,f | abc,def,def | depart,roundabout-exit-4,arrive | - | d,f | def,def,def | depart,roundabout-exit-1,arrive | - | d,c | def,abc,abc | depart,roundabout-exit-2,arrive | - | d,l | def,jkl,jkl | depart,roundabout-exit-3,arrive | - | d,i | def,ghi,ghi | depart,roundabout-exit-4,arrive | - | g,i | ghi,ghi,ghi | depart,roundabout-exit-1,arrive | - | g,f | ghi,def,def | depart,roundabout-exit-2,arrive | - | g,c | ghi,abc,abc | depart,roundabout-exit-3,arrive | - | g,l | ghi,jkl,jkl | depart,roundabout-exit-4,arrive | - | j,l | jkl,jkl,jkl | depart,roundabout-exit-1,arrive | - | j,i | jkl,ghi,ghi | depart,roundabout-exit-2,arrive | - | j,f | jkl,def,def | depart,roundabout-exit-3,arrive | - | j,c | jkl,abc,abc | depart,roundabout-exit-4,arrive | + | waypoints | route | turns | + | a,c | abc,abc,abc | depart,exit roundabout right,arrive | + | a,l | abc,jkl,jkl,jkl | depart,roundabout-exit-2,exit roundabout straight,arrive | + | a,i | abc,ghi,ghi,ghi | depart,roundabout-exit-3,exit roundabout straight,arrive | + | a,f | abc,def,def,def | depart,roundabout-exit-4,exit roundabout straight,arrive | + | d,f | def,def,def | depart,exit roundabout right,arrive | + | d,c | def,abc,abc,abc | depart,roundabout-exit-2,exit roundabout straight,arrive | + | d,l | def,jkl,jkl,jkl | depart,roundabout-exit-3,exit roundabout straight,arrive | + | d,i | def,ghi,ghi,ghi | depart,roundabout-exit-4,exit roundabout straight,arrive | + | g,i | ghi,ghi,ghi | depart,exit roundabout right,arrive | + | g,f | ghi,def,def,def | depart,roundabout-exit-2,exit roundabout straight,arrive | + | g,c | ghi,abc,abc,abc | depart,roundabout-exit-3,exit roundabout straight,arrive | + | g,l | ghi,jkl,jkl,jkl | depart,roundabout-exit-4,exit roundabout straight,arrive | + | j,l | jkl,jkl,jkl | depart,exit roundabout right,arrive | + | j,i | jkl,ghi,ghi,ghi | depart,roundabout-exit-2,exit roundabout straight,arrive | + | j,f | jkl,def,def,def | depart,roundabout-exit-3,exit roundabout straight,arrive | + | j,c | jkl,abc,abc,abc | depart,roundabout-exit-4,exit roundabout straight,arrive | diff --git a/features/guidance/roundabout-left-sided.feature b/features/guidance/roundabout-left-sided.feature index 86e084413..103da7544 100644 --- a/features/guidance/roundabout-left-sided.feature +++ b/features/guidance/roundabout-left-sided.feature @@ -52,7 +52,7 @@ Feature: Basic Roundabout | behkb | roundabout | yes | When I route I should get - | waypoints | route | turns | - | c,a | cba,cba,cba | depart,roundabout-exit-1,arrive | - | l,a | lkj,cba,cba | depart,roundabout-exit-2,arrive | - | i,a | ihg,cba,cba | depart,roundabout-exit-3,arrive | + | waypoints | route | turns | + | c,a | cba,cba,cba | depart,exit roundabout left,arrive | + | l,a | lkj,cba,cba,cba | depart,roundabout-exit-2,exit roundabout straight,arrive | + | i,a | ihg,cba,cba,cba | depart,roundabout-exit-3,exit roundabout straight,arrive | diff --git a/features/guidance/roundabout-turn-bike.feature b/features/guidance/roundabout-turn-bike.feature index 4e4873d8a..3eee61614 100644 --- a/features/guidance/roundabout-turn-bike.feature +++ b/features/guidance/roundabout-turn-bike.feature @@ -5,39 +5,6 @@ Feature: Basic Roundabout Given the profile "bicycle" 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 Scenario: Enter and Exit with changing mode Given the node map @@ -58,16 +25,16 @@ Feature: Basic Roundabout | bgecb | roundabout | residential | 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,ef | depart,roundabout turn left exit-1,notification right,arrive | - | a,h | ab,bgecb,gh,gh | depart,roundabout turn right exit-1,notification right,arrive | - | d,f | cd,ef,ef,ef | depart,roundabout turn sharp left exit-2,notification right,arrive | - | d,h | cd,gh,gh,gh | depart,roundabout turn left exit-2,notification right,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,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-2,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 | + | waypoints | route | turns | + | a,d | ab,cd,cd | depart,roundabout turn left exit-1,arrive | + | a,f | ab,ef,ef,ef | depart,roundabout turn straight exit-1,exit roundabout 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 left exit-2,exit roundabout 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 | + | 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,d | ef,cd,cd | depart,roundabout turn right exit-1,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,f | gh,ef,ef,ef | depart,roundabout turn right exit-1,exit roundabout right,arrive | diff --git a/features/guidance/roundabout-turn.feature b/features/guidance/roundabout-turn.feature index b940c76d1..93ce3c4e4 100644 --- a/features/guidance/roundabout-turn.feature +++ b/features/guidance/roundabout-turn.feature @@ -56,19 +56,19 @@ Feature: Basic Roundabout | 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 | + | 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 | Scenario: Only Enter Given the node map @@ -122,19 +122,19 @@ Feature: Basic Roundabout | bcegb | roundabout | When I route I should get - | waypoints | route | turns | - | b,d | bcegb,cd,cd | depart,roundabout-exit-1,arrive | - | b,f | bcegb,ef,ef | depart,roundabout-exit-2,arrive | - | b,h | bcegb,gh,gh | depart,roundabout-exit-3,arrive | - | c,f | bcegb,ef,ef | depart,roundabout-exit-1,arrive | - | c,h | bcegb,gh,gh | depart,roundabout-exit-2,arrive | - | c,a | bcegb,ab,ab | depart,roundabout-exit-3,arrive | - | e,h | bcegb,gh,gh | depart,roundabout-exit-1,arrive | - | e,a | bcegb,ab,ab | depart,roundabout-exit-2,arrive | - | e,d | bcegb,cd,cd | depart,roundabout-exit-3,arrive | - | g,a | bcegb,ab,ab | depart,roundabout-exit-1,arrive | - | g,d | bcegb,cd,cd | depart,roundabout-exit-2,arrive | - | g,f | bcegb,ef,ef | depart,roundabout-exit-3,arrive | + | waypoints | route | turns | + | b,d | bcegb,cd,cd | depart,exit roundabout right,arrive | + | b,f | bcegb,ef,ef | depart,exit roundabout right,arrive | + | b,h | bcegb,gh,gh | depart,exit roundabout right,arrive | + | c,f | bcegb,ef,ef | depart,exit roundabout right,arrive | + | c,h | bcegb,gh,gh | depart,exit roundabout right,arrive | + | c,a | bcegb,ab,ab | depart,exit roundabout right,arrive | + | e,h | bcegb,gh,gh | depart,exit roundabout right,arrive | + | e,a | bcegb,ab,ab | depart,exit roundabout right,arrive | + | e,d | bcegb,cd,cd | depart,exit roundabout right,arrive | + | g,a | bcegb,ab,ab | depart,exit roundabout right,arrive | + | g,d | bcegb,cd,cd | depart,exit roundabout right,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 Scenario: Drive Around @@ -189,23 +189,23 @@ Feature: Basic Roundabout | bkheb | roundabout | yes | When I route I should get - | waypoints | route | turns | - | a,c | abc,abc,abc | depart,roundabout-exit-1,arrive | - | a,l | abc,jkl,jkl | depart,roundabout-exit-2,arrive | - | a,i | abc,ghi,ghi | depart,roundabout-exit-3,arrive | - | a,f | abc,def,def | depart,roundabout-exit-4,arrive | - | d,f | def,def,def | depart,roundabout-exit-1,arrive | - | d,c | def,abc,abc | depart,roundabout-exit-2,arrive | - | d,l | def,jkl,jkl | depart,roundabout-exit-3,arrive | - | d,i | def,ghi,ghi | depart,roundabout-exit-4,arrive | - | g,i | ghi,ghi,ghi | depart,roundabout-exit-1,arrive | - | g,f | ghi,def,def | depart,roundabout-exit-2,arrive | - | g,c | ghi,abc,abc | depart,roundabout-exit-3,arrive | - | g,l | ghi,jkl,jkl | depart,roundabout-exit-4,arrive | - | j,l | jkl,jkl,jkl | depart,roundabout-exit-1,arrive | - | j,i | jkl,ghi,ghi | depart,roundabout-exit-2,arrive | - | j,f | jkl,def,def | depart,roundabout-exit-3,arrive | - | j,c | jkl,abc,abc | depart,roundabout-exit-4,arrive | + | waypoints | route | turns | + | a,c | abc,abc,abc | depart,exit roundabout right,arrive | + | a,l | abc,jkl,jkl,jkl | depart,roundabout-exit-2,exit roundabout straight,arrive | + | a,i | abc,ghi,ghi,ghi | depart,roundabout-exit-3,exit roundabout straight,arrive | + | a,f | abc,def,def,def | depart,roundabout-exit-4,exit roundabout straight,arrive | + | d,f | def,def,def | depart,exit roundabout right,arrive | + | d,c | def,abc,abc,abc | depart,roundabout-exit-2,exit roundabout straight,arrive | + | d,l | def,jkl,jkl,jkl | depart,roundabout-exit-3,exit roundabout straight,arrive | + | d,i | def,ghi,ghi,ghi | depart,roundabout-exit-4,exit roundabout straight,arrive | + | g,i | ghi,ghi,ghi | depart,exit roundabout right,arrive | + | g,f | ghi,def,def,def | depart,roundabout-exit-2,exit roundabout straight,arrive | + | g,c | ghi,abc,abc,abc | depart,roundabout-exit-3,exit roundabout straight,arrive | + | g,l | ghi,jkl,jkl,jkl | depart,roundabout-exit-4,exit roundabout straight,arrive | + | j,l | jkl,jkl,jkl | depart,exit roundabout right,arrive | + | j,i | jkl,ghi,ghi,ghi | depart,roundabout-exit-2,exit roundabout straight,arrive | + | j,f | jkl,def,def,def | depart,roundabout-exit-3,exit roundabout straight,arrive | + | j,c | jkl,abc,abc,abc | depart,roundabout-exit-4,exit roundabout straight,arrive | Scenario: Segregated roads - Not an intersection Given the node map @@ -226,23 +226,23 @@ Feature: Basic Roundabout | bkheb | roundabout | yes | When I route I should get - | waypoints | route | turns | - | a,c | abc,abc,abc | depart,roundabout-exit-4,arrive | - | a,l | abc,jkl,jkl | depart,roundabout-exit-1,arrive | - | a,i | abc,ghi,ghi | depart,roundabout-exit-2,arrive | - | a,f | abc,def,def | depart,roundabout-exit-3,arrive | - | d,f | def,def,def | depart,roundabout-exit-4,arrive | - | d,c | def,abc,abc | depart,roundabout-exit-1,arrive | - | d,l | def,jkl,jkl | depart,roundabout-exit-2,arrive | - | d,i | def,ghi,ghi | depart,roundabout-exit-3,arrive | - | g,i | ghi,ghi,ghi | depart,roundabout-exit-4,arrive | - | g,f | ghi,def,def | depart,roundabout-exit-1,arrive | - | g,c | ghi,abc,abc | depart,roundabout-exit-2,arrive | - | g,l | ghi,jkl,jkl | depart,roundabout-exit-3,arrive | - | j,l | jkl,jkl,jkl | depart,roundabout-exit-4,arrive | - | j,i | jkl,ghi,ghi | depart,roundabout-exit-1,arrive | - | j,f | jkl,def,def | depart,roundabout-exit-2,arrive | - | j,c | jkl,abc,abc | depart,roundabout-exit-3,arrive | + | waypoints | route | turns | + | a,c | abc,abc,abc,abc | depart,roundabout-exit-4,exit roundabout right,arrive | + | a,l | abc,jkl,jkl,jkl | depart,roundabout-exit-1,exit roundabout right,arrive | + | a,i | abc,ghi,ghi,ghi | depart,roundabout-exit-2,exit roundabout right,arrive | + | a,f | abc,def,def,def | depart,roundabout-exit-3,exit roundabout right,arrive | + | d,f | def,def,def,def | depart,roundabout-exit-4,exit roundabout right,arrive | + | d,c | def,abc,abc,abc | depart,roundabout-exit-1,exit roundabout right,arrive | + | d,l | def,jkl,jkl,jkl | depart,roundabout-exit-2,exit roundabout right,arrive | + | d,i | def,ghi,ghi,ghi | depart,roundabout-exit-3,exit roundabout right,arrive | + | g,i | ghi,ghi,ghi,ghi | depart,roundabout-exit-4,exit roundabout right,arrive | + | g,f | ghi,def,def,def | depart,roundabout-exit-1,exit roundabout right,arrive | + | g,c | ghi,abc,abc,abc | depart,roundabout-exit-2,exit roundabout right,arrive | + | g,l | ghi,jkl,jkl,jkl | depart,roundabout-exit-3,exit roundabout right,arrive | + | j,l | jkl,jkl,jkl,jkl | depart,roundabout-exit-4,exit roundabout right,arrive | + | j,i | jkl,ghi,ghi,ghi | depart,roundabout-exit-1,exit roundabout right,arrive | + | j,f | jkl,def,def,def | depart,roundabout-exit-2,exit roundabout right,arrive | + | j,c | jkl,abc,abc,abc | depart,roundabout-exit-3,exit roundabout right,arrive | Scenario: Collinear in X Given the node map @@ -368,19 +368,19 @@ Feature: Basic Roundabout | bigecb | roundabout | When I route I should get - | waypoints | route | turns | - | a,d | ab,cd,cd | depart,roundabout-exit-4,arrive | - | a,f | ab,ef,ef | depart,roundabout-exit-3,arrive | - | a,h | ab,gh,gh | depart,roundabout-exit-2,arrive | - | d,f | cd,ef,ef | depart,roundabout-exit-4,arrive | - | d,h | cd,gh,gh | depart,roundabout-exit-3,arrive | - | d,a | cd,ab,ab | depart,roundabout-exit-1,arrive | - | f,h | ef,gh,gh | depart,roundabout-exit-4,arrive | - | f,a | ef,ab,ab | depart,roundabout-exit-2,arrive | - | f,d | ef,cd,cd | depart,roundabout-exit-1,arrive | - | h,a | gh,ab,ab | depart,roundabout-exit-3,arrive | - | h,d | gh,cd,cd | depart,roundabout-exit-2,arrive | - | h,f | gh,ef,ef | depart,roundabout-exit-1,arrive | + | waypoints | route | turns | + | a,d | ab,cd,cd,cd | depart,roundabout-exit-4,exit roundabout right,arrive | + | a,f | ab,ef,ef,ef | depart,roundabout-exit-3,exit roundabout right,arrive | + | a,h | ab,gh,gh,gh | depart,roundabout-exit-2,exit roundabout right,arrive | + | d,f | cd,ef,ef,ef | depart,roundabout-exit-4,exit roundabout right,arrive | + | d,h | cd,gh,gh,gh | depart,roundabout-exit-3,exit roundabout right,arrive | + | d,a | cd,ab,ab,ab | depart,roundabout-exit-1,exit roundabout right,arrive | + | f,h | ef,gh,gh,gh | depart,roundabout-exit-4,exit roundabout right,arrive | + | f,a | ef,ab,ab,ab | depart,roundabout-exit-2,exit roundabout right,arrive | + | f,d | ef,cd,cd,cd | depart,roundabout-exit-1,exit roundabout right,arrive | + | h,a | gh,ab,ab,ab | depart,roundabout-exit-3,exit roundabout right,arrive | + | h,d | gh,cd,cd,cd | depart,roundabout-exit-2,exit roundabout right,arrive | + | h,f | gh,ef,ef,ef | depart,roundabout-exit-1,exit roundabout right,arrive | Scenario: Enter and Exit -- Non-Distinct Given the node map @@ -401,19 +401,19 @@ Feature: Basic Roundabout | bgecb | roundabout | When I route I should get - | waypoints | route | turns | - | a,d | ab,cd,cd | depart,roundabout-exit-3,arrive | - | a,f | ab,ef,ef | depart,roundabout-exit-2,arrive | - | a,h | ab,gh,gh | depart,roundabout-exit-1,arrive | - | d,f | cd,ef,ef | depart,roundabout-exit-3,arrive | - | d,h | cd,gh,gh | depart,roundabout-exit-2,arrive | - | d,a | cd,ab,ab | depart,roundabout-exit-1,arrive | - | f,h | ef,gh,gh | depart,roundabout-exit-3,arrive | - | f,a | ef,ab,ab | depart,roundabout-exit-2,arrive | - | f,d | ef,cd,cd | depart,roundabout-exit-1,arrive | - | h,a | gh,ab,ab | depart,roundabout-exit-3,arrive | - | h,d | gh,cd,cd | depart,roundabout-exit-2,arrive | - | h,f | gh,ef,ef | depart,roundabout-exit-1,arrive | + | waypoints | route | turns | + | a,d | ab,cd,cd,cd | depart,roundabout-exit-3,exit roundabout right,arrive | + | a,f | ab,ef,ef,ef | depart,roundabout-exit-2,exit roundabout right,arrive | + | a,h | ab,gh,gh,gh | depart,roundabout-exit-1,exit roundabout straight,arrive | + | d,f | cd,ef,ef,ef | depart,roundabout-exit-3,exit roundabout right,arrive | + | d,h | cd,gh,gh,gh | depart,roundabout-exit-2,exit roundabout straight,arrive | + | d,a | cd,ab,ab,ab | depart,roundabout-exit-1,exit roundabout right,arrive | + | f,h | ef,gh,gh,gh | depart,roundabout-exit-3,exit roundabout straight,arrive | + | f,a | ef,ab,ab,ab | depart,roundabout-exit-2,exit roundabout right,arrive | + | f,d | ef,cd,cd,cd | depart,roundabout-exit-1,exit roundabout right,arrive | + | h,a | gh,ab,ab,ab | depart,roundabout-exit-3,exit roundabout right,arrive | + | h,d | gh,cd,cd,cd | depart,roundabout-exit-2,exit roundabout right,arrive | + | h,f | gh,ef,ef,ef | depart,roundabout-exit-1,exit roundabout right,arrive | Scenario: Enter and Exit -- Bearing Given the node map diff --git a/features/guidance/roundabout.feature b/features/guidance/roundabout.feature index 474e8041a..ed0eb7a83 100644 --- a/features/guidance/roundabout.feature +++ b/features/guidance/roundabout.feature @@ -57,10 +57,10 @@ Feature: Basic Roundabout | bcegb | roundabout | primary | When I route I should get - | waypoints | route | turns | - | a,d | ab,cd,cd | depart,roundabout-exit-1,arrive | - | a,h | ab,gh,gh | depart,roundabout-exit-2,arrive | - | a,f | ab,ef,ef | depart,roundabout-exit-2,arrive | + | waypoints | route | turns | + | a,d | ab,cd,cd,cd | depart,roundabout-exit-1,exit roundabout right,arrive | + | a,h | ab,gh,gh,gh | depart,roundabout-exit-2,exit roundabout straight,arrive | + | a,f | ab,ef,ef,ef | depart,roundabout-exit-2,exit roundabout right,arrive | #2927 Scenario: Only Roundabout @@ -98,19 +98,19 @@ Feature: Basic Roundabout | bcegb | roundabout | When I route I should get - | waypoints | route | turns | - | b,d | bcegb,cd,cd | depart,roundabout-exit-1,arrive | - | b,f | bcegb,ef,ef | depart,roundabout-exit-2,arrive | - | b,h | bcegb,gh,gh | depart,roundabout-exit-3,arrive | - | c,f | bcegb,ef,ef | depart,roundabout-exit-1,arrive | - | c,h | bcegb,gh,gh | depart,roundabout-exit-2,arrive | - | c,a | bcegb,ab,ab | depart,roundabout-exit-3,arrive | - | e,h | bcegb,gh,gh | depart,roundabout-exit-1,arrive | - | e,a | bcegb,ab,ab | depart,roundabout-exit-2,arrive | - | e,d | bcegb,cd,cd | depart,roundabout-exit-3,arrive | - | g,a | bcegb,ab,ab | depart,roundabout-exit-1,arrive | - | g,d | bcegb,cd,cd | depart,roundabout-exit-2,arrive | - | g,f | bcegb,ef,ef | depart,roundabout-exit-3,arrive | + | waypoints | route | turns | + | b,d | bcegb,cd,cd | depart,exit roundabout right,arrive | + | b,f | bcegb,ef,ef | depart,exit roundabout right,arrive | + | b,h | bcegb,gh,gh | depart,exit roundabout right,arrive | + | c,f | bcegb,ef,ef | depart,exit roundabout right,arrive | + | c,h | bcegb,gh,gh | depart,exit roundabout right,arrive | + | c,a | bcegb,ab,ab | depart,exit roundabout right,arrive | + | e,h | bcegb,gh,gh | depart,exit roundabout right,arrive | + | e,a | bcegb,ab,ab | depart,exit roundabout right,arrive | + | e,d | bcegb,cd,cd | depart,exit roundabout right,arrive | + | g,a | bcegb,ab,ab | depart,exit roundabout right,arrive | + | g,d | bcegb,cd,cd | depart,exit roundabout right,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 Scenario: Drive Around @@ -165,23 +165,23 @@ Feature: Basic Roundabout | bkheb | roundabout | yes | When I route I should get - | waypoints | route | turns | - | a,c | abc,abc,abc | depart,roundabout-exit-1,arrive | - | a,l | abc,jkl,jkl | depart,roundabout-exit-2,arrive | - | a,i | abc,ghi,ghi | depart,roundabout-exit-3,arrive | - | a,f | abc,def,def | depart,roundabout-exit-4,arrive | - | d,f | def,def,def | depart,roundabout-exit-1,arrive | - | d,c | def,abc,abc | depart,roundabout-exit-2,arrive | - | d,l | def,jkl,jkl | depart,roundabout-exit-3,arrive | - | d,i | def,ghi,ghi | depart,roundabout-exit-4,arrive | - | g,i | ghi,ghi,ghi | depart,roundabout-exit-1,arrive | - | g,f | ghi,def,def | depart,roundabout-exit-2,arrive | - | g,c | ghi,abc,abc | depart,roundabout-exit-3,arrive | - | g,l | ghi,jkl,jkl | depart,roundabout-exit-4,arrive | - | j,l | jkl,jkl,jkl | depart,roundabout-exit-1,arrive | - | j,i | jkl,ghi,ghi | depart,roundabout-exit-2,arrive | - | j,f | jkl,def,def | depart,roundabout-exit-3,arrive | - | j,c | jkl,abc,abc | depart,roundabout-exit-4,arrive | + | waypoints | route | turns | + | a,c | abc,abc,abc | depart,exit roundabout right,arrive | + | a,l | abc,jkl,jkl,jkl | depart,roundabout-exit-2,exit roundabout straight,arrive | + | a,i | abc,ghi,ghi,ghi | depart,roundabout-exit-3,exit roundabout straight,arrive | + | a,f | abc,def,def,def | depart,roundabout-exit-4,exit roundabout straight,arrive | + | d,f | def,def,def | depart,exit roundabout right,arrive | + | d,c | def,abc,abc,abc | depart,roundabout-exit-2,exit roundabout straight,arrive | + | d,l | def,jkl,jkl,jkl | depart,roundabout-exit-3,exit roundabout straight,arrive | + | d,i | def,ghi,ghi,ghi | depart,roundabout-exit-4,exit roundabout straight,arrive | + | g,i | ghi,ghi,ghi | depart,exit roundabout right,arrive | + | g,f | ghi,def,def,def | depart,roundabout-exit-2,exit roundabout straight,arrive | + | g,c | ghi,abc,abc,abc | depart,roundabout-exit-3,exit roundabout straight,arrive | + | g,l | ghi,jkl,jkl,jkl | depart,roundabout-exit-4,exit roundabout straight,arrive | + | j,l | jkl,jkl,jkl | depart,exit roundabout right,arrive | + | j,i | jkl,ghi,ghi,ghi | depart,roundabout-exit-2,exit roundabout straight,arrive | + | j,f | jkl,def,def,def | depart,roundabout-exit-3,exit roundabout straight,arrive | + | j,c | jkl,abc,abc,abc | depart,roundabout-exit-4,exit roundabout straight,arrive | Scenario: Mixed Entry and Exit - segregated roads Given the node map @@ -204,23 +204,23 @@ Feature: Basic Roundabout | bkheb | roundabout | yes | When I route I should get - | waypoints | route | turns | - | a,c | abc,abc,abc | depart,roundabout-exit-4,arrive | - | a,l | abc,jkl,jkl | depart,roundabout-exit-1,arrive | - | a,i | abc,ghi,ghi | depart,roundabout-exit-2,arrive | - | a,f | abc,def,def | depart,roundabout-exit-3,arrive | - | d,f | def,def,def | depart,roundabout-exit-4,arrive | - | d,c | def,abc,abc | depart,roundabout-exit-1,arrive | - | d,l | def,jkl,jkl | depart,roundabout-exit-2,arrive | - | d,i | def,ghi,ghi | depart,roundabout-exit-3,arrive | - | g,i | ghi,ghi,ghi | depart,roundabout-exit-4,arrive | - | g,f | ghi,def,def | depart,roundabout-exit-1,arrive | - | g,c | ghi,abc,abc | depart,roundabout-exit-2,arrive | - | g,l | ghi,jkl,jkl | depart,roundabout-exit-3,arrive | - | j,l | jkl,jkl,jkl | depart,roundabout-exit-4,arrive | - | j,i | jkl,ghi,ghi | depart,roundabout-exit-1,arrive | - | j,f | jkl,def,def | depart,roundabout-exit-2,arrive | - | j,c | jkl,abc,abc | depart,roundabout-exit-3,arrive | + | waypoints | route | turns | + | a,c | abc,abc,abc,abc | depart,roundabout-exit-4,exit roundabout right,arrive | + | a,l | abc,jkl,jkl,jkl | depart,roundabout-exit-1,exit roundabout right,arrive | + | a,i | abc,ghi,ghi,ghi | depart,roundabout-exit-2,exit roundabout right,arrive | + | a,f | abc,def,def,def | depart,roundabout-exit-3,exit roundabout right,arrive | + | d,f | def,def,def,def | depart,roundabout-exit-4,exit roundabout right,arrive | + | d,c | def,abc,abc,abc | depart,roundabout-exit-1,exit roundabout right,arrive | + | d,l | def,jkl,jkl,jkl | depart,roundabout-exit-2,exit roundabout right,arrive | + | d,i | def,ghi,ghi,ghi | depart,roundabout-exit-3,exit roundabout right,arrive | + | g,i | ghi,ghi,ghi,ghi | depart,roundabout-exit-4,exit roundabout right,arrive | + | g,f | ghi,def,def,def | depart,roundabout-exit-1,exit roundabout right,arrive | + | g,c | ghi,abc,abc,abc | depart,roundabout-exit-2,exit roundabout right,arrive | + | g,l | ghi,jkl,jkl,jkl | depart,roundabout-exit-3,exit roundabout right,arrive | + | j,l | jkl,jkl,jkl,jkl | depart,roundabout-exit-4,exit roundabout right,arrive | + | j,i | jkl,ghi,ghi,ghi | depart,roundabout-exit-1,exit roundabout right,arrive | + | j,f | jkl,def,def,def | depart,roundabout-exit-2,exit roundabout right,arrive | + | j,c | jkl,abc,abc,abc | depart,roundabout-exit-3,exit roundabout right,arrive | Scenario: Mixed Entry and Exit - clockwise order Given the node map @@ -241,23 +241,23 @@ Feature: Basic Roundabout | behkb | roundabout | yes | When I route I should get - | waypoints | route | turns | - | a,c | abc,abc,abc | depart,roundabout-exit-4,arrive | - | a,l | abc,jkl,jkl | depart,roundabout-exit-3,arrive | - | a,i | abc,ghi,ghi | depart,roundabout-exit-2,arrive | - | a,f | abc,def,def | depart,roundabout-exit-1,arrive | - | d,f | def,def,def | depart,roundabout-exit-4,arrive | - | d,c | def,abc,abc | depart,roundabout-exit-3,arrive | - | d,l | def,jkl,jkl | depart,roundabout-exit-2,arrive | - | d,i | def,ghi,ghi | depart,roundabout-exit-1,arrive | - | g,i | ghi,ghi,ghi | depart,roundabout-exit-4,arrive | - | g,f | ghi,def,def | depart,roundabout-exit-3,arrive | - | g,c | ghi,abc,abc | depart,roundabout-exit-2,arrive | - | g,l | ghi,jkl,jkl | depart,roundabout-exit-1,arrive | - | j,l | jkl,jkl,jkl | depart,roundabout-exit-4,arrive | - | j,i | jkl,ghi,ghi | depart,roundabout-exit-3,arrive | - | j,f | jkl,def,def | depart,roundabout-exit-2,arrive | - | j,c | jkl,abc,abc | depart,roundabout-exit-1,arrive | + | waypoints | route | turns | + | a,c | abc,abc,abc,abc | depart,roundabout-exit-4,exit roundabout left,arrive | + | a,l | abc,jkl,jkl,jkl | depart,roundabout-exit-3,exit roundabout left,arrive | + | a,i | abc,ghi,ghi,ghi | depart,roundabout-exit-2,exit roundabout left,arrive | + | a,f | abc,def,def,def | depart,roundabout-exit-1,exit roundabout left,arrive | + | d,f | def,def,def,def | depart,roundabout-exit-4,exit roundabout left,arrive | + | d,c | def,abc,abc,abc | depart,roundabout-exit-3,exit roundabout left,arrive | + | d,l | def,jkl,jkl,jkl | depart,roundabout-exit-2,exit roundabout left,arrive | + | d,i | def,ghi,ghi,ghi | depart,roundabout-exit-1,exit roundabout left,arrive | + | g,i | ghi,ghi,ghi,ghi | depart,roundabout-exit-4,exit roundabout left,arrive | + | g,f | ghi,def,def,def | depart,roundabout-exit-3,exit roundabout left,arrive | + | g,c | ghi,abc,abc,abc | depart,roundabout-exit-2,exit roundabout left,arrive | + | g,l | ghi,jkl,jkl,jkl | depart,roundabout-exit-1,exit roundabout left,arrive | + | j,l | jkl,jkl,jkl,jkl | depart,roundabout-exit-4,exit roundabout left,arrive | + | j,i | jkl,ghi,ghi,ghi | depart,roundabout-exit-3,exit roundabout left,arrive | + | j,f | jkl,def,def,def | depart,roundabout-exit-2,exit roundabout left,arrive | + | j,c | jkl,abc,abc,abc | depart,roundabout-exit-1,exit roundabout left,arrive | Scenario: Mixed Entry and Exit - segregated roads, different names Given the node map @@ -284,23 +284,23 @@ Feature: Basic Roundabout | bkheb | roundabout | yes | When I route I should get - | waypoints | route | turns | - | a,c | ab,bc,bc | depart,roundabout-exit-4,arrive | - | a,l | ab,kl,kl | depart,roundabout-exit-1,arrive | - | a,i | ab,hi,hi | depart,roundabout-exit-2,arrive | - | a,f | ab,ef,ef | depart,roundabout-exit-3,arrive | - | d,f | de,ef,ef | depart,roundabout-exit-4,arrive | - | d,c | de,bc,bc | depart,roundabout-exit-1,arrive | - | d,l | de,kl,kl | depart,roundabout-exit-2,arrive | - | d,i | de,hi,hi | depart,roundabout-exit-3,arrive | - | g,i | gh,hi,hi | depart,roundabout-exit-4,arrive | - | g,f | gh,ef,ef | depart,roundabout-exit-1,arrive | - | g,c | gh,bc,bc | depart,roundabout-exit-2,arrive | - | g,l | gh,kl,kl | depart,roundabout-exit-3,arrive | - | j,l | jk,kl,kl | depart,roundabout-exit-4,arrive | - | j,i | jk,hi,hi | depart,roundabout-exit-1,arrive | - | j,f | jk,ef,ef | depart,roundabout-exit-2,arrive | - | j,c | jk,bc,bc | depart,roundabout-exit-3,arrive | + | waypoints | route | turns | + | a,c | ab,bc,bc,bc | depart,roundabout-exit-4,exit roundabout right,arrive | + | a,l | ab,kl,kl,kl | depart,roundabout-exit-1,exit roundabout right,arrive | + | a,i | ab,hi,hi,hi | depart,roundabout-exit-2,exit roundabout right,arrive | + | a,f | ab,ef,ef,ef | depart,roundabout-exit-3,exit roundabout right,arrive | + | d,f | de,ef,ef,ef | depart,roundabout-exit-4,exit roundabout right,arrive | + | d,c | de,bc,bc,bc | depart,roundabout-exit-1,exit roundabout right,arrive | + | d,l | de,kl,kl,kl | depart,roundabout-exit-2,exit roundabout right,arrive | + | d,i | de,hi,hi,hi | depart,roundabout-exit-3,exit roundabout right,arrive | + | g,i | gh,hi,hi,hi | depart,roundabout-exit-4,exit roundabout right,arrive | + | g,f | gh,ef,ef,ef | depart,roundabout-exit-1,exit roundabout right,arrive | + | g,c | gh,bc,bc,bc | depart,roundabout-exit-2,exit roundabout right,arrive | + | g,l | gh,kl,kl,kl | depart,roundabout-exit-3,exit roundabout right,arrive | + | j,l | jk,kl,kl,kl | depart,roundabout-exit-4,exit roundabout right,arrive | + | j,i | jk,hi,hi,hi | depart,roundabout-exit-1,exit roundabout right,arrive | + | j,f | jk,ef,ef,ef | depart,roundabout-exit-2,exit roundabout right,arrive | + | j,c | jk,bc,bc,bc | depart,roundabout-exit-3,exit roundabout right,arrive | Scenario: Motorway Roundabout #See 39.933742 -75.082345 @@ -338,11 +338,10 @@ Feature: Basic Roundabout | dmg | roundabout | | trunk_link | yes | | When I route I should get - | waypoints | route | turns | ref | - | a,e | crescent,crescent,crescent | depart,roundabout-exit-3,arrive | US 130,US 130,US 130 | - | j,l | ,, | depart,roundabout-exit-2,arrive | NJ 38,NJ 38,NJ 38 | + | waypoints | route | turns | ref | + | 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,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 # 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) @@ -389,8 +388,8 @@ Feature: Basic Roundabout | restriction | pi | ij | i | no_left_turn | When I route I should get - | waypoints | route | turns | - | a,k | massachusetts,massachusetts,massachusetts,massachusetts | depart,sheridan circle-exit-2,rotary-exit-1,arrive | + | waypoints | route | turns | + | 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 Scenario: Linked Roundabouts @@ -477,8 +476,8 @@ Feature: Basic Roundabout | cdefib | roundabout | roundabout | yes | | When I route I should get - | waypoints | route | turns | - | 1,h | roundabout,right-bot-out,right-bot-out | depart,roundabout-exit-1,arrive | + | waypoints | route | turns | + | 1,h | roundabout,right-bot-out,right-bot-out | depart,exit rotary straight,arrive | @3254 Scenario: Driving up to and through a roundabout @@ -495,15 +494,15 @@ Feature: Basic Roundabout And the ways | nodes | junction | name | highway | - | abcda | roundabout | roundabout | residential | + | abcda | roundabout | rotary | residential | | gfi | | side | residential | | efb | | left | residential | | dh | | right | residential | | ck | | bottom | residential | When I route I should get - | waypoints | route | turns | - | e,h | left,right,right | depart,roundabout-exit-2,arrive | + | waypoints | route | turns | + | e,h | left,right,right,right | depart,rotary-exit-2,exit rotary right,arrive | @3254 Scenario: Driving up to and through a roundabout @@ -520,15 +519,15 @@ Feature: Basic Roundabout And the ways | nodes | junction | name | highway | - | abcda | roundabout | roundabout | residential | + | abcda | roundabout | rotary | residential | | gfi | | side | residential | | efb | | left | residential | | dh | | right | residential | | ck | | bottom | residential | When I route I should get - | waypoints | route | turns | - | e,h | left,right,right | depart,roundabout-exit-2,arrive | + | waypoints | route | turns | + | e,h | left,right,right,right | depart,rotary-exit-2,exit rotary right,arrive | @3361 Scenario: Bersarinplatz (Not a Roundabout) @@ -565,13 +564,13 @@ Feature: Basic Roundabout | mn | | Petersburger Strasse | B 96a | primary | yes | When I route I should get - | waypoints | route | turns | - | a,g | Petersburger Strasse,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-2,arrive | - | d,g | Weidenweg,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-1,arrive | - | i,k | Petersburger Strasse,Rigaer Strasse,Rigaer Strasse | depart,Bersarinplatz-exit-1,arrive | - | i,n | Petersburger Strasse,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-2,arrive | - | i,d | Petersburger Strasse,Weidenweg,Weidenweg | depart,Bersarinplatz-exit-3,arrive | - | i,g | Petersburger Strasse,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-4,arrive | + | waypoints | route | turns | + | 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,Petersburger Strasse | depart,Bersarinplatz-exit-1,exit rotary straight,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,Petersburger Strasse | depart,Bersarinplatz-exit-2,exit rotary straight,arrive | + | i,d | Petersburger Strasse,Weidenweg,Weidenweg,Weidenweg | depart,Bersarinplatz-exit-3,exit rotary right,arrive | + | i,g | Petersburger Strasse,Petersburger Strasse,Petersburger Strasse,Petersburger Strasse | depart,Bersarinplatz-exit-4,exit rotary straight,arrive | @turboroundabout # http://www.openstreetmap.org/?mlat=48.782118&mlon=8.194456&zoom=16#map=19/48.78216/8.19457 @@ -606,11 +605,11 @@ Feature: Basic Roundabout | ob | trunk | yes | roundabout | Europaplatz | | When I route I should get - | waypoints | route | turns | - | a,d | ,Europastrasse,Europastrasse | depart,Europaplatz-exit-1,arrive | - | a,h | ,Allee Cite,Allee Cite | depart,Europaplatz-exit-2,arrive | - | a,l | ,Europastrasse,Europastrasse | depart,Europaplatz-exit-3,arrive | - | a,p | ,, | depart,Europaplatz-exit-4,arrive | + | waypoints | route | turns | + | a,d | ,Europastrasse,Europastrasse,Europastrasse | depart,Europaplatz-exit-1,exit rotary right,arrive | + | a,h | ,Allee Cite,Allee Cite,Allee Cite | depart,Europaplatz-exit-2,exit rotary right,arrive | + | a,l | ,Europastrasse,Europastrasse,Europastrasse | depart,Europaplatz-exit-3,exit rotary right,arrive | + | a,p | ,,, | depart,Europaplatz-exit-4,exit rotary right,arrive | @turboroundabout # http://www.openstreetmap.org/?mlat=50.180039&mlon=8.474939&zoom=16#map=19/50.17999/8.47506 @@ -658,14 +657,14 @@ Feature: Basic Roundabout | wb | primary | yes | roundabout | | through\|through;right | When I route I should get - | waypoints | route | turns | - | a,w | Le-Cannet-Rocheville-Strasse,, | depart,roundabout-exit-undefined,arrive | - | a,r | Le-Cannet-Rocheville-Strasse,, | depart,roundabout-exit-4,arrive | - | a,f | Le-Cannet-Rocheville-Strasse,Frankfurter Strasse,Frankfurter Strasse | depart,roundabout-exit-1,arrive | - | a,h | Le-Cannet-Rocheville-Strasse,Bischof-Kaller-Strasse,Bischof-Kaller-Strasse | depart,roundabout-exit-2,arrive | - | u,r | ,, | depart,roundabout-exit-5,arrive | - | j,h | Bischof-Kaller-Strasse,Bischof-Kaller-Strasse,Bischof-Kaller-Strasse | depart,roundabout-exit-5,arrive | - | n,m | , | depart,arrive | + | waypoints | route | turns | + | a,w | Le-Cannet-Rocheville-Strasse,, | depart,roundabout-exit-undefined,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,Frankfurter Strasse | depart,roundabout-exit-1,exit roundabout right,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,exit roundabout right,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 | @turboroundabout # http://www.openstreetmap.org/?mlat=47.57723&mlon=7.796765&zoom=16#map=19/47.57720/7.79711 @@ -708,17 +707,16 @@ Feature: Basic Roundabout | la | primary | yes | roundabout | When I route I should get - | waypoints | route | turns | - | w,r | wk,ar,ar | depart,roundabout-exit-1,arrive | - | w,s | wk,ds,ds | depart,roundabout-exit-2,arrive | - | w,t | wk,ft,ft | depart,roundabout-exit-3,arrive | - | w,v | wk,hv,hv | depart,roundabout-exit-4,arrive | - | u,v | ug,hv,hv | depart,roundabout-exit-1,arrive | - | u,w | ug,jw,jw | depart,roundabout-exit-2,arrive | - | u,r | ug,ar,ar | depart,roundabout-exit-3,arrive | - | u,s | ug,ds,ds | depart,roundabout-exit-4,arrive | - | u,t | ug,ft,ft | depart,roundabout-exit-5,arrive | - + | waypoints | route | turns | + | w,r | wk,ar,ar,ar | depart,roundabout-exit-1,exit roundabout slight right,arrive | + | w,s | wk,ds,ds,ds | depart,roundabout-exit-2,exit roundabout right,arrive | + | w,t | wk,ft,ft,ft | depart,roundabout-exit-3,exit roundabout right,arrive | + | w,v | wk,hv,hv,hv | depart,roundabout-exit-4,exit roundabout straight,arrive | + | u,v | ug,hv,hv,hv | depart,roundabout-exit-1,exit roundabout straight,arrive | + | u,w | ug,jw,jw,jw | depart,roundabout-exit-2,exit roundabout slight right,arrive | + | u,r | ug,ar,ar,ar | depart,roundabout-exit-3,exit roundabout slight right,arrive | + | u,s | ug,ds,ds,ds | depart,roundabout-exit-4,exit roundabout right,arrive | + | u,t | ug,ft,ft,ft | depart,roundabout-exit-5,exit roundabout right,arrive | @3762 Scenario: Only Enter @@ -742,8 +740,8 @@ Feature: Basic Roundabout | bcjdeb | roundabout | | When I route I should get - | waypoints | route | turns | - | a,h | ab,ef,ef,fh,fh | depart,roundabout-exit-4,notification slight right,notification straight,arrive | + | waypoints | route | turns | + | a,h | ab,ef,ef,fh,fh | depart,roundabout-exit-4,exit roundabout slight right,notification straight,arrive | Scenario: Drive through roundabout @@ -762,12 +760,12 @@ Feature: Basic Roundabout | gch | | yes | When I route I should get - | waypoints | bearings | route | turns | - | e,f | 90 90 | edf,edf | depart,arrive | - | e,h | 90 135 | edf,gch,gch | depart,roundabout-exit-2,arrive | - | g,f | 45 90 | gch,edf,edf | depart,roundabout-exit-2,arrive | - | g,h | 45 135 | gch,gch,gch | depart,roundabout-exit-1,arrive | - | e,e | 90 270 | edf,edf,edf | depart,roundabout-exit-3,arrive | + | waypoints | bearings | route | turns | + | e,f | 90 90 | edf,edf | depart,arrive | + | e,h | 90 135 | edf,gch,gch,gch | depart,roundabout-exit-2,exit roundabout straight,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,exit roundabout right,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 Given the node map @@ -787,12 +785,13 @@ Feature: Basic Roundabout | kg | tertiary | | | hl | tertiary | | + # the turn angles here are quite strange, so we do get uturns for exiting When I route I should get - | from | to | route | turns | distance | - | e | f | ed,af,af | depart,roundabout-exit-1,arrive | 80.1m | - | f | e | af,ed,ed | depart,roundabout-exit-1,arrive | 120.1m | - | k | l | kg,hl,hl | depart,roundabout-exit-1,arrive | 80.1m | - | l | k | hl,kg,kg | depart,roundabout-exit-1,arrive | 120.1m | + | from | to | route | turns | distance | + | e | f | ed,af,af,af | depart,roundabout-exit-1,exit roundabout left,arrive | 80.1m | + | f | e | af,ed,ed,ed | depart,roundabout-exit-1,exit roundabout uturn,arrive | 120.1m | + | k | l | kg,hl,hl,hl | depart,roundabout-exit-1,exit roundabout right,arrive | 80.1m | + | l | k | hl,kg,kg,kg | depart,roundabout-exit-1,exit roundabout uturn,arrive | 120.1m | @4030 @4075 Scenario: Service roundabout with service exits @@ -811,11 +810,11 @@ Feature: Basic Roundabout | bh | service | | When I route I should get - | from | to | route | turns | - | 1 | e | abcda,ce,ce | depart,roundabout-exit-1,arrive | - | 1 | f | abcda,df,df | depart,roundabout-exit-2,arrive | - | 1 | g | abcda,ag,ag | depart,roundabout-exit-3,arrive | - | 1 | h | abcda,bh,bh | depart,roundabout-exit-4,arrive | + | from | to | route | turns | + | 1 | e | abcda,ce,ce | depart,exit roundabout straight,arrive | + | 1 | f | abcda,df,df | depart,exit roundabout right,arrive | + | 1 | g | abcda,ag,ag | depart,exit roundabout straight,arrive | + | 1 | h | abcda,bh,bh | depart,exit roundabout right,arrive | Scenario: Collapsing a sliproad step after roundabouts Given the node map @@ -843,6 +842,6 @@ Feature: Basic Roundabout When I route I should get - | from | to | route | turns | distance | - | e | k | ebds,ufghl,jhik,jhik | depart,rstur-exit-2,turn right,arrive | 189.1m | - | 1 | k | ebds,ufghl,jhik,jhik | depart,rstur-exit-2,turn right,arrive | 159.1m | + | from | to | route | turns | distance | + | e | k | ebds,ufghl,ufghl,jhik,jhik | depart,rstur-exit-2,exit rotary right,turn right,arrive | 189.1m | + | 1 | k | ebds,ufghl,ufghl,jhik,jhik | depart,rstur-exit-2,exit rotary right,turn right,arrive | 159.1m | diff --git a/features/guidance/turn-angles.feature b/features/guidance/turn-angles.feature index a7870fc2c..e277a4163 100644 --- a/features/guidance/turn-angles.feature +++ b/features/guidance/turn-angles.feature @@ -248,8 +248,8 @@ Feature: Simple Turns | bcdefghijklmnob | residential | road | 1 | yes | roundabout | When I route I should get - | waypoints | route | turns | intersections | - | a,p | road,road,road | depart,roundabout turn straight exit-1,arrive | true:90;true:165 false:270 false:345,true:90 false:180 true:345;true:270 | + | waypoints | route | turns | intersections | + | a,p | road,road,road | depart,roundabout turn straight exit-1,arrive | true:90;true:165 false:270 false:345,true:90 false:180 true:345;true:270 | Scenario: Splitting Road with many lanes Given the node map @@ -1317,11 +1317,11 @@ Feature: Simple Turns #https://github.com/Project-OSRM/osrm-backend/pull/3469#issuecomment-270806580 Scenario: Oszillating Lower Priority Road - #Given the node map - # """ - # a -db c + #Given the node map + # """ + # a -db c # f - # """ + # """ Given the node locations | node | lat | lon | # | | a | 1.0 | 1.0 | | diff --git a/features/testbot/approaches.feature b/features/testbot/approaches.feature index b2eb85cef..73ca1af52 100644 --- a/features/testbot/approaches.feature +++ b/features/testbot/approaches.feature @@ -167,7 +167,7 @@ Feature: Approach parameter | 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 """ h diff --git a/include/engine/api/route_api.hpp b/include/engine/api/route_api.hpp index 19d4409b7..3f278b9b6 100644 --- a/include/engine/api/route_api.hpp +++ b/include/engine/api/route_api.hpp @@ -167,12 +167,12 @@ class RouteAPI : public BaseAPI * the overall response consistent. * * ⚠ CAUTION: order of post-processing steps is important - * - postProcess must be called before collapseTurnInstructions that expects - * post-processed roundabouts without Exit instructions + * - handleRoundabouts must be called before collapseTurnInstructions that + * expects post-processed roundabouts */ 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::anticipateLaneChange(std::move(leg.steps)); leg.steps = guidance::buildIntersections(std::move(leg.steps)); diff --git a/include/engine/guidance/post_processing.hpp b/include/engine/guidance/post_processing.hpp index ace5256b5..538f85810 100644 --- a/include/engine/guidance/post_processing.hpp +++ b/include/engine/guidance/post_processing.hpp @@ -17,7 +17,7 @@ namespace guidance // passed as none-reference to modify in-place and move out again OSRM_ATTR_WARN_UNUSED -std::vector postProcess(std::vector steps); +std::vector handleRoundabouts(std::vector steps); // trim initial/final segment of very short length. // This function uses in/out parameter passing to modify both steps and geometry in place. diff --git a/include/extractor/guidance/turn_instruction.hpp b/include/extractor/guidance/turn_instruction.hpp index 10032e46e..ddd3449f5 100644 --- a/include/extractor/guidance/turn_instruction.hpp +++ b/include/extractor/guidance/turn_instruction.hpp @@ -199,7 +199,10 @@ inline bool leavesRoundabout(const extractor::guidance::TurnInstruction instruct 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 diff --git a/package.json b/package.json index 25c8ecef7..804a8947a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "osrm", - "version": "5.12.0-latest.1", + "version": "5.12.0-roundaboutexits.1", "private": false, "description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.", "dependencies": { diff --git a/src/engine/api/json_factory.cpp b/src/engine/api/json_factory.cpp index 581cfdb39..bf216ce41 100644 --- a/src/engine/api/json_factory.cpp +++ b/src/engine/api/json_factory.cpp @@ -66,20 +66,20 @@ const constexpr TurnTypeName turn_type_names[] = { {"end of road", "end of road"}, {"notification", "notification"}, {"roundabout", "enter roundabout"}, - {"roundabout", "enter and exit roundabout"}, + {"exit roundabout", "enter and exit roundabout"}, {"rotary", "enter rotary"}, - {"rotary", "enter and exit rotary"}, + {"exit rotary", "enter and exit rotary"}, {"roundabout turn", "enter roundabout turn"}, {"roundabout turn", "enter and exit roundabout turn"}, {"use lane", "use lane"}, {"invalid", "(noturn)"}, {"invalid", "(suppressed)"}, - {"invalid", "(enter roundabout at exit)"}, - {"invalid", "(exit roundabout)"}, - {"invalid", "(enter rotary at exit)"}, - {"invalid", "(exit rotary)"}, - {"invalid", "(enter roundabout intersection at exit)"}, - {"invalid", "(exit roundabout intersection)"}, + {"roundabout", "roundabout"}, + {"exit roundabout", "exit roundabout"}, + {"rotary", "rotary"}, + {"exit rotary", "exit rotary"}, + {"roundabout turn", "roundabout turn"}, + {"exit roundabout", "exit roundabout turn"}, {"invalid", "(stay on roundabout)"}, {"invalid", "(sliproad)"}}; @@ -100,14 +100,14 @@ inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection std::string instructionTypeToString(const TurnType::Enum type) { static_assert(sizeof(turn_type_names) / sizeof(turn_type_names[0]) >= TurnType::MaxTurnType, - "Some turn types has not string representation."); + "Some turn types have no string representation."); return turn_type_names[static_cast(type)].external_name; } std::string internalInstructionTypeToString(const TurnType::Enum type) { static_assert(sizeof(turn_type_names) / sizeof(turn_type_names[0]) >= TurnType::MaxTurnType, - "Some turn types has not string representation."); + "Some turn types have no string representation."); return turn_type_names[static_cast(type)].internal_name; } diff --git a/src/engine/guidance/post_processing.cpp b/src/engine/guidance/post_processing.cpp index 940b4357a..b2b5249eb 100644 --- a/src/engine/guidance/post_processing.cpp +++ b/src/engine/guidance/post_processing.cpp @@ -7,6 +7,7 @@ #include "engine/guidance/collapsing_utility.hpp" #include "util/bearing.hpp" +#include "util/group_by.hpp" #include "util/guidance/name_announcements.hpp" #include "util/guidance/turn_lanes.hpp" @@ -14,6 +15,8 @@ #include #include +#include "engine/guidance/collapsing_utility.hpp" + #include #include #include @@ -26,6 +29,8 @@ using osrm::extractor::guidance::hasRampType; using osrm::extractor::guidance::mirrorDirectionModifier; using osrm::extractor::guidance::bearingToDirectionModifier; +using RouteStepIterator = std::vector::iterator; + namespace osrm { namespace engine @@ -36,208 +41,137 @@ namespace guidance namespace { -void fixFinalRoundabout(std::vector &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; - --propagation_index) - { - auto &propagation_step = steps[propagation_index]; - propagation_step.maneuver.exit = 0; - if (entersRoundabout(propagation_step.maneuver.instruction)) - { - // remember the current name as rotary name in tha case we end in a rotary - 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) - { - propagation_step.maneuver.instruction.type = TurnType::EnterRoundabout; - } + if (begin == end) + return; - return; - } - // accumulate turn data into the enter instructions - else if (propagation_step.maneuver.instruction.type == TurnType::StayOnRoundabout) + for (auto itr = begin + 1; itr != end; ++itr) + { + // ensure not to invalidate the final arrive + if (!hasWaypointType(*itr)) { - // 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(); + begin->ElongateBy(*itr); + itr->Invalidate(); } } } -bool setUpRoundabout(RouteStep &step) +// 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) { - // basic entry into a roundabout - // 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) + 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)) { - // 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; + // 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; } - 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 + const auto passes_exit_or_leaves_roundabout = [](auto const &step) { + return staysOnRoundabout(step.maneuver.instruction) || + leavesRoundabout(step.maneuver.instruction); + }; - // 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; + // exit count + const auto exit = std::count_if(begin, end, passes_exit_or_leaves_roundabout); + + // removes all intermediate instructions, assigns names and exit numbers + BOOST_ASSERT(leavesRoundabout(last->maneuver.instruction)); + BOOST_ASSERT(std::distance(begin, end) >= 1); + last->maneuver.exit = exit; + + // when we actually have an enter instruction, we can store all the information on it that we + // need, otherwise we only provide the exit instruciton. In case of re-routing on the + // 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]; + + BOOST_ASSERT(!begin->intersections.empty()); + const double angle = util::bearing::angleBetween( + util::bearing::reverse(entry_intersection.bearings[entry_intersection.in]), + exit_bearing); + + begin->maneuver.instruction.direction_modifier = getTurnDirection(angle); + } + begin->AdaptStepSignage(*last); + } + + // in case of a roundabout turn, we do not emit an exit as long as the mode remains the same + if ((begin->maneuver.instruction.type == TurnType::EnterRoundaboutIntersection || + begin->maneuver.instruction.type == TurnType::EnterRoundaboutIntersectionAtExit) && + begin->mode == last->mode) + { + compressRange(begin, end); } else { - return true; + // do not remove last (the exit instruction) + compressRange(begin, last); } } -void closeOffRoundabout(const bool on_roundabout, - std::vector &steps, - std::size_t step_index) +// roundabout groups are a sequence of roundabout instructions. This can contain enter/exit +// instructions in between +void processRoundaboutGroups(const std::pair &range) { - auto &step = steps[step_index]; - step.maneuver.exit += 1; - if (!on_roundabout) + const auto leaves_roundabout = [](auto const &step) { + return leavesRoundabout(step.maneuver.instruction); + }; + + auto itr = range.first; + while (itr != range.second) { - 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) + auto exit = std::find_if(itr, range.second, leaves_roundabout); + if (exit == range.second) { - steps[1].rotary_name = steps[0].name; - steps[1].rotary_pronunciation = steps[0].pronunciation; + processRoundaboutExits(itr, exit); + itr = exit; } - } - - if (step_index > 1) - { - 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)) + else { - 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--; + processRoundaboutExits(itr, exit + 1); + itr = exit + 1; } } - - // Normal exit from the roundabout, or exit from a previously fixed roundabout. Propagate the - // index back to the entering location and prepare the current silent set of instructions for - // removal. - std::vector intermediate_steps; - BOOST_ASSERT(!steps[step_index].intersections.empty()); - // the very first intersection in the steps represents the location of the turn. Following - // intersections are locations passed along the way - const auto exit_intersection = steps[step_index].intersections.front(); - const auto exit_bearing = exit_intersection.bearings[exit_intersection.out]; - const auto destination_copy = step; - - if (step_index > 1) - { - // 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( - util::bearing::reverse(entry_intersection.bearings[entry_intersection.in]), - exit_bearing); - - auto bearings = propagation_step.intersections.front().bearings; - propagation_step.maneuver.instruction.direction_modifier = - getTurnDirection(angle); - } - - propagation_step.AdaptStepSignage(destination_copy); - break; - } - } - // remove exit - } } } // namespace @@ -248,64 +182,49 @@ void closeOffRoundabout(const bool on_roundabout, // They are required for maintenance purposes. We can calculate the number // of exits to pass in a roundabout and the number of intersections // that we come across. -std::vector postProcess(std::vector steps) +std::vector handleRoundabouts(std::vector steps) { - // the steps should always include the first/last step in form of a location - BOOST_ASSERT(steps.size() >= 2); - if (steps.size() == 2) + // check if a step has roundabout type + const auto has_roundabout_type = [](auto const &step) { + 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; - // Count Street Exits forward - bool on_roundabout = false; - bool has_entered_roundabout = false; + // unless the first instruction enters the roundabout, we are currently on a roundabout. This is + // a special case that happens if the route starts on a roundabout. It is a border case, but + // 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 - // required. We might end up with only one of them (e.g. starting within a roundabout) - // or having a via-point in the roundabout. - // In this case, exits are numbered from the start of the leg. - for (std::size_t step_index = 0; step_index < steps.size(); ++step_index) - { - const auto next_step_index = step_index + 1; - auto &step = steps[step_index]; - const auto instruction = step.maneuver.instruction; - if (entersRoundabout(instruction)) + // this group by paradigm does might contain intermediate roundabout instructions, when they are + // directly connected. Otherwise it will be a sequence containing everything from enter to exit. + // If we already start on the roundabout, the first valid place will be steps.begin(). + const auto is_on_roundabout = [¤tly_on_roundabout](const auto &step) { + if (currently_on_roundabout) { - has_entered_roundabout = setUpRoundabout(step); + if (leavesRoundabout(step.maneuver.instruction)) + currently_on_roundabout = false; - if (has_entered_roundabout && next_step_index < steps.size()) - steps[next_step_index].maneuver.exit = step.maneuver.exit; + return true; } - else if (instruction.type == TurnType::StayOnRoundabout) + else { - on_roundabout = true; - // increase the exit number we require passing the exit - step.maneuver.exit += 1; - if (next_step_index < steps.size()) - steps[next_step_index].maneuver.exit = step.maneuver.exit; + currently_on_roundabout = entersRoundabout(step.maneuver.instruction); + auto result = currently_on_roundabout; + // cases that immediately exit the roundabout + if (currently_on_roundabout) + 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 - // Move backwards through the instructions until the start and remove the exit number - // A roundabout without exit translates to enter-roundabout - if (has_entered_roundabout || on_roundabout) - { - fixFinalRoundabout(steps); - } + // for each range of instructions between begin/end of a roundabout assign + util::group_by(steps.begin(), steps.end(), is_on_roundabout, processRoundaboutGroups); BOOST_ASSERT(steps.front().intersections.size() >= 1); BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1); @@ -333,8 +252,7 @@ void trimShortSegments(std::vector &steps, LegGeometry &geometry) return; // if phantom node is located at the connection of two segments, either one can be selected - // as - // turn + // as turn // // a --- b // | diff --git a/test/nodejs/constants.js b/test/nodejs/constants.js index 09cc86a83..f5746b37a 100644 --- a/test/nodejs/constants.js +++ b/test/nodejs/constants.js @@ -10,7 +10,7 @@ exports.three_test_coordinates = [[7.41337, 43.72956], exports.two_test_coordinates = exports.three_test_coordinates.slice(0, 2) -exports.test_tile = {'at': [17059, 11948, 15], 'size': 167178}; +exports.test_tile = {'at': [17059, 11948, 15], 'size': 167166}; // Test files generated by the routing engine; check test/data