Implement Turn Lane Api
This commit is contained in:
parent
ec0a1a4ab1
commit
5d91b759d1
@ -2,7 +2,7 @@
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignAfterOpenBracket: true
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -43,7 +43,6 @@ Thumbs.db
|
||||
/example/build/
|
||||
/test/data/monaco*
|
||||
/cmake/postinst
|
||||
.bundle/
|
||||
|
||||
# Eclipse related files #
|
||||
#########################
|
||||
|
@ -1,7 +1,7 @@
|
||||
# 5.3.0
|
||||
- API
|
||||
- Introduces new `TurnType` in the form of `use lane`. The type indicates that you have to stick to a lane without turning
|
||||
- Introduces lanes to the route response, indicating which lanes are to be used on a turn
|
||||
- Introduces lanes to the route response. The lane data contains both the markings at the intersection and a flag indicating their involvement in the turn
|
||||
|
||||
- Infrastructure
|
||||
- BREAKING: The new turn type changes the turn-type order. This breaks the **data format**.
|
||||
|
20
docs/http.md
20
docs/http.md
@ -437,12 +437,17 @@ step.
|
||||
| geojson | [GeoJSON `LineString`](http://geojson.org/geojson-spec.html#linestring) or [GeoJSON `Point`](http://geojson.org/geojson-spec.html#point) if it is only one coordinate (not wrapped by a GeoJSON feature)|
|
||||
|
||||
- `name`: The name of the way along which travel proceeds.
|
||||
- `lanes`: the available turn lanes at the turn
|
||||
- `marked`: markings on the road, following the OSM scheme (e.g. left, slight_right, or through)
|
||||
- `take`: a boolean flag indicating whether the lane is a possible choice in the maneuver
|
||||
- `pronunciation`: The pronunciation hint of the way name. Will be `undefined` if there is no pronunciation hit.
|
||||
- `destinations`: The destinations of the way. Will be `undefined` if there are no destinations.
|
||||
- `mode`: A string signifying the mode of transportation.
|
||||
- `maneuver`: A `StepManeuver` object representing the maneuver.
|
||||
- `intersections`: A list of `Intersections` that are passed along the segment, the very first belonging to the StepManeuver
|
||||
|
||||
Currently, the supported lane tags are: `sharp_left, left, slight_left, sharp_right, right, slight_right, through, reverse, none`.
|
||||
|
||||
#### Example
|
||||
|
||||
```
|
||||
@ -450,17 +455,24 @@ step.
|
||||
"distance":152.3,
|
||||
"duration":15.6,
|
||||
"name":"Lortzingstraße",
|
||||
"lanes":{
|
||||
{"marked":"left",
|
||||
"take":"false"},
|
||||
{"marked":"right",
|
||||
"take":"true"}
|
||||
},
|
||||
"maneuver":{
|
||||
"type":"depart",
|
||||
"modifier":"left"
|
||||
"type":"turn",
|
||||
"modifier":"right"
|
||||
},
|
||||
"geometry":"{lu_IypwpAVrAvAdI",
|
||||
"mode":"driving",
|
||||
"intersections":[
|
||||
{"location":[13.39677,52.54366],
|
||||
"in":2,
|
||||
"out":1,
|
||||
"bearings":[66,246],
|
||||
"entry":["true","true"]},
|
||||
"bearings":[10,184,270],
|
||||
"entry":[false,"true","true"]},
|
||||
{"location":[13.394718,52.543096],
|
||||
"in":0,
|
||||
"out":2,
|
||||
|
@ -26,8 +26,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes | # |
|
||||
| a,d | ab,bc,cd,cd | depart,turn right,turn left,arrive | ,1 2,1 2, | 2 hops |
|
||||
| a,e | ab,bc,cd,de,de | depart,turn right,turn left,turn right,arrive | ,1,1,0, | 3 hops |
|
||||
| a,d | ab,bc,cd,cd | depart,turn right,turn left,arrive | ,through:false right:true right:true right:false,left:true left:true through:false, | 2 hops |
|
||||
| a,e | ab,bc,cd,de,de | depart,turn right,turn left,turn right,arrive | ,through:false right:false right:true right:false,left:false left:true through:false,through:false right:true, | 3 hops |
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate Lane Change for quick same direction turns, staying on the same street
|
||||
@ -49,8 +49,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | MySt,MySt,MySt,MySt | depart,continue right,end of road right,arrive | ,0,0, |
|
||||
| e,a | MySt,MySt,MySt,MySt | depart,continue left,end of road left,arrive | ,2,1, |
|
||||
| a,e | MySt,MySt,MySt,MySt | depart,continue right,end of road right,arrive | ,through:false right:false right:true,left:false right:true, |
|
||||
| e,a | MySt,MySt,MySt,MySt | depart,continue left,end of road left,arrive | ,left:true left:false through:false,left:true right:false, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate Lane Change for quick same direction turns, changing between streets
|
||||
@ -72,8 +72,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | AXSt,BDSt,EYSt,EYSt | depart,turn right,end of road right,arrive | ,0,0, |
|
||||
| e,a | EYSt,BDSt,AXSt,AXSt | depart,turn left,end of road left,arrive | ,2,1, |
|
||||
| a,e | AXSt,BDSt,EYSt,EYSt | depart,turn right,end of road right,arrive | ,through:false right:false right:true,left:false right:true, |
|
||||
| e,a | EYSt,BDSt,AXSt,AXSt | depart,turn left,end of road left,arrive | ,left:true left:false through:false,left:true right:false, |
|
||||
|
||||
|
||||
@anticipate
|
||||
@ -93,7 +93,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive | ,0,0, |
|
||||
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive | ,slight_left:false slight_left:true,through:false slight_right:true, |
|
||||
|
||||
|
||||
@anticipate
|
||||
@ -115,8 +115,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,i | abx,bcd,di,di | depart,off ramp right,fork slight left,arrive | ,0 1,1 2, |
|
||||
| a,j | abx,bcd,dj,dj | depart,off ramp right,fork slight right,arrive | ,0 1,0 1, |
|
||||
| a,i | abx,bcd,di,di | depart,off ramp right,fork slight left,arrive | ,none:false none:false none:false slight_right:true slight_right:true,slight_left:true slight_left;slight_right:true slight_right:false, |
|
||||
| a,j | abx,bcd,dj,dj | depart,off ramp right,fork slight right,arrive | ,none:false none:false none:false slight_right:true slight_right:true,slight_left:false slight_left;slight_right:true slight_right:true, |
|
||||
|
||||
|
||||
@anticipate
|
||||
@ -136,8 +136,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,i | ab,xbcj,ci,ci | depart,merge slight left,turn slight right,arrive | ,,0, |
|
||||
| a,j | ab,xbcj,xbcj,xbcj | depart,merge slight left,use lane straight,arrive | ,,1, |
|
||||
| a,i | ab,xbcj,ci,ci | depart,merge slight left,turn slight right,arrive | ,,none:false slight_right:true, |
|
||||
| a,j | ab,xbcj,xbcj,xbcj | depart,merge slight left,use lane straight,arrive | ,,none:true slight_right:false, |
|
||||
|
||||
|
||||
@anticipate
|
||||
@ -161,8 +161,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,1,1,0, |
|
||||
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,through:false right:false right:true right:false,left:false left:true through:false,through:false right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for fan-out
|
||||
@ -185,8 +184,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,0,1 2,0 1 2, |
|
||||
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,through:false right:true,left:true left:true through:false,through:false right:true right:true right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for fan-in followed by fan-out
|
||||
@ -209,8 +207,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,1 2,1 2,0 1 2, |
|
||||
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,through:false right:true right:true right:false,left:true left:true through:false,through:false right:true right:true right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for fan-out followed by fan-in
|
||||
@ -233,8 +230,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,0,1,0, |
|
||||
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,through:false right:true,left:false left:true through:false,through:false right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for multiple hops with same number of lanes
|
||||
@ -261,9 +257,9 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | abx,bcy,cdz,dew,ef,ef | depart,turn right,turn left,turn right,turn left,arrive | ,1,1,1,1, |
|
||||
| a,f | abx,bcy,cdz,dew,ef,ef | depart,turn right,turn left,turn right,turn left,arrive | ,through:false right:false right:true right:false,left:false left:true through:false,through:false right:true right:false,left:true through:false, |
|
||||
|
||||
@anticipate
|
||||
@anticipate @bug @todo
|
||||
Scenario: Tripple Right keeping Left
|
||||
Given the node map
|
||||
| a | | | | b | | i |
|
||||
@ -285,10 +281,10 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,end of road left,arrive | ,2,2,2,2, |
|
||||
| a,g | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,end of road right,arrive | ,0 1,0 1,0 1,0 1, |
|
||||
| a,f | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,end of road left,arrive | ,none:false none:true right:false right:false,none:false none:true right:false right:false,none:false none:true right:false right:false,left:true right:false right:false, |
|
||||
| a,g | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,end of road right,arrive | ,none:false none:false right:true right:true,none:false none:false right:true right:true,none:false none:false right:true right:true,left:false right:true right:true, |
|
||||
|
||||
@anticipate
|
||||
@anticipate @bug @todo
|
||||
Scenario: Tripple Left keeping Right
|
||||
Given the node map
|
||||
| i | | b | | | | a |
|
||||
@ -310,5 +306,5 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,end of road right,arrive | ,2,2,2,2, |
|
||||
| a,g | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,end of road left,arrive | ,0 1,0 1,0 1,0 1, |
|
||||
| a,f | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,end of road right,arrive | ,left:false left:false none:true none:false,left:false left:false none:true none:false,left:false left:false none:true none:false,left:false left:false right:true, |
|
||||
| a,g | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,end of road left,arrive | ,left:true left:true none:false none:false,left:true left:true none:false none:false,left:true left:true none:false none:false,left:true left:true right:false, |
|
||||
|
@ -21,10 +21,10 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,1, |
|
||||
| a,d | in,right,right | depart,turn right,arrive | ,0, |
|
||||
| c,a | straight,in,in | depart,new name straight,arrive | ,0 1 2, |
|
||||
| c,d | straight,right,right | depart,turn left,arrive | ,3, |
|
||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,through:true right:false, |
|
||||
| a,d | in,right,right | depart,turn right,arrive | ,through:false right:true, |
|
||||
| c,a | straight,in,in | depart,new name straight,arrive | ,left:false through:true none:true none:true, |
|
||||
| c,d | straight,right,right | depart,turn left,arrive | ,left:true through:false none:false none:false, |
|
||||
|
||||
Scenario: Basic Turn Lane 4-Way Turn
|
||||
Given the node map
|
||||
@ -41,12 +41,12 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,1, |
|
||||
| a,d | in,right,right | depart,turn right,arrive | ,0, |
|
||||
| a,e | in,left,left | depart,turn left,arrive | ,1, |
|
||||
| d,a | right,in,in | depart,turn left,arrive | ,1, |
|
||||
| d,e | right,left,left | depart,new name straight,arrive | ,0, |
|
||||
| d,c | right,straight,straight | depart,turn right,arrive | ,0, |
|
||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,none:true right:false, |
|
||||
| a,d | in,right,right | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,e | in,left,left | depart,turn left,arrive | ,none:true right:false, |
|
||||
| d,a | right,in,in | depart,turn left,arrive | ,left:true none:false, |
|
||||
| d,e | right,left,left | depart,new name straight,arrive | ,left:false none:true, |
|
||||
| d,c | right,straight,straight | depart,turn right,arrive | ,left:false none:true, |
|
||||
|
||||
Scenario: Basic Turn Lane 4-Way Turn using none
|
||||
Given the node map
|
||||
@ -63,9 +63,9 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,1, |
|
||||
| a,d | in,right,right | depart,turn right,arrive | ,0, |
|
||||
| a,e | in,left,left | depart,turn left,arrive | ,1, |
|
||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,none:true right:false, |
|
||||
| a,d | in,right,right | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,e | in,left,left | depart,turn left,arrive | ,none:true right:false, |
|
||||
|
||||
Scenario: Basic Turn Lane 4-Way With U-Turn Lane
|
||||
Given the node map
|
||||
@ -82,10 +82,10 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | turns | lanes |
|
||||
| a | c | 180,180 180,180 | in,straight,straight | depart,new name straight,arrive | ,0, |
|
||||
| a | d | 180,180 180,180 | in,right,right | depart,turn right,arrive | ,0, |
|
||||
| a | e | 180,180 180,180 | in,left,left | depart,turn left,arrive | ,1, |
|
||||
| 1 | a | 90,2 270,2 | in,in,in | depart,turn uturn,arrive | ,1, |
|
||||
| a | c | 180,180 180,180 | in,straight,straight | depart,new name straight,arrive | ,reverse;left:false through;right:true, |
|
||||
| a | d | 180,180 180,180 | in,right,right | depart,turn right,arrive | ,reverse;left:false through;right:true, |
|
||||
| a | e | 180,180 180,180 | in,left,left | depart,turn left,arrive | ,reverse;left:true through;right:false, |
|
||||
| 1 | a | 90,2 270,2 | in,in,in | depart,turn uturn,arrive | ,reverse;left:true through;right:false, |
|
||||
|
||||
|
||||
#this next test requires decision on how to announce lanes for going straight if there is no turn
|
||||
@ -104,11 +104,11 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,turn,turn | depart,turn right,arrive | ,0, |
|
||||
| a,c | road,road,road | depart,use lane straight,arrive | ,1, |
|
||||
| a,d | road,turn,turn | depart,turn right,arrive | ,through:false right:true, |
|
||||
| a,c | road,road,road | depart,use lane straight,arrive | ,through:true right:false, |
|
||||
|
||||
#turn lanes are often drawn at the incoming road, even though the actual turn requires crossing the intersection first
|
||||
@TODO @WORKAROUND-FIXME
|
||||
@todo @WORKAROUND-FIXME @bug
|
||||
Scenario: Turn Lanes at Segregated Road
|
||||
Given the node map
|
||||
| | | i | l | | |
|
||||
@ -134,23 +134,57 @@ Feature: Turn Lane Guidance
|
||||
| fl | cross | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes | # |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,0, | |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,1, | #post-processing reduction |
|
||||
| a,l | road,cross,cross | depart,turn left,arrive | ,2, | |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,2, | |
|
||||
| k,d | cross,road,road | depart,turn right,arrive | ,0, | |
|
||||
| k,l | cross,cross,cross | depart,use lane straight,arrive | ,0, | |
|
||||
| k,h | cross,road,road | depart,turn left,arrive | ,1, | |
|
||||
| k,j | cross,cross,cross | depart,continue uturn,arrive | ,1, | |
|
||||
| e,l | road,cross,cross | depart,turn right,arrive | ,0, | |
|
||||
| e,h | road,road | depart,arrive | , | |
|
||||
| e,j | road,cross,cross | depart,turn left,arrive | ,2, | |
|
||||
| e,d | road,road,road | depart,continue uturn,arrive | ,2, | |
|
||||
| i,h | cross,road,road | depart,turn right,arrive | ,, | |
|
||||
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,0, | |
|
||||
| i,d | cross,road,road | depart,turn left,arrive | ,1, | |
|
||||
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,1, | |
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false through:false right:true |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,left:false through:true right:false, |
|
||||
| a,l | road,cross,cross | depart,turn left,arrive | ,left:true through:false right:false, |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,left:true through:false right:false, |
|
||||
| k,d | cross,road,road | depart,turn right,arrive | ,left:false through;right:true, |
|
||||
| k,l | cross,cross,cross | depart,use lane straight,arrive | ,left:false through;right:true, |
|
||||
| k,h | cross,road,road | depart,turn left,arrive | ,left:true through;right:false, |
|
||||
| k,j | cross,cross,cross | depart,continue uturn,arrive | ,left:true through;right:false, |
|
||||
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false through:false through;right:true, |
|
||||
| e,h | road,road | depart,arrive | ,none:false through:true through;right:true |
|
||||
| e,j | road,cross,cross | depart,turn left,arrive | ,none:true through:false through;right:false, |
|
||||
| e,d | road,road,road | depart,continue uturn,arrive | ,none:true through:false through;right:false, |
|
||||
| i,h | cross,road,road | depart,turn right,arrive | ,, |
|
||||
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false through:true, |
|
||||
| i,d | cross,road,road | depart,turn left,arrive | ,left:true through:false, |
|
||||
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true through:false, |
|
||||
|
||||
#copy of former case to prevent further regression
|
||||
Scenario: Turn Lanes at Segregated Road
|
||||
Given the node map
|
||||
| | | i | l | | |
|
||||
| | | | | | |
|
||||
| h | | g | f | | e |
|
||||
| a | | b | c | | d |
|
||||
| | | | | | |
|
||||
| | | j | k | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|through&right | yes |
|
||||
| bc | road | left\|through | yes |
|
||||
| cd | road | | yes |
|
||||
| ef | road | \|through&through;right | yes |
|
||||
| fg | road | left;through\|through& | yes |
|
||||
| gh | road | | yes |
|
||||
| ig | cross | | yes |
|
||||
| gb | cross | left\|through | yes |
|
||||
| bj | cross | | yes |
|
||||
| kc | cross | left\|through;right | yes |
|
||||
| cf | cross | left\|through | yes |
|
||||
| fl | cross | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false through:false right:true, |
|
||||
| k,d | cross,road,road | depart,turn right,arrive | ,left:false through;right:true, |
|
||||
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false through:false through;right:true, |
|
||||
| i,h | cross,road,road | depart,turn right,arrive | ,, |
|
||||
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false through:true, |
|
||||
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true through:false, |
|
||||
|
||||
Scenario: Turn Lanes at Segregated Road
|
||||
Given the node map
|
||||
@ -171,7 +205,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,0, |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false through:false right:true, |
|
||||
|
||||
#this can happen due to traffic lights / lanes not drawn up to the intersection itself
|
||||
Scenario: Turn Lanes Given earlier than actual turn
|
||||
@ -189,8 +223,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | road,turn,turn | depart,turn right,arrive | ,0, |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,1, |
|
||||
| a,e | road,turn,turn | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,none:true right:false, |
|
||||
|
||||
Scenario: Turn Lanes Given earlier than actual turn
|
||||
Given the node map
|
||||
@ -209,10 +243,10 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,k | road,second-turn,second-turn | depart,turn right,arrive | ,0, |
|
||||
| a,i | road,road,road | depart,use lane straight,arrive | ,1, |
|
||||
| i,j | road,first-turn,first-turn | depart,turn left,arrive | ,1, |
|
||||
| i,a | road,road,road | depart,use lane straight,arrive | ,0, |
|
||||
| a,k | road,second-turn,second-turn | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,i | road,road,road | depart,use lane straight,arrive | ,none:true right:false, |
|
||||
| i,j | road,first-turn,first-turn | depart,turn left,arrive | ,left:true none:false, |
|
||||
| i,a | road,road,road | depart,use lane straight,arrive | ,left:false none:true, |
|
||||
|
||||
Scenario: Passing a one-way street
|
||||
Given the node map
|
||||
@ -228,7 +262,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | road,turn,turn | depart,turn left,arrive | ,1, |
|
||||
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true through:false, |
|
||||
|
||||
Scenario: Passing a one-way street, partly pulled back lanes
|
||||
Given the node map
|
||||
@ -246,8 +280,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | road,turn,turn | depart,turn left,arrive | ,1, |
|
||||
| a,g | road,right,right | depart,turn right,arrive | ,0, |
|
||||
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true through;right:false, |
|
||||
| a,g | road,right,right | depart,turn right,arrive | ,left:false through;right:true, |
|
||||
|
||||
Scenario: Passing a one-way street, partly pulled back lanes, no through
|
||||
Given the node map
|
||||
@ -265,9 +299,10 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | road,turn,turn | depart,turn left,arrive | ,1, |
|
||||
| a,g | road,right,right | depart,turn right,arrive | ,0, |
|
||||
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true right:false, |
|
||||
| a,g | road,right,right | depart,turn right,arrive | ,left:false right:true, |
|
||||
|
||||
@todo @bug
|
||||
Scenario: Narrowing Turn Lanes
|
||||
Given the node map
|
||||
| | | | | g | |
|
||||
@ -286,9 +321,9 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,g | road,left,left | depart,turn left,arrive | ,2, |
|
||||
| a,e | road,through,through | depart,new name straight,arrive | ,1, |
|
||||
| a,f | road,right,right | depart,turn right,arrive | ,0, |
|
||||
| a,g | road,left,left | depart,turn left,arrive | ,left:true through:false right:false, |
|
||||
| a,e | road,through,through | depart,new name straight,arrive | ,left:false through:true right:false, |
|
||||
| a,f | road,right,right | depart,turn right,arrive | ,left:false through:false right:true, |
|
||||
|
||||
Scenario: Turn at a traffic light
|
||||
Given the node map
|
||||
@ -308,10 +343,10 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,1, |
|
||||
| a,e | road,turn,turn | depart,turn right,arrive | ,0, |
|
||||
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,through:true right:false, |
|
||||
| a,e | road,turn,turn | depart,turn right,arrive | ,through:false right:true, |
|
||||
|
||||
@bug @todo
|
||||
Scenario: Theodor Heuss Platz
|
||||
Given the node map
|
||||
| | | | i | o | | | l | |
|
||||
@ -344,8 +379,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| i,m | top,top-right,top-right | depart,roundabout-exit-4,arrive | ,0 1 2, |
|
||||
| i,l | top,top-right-out,top-right-out | depart,roundabout-exit-4,arrive | ,2 3, |
|
||||
| i,m | top,top-right,top-right | depart,roundabout-exit-4,arrive | ,slight_left:false slight_left;slight_right:true slight_right:true slight_right:true, |
|
||||
| i,l | top,top-right-out,top-right-out | depart,roundabout-exit-4,arrive | ,slight_left:true slight_left;slight_right:true slight_right:false slight_right:false, |
|
||||
| i,o | top,top,top | depart,roundabout-exit-5,arrive | ,, |
|
||||
|
||||
Scenario: Turn Lanes Breaking up
|
||||
@ -372,8 +407,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,g | road,cross,cross | depart,turn left,arrive | ,2 3, |
|
||||
| a,e | road,road,road | depart,use lane straight,arrive | ,0 1, |
|
||||
| a,g | road,cross,cross | depart,turn left,arrive | ,left:true left:true through:false through:false, |
|
||||
| a,e | road,road,road | depart,use lane straight,arrive | ,left:false left:false through:true through:true, |
|
||||
|
||||
Scenario: U-Turn Road at Intersection
|
||||
Given the node map
|
||||
@ -395,10 +430,10 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | turns | lanes |
|
||||
| a | g | 180,180 180,180 | road,cross,cross | depart,turn right,arrive | ,0, |
|
||||
| a | h | 180,180 180,180 | road,cross,cross | depart,turn left,arrive | ,2, |
|
||||
| a | i | 180,180 180,180 | road,road,road | depart,use lane straight,arrive | ,1 2, |
|
||||
| b | a | 90,2 270,2 | road,road,road | depart,continue uturn,arrive | ,2, |
|
||||
| a | g | 180,180 180,180 | road,cross,cross | depart,turn right,arrive | ,none:false through:false right:true, |
|
||||
| a | h | 180,180 180,180 | road,cross,cross | depart,turn left,arrive | ,none:true through:false right:false, |
|
||||
| a | i | 180,180 180,180 | road,road,road | depart,use lane straight,arrive | ,none:true through:true right:false, |
|
||||
| b | a | 90,2 270,2 | road,road,road | depart,continue uturn,arrive | ,none:true through:false right:false, |
|
||||
|
||||
Scenario: Segregated Intersection Merges With Lanes
|
||||
Given the node map
|
||||
@ -420,10 +455,11 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | road,left,left | depart,turn left,arrive | ,2 3 4, |
|
||||
| a,e | road,road,road | depart,turn uturn,arrive | ,4, |
|
||||
| a,g | road,straight,straight | depart,new name straight,arrive | ,0 1, |
|
||||
| a,f | road,left,left | depart,turn left,arrive | ,left:true left:true left:true through:false through:false, |
|
||||
| a,e | road,road,road | depart,turn uturn,arrive | ,left:true left:false left:false through:false through:false, |
|
||||
| a,g | road,straight,straight | depart,new name straight,arrive | ,left:false left:false left:false through:true through:true, |
|
||||
|
||||
@bug @todo
|
||||
Scenario: Passing Through a Roundabout
|
||||
Given the node map
|
||||
| | | h | | g | | |
|
||||
@ -467,8 +503,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,1 2 3, |
|
||||
| a,e | road,cross,cross | depart,turn slight right,arrive | ,0 1, |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,through:true through:true through;slight_right:true slight_right:false, |
|
||||
| a,e | road,cross,cross | depart,turn slight right,arrive | ,through:false through:false through;slight_right:true slight_right:true, |
|
||||
|
||||
Scenario: Highway Ramp
|
||||
Given the node map
|
||||
@ -483,9 +519,10 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | hwy,hwy,hwy | depart,use lane straight,arrive | ,1 2 3, |
|
||||
| a,e | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,0 1, |
|
||||
| a,d | hwy,hwy,hwy | depart,use lane straight,arrive | ,through:true through:true through;slight_right:true slight_right:false, |
|
||||
| a,e | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,through:false through:false through;slight_right:true slight_right:true, |
|
||||
|
||||
@bug @todo
|
||||
Scenario: Turning Off Ramp
|
||||
Given the node map
|
||||
| | a | |
|
||||
@ -503,8 +540,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | off,road,road | depart,turn_right,arrive | ,0, |
|
||||
| a,g | off,road,road | depart,turn_left,arrive | ,1, |
|
||||
| a,d | off,road,road | depart,turn_right,arrive | ,left:false right:true, |
|
||||
| a,g | off,road,road | depart,turn_left,arrive | ,left:true right:false, |
|
||||
| a,h | | | |
|
||||
|
||||
Scenario: Off Ramp In a Turn
|
||||
@ -522,8 +559,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | hwy,hwy,hwy | depart,use lane slight left,arrive | ,1 2, |
|
||||
| a,d | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,0, |
|
||||
| a,c | hwy,hwy,hwy | depart,use lane slight left,arrive | ,through:true through:true slight_right:false, |
|
||||
| a,d | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,through:false through:false slight_right:true, |
|
||||
|
||||
Scenario: Reverse Lane in Segregated Road
|
||||
Given the node map
|
||||
@ -541,7 +578,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,2, |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,reverse:true through:false through:false,|
|
||||
|
||||
Scenario: Reverse Lane in Segregated Road with none
|
||||
Given the node map
|
||||
@ -559,7 +596,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,2, |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,reverse:true through:false none:false, |
|
||||
|
||||
Scenario: Reverse Lane in Segregated Road with none, Service Turn Prior
|
||||
Given the node map
|
||||
@ -579,7 +616,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,2, |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,reverse:true through:false none:false, |
|
||||
|
||||
Scenario: Don't collapse everything to u-turn / too wide
|
||||
Given the node map
|
||||
@ -597,8 +634,8 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route | lanes |
|
||||
| a,d | depart,continue right,end of road right,arrive | road,road,road,road | ,0,, |
|
||||
| d,a | depart,continue left,end of road left,arrive | road,road,road,road | ,1,, |
|
||||
| a,d | depart,continue right,end of road right,arrive | road,road,road,road | ,through:false right:true,, |
|
||||
| d,a | depart,continue left,end of road left,arrive | road,road,road,road | ,left:true through:false,, |
|
||||
|
||||
Scenario: Merge Lanes Onto Freeway
|
||||
Given the node map
|
||||
@ -612,7 +649,7 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route | lanes |
|
||||
| d,c | depart,merge slight left,arrive | ramp,Hwy,Hwy | ,0 1, |
|
||||
| d,c | depart,merge slight left,arrive | ramp,Hwy,Hwy | ,slight_right:true slight_right:true, |
|
||||
|
||||
Scenario: Fork on motorway links - don't fork on through but use lane
|
||||
Given the node map
|
||||
@ -629,5 +666,5 @@ Feature: Turn Lane Guidance
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | on,xbcj,xbcj,xbcj | depart,merge slight left,use lane straight,arrive | ,,1, |
|
||||
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive | ,,0, |
|
||||
| a,j | on,xbcj,xbcj,xbcj | depart,merge slight left,use lane straight,arrive | ,,none:true slight_right:false, |
|
||||
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive | ,,none:false slight_right:true, |
|
||||
|
@ -223,7 +223,7 @@ module.exports = function () {
|
||||
};
|
||||
|
||||
['osrm', 'osrm.ebg', 'osrm.edges', 'osrm.enw', 'osrm.fileIndex', 'osrm.geometry', 'osrm.icd',
|
||||
'osrm.names', 'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions'].forEach(file => {
|
||||
'osrm.names', 'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions', 'osrm.tld', 'osrm.tls'].forEach(file => {
|
||||
q.defer(rename, file);
|
||||
});
|
||||
|
||||
@ -283,7 +283,7 @@ module.exports = function () {
|
||||
|
||||
['osrm', 'osrm.core', 'osrm.datasource_indexes', 'osrm.datasource_names', 'osrm.ebg','osrm.edges',
|
||||
'osrm.enw', 'osrm.fileIndex', 'osrm.geometry', 'osrm.hsgr', 'osrm.icd','osrm.level', 'osrm.names',
|
||||
'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions'].forEach((file) => {
|
||||
'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions', 'osrm.tld', 'osrm.tls'].forEach((file) => {
|
||||
q.defer(rename, file);
|
||||
});
|
||||
|
||||
|
@ -169,7 +169,14 @@ module.exports = function () {
|
||||
};
|
||||
|
||||
this.lanesList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, instruction => ('lanes' in instruction.maneuver ? instruction.maneuver.lanes.join(' ') : ''));
|
||||
return this.extractInstructionList(instructions, instruction => {
|
||||
if( 'lanes' in instruction.maneuver )
|
||||
{
|
||||
return instruction.maneuver.lanes.map( p => { return p.marked + ':' + p.take; } ).join(' ');
|
||||
} else
|
||||
{
|
||||
return '';
|
||||
}});
|
||||
};
|
||||
|
||||
this.turnList = (instructions) => {
|
||||
|
@ -33,7 +33,8 @@ module.exports = function () {
|
||||
var afterRequest = (err, res, body) => {
|
||||
if (err) return cb(err);
|
||||
if (body && body.length) {
|
||||
let destinations, pronunciations, instructions, bearings, turns, modes, times, distances, summary, intersections, lanes;
|
||||
let destinations, pronunciations, instructions, bearings, turns, modes, times,
|
||||
distances, summary, intersections, lanes;
|
||||
|
||||
let json = JSON.parse(body);
|
||||
|
||||
@ -103,12 +104,10 @@ module.exports = function () {
|
||||
got.time = instructions ? util.format('%ds', time) : '';
|
||||
}
|
||||
|
||||
|
||||
if (headers.has('lanes')) {
|
||||
got.lanes = (lanes || '').trim();
|
||||
}
|
||||
|
||||
|
||||
if (headers.has('speed')) {
|
||||
if (row.speed !== '' && instructions) {
|
||||
if (!row.speed.match(/\d+ km\/h/))
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "engine/guidance/assemble_overview.hpp"
|
||||
#include "engine/guidance/assemble_route.hpp"
|
||||
#include "engine/guidance/assemble_steps.hpp"
|
||||
#include "engine/guidance/lane_processing.hpp"
|
||||
#include "engine/guidance/post_processing.hpp"
|
||||
|
||||
#include "engine/internal_route_result.hpp"
|
||||
|
@ -138,6 +138,10 @@ class BaseDataFacade
|
||||
const int bearing,
|
||||
const int bearing_range) const = 0;
|
||||
|
||||
virtual bool hasLaneData(const EdgeID id) const = 0;
|
||||
virtual util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const = 0;
|
||||
virtual std::string GetTurnStringForID(const LaneStringID lane_string_id) const = 0;
|
||||
|
||||
virtual unsigned GetCheckSum() const = 0;
|
||||
|
||||
virtual bool IsCoreNode(const NodeID id) const = 0;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "storage/storage_config.hpp"
|
||||
#include "engine/geospatial_query.hpp"
|
||||
#include "util/graph_loader.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/io.hpp"
|
||||
#include "util/packed_vector.hpp"
|
||||
#include "util/range_table.hpp"
|
||||
@ -78,8 +79,11 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
util::ShM<NodeID, false>::vector m_via_node_list;
|
||||
util::ShM<unsigned, false>::vector m_name_ID_list;
|
||||
util::ShM<extractor::guidance::TurnInstruction, false>::vector m_turn_instruction_list;
|
||||
util::ShM<LaneDataID, false>::vector m_lane_data_id;
|
||||
util::ShM<util::guidance::LaneTupelIdPair, false>::vector m_lane_tupel_id_pairs;
|
||||
util::ShM<extractor::TravelMode, false>::vector m_travel_mode_list;
|
||||
util::ShM<char, false>::vector m_names_char_list;
|
||||
util::ShM<char, false>::vector m_lanes_char_list;
|
||||
util::ShM<unsigned, false>::vector m_geometry_indices;
|
||||
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, false>::vector m_geometry_list;
|
||||
util::ShM<bool, false>::vector m_is_core_node;
|
||||
@ -93,6 +97,7 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
boost::filesystem::path ram_index_path;
|
||||
boost::filesystem::path file_index_path;
|
||||
util::RangeTable<16, false> m_name_table;
|
||||
util::RangeTable<16, false> m_lane_string_table;
|
||||
|
||||
// bearing classes by node based node
|
||||
util::ShM<BearingClassID, false>::vector m_bearing_class_id_table;
|
||||
@ -118,6 +123,20 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
sizeof(m_profile_properties));
|
||||
}
|
||||
|
||||
void LoadLaneTupelIdPairs(const boost::filesystem::path &lane_data_path)
|
||||
{
|
||||
boost::filesystem::ifstream in_stream(lane_data_path);
|
||||
if (!in_stream)
|
||||
{
|
||||
throw util::exception("Could not open " + lane_data_path.string() + " for reading.");
|
||||
}
|
||||
std::uint64_t size;
|
||||
in_stream.read(reinterpret_cast<char *>(&size), sizeof(size));
|
||||
m_lane_tupel_id_pairs.resize(size);
|
||||
in_stream.read(reinterpret_cast<char *>(&m_lane_tupel_id_pairs[0]),
|
||||
sizeof(m_lane_tupel_id_pairs) * size);
|
||||
}
|
||||
|
||||
void LoadTimestamp(const boost::filesystem::path ×tamp_path)
|
||||
{
|
||||
util::SimpleLogger().Write() << "Loading Timestamp";
|
||||
@ -173,6 +192,7 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
m_via_node_list.resize(number_of_edges);
|
||||
m_name_ID_list.resize(number_of_edges);
|
||||
m_turn_instruction_list.resize(number_of_edges);
|
||||
m_lane_data_id.resize(number_of_edges);
|
||||
m_travel_mode_list.resize(number_of_edges);
|
||||
m_entry_class_id_list.resize(number_of_edges);
|
||||
|
||||
@ -184,6 +204,7 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
m_via_node_list[i] = current_edge_data.via_node;
|
||||
m_name_ID_list[i] = current_edge_data.name_id;
|
||||
m_turn_instruction_list[i] = current_edge_data.turn_instruction;
|
||||
m_lane_data_id[i] = current_edge_data.lane_data_id;
|
||||
m_travel_mode_list[i] = current_edge_data.travel_mode;
|
||||
m_entry_class_id_list[i] = current_edge_data.entry_classid;
|
||||
}
|
||||
@ -284,6 +305,20 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
new InternalGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
|
||||
}
|
||||
|
||||
void LoadLaneStrings(const boost::filesystem::path &lane_string_file)
|
||||
{
|
||||
boost::filesystem::ifstream lane_stream(lane_string_file, std::ios::binary);
|
||||
|
||||
lane_stream >> m_lane_string_table;
|
||||
|
||||
unsigned number_of_chars = 0;
|
||||
lane_stream.read((char *)&number_of_chars, sizeof(unsigned));
|
||||
m_lanes_char_list.resize(number_of_chars + 1); //+1 gives sentinel element
|
||||
if( number_of_chars )
|
||||
lane_stream.read((char *)&m_lanes_char_list[0], number_of_chars * sizeof(char));
|
||||
m_lanes_char_list[number_of_chars] = '\0';
|
||||
}
|
||||
|
||||
void LoadStreetNames(const boost::filesystem::path &names_file)
|
||||
{
|
||||
boost::filesystem::ifstream name_stream(names_file, std::ios::binary);
|
||||
@ -386,11 +421,17 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
util::SimpleLogger().Write() << "loading street names";
|
||||
LoadStreetNames(config.names_data_path);
|
||||
|
||||
util::SimpleLogger().Write() << "loading lane tags";
|
||||
LoadLaneStrings(config.turn_lane_string_path);
|
||||
|
||||
util::SimpleLogger().Write() << "loading rtree";
|
||||
LoadRTree();
|
||||
|
||||
util::SimpleLogger().Write() << "loading intersection class data";
|
||||
LoadIntersectionClasses(config.intersection_class_path);
|
||||
|
||||
util::SimpleLogger().Write() << "Loading Lane Data Pairs";
|
||||
LoadLaneTupelIdPairs(config.turn_lane_data_path);
|
||||
}
|
||||
|
||||
// search graph access
|
||||
@ -741,6 +782,37 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
{
|
||||
return m_entry_class_table.at(entry_class_id);
|
||||
}
|
||||
|
||||
bool hasLaneData(const EdgeID id) const override final
|
||||
{
|
||||
return m_lane_data_id[id] != INVALID_LANE_DATAID;
|
||||
}
|
||||
|
||||
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const override final
|
||||
{
|
||||
BOOST_ASSERT(hasLaneData(id));
|
||||
return m_lane_tupel_id_pairs[m_lane_data_id[id]];
|
||||
}
|
||||
|
||||
std::string GetTurnStringForID(const LaneStringID lane_string_id) const override final
|
||||
{
|
||||
if (INVALID_LANE_STRINGID == lane_string_id)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
auto range = m_lane_string_table.GetRange(lane_string_id);
|
||||
|
||||
std::string result;
|
||||
result.reserve(range.size());
|
||||
if (range.begin() != range.end())
|
||||
{
|
||||
result.resize(range.back() - range.front() + 1);
|
||||
std::copy(m_lanes_char_list.begin() + range.front(),
|
||||
m_lanes_char_list.begin() + range.back() + 1,
|
||||
result.begin());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include "engine/geospatial_query.hpp"
|
||||
#include "util/make_unique.hpp"
|
||||
@ -79,10 +80,14 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
util::PackedVector<OSMNodeID, true> m_osmnodeid_list;
|
||||
util::ShM<NodeID, true>::vector m_via_node_list;
|
||||
util::ShM<unsigned, true>::vector m_name_ID_list;
|
||||
util::ShM<LaneDataID, true>::vector m_lane_data_id;
|
||||
util::ShM<extractor::guidance::TurnInstruction, true>::vector m_turn_instruction_list;
|
||||
util::ShM<extractor::TravelMode, true>::vector m_travel_mode_list;
|
||||
util::ShM<char, true>::vector m_names_char_list;
|
||||
util::ShM<char, true>::vector m_turn_string_char_list;
|
||||
util::ShM<unsigned, true>::vector m_name_begin_indices;
|
||||
util::ShM<char, true>::vector m_lane_string_char_list;
|
||||
util::ShM<unsigned, true>::vector m_lane_string_begin_indices;
|
||||
util::ShM<unsigned, true>::vector m_geometry_indices;
|
||||
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, true>::vector m_geometry_list;
|
||||
util::ShM<bool, true>::vector m_is_core_node;
|
||||
@ -91,12 +96,14 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
util::ShM<char, true>::vector m_datasource_name_data;
|
||||
util::ShM<std::size_t, true>::vector m_datasource_name_offsets;
|
||||
util::ShM<std::size_t, true>::vector m_datasource_name_lengths;
|
||||
util::ShM<util::guidance::LaneTupelIdPair, true>::vector m_lane_tupel_id_pairs;
|
||||
|
||||
std::unique_ptr<SharedRTree> m_static_rtree;
|
||||
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
|
||||
boost::filesystem::path file_index_path;
|
||||
|
||||
std::shared_ptr<util::RangeTable<16, true>> m_name_table;
|
||||
std::shared_ptr<util::RangeTable<16, true>> m_turn_string_table;
|
||||
|
||||
// bearing classes by node based node
|
||||
util::ShM<BearingClassID, true>::vector m_bearing_class_id_table;
|
||||
@ -186,6 +193,19 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
travel_mode_list_ptr, data_layout->num_entries[storage::SharedDataLayout::TRAVEL_MODE]);
|
||||
m_travel_mode_list = std::move(travel_mode_list);
|
||||
|
||||
auto lane_data_id_ptr = data_layout->GetBlockPtr<LaneDataID>(
|
||||
shared_memory, storage::SharedDataLayout::LANE_DATA_ID);
|
||||
util::ShM<LaneDataID, true>::vector lane_data_id(
|
||||
lane_data_id_ptr, data_layout->num_entries[storage::SharedDataLayout::LANE_DATA_ID]);
|
||||
m_lane_data_id = std::move(lane_data_id);
|
||||
|
||||
auto lane_tupel_id_pair_ptr = data_layout->GetBlockPtr<util::guidance::LaneTupelIdPair>(
|
||||
shared_memory, storage::SharedDataLayout::TURN_LANE_DATA);
|
||||
util::ShM<util::guidance::LaneTupelIdPair, true>::vector lane_tupel_id_pair(
|
||||
lane_tupel_id_pair_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::TURN_LANE_DATA]);
|
||||
m_lane_tupel_id_pairs = std::move(lane_tupel_id_pair);
|
||||
|
||||
auto turn_instruction_list_ptr =
|
||||
data_layout->GetBlockPtr<extractor::guidance::TurnInstruction>(
|
||||
shared_memory, storage::SharedDataLayout::TURN_INSTRUCTION);
|
||||
@ -238,6 +258,29 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
m_names_char_list = std::move(names_char_list);
|
||||
}
|
||||
|
||||
void LoadTurnLaneStrings()
|
||||
{
|
||||
auto offsets_ptr = data_layout->GetBlockPtr<unsigned>(
|
||||
shared_memory, storage::SharedDataLayout::TURN_STRING_OFFSETS);
|
||||
auto blocks_ptr = data_layout->GetBlockPtr<IndexBlock>(
|
||||
shared_memory, storage::SharedDataLayout::TURN_STRING_BLOCKS);
|
||||
util::ShM<unsigned, true>::vector turn_string_offsets(
|
||||
offsets_ptr, data_layout->num_entries[storage::SharedDataLayout::TURN_STRING_OFFSETS]);
|
||||
util::ShM<IndexBlock, true>::vector turn_string_blocks(
|
||||
blocks_ptr, data_layout->num_entries[storage::SharedDataLayout::TURN_STRING_BLOCKS]);
|
||||
|
||||
auto turn_strings_list_ptr = data_layout->GetBlockPtr<char>(
|
||||
shared_memory, storage::SharedDataLayout::TURN_STRING_CHAR_LIST);
|
||||
util::ShM<char, true>::vector turn_strings_char_list(
|
||||
turn_strings_list_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::TURN_STRING_CHAR_LIST]);
|
||||
m_turn_string_table = util::make_unique<util::RangeTable<16, true>>(
|
||||
turn_string_offsets,
|
||||
turn_string_blocks,
|
||||
static_cast<unsigned>(turn_strings_char_list.size()));
|
||||
|
||||
m_turn_string_char_list = std::move(turn_strings_char_list);
|
||||
}
|
||||
void LoadCoreInformation()
|
||||
{
|
||||
if (data_layout->num_entries[storage::SharedDataLayout::CORE_MARKER] <= 0)
|
||||
@ -416,6 +459,7 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
LoadTimestamp();
|
||||
LoadViaNodeList();
|
||||
LoadNames();
|
||||
LoadTurnLaneStrings();
|
||||
LoadCoreInformation();
|
||||
LoadProfileProperties();
|
||||
LoadRTree();
|
||||
@ -783,6 +827,37 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
{
|
||||
return m_entry_class_table.at(entry_class_id);
|
||||
}
|
||||
|
||||
bool hasLaneData(const EdgeID id) const override final
|
||||
{
|
||||
return INVALID_LANE_DATAID != m_lane_data_id.at(id);
|
||||
}
|
||||
|
||||
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const override final
|
||||
{
|
||||
BOOST_ASSERT(hasLaneData(id));
|
||||
return m_lane_tupel_id_pairs.at(m_lane_data_id.at(id));
|
||||
}
|
||||
|
||||
std::string GetTurnStringForID(const LaneStringID lane_string_id) const override final
|
||||
{
|
||||
if (INVALID_LANE_STRINGID == lane_string_id)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
auto range = m_turn_string_table->GetRange(lane_string_id);
|
||||
|
||||
std::string result;
|
||||
result.reserve(range.size());
|
||||
if (range.begin() != range.end())
|
||||
{
|
||||
result.resize(range.back() - range.front() + 1);
|
||||
std::copy(m_turn_string_char_list.begin() + range.front(),
|
||||
m_turn_string_char_list.begin() + range.back() + 1,
|
||||
result.begin());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
@ -70,7 +71,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
bearings.second,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Depart,
|
||||
0};
|
||||
0,
|
||||
util::guidance::LaneTupel(),
|
||||
""};
|
||||
Intersection intersection{source_node.location,
|
||||
std::vector<short>({bearings.second}),
|
||||
std::vector<bool>({true}),
|
||||
@ -147,7 +150,11 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
bearings.second,
|
||||
path_point.turn_instruction,
|
||||
WaypointType::None,
|
||||
0};
|
||||
0,
|
||||
path_point.lane_data.first,
|
||||
(path_point.lane_data.second != INVALID_LANE_STRINGID
|
||||
? facade.GetTurnStringForID(path_point.lane_data.second)
|
||||
: "")};
|
||||
segment_index++;
|
||||
segment_duration = 0;
|
||||
}
|
||||
@ -202,7 +209,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
bearings.second,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Arrive,
|
||||
0};
|
||||
0,
|
||||
util::guidance::LaneTupel(),
|
||||
""};
|
||||
intersection = {
|
||||
target_node.location,
|
||||
std::vector<short>({static_cast<short>(util::bearing::reverseBearing(bearings.first))}),
|
||||
@ -233,6 +242,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
BOOST_ASSERT(steps.back().intersections.front().bearings.size() == 1);
|
||||
BOOST_ASSERT(steps.back().intersections.front().entry.size() == 1);
|
||||
BOOST_ASSERT(steps.back().maneuver.waypoint_type == WaypointType::Arrive);
|
||||
BOOST_ASSERT(steps.back().maneuver.lanes.lanes_in_turn == 0);
|
||||
BOOST_ASSERT(steps.back().maneuver.lanes.first_lane_from_the_right == INVALID_LANEID);
|
||||
BOOST_ASSERT(steps.back().maneuver.turn_lane_string == "");
|
||||
return steps;
|
||||
}
|
||||
|
||||
|
24
include/engine/guidance/lane_processing.hpp
Normal file
24
include/engine/guidance/lane_processing.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
|
||||
#define OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
// Constrains lanes for multi-hop situations where lane changes depend on earlier ones.
|
||||
// Instead of forcing users to change lanes rapidly in a short amount of time,
|
||||
// we anticipate lane changes emitting only matching lanes early on.
|
||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps);
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
#endif /* OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_ */
|
@ -43,11 +43,6 @@ std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps);
|
||||
// remove steps invalidated by post-processing
|
||||
std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> steps);
|
||||
|
||||
// Constrains lanes for multi-hop situations where lane changes depend on earlier ones.
|
||||
// Instead of forcing users to change lanes rapidly in a short amount of time,
|
||||
// we anticipate lane changes emitting only matching lanes early on.
|
||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps);
|
||||
|
||||
// postProcess will break the connection between the leg geometry
|
||||
// for which a segment is supposed to represent exactly the coordinates
|
||||
// between routing maneuvers and the route steps itself.
|
||||
|
@ -3,8 +3,10 @@
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
@ -27,8 +29,12 @@ struct StepManeuver
|
||||
short bearing_before;
|
||||
short bearing_after;
|
||||
extractor::guidance::TurnInstruction instruction;
|
||||
|
||||
WaypointType waypoint_type;
|
||||
unsigned exit;
|
||||
|
||||
util::guidance::LaneTupel lanes;
|
||||
std::string turn_lane_string;
|
||||
};
|
||||
|
||||
inline StepManeuver getInvalidStepManeuver()
|
||||
@ -38,7 +44,9 @@ inline StepManeuver getInvalidStepManeuver()
|
||||
0,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::None,
|
||||
0};
|
||||
0,
|
||||
util::guidance::LaneTupel(),
|
||||
""};
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
|
@ -4,9 +4,9 @@
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "osrm/coordinate.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -27,6 +27,8 @@ struct PathData
|
||||
EdgeWeight duration_until_turn;
|
||||
// instruction to execute at the turn
|
||||
extractor::guidance::TurnInstruction turn_instruction;
|
||||
// turn lane data
|
||||
util::guidance::LaneTupelIdPair lane_data;
|
||||
// travel mode of the street that leads to the turn
|
||||
extractor::TravelMode travel_mode : 4;
|
||||
// entry class of the turn, indicating possibility of turns
|
||||
|
@ -327,10 +327,14 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
||||
name_index,
|
||||
weight_vector[i],
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
{{0, INVALID_LANEID}, INVALID_LANE_STRINGID},
|
||||
travel_mode,
|
||||
INVALID_ENTRY_CLASSID});
|
||||
}
|
||||
BOOST_ASSERT(unpacked_path.size() > 0);
|
||||
if (facade->hasLaneData(ed.id))
|
||||
unpacked_path.back().lane_data = facade->GetLaneData(ed.id);
|
||||
|
||||
unpacked_path.back().entry_classid = facade->GetEntryClassID(ed.id);
|
||||
unpacked_path.back().turn_instruction = turn_instruction;
|
||||
unpacked_path.back().duration_until_turn += (ed.distance - total_weight);
|
||||
@ -389,6 +393,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
||||
phantom_node_pair.target_phantom.name_id,
|
||||
weight_vector[i],
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
{{0, INVALID_LANEID}, INVALID_LANE_STRINGID},
|
||||
target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode
|
||||
: phantom_node_pair.target_phantom.forward_travel_mode,
|
||||
INVALID_ENTRY_CLASSID});
|
||||
|
@ -59,6 +59,7 @@ class EdgeBasedGraphFactory
|
||||
const util::NameTable &turn_lanes);
|
||||
|
||||
void Run(const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
lua_State *lua_state,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_penalty_filename,
|
||||
@ -124,6 +125,7 @@ class EdgeBasedGraphFactory
|
||||
unsigned RenumberEdges();
|
||||
void GenerateEdgeExpandedNodes();
|
||||
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
lua_State *lua_state,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_fixed_penalties_filename,
|
||||
|
@ -2,8 +2,8 @@
|
||||
#define EXTRACTION_WAY_HPP
|
||||
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -61,7 +61,8 @@ struct ExtractorConfig
|
||||
output_file_name = basepath + ".osrm";
|
||||
restriction_file_name = basepath + ".osrm.restrictions";
|
||||
names_file_name = basepath + ".osrm.names";
|
||||
turn_lane_file_name = basepath + ".osrm.tld";
|
||||
turn_lane_strings_file_name = basepath + ".osrm.tls";
|
||||
turn_lane_data_file_name = basepath + ".osrm.tld";
|
||||
timestamp_file_name = basepath + ".osrm.timestamp";
|
||||
geometry_output_path = basepath + ".osrm.geometry";
|
||||
node_output_path = basepath + ".osrm.nodes";
|
||||
@ -83,7 +84,8 @@ struct ExtractorConfig
|
||||
std::string output_file_name;
|
||||
std::string restriction_file_name;
|
||||
std::string names_file_name;
|
||||
std::string turn_lane_file_name;
|
||||
std::string turn_lane_data_file_name;
|
||||
std::string turn_lane_strings_file_name;
|
||||
std::string timestamp_file_name;
|
||||
std::string geometry_output_path;
|
||||
std::string edge_output_path;
|
||||
|
@ -22,6 +22,7 @@ struct TurnOperation final
|
||||
EdgeID eid;
|
||||
double angle;
|
||||
TurnInstruction instruction;
|
||||
LaneDataID lane_data_id;
|
||||
};
|
||||
|
||||
// A Connected Road is the internal representation of a potential turn. Internally, we require
|
||||
|
@ -5,9 +5,9 @@
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/restriction_map.hpp"
|
||||
#include "util/name_table.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
#include "util/name_table.hpp"
|
||||
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
@ -20,10 +22,12 @@
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@ -32,6 +36,9 @@ namespace extractor
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
using util::guidance::LaneTupelIdPair;
|
||||
using LaneDataIdMap = std::unordered_map<LaneTupelIdPair, LaneDataID, boost::hash<LaneTupelIdPair>>;
|
||||
|
||||
using util::guidance::angularDeviation;
|
||||
|
||||
namespace detail
|
||||
|
@ -77,16 +77,14 @@ struct TurnInstruction
|
||||
{
|
||||
using LaneTupel = util::guidance::LaneTupel;
|
||||
TurnInstruction(const TurnType::Enum type = TurnType::Invalid,
|
||||
const DirectionModifier::Enum direction_modifier = DirectionModifier::Straight,
|
||||
const LaneTupel lane_tupel = {0, INVALID_LANEID})
|
||||
: type(type), direction_modifier(direction_modifier), lane_tupel(lane_tupel)
|
||||
const DirectionModifier::Enum direction_modifier = DirectionModifier::UTurn)
|
||||
: type(type), direction_modifier(direction_modifier)
|
||||
{
|
||||
}
|
||||
|
||||
TurnType::Enum type : 5;
|
||||
DirectionModifier::Enum direction_modifier : 3;
|
||||
// the lane tupel that is used for the turn
|
||||
LaneTupel lane_tupel;
|
||||
|
||||
static TurnInstruction INVALID() { return {TurnType::Invalid, DirectionModifier::UTurn}; }
|
||||
|
||||
@ -147,18 +145,16 @@ struct TurnInstruction
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(TurnInstruction) == 3, "TurnInstruction does not fit three byte");
|
||||
static_assert(sizeof(TurnInstruction) == 1, "TurnInstruction does not fit a byte");
|
||||
|
||||
inline bool operator!=(const TurnInstruction lhs, const TurnInstruction rhs)
|
||||
{
|
||||
return lhs.type != rhs.type || lhs.direction_modifier != rhs.direction_modifier ||
|
||||
lhs.lane_tupel != rhs.lane_tupel;
|
||||
return lhs.type != rhs.type || lhs.direction_modifier != rhs.direction_modifier;
|
||||
}
|
||||
|
||||
inline bool operator==(const TurnInstruction lhs, const TurnInstruction rhs)
|
||||
{
|
||||
return lhs.type == rhs.type && lhs.direction_modifier == rhs.direction_modifier &&
|
||||
lhs.lane_tupel == rhs.lane_tupel;
|
||||
return lhs.type == rhs.type && lhs.direction_modifier == rhs.direction_modifier;
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_HANDLER_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
#include "extractor/guidance/turn_analysis.hpp"
|
||||
#include "extractor/guidance/turn_lane_data.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
@ -13,7 +14,6 @@
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -38,13 +38,12 @@ class TurnLaneHandler
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const TurnAnalysis &turn_analysis);
|
||||
|
||||
Intersection
|
||||
assignTurnLanes(const NodeID at, const EdgeID via_edge, Intersection intersection) const;
|
||||
Intersection assignTurnLanes(const NodeID at,
|
||||
const EdgeID via_edge,
|
||||
Intersection intersection,
|
||||
LaneDataIdMap &id_map) const;
|
||||
|
||||
private:
|
||||
using LaneTupel = util::guidance::LaneTupel;
|
||||
std::unordered_map<LaneTupel, std::uint16_t> lane_tupels;
|
||||
|
||||
// we need to be able to look at previous intersections to, in some cases, find the correct turn
|
||||
// lanes for a turn
|
||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||
@ -58,7 +57,9 @@ class TurnLaneHandler
|
||||
|
||||
// in case of a simple intersection, assign the lane entries
|
||||
Intersection simpleMatchTuplesToTurns(Intersection intersection,
|
||||
const LaneDataVector &lane_data) const;
|
||||
const LaneDataVector &lane_data,
|
||||
const LaneStringID lane_string_id,
|
||||
LaneDataIdMap &id_map) const;
|
||||
|
||||
// partition lane data into lane data relevant at current turn and at next turn
|
||||
std::pair<TurnLaneHandler::LaneDataVector, TurnLaneHandler::LaneDataVector> partitionLaneData(
|
||||
@ -68,7 +69,8 @@ class TurnLaneHandler
|
||||
// intersection whose turns might be related to this current intersection
|
||||
Intersection handleTurnAtPreviousIntersection(const NodeID at,
|
||||
const EdgeID via_edge,
|
||||
Intersection intersection) const;
|
||||
Intersection intersection,
|
||||
LaneDataIdMap &id_map) const;
|
||||
};
|
||||
|
||||
} // namespace lanes
|
||||
|
@ -2,12 +2,15 @@
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_MATCHER_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_data.hpp"
|
||||
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
@ -44,7 +47,9 @@ bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &l
|
||||
// perform a trivial match on the turn lanes
|
||||
Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
||||
const LaneDataVector &lane_data,
|
||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const LaneStringID lane_string_id,
|
||||
LaneDataIdMap &lane_data_to_id);
|
||||
|
||||
} // namespace lanes
|
||||
} // namespace guidance
|
||||
|
@ -90,8 +90,8 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
|
||||
guidance::RoadClassificationData road_classification)
|
||||
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
|
||||
backward(backward), roundabout(roundabout), access_restricted(access_restricted),
|
||||
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode), lane_string_id(lane_string_id),
|
||||
road_classification(std::move(road_classification))
|
||||
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode),
|
||||
lane_string_id(lane_string_id), road_classification(std::move(road_classification))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -17,18 +17,19 @@ struct OriginalEdgeData
|
||||
{
|
||||
explicit OriginalEdgeData(NodeID via_node,
|
||||
unsigned name_id,
|
||||
LaneDataID lane_data_id,
|
||||
guidance::TurnInstruction turn_instruction,
|
||||
EntryClassID entry_classid,
|
||||
TravelMode travel_mode)
|
||||
: via_node(via_node), name_id(name_id), entry_classid(entry_classid),
|
||||
turn_instruction(turn_instruction), travel_mode(travel_mode)
|
||||
lane_data_id(lane_data_id), turn_instruction(turn_instruction), travel_mode(travel_mode)
|
||||
{
|
||||
}
|
||||
|
||||
OriginalEdgeData()
|
||||
: via_node(std::numeric_limits<unsigned>::max()),
|
||||
name_id(std::numeric_limits<unsigned>::max()), entry_classid(INVALID_ENTRY_CLASSID),
|
||||
turn_instruction(guidance::TurnInstruction::INVALID()),
|
||||
lane_data_id(INVALID_LANE_DATAID), turn_instruction(guidance::TurnInstruction::INVALID()),
|
||||
travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
||||
{
|
||||
}
|
||||
@ -36,9 +37,13 @@ struct OriginalEdgeData
|
||||
NodeID via_node;
|
||||
unsigned name_id;
|
||||
EntryClassID entry_classid;
|
||||
LaneDataID lane_data_id;
|
||||
guidance::TurnInstruction turn_instruction;
|
||||
TravelMode travel_mode;
|
||||
};
|
||||
|
||||
static_assert(sizeof(OriginalEdgeData) == 16,
|
||||
"Increasing the size of OriginalEdgeData increases memory consumption");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,41 @@ namespace storage
|
||||
// Added at the start and end of each block as sanity check
|
||||
const constexpr char CANARY[4] = {'O', 'S', 'R', 'M'};
|
||||
|
||||
const constexpr char *block_id_to_name[] = {"NAME_OFFSETS",
|
||||
"NAME_BLOCKS",
|
||||
"NAME_CHAR_LIST",
|
||||
"NAME_ID_LIST",
|
||||
"VIA_NODE_LIST",
|
||||
"GRAPH_NODE_LIST",
|
||||
"GRAPH_EDGE_LIST",
|
||||
"COORDINATE_LIST",
|
||||
"OSM_NODE_ID_LIST",
|
||||
"TURN_INSTRUCTION",
|
||||
"TRAVEL_MODE",
|
||||
"ENTRY_CLASSID",
|
||||
"R_SEARCH_TREE",
|
||||
"GEOMETRIES_INDEX",
|
||||
"GEOMETRIES_LIST",
|
||||
"HSGR_CHECKSUM",
|
||||
"TIMESTAMP",
|
||||
"FILE_INDEX_PATH",
|
||||
"CORE_MARKER",
|
||||
"DATASOURCES_LIST",
|
||||
"DATASOURCE_NAME_DATA",
|
||||
"DATASOURCE_NAME_OFFSETS",
|
||||
"DATASOURCE_NAME_LENGTHS",
|
||||
"PROPERTIES",
|
||||
"BEARING_CLASSID",
|
||||
"BEARING_OFFSETS",
|
||||
"BEARING_BLOCKS",
|
||||
"BEARING_VALUES",
|
||||
"ENTRY_CLASS",
|
||||
"LANE_DATA_ID",
|
||||
"TURN_LANE_DATA",
|
||||
"TURN_STRING_OFFSETS",
|
||||
"TURN_STRING_BLOCKS",
|
||||
"TURN_STRING_CHAR_LIST"};
|
||||
|
||||
struct SharedDataLayout
|
||||
{
|
||||
enum BlockID
|
||||
@ -30,8 +65,8 @@ struct SharedDataLayout
|
||||
COORDINATE_LIST,
|
||||
OSM_NODE_ID_LIST,
|
||||
TURN_INSTRUCTION,
|
||||
ENTRY_CLASSID,
|
||||
TRAVEL_MODE,
|
||||
ENTRY_CLASSID,
|
||||
R_SEARCH_TREE,
|
||||
GEOMETRIES_INDEX,
|
||||
GEOMETRIES_LIST,
|
||||
@ -49,6 +84,11 @@ struct SharedDataLayout
|
||||
BEARING_BLOCKS,
|
||||
BEARING_VALUES,
|
||||
ENTRY_CLASS,
|
||||
LANE_DATA_ID,
|
||||
TURN_LANE_DATA,
|
||||
TURN_STRING_OFFSETS,
|
||||
TURN_STRING_BLOCKS,
|
||||
TURN_STRING_CHAR_LIST,
|
||||
NUM_BLOCKS
|
||||
};
|
||||
|
||||
@ -113,11 +153,13 @@ struct SharedDataLayout
|
||||
bool end_canary_alive = std::equal(CANARY, CANARY + sizeof(CANARY), end_canary_ptr);
|
||||
if (!start_canary_alive)
|
||||
{
|
||||
throw util::exception("Start canary of block corrupted.");
|
||||
throw util::exception(std::string("Start canary of block corrupted. (") +
|
||||
block_id_to_name[bid] + ")");
|
||||
}
|
||||
if (!end_canary_alive)
|
||||
{
|
||||
throw util::exception("End canary of block corrupted.");
|
||||
throw util::exception(std::string("End canary of block corrupted. (") +
|
||||
block_id_to_name[bid] + ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,8 @@ struct StorageConfig final
|
||||
boost::filesystem::path names_data_path;
|
||||
boost::filesystem::path properties_path;
|
||||
boost::filesystem::path intersection_class_path;
|
||||
boost::filesystem::path turn_lane_data_path;
|
||||
boost::filesystem::path turn_lane_string_path;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -65,21 +65,18 @@ class LaneTupel
|
||||
LaneID lanes_in_turn;
|
||||
LaneID first_lane_from_the_right;
|
||||
|
||||
friend std::size_t std::hash<LaneTupel>::operator()(const LaneTupel &) const;
|
||||
friend std::size_t hash_value(const LaneTupel &tup)
|
||||
{
|
||||
std::size_t seed{0};
|
||||
boost::hash_combine(seed, tup.lanes_in_turn);
|
||||
boost::hash_combine(seed, tup.first_lane_from_the_right);
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
using LaneTupelIdPair = std::pair<util::guidance::LaneTupel, LaneStringID>;
|
||||
} // namespace guidance
|
||||
} // namespace util
|
||||
} // namespace osrm
|
||||
|
||||
// make Bearing Class hasbable
|
||||
namespace std
|
||||
{
|
||||
inline size_t hash<::osrm::util::guidance::LaneTupel>::
|
||||
operator()(const ::osrm::util::guidance::LaneTupel &lane_tupel) const
|
||||
{
|
||||
return boost::hash_value(*reinterpret_cast<const std::uint16_t *>(&lane_tupel));
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
#endif /* OSRM_UTIL_GUIDANCE_TURN_LANES_HPP */
|
||||
|
@ -20,7 +20,8 @@ struct NodeBasedEdgeData
|
||||
NodeBasedEdgeData()
|
||||
: distance(INVALID_EDGE_WEIGHT), edge_id(SPECIAL_NODEID),
|
||||
name_id(std::numeric_limits<unsigned>::max()), access_restricted(false), reversed(false),
|
||||
roundabout(false), travel_mode(TRAVEL_MODE_INACCESSIBLE), lane_string_id(INVALID_LANE_STRINGID)
|
||||
roundabout(false), travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
||||
lane_string_id(INVALID_LANE_STRINGID)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -60,9 +60,11 @@ using NameID = std::uint32_t;
|
||||
using EdgeWeight = std::int32_t;
|
||||
|
||||
using LaneStringID = std::uint16_t;
|
||||
static const LaneStringID INVALID_LANE_STRINGID = std::numeric_limits<LaneStringID>::max();
|
||||
using LaneID = std::uint8_t;
|
||||
static const LaneID INVALID_LANEID = std::numeric_limits<LaneID>::max();
|
||||
static const LaneStringID INVALID_LANE_STRINGID = std::numeric_limits<LaneStringID>::max();
|
||||
using LaneDataID = std::uint16_t;
|
||||
static const LaneDataID INVALID_LANE_DATAID = std::numeric_limits<LaneStringID>::max();
|
||||
|
||||
using BearingClassID = std::uint32_t;
|
||||
static const BearingClassID INVALID_BEARING_CLASSID = std::numeric_limits<BearingClassID>::max();
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
@ -63,7 +64,7 @@ inline bool isValidModifier(const guidance::StepManeuver maneuver)
|
||||
|
||||
inline bool hasValidLanes(const guidance::StepManeuver maneuver)
|
||||
{
|
||||
return maneuver.instruction.lane_tupel.lanes_in_turn > 0;
|
||||
return maneuver.lanes.lanes_in_turn > 0;
|
||||
}
|
||||
|
||||
std::string instructionTypeToString(const TurnType::Enum type)
|
||||
@ -71,12 +72,31 @@ std::string instructionTypeToString(const TurnType::Enum type)
|
||||
return turn_type_names[static_cast<std::size_t>(type)];
|
||||
}
|
||||
|
||||
util::json::Array laneArrayFromLaneTupe(const util::guidance::LaneTupel lane_tupel)
|
||||
util::json::Array lanesFromManeuver(const guidance::StepManeuver &maneuver)
|
||||
{
|
||||
BOOST_ASSERT(lane_tupel.lanes_in_turn >= 1);
|
||||
BOOST_ASSERT(maneuver.lanes.lanes_in_turn >= 1);
|
||||
util::json::Array result;
|
||||
for (LaneID i = 0; i < lane_tupel.lanes_in_turn; ++i)
|
||||
result.values.push_back(lane_tupel.first_lane_from_the_right + i);
|
||||
LaneID lane_id = 0;
|
||||
typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
|
||||
boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
|
||||
tokenizer tokens(maneuver.turn_lane_string, sep);
|
||||
|
||||
lane_id = std::distance(tokens.begin(), tokens.end());
|
||||
|
||||
for (auto iter = tokens.begin(); iter != tokens.end(); ++iter)
|
||||
{
|
||||
--lane_id;
|
||||
util::json::Object lane;
|
||||
lane.values["marked"] = (iter->empty() ? "none" : *iter);
|
||||
if (lane_id >= maneuver.lanes.first_lane_from_the_right &&
|
||||
lane_id < maneuver.lanes.first_lane_from_the_right + maneuver.lanes.lanes_in_turn)
|
||||
lane.values["take"] = util::json::True();
|
||||
else
|
||||
lane.values["take"] = util::json::False();
|
||||
|
||||
result.values.push_back(lane);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -162,8 +182,7 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
|
||||
detail::instructionModifierToString(maneuver.instruction.direction_modifier);
|
||||
|
||||
if (detail::hasValidLanes(maneuver))
|
||||
step_maneuver.values["lanes"] =
|
||||
detail::laneArrayFromLaneTupe(maneuver.instruction.lane_tupel);
|
||||
step_maneuver.values["lanes"] = detail::lanesFromManeuver(maneuver);
|
||||
|
||||
step_maneuver.values["location"] = detail::coordinateToLonLat(maneuver.location);
|
||||
step_maneuver.values["bearing_before"] = std::round(maneuver.bearing_before);
|
||||
|
111
src/engine/guidance/lane_processing.cpp
Normal file
111
src/engine/guidance/lane_processing.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include "util/for_each_pair.hpp"
|
||||
#include "util/group_by.hpp"
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
using TurnInstruction = osrm::extractor::guidance::TurnInstruction;
|
||||
namespace TurnType = osrm::extractor::guidance::TurnType;
|
||||
namespace DirectionModifier = osrm::extractor::guidance::DirectionModifier;
|
||||
|
||||
using osrm::util::guidance::isLeftTurn;
|
||||
using osrm::util::guidance::isRightTurn;
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps)
|
||||
{
|
||||
const constexpr auto MIN_DURATION_NEEDED_FOR_LANE_CHANGE = 15.;
|
||||
|
||||
// Postprocessing does not strictly guarantee for only turns
|
||||
const auto is_turn = [](const RouteStep &step) {
|
||||
return step.maneuver.instruction.type != TurnType::NewName &&
|
||||
step.maneuver.instruction.type != TurnType::Notification;
|
||||
};
|
||||
|
||||
const auto is_quick = [MIN_DURATION_NEEDED_FOR_LANE_CHANGE](const RouteStep &step) {
|
||||
return step.duration < MIN_DURATION_NEEDED_FOR_LANE_CHANGE;
|
||||
};
|
||||
|
||||
const auto is_quick_turn = [&](const RouteStep &step) {
|
||||
return is_turn(step) && is_quick(step);
|
||||
};
|
||||
|
||||
// Determine range of subsequent quick turns, candidates for possible lane anticipation
|
||||
using StepIter = decltype(steps)::iterator;
|
||||
using StepIterRange = std::pair<StepIter, StepIter>;
|
||||
|
||||
std::vector<StepIterRange> subsequent_quick_turns;
|
||||
|
||||
const auto keep_turn_range = [&](StepIterRange range) {
|
||||
if (std::distance(range.first, range.second) > 1)
|
||||
subsequent_quick_turns.push_back(std::move(range));
|
||||
};
|
||||
|
||||
util::group_by(begin(steps), end(steps), is_quick_turn, keep_turn_range);
|
||||
|
||||
// Walk backwards over all turns, constraining possible turn lanes.
|
||||
// Later turn lanes constrain earlier ones: we have to anticipate lane changes.
|
||||
const auto constrain_lanes = [](const StepIterRange &turns) {
|
||||
const std::reverse_iterator<StepIter> rev_first{turns.second};
|
||||
const std::reverse_iterator<StepIter> rev_last{turns.first};
|
||||
|
||||
// We're walking backwards over all adjacent turns:
|
||||
// the current turn lanes constrain the lanes we have to take in the previous turn.
|
||||
util::for_each_pair(rev_first, rev_last, [](RouteStep ¤t, RouteStep &previous) {
|
||||
const auto current_inst = current.maneuver.instruction;
|
||||
const auto current_lanes = current.maneuver.lanes;
|
||||
|
||||
// Constrain the previous turn's lanes
|
||||
auto &previous_inst = previous.maneuver.instruction;
|
||||
auto &previous_lanes = previous.maneuver.lanes;
|
||||
// Lane mapping (N:M) from previous lanes (N) to current lanes (M), with:
|
||||
// N > M, N > 1 fan-in situation, constrain N lanes to min(N,M) shared lanes
|
||||
// otherwise nothing to constrain
|
||||
const bool lanes_to_constrain = previous_lanes.lanes_in_turn > 1;
|
||||
const bool lanes_fan_in = previous_lanes.lanes_in_turn > current_lanes.lanes_in_turn;
|
||||
|
||||
if (!lanes_to_constrain || !lanes_fan_in)
|
||||
return;
|
||||
|
||||
// In case there is no lane information we work with one artificial lane
|
||||
const auto current_adjusted_lanes = std::max(current_lanes.lanes_in_turn, LaneID{1});
|
||||
|
||||
const auto num_shared_lanes = std::min(current_adjusted_lanes, //
|
||||
previous_lanes.lanes_in_turn);
|
||||
|
||||
if (isRightTurn(current_inst))
|
||||
{
|
||||
// Current turn is right turn, already keep right during the previous turn.
|
||||
// This implies constraining the leftmost lanes in the previous turn step.
|
||||
previous_lanes = {num_shared_lanes, previous_lanes.first_lane_from_the_right};
|
||||
}
|
||||
else if (isLeftTurn(current_inst))
|
||||
{
|
||||
// Current turn is left turn, already keep left during previous turn.
|
||||
// This implies constraining the rightmost lanes in the previous turn step.
|
||||
const LaneID shared_lane_delta = previous_lanes.lanes_in_turn - num_shared_lanes;
|
||||
const LaneID previous_adjusted_lanes =
|
||||
std::min(current_adjusted_lanes, shared_lane_delta);
|
||||
const LaneID constraint_first_lane_from_the_right =
|
||||
previous_lanes.first_lane_from_the_right + previous_adjusted_lanes;
|
||||
|
||||
previous_lanes = {num_shared_lanes, constraint_first_lane_from_the_right};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
std::for_each(begin(subsequent_quick_turns), end(subsequent_quick_turns), constrain_lanes);
|
||||
return steps;
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
@ -4,9 +4,8 @@
|
||||
#include "engine/guidance/assemble_steps.hpp"
|
||||
#include "engine/guidance/toolkit.hpp"
|
||||
|
||||
#include "util/for_each_pair.hpp"
|
||||
#include "util/group_by.hpp"
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/range/algorithm_ext/erase.hpp>
|
||||
@ -15,7 +14,6 @@
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
||||
@ -24,8 +22,6 @@ namespace TurnType = osrm::extractor::guidance::TurnType;
|
||||
namespace DirectionModifier = osrm::extractor::guidance::DirectionModifier;
|
||||
using osrm::util::guidance::angularDeviation;
|
||||
using osrm::util::guidance::getTurnDirection;
|
||||
using osrm::util::guidance::isLeftTurn;
|
||||
using osrm::util::guidance::isRightTurn;
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@ -867,6 +863,8 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
||||
designated_depart.maneuver.instruction = TurnInstruction::NO_TURN();
|
||||
// we need to make this conform with the intersection format for the first intersection
|
||||
auto &first_intersection = designated_depart.intersections.front();
|
||||
designated_depart.maneuver.lanes = util::guidance::LaneTupel();
|
||||
designated_depart.maneuver.turn_lane_string = "";
|
||||
first_intersection.bearings = {first_intersection.bearings[first_intersection.out]};
|
||||
first_intersection.entry = {true};
|
||||
first_intersection.in = Intersection::NO_INDEX;
|
||||
@ -933,6 +931,8 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
||||
next_to_last_step.maneuver.waypoint_type = WaypointType::Arrive;
|
||||
next_to_last_step.maneuver.instruction = TurnInstruction::NO_TURN();
|
||||
next_to_last_step.maneuver.bearing_after = 0;
|
||||
next_to_last_step.maneuver.lanes = util::guidance::LaneTupel();
|
||||
next_to_last_step.maneuver.turn_lane_string = "";
|
||||
BOOST_ASSERT(next_to_last_step.intersections.size() == 1);
|
||||
auto &last_intersection = next_to_last_step.intersections.back();
|
||||
last_intersection.bearings = {last_intersection.bearings[last_intersection.in]};
|
||||
@ -1038,94 +1038,6 @@ std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps,
|
||||
return steps;
|
||||
}
|
||||
|
||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps)
|
||||
{
|
||||
const constexpr auto MIN_DURATION_NEEDED_FOR_LANE_CHANGE = 15.;
|
||||
|
||||
// Postprocessing does not strictly guarantee for only turns
|
||||
const auto is_turn = [](const RouteStep &step) {
|
||||
return step.maneuver.instruction.type != TurnType::NewName &&
|
||||
step.maneuver.instruction.type != TurnType::Notification;
|
||||
};
|
||||
|
||||
const auto is_quick = [](const RouteStep &step) {
|
||||
return step.duration < MIN_DURATION_NEEDED_FOR_LANE_CHANGE;
|
||||
};
|
||||
|
||||
const auto is_quick_turn = [&](const RouteStep &step) {
|
||||
return is_turn(step) && is_quick(step);
|
||||
};
|
||||
|
||||
// Determine range of subsequent quick turns, candidates for possible lane anticipation
|
||||
using StepIter = decltype(steps)::iterator;
|
||||
using StepIterRange = std::pair<StepIter, StepIter>;
|
||||
|
||||
std::vector<StepIterRange> subsequent_quick_turns;
|
||||
|
||||
const auto keep_turn_range = [&](StepIterRange range) {
|
||||
if (std::distance(range.first, range.second) > 1)
|
||||
subsequent_quick_turns.push_back(std::move(range));
|
||||
};
|
||||
|
||||
util::group_by(begin(steps), end(steps), is_quick_turn, keep_turn_range);
|
||||
|
||||
// Walk backwards over all turns, constraining possible turn lanes.
|
||||
// Later turn lanes constrain earlier ones: we have to anticipate lane changes.
|
||||
const auto constrain_lanes = [](const StepIterRange &turns) {
|
||||
const std::reverse_iterator<StepIter> rev_first{turns.second};
|
||||
const std::reverse_iterator<StepIter> rev_last{turns.first};
|
||||
|
||||
// We're walking backwards over all adjacent turns:
|
||||
// the current turn lanes constrain the lanes we have to take in the previous turn.
|
||||
util::for_each_pair(rev_first, rev_last, [](RouteStep ¤t, RouteStep &previous) {
|
||||
const auto current_inst = current.maneuver.instruction;
|
||||
const auto current_lanes = current_inst.lane_tupel;
|
||||
|
||||
// Constrain the previous turn's lanes
|
||||
auto &previous_inst = previous.maneuver.instruction;
|
||||
auto &previous_lanes = previous_inst.lane_tupel;
|
||||
|
||||
// Lane mapping (N:M) from previous lanes (N) to current lanes (M), with:
|
||||
// N > M, N > 1 fan-in situation, constrain N lanes to min(N,M) shared lanes
|
||||
// otherwise nothing to constrain
|
||||
const bool lanes_to_constrain = previous_lanes.lanes_in_turn > 1;
|
||||
const bool lanes_fan_in = previous_lanes.lanes_in_turn > current_lanes.lanes_in_turn;
|
||||
|
||||
if (!lanes_to_constrain || !lanes_fan_in)
|
||||
return;
|
||||
|
||||
// In case there is no lane information we work with one artificial lane
|
||||
const auto current_adjusted_lanes = std::max(current_lanes.lanes_in_turn, LaneID{1});
|
||||
|
||||
const auto num_shared_lanes = std::min(current_adjusted_lanes, //
|
||||
previous_lanes.lanes_in_turn);
|
||||
|
||||
if (isRightTurn(current_inst))
|
||||
{
|
||||
// Current turn is right turn, already keep right during the previous turn.
|
||||
// This implies constraining the leftmost lanes in the previous turn step.
|
||||
previous_lanes = {num_shared_lanes, previous_lanes.first_lane_from_the_right};
|
||||
}
|
||||
else if (isLeftTurn(current_inst))
|
||||
{
|
||||
// Current turn is left turn, already keep left during previous turn.
|
||||
// This implies constraining the rightmost lanes in the previous turn step.
|
||||
const LaneID shared_lane_delta = previous_lanes.lanes_in_turn - num_shared_lanes;
|
||||
const LaneID previous_adjusted_lanes =
|
||||
std::min(current_adjusted_lanes, shared_lane_delta);
|
||||
const LaneID constraint_first_lane_from_the_right =
|
||||
previous_lanes.first_lane_from_the_right + previous_adjusted_lanes;
|
||||
|
||||
previous_lanes = {num_shared_lanes, constraint_first_lane_from_the_right};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
std::for_each(begin(subsequent_quick_turns), end(subsequent_quick_turns), constrain_lanes);
|
||||
|
||||
return steps;
|
||||
}
|
||||
|
||||
LegGeometry resyncGeometry(LegGeometry leg_geometry, const std::vector<RouteStep> &steps)
|
||||
{
|
||||
// The geometry uses an adjacency array-like structure for representation.
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "extractor/edge_based_graph_factory.hpp"
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/exception.hpp"
|
||||
@ -182,6 +182,7 @@ void EdgeBasedGraphFactory::FlushVectorToStream(
|
||||
}
|
||||
|
||||
void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
lua_State *lua_state,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_penalty_filename,
|
||||
@ -198,6 +199,7 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
|
||||
|
||||
TIMER_START(generate_edges);
|
||||
GenerateEdgeExpandedEdges(original_edge_data_filename,
|
||||
turn_lane_data_filename,
|
||||
lua_state,
|
||||
edge_segment_lookup_filename,
|
||||
edge_penalty_filename,
|
||||
@ -296,6 +298,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
|
||||
/// Actually it also generates OriginalEdgeData and serializes them...
|
||||
void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
lua_State *lua_state,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_fixed_penalties_filename,
|
||||
@ -348,6 +351,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
bearing_class_by_node_based_node.resize(m_node_based_graph->GetNumberOfNodes(),
|
||||
std::numeric_limits<std::uint32_t>::max());
|
||||
|
||||
guidance::LaneDataIdMap lane_data_map;
|
||||
for (const auto node_u : util::irange(0u, m_node_based_graph->GetNumberOfNodes()))
|
||||
{
|
||||
progress.PrintStatus(node_u);
|
||||
@ -364,8 +368,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
intersection =
|
||||
turn_analysis.assignTurnTypes(node_u, edge_from_u, std::move(intersection));
|
||||
|
||||
intersection =
|
||||
turn_lane_handler.assignTurnLanes(node_u, edge_from_u, std::move(intersection));
|
||||
intersection = turn_lane_handler.assignTurnLanes(
|
||||
node_u, edge_from_u, std::move(intersection), lane_data_map);
|
||||
const auto possible_turns = turn_analysis.transformIntersectionIntoTurns(intersection);
|
||||
|
||||
// the entry class depends on the turn, so we have to classify the interesction for
|
||||
@ -437,6 +441,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
original_edge_data_vector.emplace_back(
|
||||
m_compressed_edge_container.GetPositionForID(edge_from_u),
|
||||
edge_data1.name_id,
|
||||
turn.lane_data_id,
|
||||
turn_instruction,
|
||||
entry_class_id,
|
||||
edge_data1.travel_mode);
|
||||
@ -541,6 +546,22 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
util::SimpleLogger().Write() << "Created " << entry_class_hash.size() << " entry classes and "
|
||||
<< bearing_class_hash.size() << " Bearing Classes";
|
||||
|
||||
util::SimpleLogger().Write() << "Writing Turn Lane Data to File...";
|
||||
std::ofstream turn_lane_data_file(turn_lane_data_filename.c_str(), std::ios::binary);
|
||||
std::vector<util::guidance::LaneTupelIdPair> lane_data(lane_data_map.size());
|
||||
// extract lane data sorted by ID
|
||||
for (auto itr : lane_data_map)
|
||||
lane_data[itr.second] = itr.first;
|
||||
|
||||
std::uint64_t size = lane_data.size();
|
||||
turn_lane_data_file.write(reinterpret_cast<const char *>(&size), sizeof(size));
|
||||
|
||||
if (!lane_data.empty())
|
||||
turn_lane_data_file.write(reinterpret_cast<const char *>(&lane_data[0]),
|
||||
sizeof(util::guidance::LaneTupelIdPair) * lane_data.size());
|
||||
|
||||
util::SimpleLogger().Write() << "done.";
|
||||
|
||||
FlushVectorToStream(edge_data_file, original_edge_data_vector);
|
||||
|
||||
// Finally jump back to the empty space at the beginning and write length prefix
|
||||
|
@ -51,8 +51,6 @@ ExtractionContainers::ExtractionContainers()
|
||||
name_lengths.push_back(0);
|
||||
name_lengths.push_back(0);
|
||||
name_lengths.push_back(0);
|
||||
name_lengths.push_back(0);
|
||||
name_lengths.push_back(0);
|
||||
turn_lane_lengths.push_back(0);
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ int Extractor::run()
|
||||
extraction_containers.PrepareData(config.output_file_name,
|
||||
config.restriction_file_name,
|
||||
config.names_file_name,
|
||||
config.turn_lane_file_name,
|
||||
config.turn_lane_strings_file_name,
|
||||
main_context.state);
|
||||
|
||||
WriteProfileProperties(config.profile_properties_output_path, main_context.properties);
|
||||
@ -504,7 +504,7 @@ Extractor::BuildEdgeExpandedGraph(lua_State *lua_state,
|
||||
compressed_edge_container.SerializeInternalVector(config.geometry_output_path);
|
||||
|
||||
util::NameTable name_table(config.names_file_name);
|
||||
util::NameTable turn_lanes(config.turn_lane_file_name);
|
||||
util::NameTable turn_lanes(config.turn_lane_strings_file_name);
|
||||
|
||||
EdgeBasedGraphFactory edge_based_graph_factory(
|
||||
node_based_graph,
|
||||
@ -518,6 +518,7 @@ Extractor::BuildEdgeExpandedGraph(lua_State *lua_state,
|
||||
turn_lanes);
|
||||
|
||||
edge_based_graph_factory.Run(config.edge_output_path,
|
||||
config.turn_lane_data_file_name,
|
||||
lua_state,
|
||||
config.edge_segment_lookup_path,
|
||||
config.edge_penalty_path,
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "extractor/extractor_callbacks.hpp"
|
||||
#include "extractor/extraction_containers.hpp"
|
||||
#include "extractor/extraction_node.hpp"
|
||||
#include "extractor/extraction_way.hpp"
|
||||
#include "extractor/extractor_callbacks.hpp"
|
||||
|
||||
#include "extractor/external_memory_node.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
@ -149,9 +149,17 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
// Otherwise fetches the id based on the name and returns it without insertion.
|
||||
|
||||
const constexpr auto MAX_STRING_LENGTH = 255u;
|
||||
const auto requestId = [this,MAX_STRING_LENGTH](const std::string turn_lane_string) {
|
||||
if( turn_lane_string == "" )
|
||||
const auto requestId = [this, MAX_STRING_LENGTH](const std::string &turn_lane_string_) {
|
||||
if (turn_lane_string_ == "")
|
||||
return INVALID_LANE_STRINGID;
|
||||
|
||||
// requires https://github.com/cucumber/cucumber-js/issues/417
|
||||
// remove this handling when the issue is contained
|
||||
std::string turn_lane_string = turn_lane_string_;
|
||||
for (auto &val : turn_lane_string)
|
||||
if (val == '&')
|
||||
val = '|';
|
||||
|
||||
const auto &lane_map_iterator = lane_map.find(turn_lane_string);
|
||||
if (lane_map.end() == lane_map_iterator)
|
||||
{
|
||||
|
@ -168,10 +168,10 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
return front;
|
||||
return back;
|
||||
};
|
||||
graph.GetEdgeData(forward_e1).lane_string_id =
|
||||
selectLaneID(graph.GetEdgeData(forward_e1).lane_string_id, fwd_edge_data2.lane_string_id);
|
||||
graph.GetEdgeData(reverse_e1).lane_string_id =
|
||||
selectLaneID(graph.GetEdgeData(reverse_e1).lane_string_id, rev_edge_data2.lane_string_id);
|
||||
graph.GetEdgeData(forward_e1).lane_string_id = selectLaneID(
|
||||
graph.GetEdgeData(forward_e1).lane_string_id, fwd_edge_data2.lane_string_id);
|
||||
graph.GetEdgeData(reverse_e1).lane_string_id = selectLaneID(
|
||||
graph.GetEdgeData(reverse_e1).lane_string_id, rev_edge_data2.lane_string_id);
|
||||
|
||||
// remove e2's (if bidir, otherwise only one)
|
||||
graph.DeleteEdge(node_v, forward_e2);
|
||||
|
@ -22,12 +22,9 @@ std::string toString(const ConnectedRoad &road)
|
||||
result += " angle: ";
|
||||
result += std::to_string(road.turn.angle);
|
||||
result += " instruction: ";
|
||||
result +=
|
||||
std::to_string(static_cast<std::int32_t>(road.turn.instruction.type)) + " " +
|
||||
std::to_string(static_cast<std::int32_t>(road.turn.instruction.direction_modifier)) + " " +
|
||||
std::to_string(static_cast<std::int32_t>(road.turn.instruction.lane_tupel.lanes_in_turn)) +
|
||||
" " + std::to_string(static_cast<std::int32_t>(
|
||||
road.turn.instruction.lane_tupel.first_lane_from_the_right));
|
||||
result += std::to_string(static_cast<std::int32_t>(road.turn.instruction.type)) + " " +
|
||||
std::to_string(static_cast<std::int32_t>(road.turn.instruction.direction_modifier)) +
|
||||
" " + std::to_string(static_cast<std::int32_t>(road.turn.lane_data_id));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "extractor/guidance/constants.hpp"
|
||||
#include "extractor/guidance/intersection_generator.hpp"
|
||||
#include "extractor/guidance/constants.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@ -114,8 +114,11 @@ Intersection IntersectionGenerator::getConnectedRoads(const NodeID from_node,
|
||||
has_uturn_edge = true;
|
||||
}
|
||||
|
||||
intersection.push_back(ConnectedRoad(
|
||||
TurnOperation{onto_edge, angle, {TurnType::Invalid, DirectionModifier::UTurn}},
|
||||
intersection.push_back(
|
||||
ConnectedRoad(TurnOperation{onto_edge,
|
||||
angle,
|
||||
{TurnType::Invalid, DirectionModifier::UTurn},
|
||||
INVALID_LANE_DATAID},
|
||||
turn_is_valid));
|
||||
}
|
||||
|
||||
@ -124,7 +127,9 @@ Intersection IntersectionGenerator::getConnectedRoads(const NodeID from_node,
|
||||
if (!has_uturn_edge)
|
||||
{
|
||||
intersection.push_back(
|
||||
{TurnOperation{via_eid, 0., {TurnType::Invalid, DirectionModifier::UTurn}}, false});
|
||||
{TurnOperation{
|
||||
via_eid, 0., {TurnType::Invalid, DirectionModifier::UTurn}, INVALID_LANE_DATAID},
|
||||
false});
|
||||
}
|
||||
|
||||
const auto ByAngle = [](const ConnectedRoad &first, const ConnectedRoad second) {
|
||||
|
@ -377,7 +377,8 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
|
||||
turn.instruction = TurnInstruction::NO_TURN();
|
||||
else
|
||||
{
|
||||
turn.instruction.type = TurnType::Suppressed; //make sure to report intersection
|
||||
turn.instruction.type =
|
||||
TurnType::Suppressed; // make sure to report intersection
|
||||
turn.instruction.direction_modifier = getTurnDirection(turn.angle);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "extractor/guidance/constants.hpp"
|
||||
#include "extractor/guidance/turn_discovery.hpp"
|
||||
#include "extractor/guidance/constants.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
|
@ -2,9 +2,9 @@
|
||||
#include "util/simple_logger.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@ -171,7 +171,6 @@ LaneDataVector handleRenamingSituations(const std::size_t none_index,
|
||||
has_left |= modifier == DirectionModifier::SharpLeft;
|
||||
}
|
||||
|
||||
|
||||
// find missing tag and augment neighboring, if possible
|
||||
if (none_index == 0)
|
||||
{
|
||||
|
@ -52,8 +52,7 @@ LaneDataVector laneDataFromString(std::string turn_lane_string)
|
||||
// count the number of lanes
|
||||
const auto num_lanes = [](const std::string &turn_lane_string) {
|
||||
return boost::numeric_cast<LaneID>(
|
||||
std::count(turn_lane_string.begin(), turn_lane_string.end(), '|') + 1 +
|
||||
std::count(turn_lane_string.begin(), turn_lane_string.end(), '&'));
|
||||
std::count(turn_lane_string.begin(), turn_lane_string.end(), '|') + 1);
|
||||
}(turn_lane_string);
|
||||
|
||||
const auto getNextTag = [](std::string &string, const char *separators) {
|
||||
@ -103,7 +102,7 @@ LaneDataVector laneDataFromString(std::string turn_lane_string)
|
||||
// FIXME this is a cucumber workaround, since escaping does not work properly in
|
||||
// cucumber.js (see https://github.com/cucumber/cucumber-js/issues/417). Needs to be
|
||||
// changed to "|" only, when the bug is fixed
|
||||
auto lane = getNextTag(turn_lane_string, "|&");
|
||||
auto lane = getNextTag(turn_lane_string, "|");
|
||||
setLaneData(lane_map, lane, lane_nr);
|
||||
++lane_nr;
|
||||
} while (lane_nr < num_lanes);
|
||||
@ -135,7 +134,8 @@ LaneDataVector::const_iterator findTag(const std::string &tag, const LaneDataVec
|
||||
});
|
||||
}
|
||||
|
||||
bool hasTag(const std::string &tag, const LaneDataVector &data){
|
||||
bool hasTag(const std::string &tag, const LaneDataVector &data)
|
||||
{
|
||||
return findTag(tag, data) != data.cend();
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "extractor/guidance/turn_lane_handler.hpp"
|
||||
#include "extractor/guidance/constants.hpp"
|
||||
#include "extractor/guidance/turn_discovery.hpp"
|
||||
#include "extractor/guidance/turn_lane_handler.hpp"
|
||||
#include "extractor/guidance/turn_lane_matcher.hpp"
|
||||
#include "extractor/guidance/turn_lane_augmentation.hpp"
|
||||
#include "extractor/guidance/turn_lane_matcher.hpp"
|
||||
#include "util/simple_logger.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
@ -58,11 +58,9 @@ TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_g
|
||||
*/
|
||||
Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
|
||||
const EdgeID via_edge,
|
||||
Intersection intersection) const
|
||||
Intersection intersection,
|
||||
LaneDataIdMap &id_map) const
|
||||
{
|
||||
// initialize to invalid
|
||||
for (auto &road : intersection)
|
||||
road.turn.instruction.lane_tupel = {0, INVALID_LANEID};
|
||||
const auto &data = node_based_graph.GetEdgeData(via_edge);
|
||||
const auto turn_lane_string = data.lane_string_id != INVALID_LANE_STRINGID
|
||||
? turn_lane_strings.GetNameForID(data.lane_string_id)
|
||||
@ -89,17 +87,15 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
|
||||
const std::size_t possible_entries = getNumberOfTurns(intersection);
|
||||
|
||||
// merge does not justify an instruction
|
||||
const bool has_merge_lane = (hasTag("merge_to_left", lane_data) ||
|
||||
hasTag("merge_to_right", lane_data));
|
||||
const bool has_merge_lane =
|
||||
(hasTag("merge_to_left", lane_data) || hasTag("merge_to_right", lane_data));
|
||||
|
||||
// Dead end streets that don't have any left-tag. This can happen due to the fallbacks for
|
||||
// broken data/barriers.
|
||||
const bool has_non_usable_u_turn =
|
||||
(intersection[0].entry_allowed && !hasTag("none", lane_data) &&
|
||||
!hasTag("left", lane_data) &&
|
||||
!hasTag("sharp_left", lane_data) &&
|
||||
!hasTag("reverse", lane_data) &&
|
||||
lane_data.size() + 1 == possible_entries);
|
||||
!hasTag("left", lane_data) && !hasTag("sharp_left", lane_data) &&
|
||||
!hasTag("reverse", lane_data) && lane_data.size() + 1 == possible_entries);
|
||||
|
||||
if (has_merge_lane || has_non_usable_u_turn)
|
||||
return std::move(intersection);
|
||||
@ -118,7 +114,8 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
|
||||
if (is_simple)
|
||||
{
|
||||
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
|
||||
return simpleMatchTuplesToTurns(std::move(intersection), lane_data);
|
||||
return simpleMatchTuplesToTurns(
|
||||
std::move(intersection), lane_data, data.lane_string_id, id_map);
|
||||
}
|
||||
// if the intersection is not simple but we have lane data, we check for intersections with
|
||||
// middle islands. We have two cases. The first one is providing lane data on the current
|
||||
@ -138,7 +135,8 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
|
||||
isSimpleIntersection(lane_data, intersection))
|
||||
{
|
||||
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
|
||||
return simpleMatchTuplesToTurns(std::move(intersection), lane_data);
|
||||
return simpleMatchTuplesToTurns(
|
||||
std::move(intersection), lane_data, data.lane_string_id, id_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -148,7 +146,7 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
|
||||
{
|
||||
// acquire the lane data of a previous segment and, if possible, use it for the current
|
||||
// intersection.
|
||||
return handleTurnAtPreviousIntersection(at, via_edge, std::move(intersection));
|
||||
return handleTurnAtPreviousIntersection(at, via_edge, std::move(intersection), id_map);
|
||||
}
|
||||
|
||||
return std::move(intersection);
|
||||
@ -158,7 +156,8 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
|
||||
// actually take the turn, we need to look back to the edge we drove onto the intersection with.
|
||||
Intersection TurnLaneHandler::handleTurnAtPreviousIntersection(const NodeID at,
|
||||
const EdgeID via_edge,
|
||||
Intersection intersection) const
|
||||
Intersection intersection,
|
||||
LaneDataIdMap &id_map) const
|
||||
{
|
||||
NodeID previous_node = SPECIAL_NODEID;
|
||||
Intersection previous_intersection;
|
||||
@ -176,6 +175,7 @@ Intersection TurnLaneHandler::handleTurnAtPreviousIntersection(const NodeID at,
|
||||
previous_id,
|
||||
previous_intersection))
|
||||
return "";
|
||||
BOOST_ASSERT(previous_id != SPECIAL_EDGEID);
|
||||
|
||||
const auto &previous_data = node_based_graph.GetEdgeData(previous_id);
|
||||
auto previous_string = previous_data.lane_string_id != INVALID_LANE_STRINGID
|
||||
@ -204,11 +204,13 @@ Intersection TurnLaneHandler::handleTurnAtPreviousIntersection(const NodeID at,
|
||||
if (lane_data.empty())
|
||||
return std::move(intersection);
|
||||
|
||||
const auto &previous_data = node_based_graph.GetEdgeData(previous_id);
|
||||
const auto is_simple = isSimpleIntersection(lane_data, intersection);
|
||||
if (is_simple)
|
||||
{
|
||||
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
|
||||
return simpleMatchTuplesToTurns(std::move(intersection), lane_data);
|
||||
return simpleMatchTuplesToTurns(
|
||||
std::move(intersection), lane_data, previous_data.lane_string_id, id_map);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -227,14 +229,14 @@ Intersection TurnLaneHandler::handleTurnAtPreviousIntersection(const NodeID at,
|
||||
isSimpleIntersection(lane_data, intersection))
|
||||
{
|
||||
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
|
||||
return simpleMatchTuplesToTurns(std::move(intersection), lane_data);
|
||||
return simpleMatchTuplesToTurns(
|
||||
std::move(intersection), lane_data, previous_data.lane_string_id, id_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::move(intersection);
|
||||
}
|
||||
|
||||
|
||||
/* A simple intersection does not depend on the next intersection coming up. This is important
|
||||
* for turn lanes, since traffic signals and/or segregated a intersection can influence the
|
||||
* interpretation of turn-lanes at a given turn.
|
||||
@ -486,7 +488,9 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
|
||||
}
|
||||
|
||||
Intersection TurnLaneHandler::simpleMatchTuplesToTurns(Intersection intersection,
|
||||
const LaneDataVector &lane_data) const
|
||||
const LaneDataVector &lane_data,
|
||||
const LaneStringID lane_string_id,
|
||||
LaneDataIdMap &id_map) const
|
||||
{
|
||||
if (lane_data.empty() || !canMatchTrivially(intersection, lane_data))
|
||||
return std::move(intersection);
|
||||
@ -496,7 +500,8 @@ Intersection TurnLaneHandler::simpleMatchTuplesToTurns(Intersection intersection
|
||||
return boost::starts_with(data.tag, "merge");
|
||||
}) == 0);
|
||||
|
||||
return triviallyMatchLanesToTurns(std::move(intersection), lane_data, node_based_graph);
|
||||
return triviallyMatchLanesToTurns(
|
||||
std::move(intersection), lane_data, node_based_graph, lane_string_id, id_map);
|
||||
}
|
||||
|
||||
} // namespace lanes
|
||||
|
@ -1,8 +1,11 @@
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
#include "extractor/guidance/turn_lane_matcher.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@ -169,9 +172,27 @@ bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &l
|
||||
|
||||
Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
||||
const LaneDataVector &lane_data,
|
||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const LaneStringID lane_string_id,
|
||||
LaneDataIdMap &lane_data_to_id)
|
||||
{
|
||||
std::size_t road_index = 1, lane = 0;
|
||||
|
||||
const auto matchRoad = [&](ConnectedRoad &road, const TurnLaneData &data) {
|
||||
LaneTupelIdPair key{{LaneID(data.to - data.from + 1), data.from}, lane_string_id};
|
||||
|
||||
auto lane_data_id = boost::numeric_cast<LaneDataID>(lane_data_to_id.size());
|
||||
const auto it = lane_data_to_id.find(key);
|
||||
|
||||
if (it == lane_data_to_id.end())
|
||||
lane_data_to_id.insert({key, lane_data_id});
|
||||
else
|
||||
lane_data_id = it->second;
|
||||
|
||||
// set lane id instead after the switch:
|
||||
road.turn.lane_data_id = lane_data_id;
|
||||
};
|
||||
|
||||
for (; road_index < intersection.size() && lane < lane_data.size(); ++road_index)
|
||||
{
|
||||
if (intersection[road_index].entry_allowed)
|
||||
@ -185,8 +206,7 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
||||
if (TurnType::Suppressed == intersection[road_index].turn.instruction.type)
|
||||
intersection[road_index].turn.instruction.type = TurnType::UseLane;
|
||||
|
||||
intersection[road_index].turn.instruction.lane_tupel = {
|
||||
LaneID(lane_data[lane].to - lane_data[lane].from + 1), lane_data[lane].from};
|
||||
matchRoad(intersection[road_index], lane_data[lane]);
|
||||
++lane;
|
||||
}
|
||||
}
|
||||
@ -209,8 +229,8 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
||||
intersection[u_turn].entry_allowed = true;
|
||||
intersection[u_turn].turn.instruction.type = TurnType::Turn;
|
||||
intersection[u_turn].turn.instruction.direction_modifier = DirectionModifier::UTurn;
|
||||
intersection[u_turn].turn.instruction.lane_tupel = {
|
||||
LaneID(lane_data.back().to - lane_data.back().from + 1), lane_data.back().from};
|
||||
|
||||
matchRoad(intersection[u_turn], lane_data.back());
|
||||
}
|
||||
return std::move(intersection);
|
||||
}
|
||||
|
@ -147,6 +147,26 @@ int Storage::Run()
|
||||
name_stream.read((char *)&number_of_chars, sizeof(unsigned));
|
||||
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::NAME_CHAR_LIST, number_of_chars);
|
||||
|
||||
boost::filesystem::ifstream turn_string_stream(config.turn_lane_string_path, std::ios::binary);
|
||||
if (!turn_string_stream)
|
||||
{
|
||||
throw util::exception("Could not open " + config.turn_lane_string_path.string() +
|
||||
" for reading.");
|
||||
}
|
||||
|
||||
unsigned turn_string_blocks = 0;
|
||||
turn_string_stream.read((char *)&turn_string_blocks, sizeof(unsigned));
|
||||
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::TURN_STRING_OFFSETS,
|
||||
turn_string_blocks);
|
||||
shared_layout_ptr->SetBlockSize<typename util::RangeTable<16, true>::BlockT>(
|
||||
SharedDataLayout::TURN_STRING_BLOCKS, turn_string_blocks);
|
||||
BOOST_ASSERT_MSG(0 != turn_string_blocks, "turn string file broken");
|
||||
|
||||
unsigned number_of_turn_string_chars = 0;
|
||||
turn_string_stream.read((char *)&number_of_turn_string_chars, sizeof(unsigned));
|
||||
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::TURN_STRING_CHAR_LIST,
|
||||
number_of_turn_string_chars);
|
||||
|
||||
// Loading information for original edges
|
||||
boost::filesystem::ifstream edges_input_stream(config.edges_data_path, std::ios::binary);
|
||||
if (!edges_input_stream)
|
||||
@ -166,6 +186,8 @@ int Storage::Run()
|
||||
number_of_original_edges);
|
||||
shared_layout_ptr->SetBlockSize<extractor::guidance::TurnInstruction>(
|
||||
SharedDataLayout::TURN_INSTRUCTION, number_of_original_edges);
|
||||
shared_layout_ptr->SetBlockSize<LaneDataID>(SharedDataLayout::LANE_DATA_ID,
|
||||
number_of_original_edges);
|
||||
shared_layout_ptr->SetBlockSize<EntryClassID>(SharedDataLayout::ENTRY_CLASSID,
|
||||
number_of_original_edges);
|
||||
|
||||
@ -368,6 +390,14 @@ int Storage::Run()
|
||||
sizeof(bearing_class_table[0]) * num_bearings);
|
||||
shared_layout_ptr->SetBlockSize<DiscreteBearing>(SharedDataLayout::BEARING_VALUES,
|
||||
num_bearings);
|
||||
|
||||
// Loading turn lane data
|
||||
boost::filesystem::ifstream lane_data_stream(config.turn_lane_data_path, std::ios::binary);
|
||||
std::uint64_t lane_tupel_count = 0;
|
||||
lane_data_stream.read(reinterpret_cast<char *>(&lane_tupel_count), sizeof(lane_tupel_count));
|
||||
shared_layout_ptr->SetBlockSize<util::guidance::LaneTupelIdPair>(
|
||||
SharedDataLayout::TURN_LANE_DATA, lane_tupel_count);
|
||||
|
||||
if (!static_cast<bool>(intersection_stream))
|
||||
throw util::exception("Failed to read bearing values from " +
|
||||
config.intersection_class_path.string());
|
||||
@ -436,9 +466,54 @@ int Storage::Run()
|
||||
name_stream.read(name_char_ptr,
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_CHAR_LIST));
|
||||
}
|
||||
|
||||
name_stream.close();
|
||||
|
||||
// Loading turn lane strings
|
||||
unsigned *turn_string_offsets_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
|
||||
shared_memory_ptr, SharedDataLayout::TURN_STRING_OFFSETS);
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_STRING_OFFSETS) > 0)
|
||||
{
|
||||
turn_string_stream.read(
|
||||
(char *)turn_string_offsets_ptr,
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_STRING_OFFSETS));
|
||||
}
|
||||
|
||||
// make sure do write canary...
|
||||
auto *turn_lane_data_ptr =
|
||||
shared_layout_ptr->GetBlockPtr<util::guidance::LaneTupelIdPair, true>(
|
||||
shared_memory_ptr, SharedDataLayout::TURN_LANE_DATA);
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_LANE_DATA) > 0)
|
||||
{
|
||||
lane_data_stream.read(reinterpret_cast<char *>(turn_lane_data_ptr),
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_LANE_DATA));
|
||||
}
|
||||
lane_data_stream.close();
|
||||
|
||||
unsigned *turn_string_blocks_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
|
||||
shared_memory_ptr, SharedDataLayout::TURN_STRING_BLOCKS);
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_STRING_BLOCKS) > 0)
|
||||
{
|
||||
turn_string_stream.read(
|
||||
(char *)turn_string_blocks_ptr,
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_STRING_BLOCKS));
|
||||
}
|
||||
|
||||
char *turn_string_char_ptr = shared_layout_ptr->GetBlockPtr<char, true>(
|
||||
shared_memory_ptr, SharedDataLayout::TURN_STRING_CHAR_LIST);
|
||||
turn_string_stream.read((char *)&temp_length, sizeof(unsigned));
|
||||
|
||||
BOOST_ASSERT_MSG(temp_length ==
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_STRING_CHAR_LIST),
|
||||
"turn string file corrupted!");
|
||||
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_STRING_CHAR_LIST) > 0)
|
||||
{
|
||||
turn_string_stream.read(
|
||||
turn_string_char_ptr,
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_STRING_CHAR_LIST));
|
||||
}
|
||||
turn_string_stream.close();
|
||||
|
||||
// load original edge information
|
||||
NodeID *via_node_ptr = shared_layout_ptr->GetBlockPtr<NodeID, true>(
|
||||
shared_memory_ptr, SharedDataLayout::VIA_NODE_LIST);
|
||||
@ -450,6 +525,9 @@ int Storage::Run()
|
||||
shared_layout_ptr->GetBlockPtr<extractor::TravelMode, true>(shared_memory_ptr,
|
||||
SharedDataLayout::TRAVEL_MODE);
|
||||
|
||||
LaneDataID *lane_data_id_ptr = shared_layout_ptr->GetBlockPtr<LaneDataID, true>(
|
||||
shared_memory_ptr, SharedDataLayout::LANE_DATA_ID);
|
||||
|
||||
extractor::guidance::TurnInstruction *turn_instructions_ptr =
|
||||
shared_layout_ptr->GetBlockPtr<extractor::guidance::TurnInstruction, true>(
|
||||
shared_memory_ptr, SharedDataLayout::TURN_INSTRUCTION);
|
||||
@ -464,6 +542,7 @@ int Storage::Run()
|
||||
via_node_ptr[i] = current_edge_data.via_node;
|
||||
name_id_ptr[i] = current_edge_data.name_id;
|
||||
travel_mode_ptr[i] = current_edge_data.travel_mode;
|
||||
lane_data_id_ptr[i] = current_edge_data.lane_data_id;
|
||||
turn_instructions_ptr[i] = current_edge_data.turn_instruction;
|
||||
entry_class_id_ptr[i] = current_edge_data.entry_classid;
|
||||
}
|
||||
@ -514,7 +593,8 @@ int Storage::Run()
|
||||
shared_memory_ptr, SharedDataLayout::DATASOURCE_NAME_DATA);
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::DATASOURCE_NAME_DATA) > 0)
|
||||
{
|
||||
std::cout << "Copying " << (m_datasource_name_data.end() - m_datasource_name_data.begin())
|
||||
util::SimpleLogger().Write()
|
||||
<< "Copying " << (m_datasource_name_data.end() - m_datasource_name_data.begin())
|
||||
<< " chars into name data ptr\n";
|
||||
std::copy(
|
||||
m_datasource_name_data.begin(), m_datasource_name_data.end(), datasource_name_data_ptr);
|
||||
|
@ -16,7 +16,8 @@ StorageConfig::StorageConfig(const boost::filesystem::path &base)
|
||||
datasource_names_path{base.string() + ".datasource_names"},
|
||||
datasource_indexes_path{base.string() + ".datasource_indexes"},
|
||||
names_data_path{base.string() + ".names"}, properties_path{base.string() + ".properties"},
|
||||
intersection_class_path{base.string() + ".icd"}
|
||||
intersection_class_path{base.string() + ".icd"}, turn_lane_data_path{base.string() + ".tld"},
|
||||
turn_lane_string_path{base.string() + ".tls"}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,7 @@ namespace util
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
LaneTupel::LaneTupel()
|
||||
: lanes_in_turn(0), first_lane_from_the_right(INVALID_LANEID)
|
||||
LaneTupel::LaneTupel() : lanes_in_turn(0), first_lane_from_the_right(INVALID_LANEID)
|
||||
{
|
||||
// basic constructor, set everything to zero
|
||||
}
|
||||
|
@ -36,11 +36,13 @@ NameTable::NameTable(const std::string &filename)
|
||||
}
|
||||
else
|
||||
{
|
||||
util::SimpleLogger().Write(logINFO) << "list of street names is empty in construction of name table from: \"" << filename << "\"";
|
||||
util::SimpleLogger().Write(logINFO)
|
||||
<< "list of street names is empty in construction of name table from: \"" << filename
|
||||
<< "\"";
|
||||
}
|
||||
if (!name_stream)
|
||||
throw exception("Failed to read " + std::to_string(number_of_chars) +
|
||||
" characters from " + filename);
|
||||
throw exception("Failed to read " + std::to_string(number_of_chars) + " characters from " +
|
||||
filename);
|
||||
}
|
||||
|
||||
std::string NameTable::GetNameForID(const unsigned name_id) const
|
||||
|
@ -30,14 +30,94 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
||||
|
||||
std::vector<InputEdge> edges = {
|
||||
// src, tgt, dist, edge_id, name_id, access_restricted, fwd, bkwd, roundabout, travel_mode
|
||||
{0, 1, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{1, 0, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{1, 2, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{2, 1, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{2, 3, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{3, 2, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{3, 4, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{4, 3, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID}};
|
||||
{0,
|
||||
1,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{1,
|
||||
0,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{1,
|
||||
2,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{2,
|
||||
1,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{2,
|
||||
3,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{3,
|
||||
2,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{3,
|
||||
4,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{4,
|
||||
3,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID}};
|
||||
|
||||
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[2].data));
|
||||
BOOST_ASSERT(edges[2].data.IsCompatibleTo(edges[4].data));
|
||||
@ -69,18 +149,138 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
||||
|
||||
std::vector<InputEdge> edges = {
|
||||
// src, tgt, dist, edge_id, name_id, access_restricted, fwd, bkwd, roundabout, travel_mode
|
||||
{0, 1, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{0, 5, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{1, 0, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{1, 2, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{2, 1, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{2, 3, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{3, 2, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{3, 4, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{4, 3, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{4, 5, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{5, 0, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{5, 4, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{0,
|
||||
1,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{0,
|
||||
5,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{1,
|
||||
0,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{1,
|
||||
2,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{2,
|
||||
1,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{2,
|
||||
3,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{3,
|
||||
2,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{3,
|
||||
4,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{4,
|
||||
3,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{4,
|
||||
5,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{5,
|
||||
0,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{5,
|
||||
4,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
};
|
||||
|
||||
BOOST_ASSERT(edges.size() == 12);
|
||||
@ -124,12 +324,72 @@ BOOST_AUTO_TEST_CASE(t_intersection)
|
||||
|
||||
std::vector<InputEdge> edges = {
|
||||
// src, tgt, dist, edge_id, name_id, access_restricted, fwd, bkwd, roundabout, travel_mode
|
||||
{0, 1, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{1, 0, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{1, 2, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{1, 3, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{2, 1, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{3, 1, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{0,
|
||||
1,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{1,
|
||||
0,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{1,
|
||||
2,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{1,
|
||||
3,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{2,
|
||||
1,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{3,
|
||||
1,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
};
|
||||
|
||||
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[1].data));
|
||||
@ -160,10 +420,50 @@ BOOST_AUTO_TEST_CASE(street_name_changes)
|
||||
|
||||
std::vector<InputEdge> edges = {
|
||||
// src, tgt, dist, edge_id, name_id, access_restricted, fwd, bkwd, roundabout, travel_mode
|
||||
{0, 1, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{1, 0, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{1, 2, 1, SPECIAL_EDGEID, 1, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{2, 1, 1, SPECIAL_EDGEID, 1, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{0,
|
||||
1,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{1,
|
||||
0,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{1,
|
||||
2,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
1,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{2,
|
||||
1,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
1,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
};
|
||||
|
||||
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[1].data));
|
||||
@ -190,10 +490,50 @@ BOOST_AUTO_TEST_CASE(direction_changes)
|
||||
|
||||
std::vector<InputEdge> edges = {
|
||||
// src, tgt, dist, edge_id, name_id, access_restricted, fwd, bkwd, roundabout, travel_mode
|
||||
{0, 1, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{1, 0, 1, SPECIAL_EDGEID, 0, false, true, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{1, 2, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{2, 1, 1, SPECIAL_EDGEID, 0, false, false, false, true, TRAVEL_MODE_INACCESSIBLE,INVALID_LANE_STRINGID},
|
||||
{0,
|
||||
1,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{1,
|
||||
0,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{1,
|
||||
2,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
{2,
|
||||
1,
|
||||
1,
|
||||
SPECIAL_EDGEID,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_STRINGID},
|
||||
};
|
||||
|
||||
Graph graph(5, edges);
|
||||
|
@ -180,6 +180,10 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade
|
||||
BearingClassID GetBearingClassID(const NodeID /*id*/) const override { return 0; };
|
||||
EntryClassID GetEntryClassID(const EdgeID /*id*/) const override { return 0; }
|
||||
|
||||
bool hasLaneData(const EdgeID /*id*/) const { return true; };
|
||||
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID /*id*/) const { return {{0, 0}, 0}; }
|
||||
std::string GetTurnStringForID(const LaneStringID /*lane_string_id*/) const { return ""; };
|
||||
|
||||
util::guidance::BearingClass
|
||||
GetBearingClass(const BearingClassID /*bearing_class_id*/) const override
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user