expose lanes as enums, adjusted for comments
This commit is contained in:
parent
5d91b759d1
commit
5905708111
@ -2,7 +2,7 @@
|
|||||||
Language: Cpp
|
Language: Cpp
|
||||||
# BasedOnStyle: LLVM
|
# BasedOnStyle: LLVM
|
||||||
AccessModifierOffset: -2
|
AccessModifierOffset: -2
|
||||||
AlignAfterOpenBracket: true
|
AlignAfterOpenBracket: Align
|
||||||
AlignConsecutiveAssignments: false
|
AlignConsecutiveAssignments: false
|
||||||
AlignConsecutiveDeclarations: false
|
AlignConsecutiveDeclarations: false
|
||||||
AlignEscapedNewlinesLeft: false
|
AlignEscapedNewlinesLeft: false
|
||||||
|
70
docs/http.md
70
docs/http.md
@ -437,16 +437,11 @@ 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)|
|
| 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.
|
- `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.
|
- `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.
|
- `destinations`: The destinations of the way. Will be `undefined` if there are no destinations.
|
||||||
- `mode`: A string signifying the mode of transportation.
|
- `mode`: A string signifying the mode of transportation.
|
||||||
- `maneuver`: A `StepManeuver` object representing the maneuver.
|
- `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
|
- `intersections`: A list of `Intersection` objects 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
|
#### Example
|
||||||
|
|
||||||
@ -455,23 +450,20 @@ Currently, the supported lane tags are: `sharp_left, left, slight_left, sharp_ri
|
|||||||
"distance":152.3,
|
"distance":152.3,
|
||||||
"duration":15.6,
|
"duration":15.6,
|
||||||
"name":"Lortzingstraße",
|
"name":"Lortzingstraße",
|
||||||
"lanes":{
|
|
||||||
{"marked":"left",
|
|
||||||
"take":"false"},
|
|
||||||
{"marked":"right",
|
|
||||||
"take":"true"}
|
|
||||||
},
|
|
||||||
"maneuver":{
|
"maneuver":{
|
||||||
"type":"turn",
|
"type":"turn",
|
||||||
"modifier":"right"
|
"modifier":"right",
|
||||||
},
|
"lanes":[
|
||||||
|
{"indications":["left","straight"], "valid":"false"},
|
||||||
|
{"indications":["right"], "valid":"true"}
|
||||||
|
]},
|
||||||
"geometry":"{lu_IypwpAVrAvAdI",
|
"geometry":"{lu_IypwpAVrAvAdI",
|
||||||
"mode":"driving",
|
"mode":"driving",
|
||||||
"intersections":[
|
"intersections":[
|
||||||
{"location":[13.39677,52.54366],
|
{"location":[13.39677,52.54366],
|
||||||
"in":2,
|
"in":3,
|
||||||
"out":1,
|
"out":1,
|
||||||
"bearings":[10,184,270],
|
"bearings":[10,92,184,270],
|
||||||
"entry":[false,"true","true"]},
|
"entry":[false,"true","true"]},
|
||||||
{"location":[13.394718,52.543096],
|
{"location":[13.394718,52.543096],
|
||||||
"in":0,
|
"in":0,
|
||||||
@ -515,9 +507,8 @@ Currently, the supported lane tags are: `sharp_left, left, slight_left, sharp_ri
|
|||||||
Please note that even though there are `new name` and `notification` instructions, the `mode` and `name` can change
|
Please note that even though there are `new name` and `notification` instructions, the `mode` and `name` can change
|
||||||
between all instructions. They only offer a fallback in case nothing else is to report.
|
between all instructions. They only offer a fallback in case nothing else is to report.
|
||||||
|
|
||||||
|
|
||||||
- `modifier` An optional `string` indicating the direction change of the maneuver.
|
- `modifier` An optional `string` indicating the direction change of the maneuver.
|
||||||
|
|
||||||
| `modifier` | Description |
|
| `modifier` | Description |
|
||||||
|-------------------|-------------------------------------------|
|
|-------------------|-------------------------------------------|
|
||||||
| uturn | indicates reversal of direction |
|
| uturn | indicates reversal of direction |
|
||||||
@ -528,17 +519,16 @@ Currently, the supported lane tags are: `sharp_left, left, slight_left, sharp_ri
|
|||||||
| slight left | a slight turn to the left |
|
| slight left | a slight turn to the left |
|
||||||
| left | a normal turn to the left |
|
| left | a normal turn to the left |
|
||||||
| sharp left | a sharp turn to the left |
|
| sharp left | a sharp turn to the left |
|
||||||
|
|
||||||
The list of turns without a modifier is limited to: `depart/arrive`. If the source/target location is close enough to the `depart/arrive` location, no modifier will be given.
|
The list of turns without a modifier is limited to: `depart/arrive`. If the source/target location is close enough to the `depart/arrive` location, no modifier will be given.
|
||||||
|
|
||||||
The meaning depends on the `type` field.
|
The meaning depends on the `type` field.
|
||||||
|
|
||||||
| `type` | Description |
|
| `type` | Description |
|
||||||
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
|
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
|
||||||
| `turn` | `modifier` indicates the change in direction accomplished through the turn |
|
| `turn` | `modifier` indicates the change in direction accomplished through the turn |
|
||||||
| `depart`/`arrive` | `modifier` indicates the position of departure point and arrival point in relation to the current direction of travel |
|
| `depart`/`arrive` | `modifier` indicates the position of departure point and arrival point in relation to the current direction of travel |
|
||||||
|
|
||||||
|
|
||||||
- `exit` An optional `integer` indicating number of the exit to take. The field exists for the following `type` field:
|
- `exit` An optional `integer` indicating number of the exit to take. The field exists for the following `type` field:
|
||||||
|
|
||||||
| `type` | Description |
|
| `type` | Description |
|
||||||
@ -546,10 +536,42 @@ Currently, the supported lane tags are: `sharp_left, left, slight_left, sharp_ri
|
|||||||
| `roundabout` | Number of the roundabout exit to take. If exit is `undefined` the destination is on the roundabout. |
|
| `roundabout` | Number of the roundabout exit to take. If exit is `undefined` the destination is on the roundabout. |
|
||||||
| else | Indicates the number of intersections passed until the turn. Example instruction: `at the fourth intersection, turn left` |
|
| else | Indicates the number of intersections passed until the turn. Example instruction: `at the fourth intersection, turn left` |
|
||||||
|
|
||||||
|
- `lanes`: Array of `Lane` objects that denote the available turn lanes at the turn location
|
||||||
|
|
||||||
New properties (potentially depending on `type`) may be introduced in the future without an API version change.
|
New properties (potentially depending on `type`) may be introduced in the future without an API version change.
|
||||||
|
|
||||||
### Intersections
|
### Lane
|
||||||
|
|
||||||
|
A lane give a representation of turn lane at the corresponding turn location.
|
||||||
|
|
||||||
|
#### Properties
|
||||||
|
|
||||||
|
- `indications`: a indication (e.g. marking on the road) specifying the turn lane. A road can have multiple indications (e.g. an arrow pointing straight and left). The indications are given in an array, each containing one of the following types. Further indications might be added on without an API version change.
|
||||||
|
|
||||||
|
| `value` | Description |
|
||||||
|
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| `none` | No dedicated indication is shown. |
|
||||||
|
| `sharp right` | An indication indicating a sharp right turn (i.e. strongly bend arrow). |
|
||||||
|
| `right` | An indication indicating a right turn (i.e. bend arrow). |
|
||||||
|
| `sharp right` | An indication indicating a slight right turn (i.e. slightly bend arrow). |
|
||||||
|
| `straight` | No dedicated indication is shown (i.e. straight arrow). |
|
||||||
|
| `sharp left` | An indication indicating a sharp left turn (i.e. strongly bend arrow). |
|
||||||
|
| `left` | An indication indicating a left turn (i.e. bend arrow). |
|
||||||
|
| `sharp left` | An indication indicating a slight left turn (i.e. slightly bend arrow). |
|
||||||
|
| `uturn` | An indication signaling the possibility to reverse (i.e. fully bend arrow). |
|
||||||
|
|
||||||
|
- `valid`: a boolean flag indicating whether the lane is a valid choice in the current maneuver
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"indication": ["left", "straight"],
|
||||||
|
"valid": "false"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Intersection
|
||||||
|
|
||||||
An intersection gives a full representation of any cross-way the path passes bay. For every step, the very first intersection (`intersections[0]`) corresponds to the
|
An intersection gives a full representation of any cross-way the path passes bay. For every step, the very first intersection (`intersections[0]`) corresponds to the
|
||||||
location of the StepManeuver. Further intersections are listed for every cross-way until the next turn instruction.
|
location of the StepManeuver. Further intersections are listed for every cross-way until the next turn instruction.
|
||||||
|
@ -25,9 +25,9 @@ Feature: Turn Lane Guidance
|
|||||||
| de | |
|
| de | |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes | # |
|
| waypoints | route | turns | lanes | # |
|
||||||
| 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,d | ab,bc,cd,cd | depart,turn right,turn left,arrive | ,straight:false right:true right:true right:false,left:true left:true straight: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 |
|
| a,e | ab,bc,cd,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true, | 3 hops |
|
||||||
|
|
||||||
@anticipate
|
@anticipate
|
||||||
Scenario: Anticipate Lane Change for quick same direction turns, staying on the same street
|
Scenario: Anticipate Lane Change for quick same direction turns, staying on the same street
|
||||||
@ -48,9 +48,9 @@ Feature: Turn Lane Guidance
|
|||||||
| dy | | | YSt |
|
| dy | | | YSt |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,e | MySt,MySt,MySt,MySt | depart,continue right,end of road right,arrive | ,through:false right:false right:true,left:false right:true, |
|
| a,e | MySt,MySt,MySt,MySt | depart,continue right,turn right,arrive | ,straight: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, |
|
| e,a | MySt,MySt,MySt,MySt | depart,continue left,turn left,arrive | ,left:true left:false straight:false,left:true right:false, |
|
||||||
|
|
||||||
@anticipate
|
@anticipate
|
||||||
Scenario: Anticipate Lane Change for quick same direction turns, changing between streets
|
Scenario: Anticipate Lane Change for quick same direction turns, changing between streets
|
||||||
@ -71,9 +71,9 @@ Feature: Turn Lane Guidance
|
|||||||
| dy | | | EYSt |
|
| dy | | | EYSt |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,e | AXSt,BDSt,EYSt,EYSt | depart,turn right,end of road right,arrive | ,through:false right:false right:true,left:false right:true, |
|
| a,e | AXSt,BDSt,EYSt,EYSt | depart,turn right,turn right,arrive | ,straight: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, |
|
| e,a | EYSt,BDSt,AXSt,AXSt | depart,turn left,turn left,arrive | ,left:true left:false straight:false,left:true right:false, |
|
||||||
|
|
||||||
|
|
||||||
@anticipate
|
@anticipate
|
||||||
@ -92,8 +92,8 @@ Feature: Turn Lane Guidance
|
|||||||
| cy | | Hwy | motorway | |
|
| cy | | Hwy | motorway | |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| 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, |
|
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive | ,slight left:false slight left:true,straight:false slight right:true, |
|
||||||
|
|
||||||
|
|
||||||
@anticipate
|
@anticipate
|
||||||
@ -115,8 +115,8 @@ Feature: Turn Lane Guidance
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,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,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, |
|
| 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
|
@anticipate
|
||||||
@ -136,8 +136,8 @@ Feature: Turn Lane Guidance
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,i | ab,xbcj,ci,ci | depart,merge slight left,turn slight right,arrive | ,,none:false slight_right:true, |
|
| 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, |
|
| a,j | ab,xbcj,xbcj,xbcj | depart,merge slight left,use lane straight,arrive | ,,none:true slight right:false, |
|
||||||
|
|
||||||
|
|
||||||
@anticipate
|
@anticipate
|
||||||
@ -160,8 +160,8 @@ Feature: Turn Lane Guidance
|
|||||||
| de | | de |
|
| de | | de |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| 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, |
|
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true, |
|
||||||
|
|
||||||
@anticipate
|
@anticipate
|
||||||
Scenario: Lane anticipation for fan-out
|
Scenario: Lane anticipation for fan-out
|
||||||
@ -183,8 +183,8 @@ Feature: Turn Lane Guidance
|
|||||||
| de | | de |
|
| de | | de |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| 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, |
|
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:true,left:true left:true straight:false,straight:false right:true right:true right:true, |
|
||||||
|
|
||||||
@anticipate
|
@anticipate
|
||||||
Scenario: Lane anticipation for fan-in followed by fan-out
|
Scenario: Lane anticipation for fan-in followed by fan-out
|
||||||
@ -206,8 +206,8 @@ Feature: Turn Lane Guidance
|
|||||||
| de | | de |
|
| de | | de |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| 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, |
|
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:true right:true right:false,left:true left:true straight:false,straight:false right:true right:true right:true, |
|
||||||
|
|
||||||
@anticipate
|
@anticipate
|
||||||
Scenario: Lane anticipation for fan-out followed by fan-in
|
Scenario: Lane anticipation for fan-out followed by fan-in
|
||||||
@ -229,8 +229,8 @@ Feature: Turn Lane Guidance
|
|||||||
| de | | de |
|
| de | | de |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| 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, |
|
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:true,left:false left:true straight:false,straight:false right:true, |
|
||||||
|
|
||||||
@anticipate
|
@anticipate
|
||||||
Scenario: Lane anticipation for multiple hops with same number of lanes
|
Scenario: Lane anticipation for multiple hops with same number of lanes
|
||||||
@ -256,8 +256,8 @@ Feature: Turn Lane Guidance
|
|||||||
| ef | | ef |
|
| ef | | ef |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| 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, |
|
| a,f | abx,bcy,cdz,dew,ef,ef | depart,turn right,turn left,turn right,turn left,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true right:false,left:true straight:false, |
|
||||||
|
|
||||||
@anticipate @bug @todo
|
@anticipate @bug @todo
|
||||||
Scenario: Tripple Right keeping Left
|
Scenario: Tripple Right keeping Left
|
||||||
|
@ -20,11 +20,11 @@ Feature: Turn Lane Guidance
|
|||||||
| bd | | | left\|right | right |
|
| bd | | | left\|right | right |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,through:true right:false, |
|
| a,c | in,straight,straight | depart,new name straight,arrive | ,straight:true right:false, |
|
||||||
| a,d | in,right,right | depart,turn right,arrive | ,through:false right:true, |
|
| a,d | in,right,right | depart,turn right,arrive | ,straight:false right:true, |
|
||||||
| c,a | straight,in,in | depart,new name straight,arrive | ,left:false through:true none:true none:true, |
|
| c,a | straight,in,in | depart,new name straight,arrive | ,left:false straight:true none:true none:true, |
|
||||||
| c,d | straight,right,right | depart,turn left,arrive | ,left:true through:false none:false none:false, |
|
| c,d | straight,right,right | depart,turn left,arrive | ,left:true straight:false none:false none:false, |
|
||||||
|
|
||||||
Scenario: Basic Turn Lane 4-Way Turn
|
Scenario: Basic Turn Lane 4-Way Turn
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -81,11 +81,11 @@ Feature: Turn Lane Guidance
|
|||||||
| be | | | left |
|
| be | | | left |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | bearings | route | turns | lanes |
|
| from | to | bearings | route | turns | lanes |
|
||||||
| a | c | 180,180 180,180 | in,straight,straight | depart,new name straight,arrive | ,reverse;left:false through;right:true, |
|
| a | c | 180,180 180,180 | in,straight,straight | depart,new name straight,arrive | ,left;uturn:false straight;right:true, |
|
||||||
| a | d | 180,180 180,180 | in,right,right | depart,turn right,arrive | ,reverse;left:false through;right:true, |
|
| a | d | 180,180 180,180 | in,right,right | depart,turn right,arrive | ,left;uturn:false straight;right:true, |
|
||||||
| a | e | 180,180 180,180 | in,left,left | depart,turn left,arrive | ,reverse;left:true through;right:false, |
|
| a | e | 180,180 180,180 | in,left,left | depart,turn left,arrive | ,left;uturn:true straight;right:false, |
|
||||||
| 1 | a | 90,2 270,2 | in,in,in | depart,turn uturn,arrive | ,reverse;left:true through;right:false, |
|
| 1 | a | 90,2 270,2 | in,in,in | depart,turn uturn,arrive | ,left;uturn:true straight;right:false, |
|
||||||
|
|
||||||
|
|
||||||
#this next test requires decision on how to announce lanes for going straight if there is no turn
|
#this next test requires decision on how to announce lanes for going straight if there is no turn
|
||||||
@ -103,9 +103,9 @@ Feature: Turn Lane Guidance
|
|||||||
| bd | turn | | |
|
| bd | turn | | |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,d | road,turn,turn | depart,turn right,arrive | ,through:false right:true, |
|
| a,d | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
|
||||||
| a,c | road,road,road | depart,use lane straight,arrive | ,through:true right:false, |
|
| a,c | road,road,road | depart,use lane straight,arrive | ,straight:true right:false, |
|
||||||
|
|
||||||
#turn lanes are often drawn at the incoming road, even though the actual turn requires crossing the intersection first
|
#turn lanes are often drawn at the incoming road, even though the actual turn requires crossing the intersection first
|
||||||
@todo @WORKAROUND-FIXME @bug
|
@todo @WORKAROUND-FIXME @bug
|
||||||
@ -134,23 +134,23 @@ Feature: Turn Lane Guidance
|
|||||||
| fl | cross | | yes |
|
| fl | cross | | yes |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false through:false right:true |
|
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true |
|
||||||
| a,d | road,road,road | depart,use lane straight,arrive | ,left:false through:true right:false, |
|
| a,d | road,road,road | depart,use lane straight,arrive | ,left:false straight:true right:false, |
|
||||||
| a,l | road,cross,cross | depart,turn left,arrive | ,left:true through:false right:false, |
|
| a,l | road,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, |
|
||||||
| a,h | road,road,road | depart,continue uturn,arrive | ,left:true through:false right:false, |
|
| a,h | road,road,road | depart,continue uturn,arrive | ,left:true straight:false right:false, |
|
||||||
| k,d | cross,road,road | depart,turn right,arrive | ,left:false through;right:true, |
|
| k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, |
|
||||||
| k,l | cross,cross,cross | depart,use lane straight,arrive | ,left:false through;right:true, |
|
| k,l | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight;right:true, |
|
||||||
| k,h | cross,road,road | depart,turn left,arrive | ,left:true through;right:false, |
|
| k,h | cross,road,road | depart,turn left,arrive | ,left:true straight;right:false, |
|
||||||
| k,j | cross,cross,cross | depart,continue uturn,arrive | ,left:true through;right:false, |
|
| k,j | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight;right:false, |
|
||||||
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false through:false through;right:true, |
|
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, |
|
||||||
| e,h | road,road | depart,arrive | ,none:false through:true through;right:true |
|
| e,h | road,road | depart,arrive | ,none:false straight:true straight;right:true |
|
||||||
| e,j | road,cross,cross | depart,turn left,arrive | ,none:true through:false through;right:false, |
|
| e,j | road,cross,cross | depart,turn left,arrive | ,none:true straight:false straight;right:false, |
|
||||||
| e,d | road,road,road | depart,continue uturn,arrive | ,none:true through:false through;right:false, |
|
| e,d | road,road,road | depart,continue uturn,arrive | ,none:true straight:false straight;right:false, |
|
||||||
| i,h | cross,road,road | depart,turn right,arrive | ,, |
|
| i,h | cross,road,road | depart,turn right,arrive | ,, |
|
||||||
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false through:true, |
|
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight:true, |
|
||||||
| i,d | cross,road,road | depart,turn left,arrive | ,left:true through:false, |
|
| i,d | cross,road,road | depart,turn left,arrive | ,left:true straight:false, |
|
||||||
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true through:false, |
|
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, |
|
||||||
|
|
||||||
#copy of former case to prevent further regression
|
#copy of former case to prevent further regression
|
||||||
Scenario: Turn Lanes at Segregated Road
|
Scenario: Turn Lanes at Segregated Road
|
||||||
@ -178,13 +178,13 @@ Feature: Turn Lane Guidance
|
|||||||
| fl | cross | | yes |
|
| fl | cross | | yes |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false through:false right:true, |
|
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
|
||||||
| k,d | cross,road,road | depart,turn right,arrive | ,left:false through;right:true, |
|
| k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, |
|
||||||
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false through:false through;right:true, |
|
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, |
|
||||||
| i,h | cross,road,road | depart,turn right,arrive | ,, |
|
| i,h | cross,road,road | depart,turn right,arrive | ,, |
|
||||||
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false through:true, |
|
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight:true, |
|
||||||
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true through:false, |
|
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, |
|
||||||
|
|
||||||
Scenario: Turn Lanes at Segregated Road
|
Scenario: Turn Lanes at Segregated Road
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -204,8 +204,8 @@ Feature: Turn Lane Guidance
|
|||||||
| cf | cross | | yes |
|
| cf | cross | | yes |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false through:false right:true, |
|
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
|
||||||
|
|
||||||
#this can happen due to traffic lights / lanes not drawn up to the intersection itself
|
#this can happen due to traffic lights / lanes not drawn up to the intersection itself
|
||||||
Scenario: Turn Lanes Given earlier than actual turn
|
Scenario: Turn Lanes Given earlier than actual turn
|
||||||
@ -261,8 +261,8 @@ Feature: Turn Lane Guidance
|
|||||||
| cf | turn | | |
|
| cf | turn | | |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true through:false, |
|
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true straight:false, |
|
||||||
|
|
||||||
Scenario: Passing a one-way street, partly pulled back lanes
|
Scenario: Passing a one-way street, partly pulled back lanes
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -279,9 +279,9 @@ Feature: Turn Lane Guidance
|
|||||||
| bg | right | | no |
|
| bg | right | | no |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true through;right:false, |
|
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true straight;right:false, |
|
||||||
| a,g | road,right,right | depart,turn right,arrive | ,left:false through;right:true, |
|
| a,g | road,right,right | depart,turn right,arrive | ,left:false straight;right:true, |
|
||||||
|
|
||||||
Scenario: Passing a one-way street, partly pulled back lanes, no through
|
Scenario: Passing a one-way street, partly pulled back lanes, no through
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -320,10 +320,10 @@ Feature: Turn Lane Guidance
|
|||||||
| cf | right | |
|
| cf | right | |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,g | road,left,left | depart,turn left,arrive | ,left:true through:false right:false, |
|
| a,g | road,left,left | depart,turn left,arrive | ,left:true straight:false right:false, |
|
||||||
| a,e | road,through,through | depart,new name straight,arrive | ,left:false through:true right:false, |
|
| a,e | road,through,through | depart,new name straight,arrive | ,left:false straight:true right:false, |
|
||||||
| a,f | road,right,right | depart,turn right,arrive | ,left:false through:false right:true, |
|
| a,f | road,right,right | depart,turn right,arrive | ,left:false straight:false right:true, |
|
||||||
|
|
||||||
Scenario: Turn at a traffic light
|
Scenario: Turn at a traffic light
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -342,9 +342,9 @@ Feature: Turn Lane Guidance
|
|||||||
| ce | turn | |
|
| ce | turn | |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,d | road,road,road | depart,use lane straight,arrive | ,through:true right:false, |
|
| a,d | road,road,road | depart,use lane straight,arrive | ,straight:true right:false, |
|
||||||
| a,e | road,turn,turn | depart,turn right,arrive | ,through:false right:true, |
|
| a,e | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
|
||||||
|
|
||||||
@bug @todo
|
@bug @todo
|
||||||
Scenario: Theodor Heuss Platz
|
Scenario: Theodor Heuss Platz
|
||||||
@ -379,8 +379,8 @@ Feature: Turn Lane Guidance
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| 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,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,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 | ,, |
|
| i,o | top,top,top | depart,roundabout-exit-5,arrive | ,, |
|
||||||
|
|
||||||
Scenario: Turn Lanes Breaking up
|
Scenario: Turn Lanes Breaking up
|
||||||
@ -406,9 +406,9 @@ Feature: Turn Lane Guidance
|
|||||||
| restriction | bc | fdcg | c | no_right_turn |
|
| restriction | bc | fdcg | c | no_right_turn |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,g | road,cross,cross | depart,turn left,arrive | ,left:true left:true through:false through:false, |
|
| a,g | road,cross,cross | depart,turn left,arrive | ,left:true left:true straight:false straight:false, |
|
||||||
| a,e | road,road,road | depart,use lane straight,arrive | ,left:false left:false through:true through:true, |
|
| a,e | road,road,road | depart,use lane straight,arrive | ,left:false left:false straight:true straight:true, |
|
||||||
|
|
||||||
Scenario: U-Turn Road at Intersection
|
Scenario: U-Turn Road at Intersection
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -429,11 +429,11 @@ Feature: Turn Lane Guidance
|
|||||||
| gdeh | cross | | no | primary |
|
| gdeh | cross | | no | primary |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | bearings | route | turns | lanes |
|
| from | to | bearings | route | turns | lanes |
|
||||||
| a | g | 180,180 180,180 | road,cross,cross | depart,turn right,arrive | ,none:false through:false right:true, |
|
| a | g | 180,180 180,180 | road,cross,cross | depart,turn right,arrive | ,none:false straight:false right:true, |
|
||||||
| a | h | 180,180 180,180 | road,cross,cross | depart,turn left,arrive | ,none:true through:false right:false, |
|
| a | h | 180,180 180,180 | road,cross,cross | depart,turn left,arrive | ,none:true straight:false right:false, |
|
||||||
| a | i | 180,180 180,180 | road,road,road | depart,use lane straight,arrive | ,none:true through:true right:false, |
|
| a | i | 180,180 180,180 | road,road,road | depart,use lane straight,arrive | ,none:true straight:true right:false, |
|
||||||
| b | a | 90,2 270,2 | road,road,road | depart,continue uturn,arrive | ,none:true through:false right:false, |
|
| b | a | 90,2 270,2 | road,road,road | depart,continue uturn,arrive | ,none:true straight:false right:false, |
|
||||||
|
|
||||||
Scenario: Segregated Intersection Merges With Lanes
|
Scenario: Segregated Intersection Merges With Lanes
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -454,10 +454,10 @@ Feature: Turn Lane Guidance
|
|||||||
| cf | left | | yes | primary |
|
| cf | left | | yes | primary |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,f | road,left,left | depart,turn left,arrive | ,left:true left:true left:true through:false through:false, |
|
| a,f | road,left,left | depart,turn left,arrive | ,left:true left:true left:true straight:false straight:false, |
|
||||||
| a,e | road,road,road | depart,turn uturn,arrive | ,left:true left:false left:false through:false through:false, |
|
| a,e | road,road,road | depart,turn uturn,arrive | ,left:true left:false left:false straight:false straight:false, |
|
||||||
| a,g | road,straight,straight | depart,new name straight,arrive | ,left:false left:false left:false through:true through:true, |
|
| a,g | road,straight,straight | depart,new name straight,arrive | ,left:false left:false left:false straight:true straight:true, |
|
||||||
|
|
||||||
@bug @todo
|
@bug @todo
|
||||||
Scenario: Passing Through a Roundabout
|
Scenario: Passing Through a Roundabout
|
||||||
@ -502,9 +502,9 @@ Feature: Turn Lane Guidance
|
|||||||
| ce | cross | | primary |
|
| ce | cross | | primary |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,d | road,road,road | depart,use lane straight,arrive | ,through:true through:true through;slight_right:true slight_right:false, |
|
| a,d | road,road,road | depart,use lane straight,arrive | ,straight:true straight:true straight;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, |
|
| a,e | road,cross,cross | depart,turn slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
|
||||||
|
|
||||||
Scenario: Highway Ramp
|
Scenario: Highway Ramp
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -518,9 +518,9 @@ Feature: Turn Lane Guidance
|
|||||||
| ce | ramp | | motorway_link |
|
| ce | ramp | | motorway_link |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,d | hwy,hwy,hwy | depart,use lane straight,arrive | ,through:true through:true through;slight_right:true slight_right:false, |
|
| a,d | hwy,hwy,hwy | depart,use lane straight,arrive | ,straight:true straight:true straight;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, |
|
| a,e | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
|
||||||
|
|
||||||
@bug @todo
|
@bug @todo
|
||||||
Scenario: Turning Off Ramp
|
Scenario: Turning Off Ramp
|
||||||
@ -558,9 +558,9 @@ Feature: Turn Lane Guidance
|
|||||||
| bd | ramp | | motorway_link | yes |
|
| bd | ramp | | motorway_link | yes |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,c | hwy,hwy,hwy | depart,use lane slight left,arrive | ,through:true through:true slight_right:false, |
|
| a,c | hwy,hwy,hwy | depart,use lane slight left,arrive | ,straight:true straight:true slight right:false, |
|
||||||
| a,d | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,through:false through:false slight_right:true, |
|
| a,d | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false slight right:true, |
|
||||||
|
|
||||||
Scenario: Reverse Lane in Segregated Road
|
Scenario: Reverse Lane in Segregated Road
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -578,7 +578,7 @@ Feature: Turn Lane Guidance
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,h | road,road,road | depart,continue uturn,arrive | ,reverse:true through:false through:false,|
|
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false straight:false,|
|
||||||
|
|
||||||
Scenario: Reverse Lane in Segregated Road with none
|
Scenario: Reverse Lane in Segregated Road with none
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -595,8 +595,8 @@ Feature: Turn Lane Guidance
|
|||||||
| fgh | road | | primary | yes |
|
| fgh | road | | primary | yes |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,h | road,road,road | depart,continue uturn,arrive | ,reverse:true through:false none:false, |
|
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false, |
|
||||||
|
|
||||||
Scenario: Reverse Lane in Segregated Road with none, Service Turn Prior
|
Scenario: Reverse Lane in Segregated Road with none, Service Turn Prior
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -615,8 +615,8 @@ Feature: Turn Lane Guidance
|
|||||||
| ji | park | | service | no |
|
| ji | park | | service | no |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,h | road,road,road | depart,continue uturn,arrive | ,reverse:true through:false none:false, |
|
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false, |
|
||||||
|
|
||||||
Scenario: Don't collapse everything to u-turn / too wide
|
Scenario: Don't collapse everything to u-turn / too wide
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -633,9 +633,9 @@ Feature: Turn Lane Guidance
|
|||||||
| cf | secondary | bottom | |
|
| cf | secondary | bottom | |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | turns | route | lanes |
|
| waypoints | turns | route | lanes |
|
||||||
| a,d | depart,continue right,end of road right,arrive | road,road,road,road | ,through:false right:true,, |
|
| a,d | depart,continue right,turn right,arrive | road,road,road,road | ,straight:false right:true,, |
|
||||||
| d,a | depart,continue left,end of road left,arrive | road,road,road,road | ,left:true through:false,, |
|
| d,a | depart,continue left,turn left,arrive | road,road,road,road | ,left:true straight:false,, |
|
||||||
|
|
||||||
Scenario: Merge Lanes Onto Freeway
|
Scenario: Merge Lanes Onto Freeway
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -649,7 +649,7 @@ Feature: Turn Lane Guidance
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | turns | route | lanes |
|
| waypoints | turns | route | lanes |
|
||||||
| d,c | depart,merge slight left,arrive | ramp,Hwy,Hwy | ,slight_right:true slight_right:true, |
|
| 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
|
Scenario: Fork on motorway links - don't fork on through but use lane
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -666,5 +666,5 @@ Feature: Turn Lane Guidance
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns | lanes |
|
| waypoints | route | turns | lanes |
|
||||||
| a,j | on,xbcj,xbcj,xbcj | depart,merge slight left,use lane straight,arrive | ,,none:true slight_right:false, |
|
| 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, |
|
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
|
||||||
|
@ -172,7 +172,7 @@ module.exports = function () {
|
|||||||
return this.extractInstructionList(instructions, instruction => {
|
return this.extractInstructionList(instructions, instruction => {
|
||||||
if( 'lanes' in instruction.maneuver )
|
if( 'lanes' in instruction.maneuver )
|
||||||
{
|
{
|
||||||
return instruction.maneuver.lanes.map( p => { return p.marked + ':' + p.take; } ).join(' ');
|
return instruction.maneuver.lanes.map( p => { return (p.indications).join(';') + ':' + p.valid; } ).join(' ');
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "extractor/edge_based_node.hpp"
|
#include "extractor/edge_based_node.hpp"
|
||||||
#include "extractor/external_memory_node.hpp"
|
#include "extractor/external_memory_node.hpp"
|
||||||
#include "extractor/guidance/turn_instruction.hpp"
|
#include "extractor/guidance/turn_instruction.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
#include "engine/phantom_node.hpp"
|
#include "engine/phantom_node.hpp"
|
||||||
#include "util/exception.hpp"
|
#include "util/exception.hpp"
|
||||||
#include "util/guidance/bearing_class.hpp"
|
#include "util/guidance/bearing_class.hpp"
|
||||||
@ -140,7 +141,8 @@ class BaseDataFacade
|
|||||||
|
|
||||||
virtual bool hasLaneData(const EdgeID id) const = 0;
|
virtual bool hasLaneData(const EdgeID id) const = 0;
|
||||||
virtual util::guidance::LaneTupelIdPair GetLaneData(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 extractor::guidance::TurnLaneDescription
|
||||||
|
GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0;
|
||||||
|
|
||||||
virtual unsigned GetCheckSum() const = 0;
|
virtual unsigned GetCheckSum() const = 0;
|
||||||
|
|
||||||
|
@ -83,13 +83,14 @@ class InternalDataFacade final : public BaseDataFacade
|
|||||||
util::ShM<util::guidance::LaneTupelIdPair, false>::vector m_lane_tupel_id_pairs;
|
util::ShM<util::guidance::LaneTupelIdPair, false>::vector m_lane_tupel_id_pairs;
|
||||||
util::ShM<extractor::TravelMode, false>::vector m_travel_mode_list;
|
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_names_char_list;
|
||||||
util::ShM<char, false>::vector m_lanes_char_list;
|
|
||||||
util::ShM<unsigned, false>::vector m_geometry_indices;
|
util::ShM<unsigned, false>::vector m_geometry_indices;
|
||||||
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, false>::vector m_geometry_list;
|
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, false>::vector m_geometry_list;
|
||||||
util::ShM<bool, false>::vector m_is_core_node;
|
util::ShM<bool, false>::vector m_is_core_node;
|
||||||
util::ShM<unsigned, false>::vector m_segment_weights;
|
util::ShM<unsigned, false>::vector m_segment_weights;
|
||||||
util::ShM<uint8_t, false>::vector m_datasource_list;
|
util::ShM<uint8_t, false>::vector m_datasource_list;
|
||||||
util::ShM<std::string, false>::vector m_datasource_names;
|
util::ShM<std::string, false>::vector m_datasource_names;
|
||||||
|
util::ShM<std::uint32_t, false>::vector m_lane_description_offsets;
|
||||||
|
util::ShM<extractor::guidance::TurnLaneType::Mask, false>::vector m_lane_description_masks;
|
||||||
extractor::ProfileProperties m_profile_properties;
|
extractor::ProfileProperties m_profile_properties;
|
||||||
|
|
||||||
std::unique_ptr<InternalRTree> m_static_rtree;
|
std::unique_ptr<InternalRTree> m_static_rtree;
|
||||||
@ -97,7 +98,6 @@ class InternalDataFacade final : public BaseDataFacade
|
|||||||
boost::filesystem::path ram_index_path;
|
boost::filesystem::path ram_index_path;
|
||||||
boost::filesystem::path file_index_path;
|
boost::filesystem::path file_index_path;
|
||||||
util::RangeTable<16, false> m_name_table;
|
util::RangeTable<16, false> m_name_table;
|
||||||
util::RangeTable<16, false> m_lane_string_table;
|
|
||||||
|
|
||||||
// bearing classes by node based node
|
// bearing classes by node based node
|
||||||
util::ShM<BearingClassID, false>::vector m_bearing_class_id_table;
|
util::ShM<BearingClassID, false>::vector m_bearing_class_id_table;
|
||||||
@ -305,18 +305,13 @@ class InternalDataFacade final : public BaseDataFacade
|
|||||||
new InternalGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
|
new InternalGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadLaneStrings(const boost::filesystem::path &lane_string_file)
|
void LoadLaneDescriptions(const boost::filesystem::path &lane_description_file)
|
||||||
{
|
{
|
||||||
boost::filesystem::ifstream lane_stream(lane_string_file, std::ios::binary);
|
if (!util::deserializeAdjacencyArray(lane_description_file.string(),
|
||||||
|
m_lane_description_offsets,
|
||||||
lane_stream >> m_lane_string_table;
|
m_lane_description_masks))
|
||||||
|
util::SimpleLogger().Write(logWARNING) << "Failed to read turn lane descriptions from "
|
||||||
unsigned number_of_chars = 0;
|
<< lane_description_file.string();
|
||||||
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)
|
void LoadStreetNames(const boost::filesystem::path &names_file)
|
||||||
@ -422,7 +417,7 @@ class InternalDataFacade final : public BaseDataFacade
|
|||||||
LoadStreetNames(config.names_data_path);
|
LoadStreetNames(config.names_data_path);
|
||||||
|
|
||||||
util::SimpleLogger().Write() << "loading lane tags";
|
util::SimpleLogger().Write() << "loading lane tags";
|
||||||
LoadLaneStrings(config.turn_lane_string_path);
|
LoadLaneDescriptions(config.turn_lane_description_path);
|
||||||
|
|
||||||
util::SimpleLogger().Write() << "loading rtree";
|
util::SimpleLogger().Write() << "loading rtree";
|
||||||
LoadRTree();
|
LoadRTree();
|
||||||
@ -794,24 +789,16 @@ class InternalDataFacade final : public BaseDataFacade
|
|||||||
return m_lane_tupel_id_pairs[m_lane_data_id[id]];
|
return m_lane_tupel_id_pairs[m_lane_data_id[id]];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetTurnStringForID(const LaneStringID lane_string_id) const override final
|
extractor::guidance::TurnLaneDescription
|
||||||
|
GetTurnDescription(const LaneDescriptionID lane_description_id) const override final
|
||||||
{
|
{
|
||||||
if (INVALID_LANE_STRINGID == lane_string_id)
|
if (lane_description_id == INVALID_LANE_DESCRIPTIONID)
|
||||||
{
|
return {};
|
||||||
return "";
|
else
|
||||||
}
|
return extractor::guidance::TurnLaneDescription(
|
||||||
auto range = m_lane_string_table.GetRange(lane_string_id);
|
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id],
|
||||||
|
m_lane_description_masks.begin() +
|
||||||
std::string result;
|
m_lane_description_offsets[lane_description_id + 1]);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "extractor/compressed_edge_container.hpp"
|
#include "extractor/compressed_edge_container.hpp"
|
||||||
#include "extractor/guidance/turn_instruction.hpp"
|
#include "extractor/guidance/turn_instruction.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
#include "extractor/profile_properties.hpp"
|
#include "extractor/profile_properties.hpp"
|
||||||
#include "util/guidance/bearing_class.hpp"
|
#include "util/guidance/bearing_class.hpp"
|
||||||
#include "util/guidance/entry_class.hpp"
|
#include "util/guidance/entry_class.hpp"
|
||||||
@ -84,14 +85,13 @@ class SharedDataFacade final : public BaseDataFacade
|
|||||||
util::ShM<extractor::guidance::TurnInstruction, true>::vector m_turn_instruction_list;
|
util::ShM<extractor::guidance::TurnInstruction, true>::vector m_turn_instruction_list;
|
||||||
util::ShM<extractor::TravelMode, true>::vector m_travel_mode_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_names_char_list;
|
||||||
util::ShM<char, true>::vector m_turn_string_char_list;
|
|
||||||
util::ShM<unsigned, true>::vector m_name_begin_indices;
|
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<unsigned, true>::vector m_geometry_indices;
|
||||||
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, true>::vector m_geometry_list;
|
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, true>::vector m_geometry_list;
|
||||||
util::ShM<bool, true>::vector m_is_core_node;
|
util::ShM<bool, true>::vector m_is_core_node;
|
||||||
util::ShM<uint8_t, true>::vector m_datasource_list;
|
util::ShM<uint8_t, true>::vector m_datasource_list;
|
||||||
|
util::ShM<std::uint32_t, true>::vector m_lane_description_offsets;
|
||||||
|
util::ShM<extractor::guidance::TurnLaneType::Mask, true>::vector m_lane_description_masks;
|
||||||
|
|
||||||
util::ShM<char, true>::vector m_datasource_name_data;
|
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_offsets;
|
||||||
@ -103,7 +103,6 @@ class SharedDataFacade final : public BaseDataFacade
|
|||||||
boost::filesystem::path file_index_path;
|
boost::filesystem::path file_index_path;
|
||||||
|
|
||||||
std::shared_ptr<util::RangeTable<16, true>> m_name_table;
|
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
|
// bearing classes by node based node
|
||||||
util::ShM<BearingClassID, true>::vector m_bearing_class_id_table;
|
util::ShM<BearingClassID, true>::vector m_bearing_class_id_table;
|
||||||
@ -258,29 +257,23 @@ class SharedDataFacade final : public BaseDataFacade
|
|||||||
m_names_char_list = std::move(names_char_list);
|
m_names_char_list = std::move(names_char_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadTurnLaneStrings()
|
void LoadTurnLaneDescriptions()
|
||||||
{
|
{
|
||||||
auto offsets_ptr = data_layout->GetBlockPtr<unsigned>(
|
auto offsets_ptr = data_layout->GetBlockPtr<std::uint32_t>(
|
||||||
shared_memory, storage::SharedDataLayout::TURN_STRING_OFFSETS);
|
shared_memory, storage::SharedDataLayout::LANE_DESCRIPTION_OFFSETS);
|
||||||
auto blocks_ptr = data_layout->GetBlockPtr<IndexBlock>(
|
util::ShM<std::uint32_t, true>::vector offsets(
|
||||||
shared_memory, storage::SharedDataLayout::TURN_STRING_BLOCKS);
|
offsets_ptr,
|
||||||
util::ShM<unsigned, true>::vector turn_string_offsets(
|
data_layout->num_entries[storage::SharedDataLayout::LANE_DESCRIPTION_OFFSETS]);
|
||||||
offsets_ptr, data_layout->num_entries[storage::SharedDataLayout::TURN_STRING_OFFSETS]);
|
m_lane_description_offsets = std::move(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>(
|
auto masks_ptr = data_layout->GetBlockPtr<extractor::guidance::TurnLaneType::Mask>(
|
||||||
shared_memory, storage::SharedDataLayout::TURN_STRING_CHAR_LIST);
|
shared_memory, storage::SharedDataLayout::LANE_DESCRIPTION_MASKS);
|
||||||
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);
|
util::ShM<extractor::guidance::TurnLaneType::Mask, true>::vector masks(
|
||||||
|
masks_ptr, data_layout->num_entries[storage::SharedDataLayout::LANE_DESCRIPTION_MASKS]);
|
||||||
|
m_lane_description_masks = std::move(masks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadCoreInformation()
|
void LoadCoreInformation()
|
||||||
{
|
{
|
||||||
if (data_layout->num_entries[storage::SharedDataLayout::CORE_MARKER] <= 0)
|
if (data_layout->num_entries[storage::SharedDataLayout::CORE_MARKER] <= 0)
|
||||||
@ -459,7 +452,7 @@ class SharedDataFacade final : public BaseDataFacade
|
|||||||
LoadTimestamp();
|
LoadTimestamp();
|
||||||
LoadViaNodeList();
|
LoadViaNodeList();
|
||||||
LoadNames();
|
LoadNames();
|
||||||
LoadTurnLaneStrings();
|
LoadTurnLaneDescriptions();
|
||||||
LoadCoreInformation();
|
LoadCoreInformation();
|
||||||
LoadProfileProperties();
|
LoadProfileProperties();
|
||||||
LoadRTree();
|
LoadRTree();
|
||||||
@ -839,24 +832,15 @@ class SharedDataFacade final : public BaseDataFacade
|
|||||||
return m_lane_tupel_id_pairs.at(m_lane_data_id.at(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
|
extractor::guidance::TurnLaneDescription
|
||||||
|
GetTurnDescription(const LaneDescriptionID lane_description_id) const override final
|
||||||
{
|
{
|
||||||
if (INVALID_LANE_STRINGID == lane_string_id)
|
if (lane_description_id == INVALID_LANE_DESCRIPTIONID)
|
||||||
{
|
return {};
|
||||||
return "";
|
else
|
||||||
}
|
return extractor::guidance::TurnLaneDescription(
|
||||||
auto range = m_turn_string_table->GetRange(lane_string_id);
|
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id],
|
||||||
|
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id + 1]);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "extractor/guidance/turn_instruction.hpp"
|
#include "extractor/guidance/turn_instruction.hpp"
|
||||||
#include "extractor/travel_mode.hpp"
|
#include "extractor/travel_mode.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
#include "engine/datafacade/datafacade_base.hpp"
|
#include "engine/datafacade/datafacade_base.hpp"
|
||||||
#include "engine/guidance/leg_geometry.hpp"
|
#include "engine/guidance/leg_geometry.hpp"
|
||||||
#include "engine/guidance/route_step.hpp"
|
#include "engine/guidance/route_step.hpp"
|
||||||
@ -73,7 +74,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
WaypointType::Depart,
|
WaypointType::Depart,
|
||||||
0,
|
0,
|
||||||
util::guidance::LaneTupel(),
|
util::guidance::LaneTupel(),
|
||||||
""};
|
{}};
|
||||||
Intersection intersection{source_node.location,
|
Intersection intersection{source_node.location,
|
||||||
std::vector<short>({bearings.second}),
|
std::vector<short>({bearings.second}),
|
||||||
std::vector<bool>({true}),
|
std::vector<bool>({true}),
|
||||||
@ -152,9 +153,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
WaypointType::None,
|
WaypointType::None,
|
||||||
0,
|
0,
|
||||||
path_point.lane_data.first,
|
path_point.lane_data.first,
|
||||||
(path_point.lane_data.second != INVALID_LANE_STRINGID
|
(path_point.lane_data.second != INVALID_LANE_DESCRIPTIONID
|
||||||
? facade.GetTurnStringForID(path_point.lane_data.second)
|
? facade.GetTurnDescription(path_point.lane_data.second)
|
||||||
: "")};
|
: extractor::guidance::TurnLaneDescription())};
|
||||||
segment_index++;
|
segment_index++;
|
||||||
segment_duration = 0;
|
segment_duration = 0;
|
||||||
}
|
}
|
||||||
@ -211,7 +212,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
WaypointType::Arrive,
|
WaypointType::Arrive,
|
||||||
0,
|
0,
|
||||||
util::guidance::LaneTupel(),
|
util::guidance::LaneTupel(),
|
||||||
""};
|
{}};
|
||||||
intersection = {
|
intersection = {
|
||||||
target_node.location,
|
target_node.location,
|
||||||
std::vector<short>({static_cast<short>(util::bearing::reverseBearing(bearings.first))}),
|
std::vector<short>({static_cast<short>(util::bearing::reverseBearing(bearings.first))}),
|
||||||
@ -244,7 +245,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
|||||||
BOOST_ASSERT(steps.back().maneuver.waypoint_type == WaypointType::Arrive);
|
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.lanes_in_turn == 0);
|
||||||
BOOST_ASSERT(steps.back().maneuver.lanes.first_lane_from_the_right == INVALID_LANEID);
|
BOOST_ASSERT(steps.back().maneuver.lanes.first_lane_from_the_right == INVALID_LANEID);
|
||||||
BOOST_ASSERT(steps.back().maneuver.turn_lane_string == "");
|
BOOST_ASSERT(steps.back().maneuver.lane_description.empty());
|
||||||
return steps;
|
return steps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
#ifndef OSRM_ENGINE_GUIDANCE_DEBUG_HPP_
|
|
||||||
#define OSRM_ENGINE_GUIDANCE_DEBUG_HPP_
|
|
||||||
|
|
||||||
#include "engine/guidance/route_step.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace osrm
|
|
||||||
{
|
|
||||||
namespace engine
|
|
||||||
{
|
|
||||||
namespace guidance
|
|
||||||
{
|
|
||||||
inline void print(const RouteStep &step)
|
|
||||||
{
|
|
||||||
std::cout << static_cast<int>(step.maneuver.instruction.type) << " "
|
|
||||||
<< static_cast<int>(step.maneuver.instruction.direction_modifier) << " "
|
|
||||||
<< static_cast<int>(step.maneuver.waypoint_type) << " Duration: " << step.duration
|
|
||||||
<< " Distance: " << step.distance << " Geometry: " << step.geometry_begin << " "
|
|
||||||
<< step.geometry_end << " exit: " << step.maneuver.exit
|
|
||||||
<< " Intersections: " << step.intersections.size() << " [";
|
|
||||||
|
|
||||||
for (const auto &intersection : step.intersections)
|
|
||||||
{
|
|
||||||
std::cout << "(bearings:";
|
|
||||||
for (auto bearing : intersection.bearings)
|
|
||||||
std::cout << " " << bearing;
|
|
||||||
std::cout << ", entry: ";
|
|
||||||
for (auto entry : intersection.entry)
|
|
||||||
std::cout << " " << entry;
|
|
||||||
std::cout << ")";
|
|
||||||
}
|
|
||||||
std::cout << "] name[" << step.name_id << "]: " << step.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void print(const std::vector<RouteStep> &steps)
|
|
||||||
{
|
|
||||||
std::cout << "Path\n";
|
|
||||||
int segment = 0;
|
|
||||||
for (const auto &step : steps)
|
|
||||||
{
|
|
||||||
std::cout << "\t[" << segment++ << "]: ";
|
|
||||||
print(step);
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace guidance
|
|
||||||
} // namespace engine
|
|
||||||
} // namespace osrm
|
|
||||||
|
|
||||||
#endif /*OSRM_ENGINE_GUIDANCE_DEBUG_HPP_*/
|
|
@ -2,6 +2,7 @@
|
|||||||
#define ENGINE_GUIDANCE_STEP_MANEUVER_HPP
|
#define ENGINE_GUIDANCE_STEP_MANEUVER_HPP
|
||||||
|
|
||||||
#include "extractor/guidance/turn_instruction.hpp"
|
#include "extractor/guidance/turn_instruction.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
#include "util/guidance/turn_lanes.hpp"
|
#include "util/guidance/turn_lanes.hpp"
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ struct StepManeuver
|
|||||||
unsigned exit;
|
unsigned exit;
|
||||||
|
|
||||||
util::guidance::LaneTupel lanes;
|
util::guidance::LaneTupel lanes;
|
||||||
std::string turn_lane_string;
|
extractor::guidance::TurnLaneDescription lane_description;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline StepManeuver getInvalidStepManeuver()
|
inline StepManeuver getInvalidStepManeuver()
|
||||||
@ -46,7 +47,7 @@ inline StepManeuver getInvalidStepManeuver()
|
|||||||
WaypointType::None,
|
WaypointType::None,
|
||||||
0,
|
0,
|
||||||
util::guidance::LaneTupel(),
|
util::guidance::LaneTupel(),
|
||||||
""};
|
{}};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace guidance
|
} // namespace guidance
|
||||||
|
@ -327,7 +327,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
|||||||
name_index,
|
name_index,
|
||||||
weight_vector[i],
|
weight_vector[i],
|
||||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||||
{{0, INVALID_LANEID}, INVALID_LANE_STRINGID},
|
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
|
||||||
travel_mode,
|
travel_mode,
|
||||||
INVALID_ENTRY_CLASSID});
|
INVALID_ENTRY_CLASSID});
|
||||||
}
|
}
|
||||||
@ -393,7 +393,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
|||||||
phantom_node_pair.target_phantom.name_id,
|
phantom_node_pair.target_phantom.name_id,
|
||||||
weight_vector[i],
|
weight_vector[i],
|
||||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||||
{{0, INVALID_LANEID}, INVALID_LANE_STRINGID},
|
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
|
||||||
target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode
|
target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode
|
||||||
: phantom_node_pair.target_phantom.forward_travel_mode,
|
: phantom_node_pair.target_phantom.forward_travel_mode,
|
||||||
INVALID_ENTRY_CLASSID});
|
INVALID_ENTRY_CLASSID});
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "extractor/guidance/turn_analysis.hpp"
|
#include "extractor/guidance/turn_analysis.hpp"
|
||||||
#include "extractor/guidance/turn_instruction.hpp"
|
#include "extractor/guidance/turn_instruction.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
#include "util/guidance/bearing_class.hpp"
|
#include "util/guidance/bearing_class.hpp"
|
||||||
#include "util/guidance/entry_class.hpp"
|
#include "util/guidance/entry_class.hpp"
|
||||||
|
|
||||||
@ -48,15 +49,17 @@ class EdgeBasedGraphFactory
|
|||||||
EdgeBasedGraphFactory(const EdgeBasedGraphFactory &) = delete;
|
EdgeBasedGraphFactory(const EdgeBasedGraphFactory &) = delete;
|
||||||
EdgeBasedGraphFactory &operator=(const EdgeBasedGraphFactory &) = delete;
|
EdgeBasedGraphFactory &operator=(const EdgeBasedGraphFactory &) = delete;
|
||||||
|
|
||||||
explicit EdgeBasedGraphFactory(std::shared_ptr<util::NodeBasedDynamicGraph> node_based_graph,
|
explicit EdgeBasedGraphFactory(
|
||||||
const CompressedEdgeContainer &compressed_edge_container,
|
std::shared_ptr<util::NodeBasedDynamicGraph> node_based_graph,
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
const CompressedEdgeContainer &compressed_edge_container,
|
||||||
const std::unordered_set<NodeID> &traffic_lights,
|
const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
std::shared_ptr<const RestrictionMap> restriction_map,
|
const std::unordered_set<NodeID> &traffic_lights,
|
||||||
const std::vector<QueryNode> &node_info_list,
|
std::shared_ptr<const RestrictionMap> restriction_map,
|
||||||
ProfileProperties profile_properties,
|
const std::vector<QueryNode> &node_info_list,
|
||||||
const util::NameTable &name_table,
|
ProfileProperties profile_properties,
|
||||||
const util::NameTable &turn_lanes);
|
const util::NameTable &name_table,
|
||||||
|
const std::vector<std::uint32_t> &turn_lane_offsets,
|
||||||
|
const std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks);
|
||||||
|
|
||||||
void Run(const std::string &original_edge_data_filename,
|
void Run(const std::string &original_edge_data_filename,
|
||||||
const std::string &turn_lane_data_filename,
|
const std::string &turn_lane_data_filename,
|
||||||
@ -119,7 +122,8 @@ class EdgeBasedGraphFactory
|
|||||||
ProfileProperties profile_properties;
|
ProfileProperties profile_properties;
|
||||||
|
|
||||||
const util::NameTable &name_table;
|
const util::NameTable &name_table;
|
||||||
const util::NameTable &turn_lanes;
|
const std::vector<std::uint32_t> &turn_lane_offsets;
|
||||||
|
const std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks;
|
||||||
|
|
||||||
void CompressGeometry();
|
void CompressGeometry();
|
||||||
unsigned RenumberEdges();
|
unsigned RenumberEdges();
|
||||||
|
@ -3,12 +3,14 @@
|
|||||||
|
|
||||||
#include "extractor/external_memory_node.hpp"
|
#include "extractor/external_memory_node.hpp"
|
||||||
#include "extractor/first_and_last_segment_of_way.hpp"
|
#include "extractor/first_and_last_segment_of_way.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
#include "extractor/internal_extractor_edge.hpp"
|
#include "extractor/internal_extractor_edge.hpp"
|
||||||
#include "extractor/restriction.hpp"
|
#include "extractor/restriction.hpp"
|
||||||
#include "extractor/scripting_environment.hpp"
|
#include "extractor/scripting_environment.hpp"
|
||||||
|
|
||||||
#include <stxxl/vector>
|
#include <stxxl/vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
@ -40,6 +42,9 @@ class ExtractionContainers
|
|||||||
void WriteCharData(const std::string &file_name,
|
void WriteCharData(const std::string &file_name,
|
||||||
const stxxl::vector<unsigned> &offests,
|
const stxxl::vector<unsigned> &offests,
|
||||||
const stxxl::vector<char> &char_data) const;
|
const stxxl::vector<char> &char_data) const;
|
||||||
|
void WriteTurnLaneMasks(const std::string &file_name,
|
||||||
|
const stxxl::vector<std::uint32_t> &turn_lane_offsets,
|
||||||
|
const stxxl::vector<guidance::TurnLaneType::Mask> &turn_lane_masks) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using STXXLNodeIDVector = stxxl::vector<OSMNodeID>;
|
using STXXLNodeIDVector = stxxl::vector<OSMNodeID>;
|
||||||
@ -53,8 +58,9 @@ class ExtractionContainers
|
|||||||
STXXLEdgeVector all_edges_list;
|
STXXLEdgeVector all_edges_list;
|
||||||
stxxl::vector<char> name_char_data;
|
stxxl::vector<char> name_char_data;
|
||||||
stxxl::vector<unsigned> name_lengths;
|
stxxl::vector<unsigned> name_lengths;
|
||||||
stxxl::vector<char> turn_lane_char_data;
|
// an adjacency array containing all turn lane masks
|
||||||
stxxl::vector<unsigned> turn_lane_lengths;
|
stxxl::vector<std::uint32_t> turn_lane_offsets;
|
||||||
|
stxxl::vector<guidance::TurnLaneType::Mask> turn_lane_masks;
|
||||||
STXXLRestrictionsVector restrictions_list;
|
STXXLRestrictionsVector restrictions_list;
|
||||||
STXXLWayIDStartEndVector way_start_end_id_list;
|
STXXLWayIDStartEndVector way_start_end_id_list;
|
||||||
std::unordered_map<OSMNodeID, NodeID> external_to_internal_node_id_map;
|
std::unordered_map<OSMNodeID, NodeID> external_to_internal_node_id_map;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#define EXTRACTOR_CALLBACKS_HPP
|
#define EXTRACTOR_CALLBACKS_HPP
|
||||||
|
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
|
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/functional/hash.hpp>
|
||||||
#include <boost/optional/optional_fwd.hpp>
|
#include <boost/optional/optional_fwd.hpp>
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ class ExtractorCallbacks
|
|||||||
using MapKey = std::pair<std::string, std::string>;
|
using MapKey = std::pair<std::string, std::string>;
|
||||||
using MapVal = unsigned;
|
using MapVal = unsigned;
|
||||||
std::unordered_map<MapKey, MapVal, boost::hash<MapKey>> string_map;
|
std::unordered_map<MapKey, MapVal, boost::hash<MapKey>> string_map;
|
||||||
std::unordered_map<std::string, LaneStringID> lane_map;
|
std::unordered_map<guidance::TurnLaneDescription,LaneDescriptionID,guidance::TurnLaneDescription_hash> lane_description_map;
|
||||||
ExtractionContainers &external_memory;
|
ExtractionContainers &external_memory;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -61,7 +61,7 @@ struct ExtractorConfig
|
|||||||
output_file_name = basepath + ".osrm";
|
output_file_name = basepath + ".osrm";
|
||||||
restriction_file_name = basepath + ".osrm.restrictions";
|
restriction_file_name = basepath + ".osrm.restrictions";
|
||||||
names_file_name = basepath + ".osrm.names";
|
names_file_name = basepath + ".osrm.names";
|
||||||
turn_lane_strings_file_name = basepath + ".osrm.tls";
|
turn_lane_descriptions_file_name = basepath + ".osrm.tls";
|
||||||
turn_lane_data_file_name = basepath + ".osrm.tld";
|
turn_lane_data_file_name = basepath + ".osrm.tld";
|
||||||
timestamp_file_name = basepath + ".osrm.timestamp";
|
timestamp_file_name = basepath + ".osrm.timestamp";
|
||||||
geometry_output_path = basepath + ".osrm.geometry";
|
geometry_output_path = basepath + ".osrm.geometry";
|
||||||
@ -85,7 +85,7 @@ struct ExtractorConfig
|
|||||||
std::string restriction_file_name;
|
std::string restriction_file_name;
|
||||||
std::string names_file_name;
|
std::string names_file_name;
|
||||||
std::string turn_lane_data_file_name;
|
std::string turn_lane_data_file_name;
|
||||||
std::string turn_lane_strings_file_name;
|
std::string turn_lane_descriptions_file_name;
|
||||||
std::string timestamp_file_name;
|
std::string timestamp_file_name;
|
||||||
std::string geometry_output_path;
|
std::string geometry_output_path;
|
||||||
std::string edge_output_path;
|
std::string edge_output_path;
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_DEBUG_HPP_
|
|
||||||
#define OSRM_EXTRACTOR_GUIDANCE_DEBUG_HPP_
|
|
||||||
|
|
||||||
#include <iomanip>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace osrm
|
|
||||||
{
|
|
||||||
namespace extractor
|
|
||||||
{
|
|
||||||
namespace guidance
|
|
||||||
{
|
|
||||||
|
|
||||||
inline void print(const LaneDataVector &turn_lane_data)
|
|
||||||
{
|
|
||||||
std::cout << " Tags:\n";
|
|
||||||
for (auto entry : turn_lane_data)
|
|
||||||
std::cout << "\t" << entry.tag << " from: " << static_cast<int>(entry.from)
|
|
||||||
<< " to: " << static_cast<int>(entry.to) << "\n";
|
|
||||||
std::cout << std::flush;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void printTurnAssignmentData(const NodeID at,
|
|
||||||
const LaneDataVector &turn_lane_data,
|
|
||||||
const Intersection &intersection,
|
|
||||||
const std::vector<QueryNode> &node_info_list)
|
|
||||||
{
|
|
||||||
std::cout << "[Turn Assignment Progress]\nLocation:";
|
|
||||||
auto coordinate = node_info_list[at];
|
|
||||||
std::cout << std::setprecision(12) << toFloating(coordinate.lat) << " "
|
|
||||||
<< toFloating(coordinate.lon) << "\n";
|
|
||||||
|
|
||||||
std::cout << " Intersection:\n";
|
|
||||||
for (const auto &road)
|
|
||||||
std::cout << "\t" << toString(road) << "\n";
|
|
||||||
|
|
||||||
// flushes as well
|
|
||||||
print(turn_lane_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace guidance
|
|
||||||
} // namespace extractor
|
|
||||||
} // namespace osrm
|
|
||||||
|
|
||||||
#endif /* OSRM_EXTRACTOR_GUIDANCE_DEBUG_HPP_ */
|
|
@ -2,6 +2,7 @@
|
|||||||
#define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_DATA_HPP_
|
#define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_DATA_HPP_
|
||||||
|
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ namespace lanes
|
|||||||
|
|
||||||
struct TurnLaneData
|
struct TurnLaneData
|
||||||
{
|
{
|
||||||
std::string tag;
|
TurnLaneType::Mask tag;
|
||||||
LaneID from;
|
LaneID from;
|
||||||
LaneID to;
|
LaneID to;
|
||||||
|
|
||||||
@ -25,13 +26,14 @@ struct TurnLaneData
|
|||||||
typedef std::vector<TurnLaneData> LaneDataVector;
|
typedef std::vector<TurnLaneData> LaneDataVector;
|
||||||
|
|
||||||
// convertes a string given in the OSM format into a TurnLaneData vector
|
// convertes a string given in the OSM format into a TurnLaneData vector
|
||||||
LaneDataVector laneDataFromString(std::string turn_lane_string);
|
LaneDataVector laneDataFromDescription(const TurnLaneDescription &turn_lane_description);
|
||||||
|
|
||||||
// Locate A Tag in a lane data vector
|
// Locate A Tag in a lane data vector (if multiple tags are set, the first one found is returned)
|
||||||
LaneDataVector::const_iterator findTag(const std::string &tag, const LaneDataVector &data);
|
LaneDataVector::const_iterator findTag(const TurnLaneType::Mask tag, const LaneDataVector &data);
|
||||||
LaneDataVector::iterator findTag(const std::string &tag, LaneDataVector &data);
|
LaneDataVector::iterator findTag(const TurnLaneType::Mask tag, LaneDataVector &data);
|
||||||
|
|
||||||
bool hasTag(const std::string &tag, const LaneDataVector &data);
|
// Returns true if any of the queried tags is contained
|
||||||
|
bool hasTag(const TurnLaneType::Mask tag, const LaneDataVector &data);
|
||||||
|
|
||||||
} // namespace lane_data_generation
|
} // namespace lane_data_generation
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "extractor/guidance/toolkit.hpp"
|
#include "extractor/guidance/toolkit.hpp"
|
||||||
#include "extractor/guidance/turn_analysis.hpp"
|
#include "extractor/guidance/turn_analysis.hpp"
|
||||||
#include "extractor/guidance/turn_lane_data.hpp"
|
#include "extractor/guidance/turn_lane_data.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
#include "extractor/query_node.hpp"
|
#include "extractor/query_node.hpp"
|
||||||
|
|
||||||
#include "util/guidance/turn_lanes.hpp"
|
#include "util/guidance/turn_lanes.hpp"
|
||||||
@ -12,6 +13,7 @@
|
|||||||
#include "util/node_based_graph.hpp"
|
#include "util/node_based_graph.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -34,7 +36,8 @@ class TurnLaneHandler
|
|||||||
typedef std::vector<TurnLaneData> LaneDataVector;
|
typedef std::vector<TurnLaneData> LaneDataVector;
|
||||||
|
|
||||||
TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const util::NameTable &turn_lane_strings,
|
const std::vector<std::uint32_t> &turn_lane_offsets,
|
||||||
|
const std::vector<TurnLaneType::Mask> &turn_lane_masks,
|
||||||
const std::vector<QueryNode> &node_info_list,
|
const std::vector<QueryNode> &node_info_list,
|
||||||
const TurnAnalysis &turn_analysis);
|
const TurnAnalysis &turn_analysis);
|
||||||
|
|
||||||
@ -47,7 +50,8 @@ class TurnLaneHandler
|
|||||||
// we need to be able to look at previous intersections to, in some cases, find the correct turn
|
// we need to be able to look at previous intersections to, in some cases, find the correct turn
|
||||||
// lanes for a turn
|
// lanes for a turn
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||||
const util::NameTable &turn_lane_strings;
|
const std::vector<std::uint32_t> &turn_lane_offsets;
|
||||||
|
const std::vector<TurnLaneType::Mask> &turn_lane_masks;
|
||||||
const std::vector<QueryNode> &node_info_list;
|
const std::vector<QueryNode> &node_info_list;
|
||||||
const TurnAnalysis &turn_analysis;
|
const TurnAnalysis &turn_analysis;
|
||||||
|
|
||||||
@ -58,7 +62,7 @@ class TurnLaneHandler
|
|||||||
// in case of a simple intersection, assign the lane entries
|
// in case of a simple intersection, assign the lane entries
|
||||||
Intersection simpleMatchTuplesToTurns(Intersection intersection,
|
Intersection simpleMatchTuplesToTurns(Intersection intersection,
|
||||||
const LaneDataVector &lane_data,
|
const LaneDataVector &lane_data,
|
||||||
const LaneStringID lane_string_id,
|
const LaneDescriptionID lane_string_id,
|
||||||
LaneDataIdMap &id_map) const;
|
LaneDataIdMap &id_map) const;
|
||||||
|
|
||||||
// partition lane data into lane data relevant at current turn and at next turn
|
// partition lane data into lane data relevant at current turn and at next turn
|
||||||
|
@ -21,24 +21,16 @@ namespace lanes
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Translate Turn Lane Tags into a matching modifier
|
// Translate Turn Lane Tags into a matching modifier
|
||||||
DirectionModifier::Enum getMatchingModifier(const std::string &tag);
|
DirectionModifier::Enum getMatchingModifier(const TurnLaneType::Mask &tag);
|
||||||
|
|
||||||
// check whether a match of a given tag and a turn instruction can be seen as valid
|
// check whether a match of a given tag and a turn instruction can be seen as valid
|
||||||
bool isValidMatch(const std::string &tag, const TurnInstruction instruction);
|
bool isValidMatch(const TurnLaneType::Mask &tag, const TurnInstruction instruction);
|
||||||
|
|
||||||
// Every tag is somewhat idealized in form of the expected angle. A through lane should go straight
|
// localisation of the best possible match for a tag
|
||||||
// (or follow a 180 degree turn angle between in/out segments.) The following function tries to find
|
typename Intersection::const_iterator findBestMatch(const TurnLaneType::Mask &tag,
|
||||||
// the best possible match for every tag in a given intersection, considering a few corner cases
|
|
||||||
// introduced to OSRM handling u-turns
|
|
||||||
typename Intersection::const_iterator findBestMatch(const std::string &tag,
|
|
||||||
const Intersection &intersection);
|
const Intersection &intersection);
|
||||||
// Reverse is a special case, because it requires access to the leftmost tag. It has its own
|
typename Intersection::const_iterator
|
||||||
// matching function as a result of that. The leftmost tag is required, since u-turns are disabled
|
findBestMatchForReverse(const TurnLaneType::Mask &leftmost_tag, const Intersection &intersection);
|
||||||
// by default in OSRM. Therefor we cannot check whether a turn is allowed, since it could be
|
|
||||||
// possible that it is forbidden. In addition, the best u-turn angle does not necessarily represent
|
|
||||||
// the u-turn, since it could be a sharp-left turn instead on a road with a middle island.
|
|
||||||
typename Intersection::const_iterator findBestMatchForReverse(const std::string &leftmost_tag,
|
|
||||||
const Intersection &intersection);
|
|
||||||
|
|
||||||
// a match is trivial if all turns can be associated with their best match in a valid way and the
|
// a match is trivial if all turns can be associated with their best match in a valid way and the
|
||||||
// matches occur in order
|
// matches occur in order
|
||||||
@ -48,7 +40,7 @@ bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &l
|
|||||||
Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
||||||
const LaneDataVector &lane_data,
|
const LaneDataVector &lane_data,
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const LaneStringID lane_string_id,
|
const LaneDescriptionID lane_string_id,
|
||||||
LaneDataIdMap &lane_data_to_id);
|
LaneDataIdMap &lane_data_to_id);
|
||||||
|
|
||||||
} // namespace lanes
|
} // namespace lanes
|
||||||
|
102
include/extractor/guidance/turn_lane_types.hpp
Normal file
102
include/extractor/guidance/turn_lane_types.hpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#ifndef OSRM_GUIDANCE_TURN_LANE_TYPES_HPP_
|
||||||
|
#define OSRM_GUIDANCE_TURN_LANE_TYPES_HPP_
|
||||||
|
|
||||||
|
#include <bitset>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/functional/hash_fwd.hpp>
|
||||||
|
|
||||||
|
#include "util/simple_logger.hpp"
|
||||||
|
#include "util/typedefs.hpp"
|
||||||
|
#include "util/json_container.hpp"
|
||||||
|
|
||||||
|
namespace osrm
|
||||||
|
{
|
||||||
|
namespace extractor
|
||||||
|
{
|
||||||
|
namespace guidance
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace TurnLaneType
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
const constexpr std::size_t num_supported_lane_types = 11;
|
||||||
|
|
||||||
|
const constexpr char *translations[detail::num_supported_lane_types] = {"none",
|
||||||
|
"straight",
|
||||||
|
"sharp left",
|
||||||
|
"left",
|
||||||
|
"slight left",
|
||||||
|
"slight right",
|
||||||
|
"right",
|
||||||
|
"sharp right",
|
||||||
|
"uturn",
|
||||||
|
"merge to left",
|
||||||
|
"merge to right"};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
typedef std::uint16_t Mask;
|
||||||
|
const constexpr Mask empty = 0u;
|
||||||
|
const constexpr Mask none = 1u << 0u;
|
||||||
|
const constexpr Mask straight = 1u << 1u;
|
||||||
|
const constexpr Mask sharp_left = 1u << 2u;
|
||||||
|
const constexpr Mask left = 1u << 3u;
|
||||||
|
const constexpr Mask slight_left = 1u << 4u;
|
||||||
|
const constexpr Mask slight_right = 1u << 5u;
|
||||||
|
const constexpr Mask right = 1u << 6u;
|
||||||
|
const constexpr Mask sharp_right = 1u << 7u;
|
||||||
|
const constexpr Mask uturn = 1u << 8u;
|
||||||
|
const constexpr Mask merge_to_left = 1u << 9u;
|
||||||
|
const constexpr Mask merge_to_right = 1u << 10u;
|
||||||
|
|
||||||
|
inline std::string toString(const Mask lane_type)
|
||||||
|
{
|
||||||
|
if (lane_type == 0)
|
||||||
|
return "none";
|
||||||
|
|
||||||
|
std::bitset<8 * sizeof(Mask)> mask(lane_type);
|
||||||
|
std::string result = "";
|
||||||
|
for (std::size_t lane_id_nr = 0; lane_id_nr < detail::num_supported_lane_types; ++lane_id_nr)
|
||||||
|
if (mask[lane_id_nr])
|
||||||
|
result += (result.empty() ? detail::translations[lane_id_nr]
|
||||||
|
: (std::string(";") + detail::translations[lane_id_nr]));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline util::json::Array toJsonArray(const Mask lane_type)
|
||||||
|
{
|
||||||
|
util::json::Array result;
|
||||||
|
std::bitset<8 * sizeof(Mask)> mask(lane_type);
|
||||||
|
for (std::size_t lane_id_nr = 0; lane_id_nr < detail::num_supported_lane_types; ++lane_id_nr)
|
||||||
|
if (mask[lane_id_nr])
|
||||||
|
result.values.push_back(detail::translations[lane_id_nr]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} // TurnLaneType
|
||||||
|
|
||||||
|
typedef std::vector<TurnLaneType::Mask> TurnLaneDescription;
|
||||||
|
|
||||||
|
// hash function for TurnLaneDescription
|
||||||
|
struct TurnLaneDescription_hash
|
||||||
|
{
|
||||||
|
std::size_t operator()(const TurnLaneDescription &lane_description) const
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
for (auto val : lane_description)
|
||||||
|
boost::hash_combine(seed, val);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // guidance
|
||||||
|
} // extractor
|
||||||
|
} // osrm
|
||||||
|
|
||||||
|
#endif /* OSRM_GUIDANCE_TURN_LANE_TYPES_HPP_ */
|
@ -50,7 +50,7 @@ struct InternalExtractorEdge
|
|||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
false,
|
false,
|
||||||
INVALID_LANE_STRINGID,
|
guidance::TurnLaneType::empty,
|
||||||
guidance::RoadClassificationData())
|
guidance::RoadClassificationData())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ struct InternalExtractorEdge
|
|||||||
bool startpoint,
|
bool startpoint,
|
||||||
TravelMode travel_mode,
|
TravelMode travel_mode,
|
||||||
bool is_split,
|
bool is_split,
|
||||||
const LaneStringID lane_id,
|
LaneDescriptionID lane_description,
|
||||||
guidance::RoadClassificationData road_classification)
|
guidance::RoadClassificationData road_classification)
|
||||||
: result(OSMNodeID(source),
|
: result(OSMNodeID(source),
|
||||||
OSMNodeID(target),
|
OSMNodeID(target),
|
||||||
@ -79,7 +79,7 @@ struct InternalExtractorEdge
|
|||||||
startpoint,
|
startpoint,
|
||||||
travel_mode,
|
travel_mode,
|
||||||
is_split,
|
is_split,
|
||||||
lane_id,
|
lane_description,
|
||||||
std::move(road_classification)),
|
std::move(road_classification)),
|
||||||
weight_data(std::move(weight_data))
|
weight_data(std::move(weight_data))
|
||||||
{
|
{
|
||||||
@ -106,7 +106,7 @@ struct InternalExtractorEdge
|
|||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
false,
|
false,
|
||||||
INVALID_LANE_STRINGID,
|
INVALID_LANE_DESCRIPTIONID,
|
||||||
guidance::RoadClassificationData());
|
guidance::RoadClassificationData());
|
||||||
}
|
}
|
||||||
static InternalExtractorEdge max_osm_value()
|
static InternalExtractorEdge max_osm_value()
|
||||||
@ -122,7 +122,7 @@ struct InternalExtractorEdge
|
|||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
false,
|
false,
|
||||||
INVALID_LANE_STRINGID,
|
INVALID_LANE_DESCRIPTIONID,
|
||||||
guidance::RoadClassificationData());
|
guidance::RoadClassificationData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ struct NodeBasedEdge
|
|||||||
bool startpoint,
|
bool startpoint,
|
||||||
TravelMode travel_mode,
|
TravelMode travel_mode,
|
||||||
bool is_split,
|
bool is_split,
|
||||||
const LaneStringID lane_id,
|
const LaneDescriptionID lane_description_id,
|
||||||
guidance::RoadClassificationData road_classification);
|
guidance::RoadClassificationData road_classification);
|
||||||
|
|
||||||
bool operator<(const NodeBasedEdge &other) const;
|
bool operator<(const NodeBasedEdge &other) const;
|
||||||
@ -42,7 +42,7 @@ struct NodeBasedEdge
|
|||||||
bool startpoint : 1;
|
bool startpoint : 1;
|
||||||
bool is_split : 1;
|
bool is_split : 1;
|
||||||
TravelMode travel_mode : 4;
|
TravelMode travel_mode : 4;
|
||||||
LaneStringID lane_string_id;
|
LaneDescriptionID lane_description_id;
|
||||||
guidance::RoadClassificationData road_classification;
|
guidance::RoadClassificationData road_classification;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
|||||||
bool startpoint,
|
bool startpoint,
|
||||||
TravelMode travel_mode,
|
TravelMode travel_mode,
|
||||||
bool is_split,
|
bool is_split,
|
||||||
const LaneStringID lane_string_id,
|
const LaneDescriptionID lane_description_id,
|
||||||
guidance::RoadClassificationData road_classification);
|
guidance::RoadClassificationData road_classification);
|
||||||
|
|
||||||
OSMNodeID osm_source_id;
|
OSMNodeID osm_source_id;
|
||||||
@ -71,7 +71,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
|||||||
inline NodeBasedEdge::NodeBasedEdge()
|
inline NodeBasedEdge::NodeBasedEdge()
|
||||||
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), forward(false),
|
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), forward(false),
|
||||||
backward(false), roundabout(false), access_restricted(false), startpoint(true),
|
backward(false), roundabout(false), access_restricted(false), startpoint(true),
|
||||||
is_split(false), travel_mode(false), lane_string_id(0)
|
is_split(false), travel_mode(false), lane_description_id(INVALID_LANE_DESCRIPTIONID)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,12 +86,12 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
|
|||||||
bool startpoint,
|
bool startpoint,
|
||||||
TravelMode travel_mode,
|
TravelMode travel_mode,
|
||||||
bool is_split,
|
bool is_split,
|
||||||
const LaneStringID lane_string_id,
|
const LaneDescriptionID lane_description_id,
|
||||||
guidance::RoadClassificationData road_classification)
|
guidance::RoadClassificationData road_classification)
|
||||||
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
|
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
|
||||||
backward(backward), roundabout(roundabout), access_restricted(access_restricted),
|
backward(backward), roundabout(roundabout), access_restricted(access_restricted),
|
||||||
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode),
|
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode),
|
||||||
lane_string_id(lane_string_id), road_classification(std::move(road_classification))
|
lane_description_id(lane_description_id), road_classification(std::move(road_classification))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(
|
|||||||
bool startpoint,
|
bool startpoint,
|
||||||
TravelMode travel_mode,
|
TravelMode travel_mode,
|
||||||
bool is_split,
|
bool is_split,
|
||||||
const LaneStringID lane_string_id,
|
const LaneDescriptionID lane_description_id,
|
||||||
guidance::RoadClassificationData road_classification)
|
guidance::RoadClassificationData road_classification)
|
||||||
: NodeBasedEdge(SPECIAL_NODEID,
|
: NodeBasedEdge(SPECIAL_NODEID,
|
||||||
SPECIAL_NODEID,
|
SPECIAL_NODEID,
|
||||||
@ -137,7 +137,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(
|
|||||||
startpoint,
|
startpoint,
|
||||||
travel_mode,
|
travel_mode,
|
||||||
is_split,
|
is_split,
|
||||||
lane_string_id,
|
lane_description_id,
|
||||||
std::move(road_classification)),
|
std::move(road_classification)),
|
||||||
osm_source_id(std::move(source)), osm_target_id(std::move(target))
|
osm_source_id(std::move(source)), osm_target_id(std::move(target))
|
||||||
{
|
{
|
||||||
|
@ -47,9 +47,8 @@ const constexpr char *block_id_to_name[] = {"NAME_OFFSETS",
|
|||||||
"ENTRY_CLASS",
|
"ENTRY_CLASS",
|
||||||
"LANE_DATA_ID",
|
"LANE_DATA_ID",
|
||||||
"TURN_LANE_DATA",
|
"TURN_LANE_DATA",
|
||||||
"TURN_STRING_OFFSETS",
|
"LANE_DESCRIPTION_OFFSETS",
|
||||||
"TURN_STRING_BLOCKS",
|
"LANE_DESCRIPTION_MASKS"};
|
||||||
"TURN_STRING_CHAR_LIST"};
|
|
||||||
|
|
||||||
struct SharedDataLayout
|
struct SharedDataLayout
|
||||||
{
|
{
|
||||||
@ -86,9 +85,8 @@ struct SharedDataLayout
|
|||||||
ENTRY_CLASS,
|
ENTRY_CLASS,
|
||||||
LANE_DATA_ID,
|
LANE_DATA_ID,
|
||||||
TURN_LANE_DATA,
|
TURN_LANE_DATA,
|
||||||
TURN_STRING_OFFSETS,
|
LANE_DESCRIPTION_OFFSETS,
|
||||||
TURN_STRING_BLOCKS,
|
LANE_DESCRIPTION_MASKS,
|
||||||
TURN_STRING_CHAR_LIST,
|
|
||||||
NUM_BLOCKS
|
NUM_BLOCKS
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -184,6 +182,9 @@ struct SharedDataTimestamp
|
|||||||
SharedDataType data;
|
SharedDataType data;
|
||||||
unsigned timestamp;
|
unsigned timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(block_id_to_name) / sizeof(*block_id_to_name) == SharedDataLayout::NUM_BLOCKS,
|
||||||
|
"Number of blocks needs to match the number of Block names.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ struct StorageConfig final
|
|||||||
boost::filesystem::path properties_path;
|
boost::filesystem::path properties_path;
|
||||||
boost::filesystem::path intersection_class_path;
|
boost::filesystem::path intersection_class_path;
|
||||||
boost::filesystem::path turn_lane_data_path;
|
boost::filesystem::path turn_lane_data_path;
|
||||||
boost::filesystem::path turn_lane_string_path;
|
boost::filesystem::path turn_lane_description_path;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
88
include/util/debug.hpp
Normal file
88
include/util/debug.hpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#ifndef OSRM_ENGINE_GUIDANCE_DEBUG_HPP_
|
||||||
|
#define OSRM_ENGINE_GUIDANCE_DEBUG_HPP_
|
||||||
|
|
||||||
|
#include "extractor/guidance/intersection.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_data.hpp"
|
||||||
|
#include "extractor/query_node.hpp"
|
||||||
|
#include "engine/guidance/route_step.hpp"
|
||||||
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace osrm
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
namespace guidance
|
||||||
|
{
|
||||||
|
inline void print(const engine::guidance::RouteStep &step)
|
||||||
|
{
|
||||||
|
std::cout << static_cast<int>(step.maneuver.instruction.type) << " "
|
||||||
|
<< static_cast<int>(step.maneuver.instruction.direction_modifier) << " "
|
||||||
|
<< static_cast<int>(step.maneuver.waypoint_type) << " Duration: " << step.duration
|
||||||
|
<< " Distance: " << step.distance << " Geometry: " << step.geometry_begin << " "
|
||||||
|
<< step.geometry_end << " exit: " << step.maneuver.exit
|
||||||
|
<< " Intersections: " << step.intersections.size() << " [";
|
||||||
|
|
||||||
|
for (const auto &intersection : step.intersections)
|
||||||
|
{
|
||||||
|
std::cout << "(bearings:";
|
||||||
|
for (auto bearing : intersection.bearings)
|
||||||
|
std::cout << " " << bearing;
|
||||||
|
std::cout << ", entry: ";
|
||||||
|
for (auto entry : intersection.entry)
|
||||||
|
std::cout << " " << (entry ? "true" : "false");
|
||||||
|
std::cout << ")";
|
||||||
|
}
|
||||||
|
std::cout << "] name[" << step.name_id << "]: " << step.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void print(const std::vector<engine::guidance::RouteStep> &steps)
|
||||||
|
{
|
||||||
|
std::cout << "Path\n";
|
||||||
|
int segment = 0;
|
||||||
|
for (const auto &step : steps)
|
||||||
|
{
|
||||||
|
std::cout << "\t[" << segment++ << "]: ";
|
||||||
|
print(step);
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void print(const extractor::guidance::lanes::LaneDataVector &turn_lane_data)
|
||||||
|
{
|
||||||
|
std::cout << " Tags:\n";
|
||||||
|
for (auto entry : turn_lane_data)
|
||||||
|
std::cout << "\t" << entry.tag << "("
|
||||||
|
<< extractor::guidance::TurnLaneType::toString(entry.tag)
|
||||||
|
<< ") from: " << static_cast<int>(entry.from)
|
||||||
|
<< " to: " << static_cast<int>(entry.to) << "\n";
|
||||||
|
std::cout << std::flush;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
printTurnAssignmentData(const NodeID at,
|
||||||
|
const extractor::guidance::lanes::LaneDataVector &turn_lane_data,
|
||||||
|
const extractor::guidance::Intersection &intersection,
|
||||||
|
const std::vector<extractor::QueryNode> &node_info_list)
|
||||||
|
{
|
||||||
|
std::cout << "[Turn Assignment Progress]\nLocation:";
|
||||||
|
auto coordinate = node_info_list[at];
|
||||||
|
std::cout << std::setprecision(12) << toFloating(coordinate.lat) << " "
|
||||||
|
<< toFloating(coordinate.lon) << "\n";
|
||||||
|
|
||||||
|
std::cout << " Intersection:\n";
|
||||||
|
for (const auto &road : intersection)
|
||||||
|
std::cout << "\t" << toString(road) << "\n";
|
||||||
|
|
||||||
|
// flushes as well
|
||||||
|
print(turn_lane_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace guidance
|
||||||
|
} // namespace util
|
||||||
|
} // namespace osrm
|
||||||
|
|
||||||
|
#endif /*OSRM_ENGINE_GUIDANCE_DEBUG_HPP_*/
|
@ -74,7 +74,7 @@ class LaneTupel
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using LaneTupelIdPair = std::pair<util::guidance::LaneTupel, LaneStringID>;
|
using LaneTupelIdPair = std::pair<util::guidance::LaneTupel, LaneDescriptionID>;
|
||||||
} // namespace guidance
|
} // namespace guidance
|
||||||
} // namespace util
|
} // namespace util
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -4,12 +4,14 @@
|
|||||||
#include "util/simple_logger.hpp"
|
#include "util/simple_logger.hpp"
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/numeric/conversion/cast.hpp>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <stxxl/vector>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "util/fingerprint.hpp"
|
#include "util/fingerprint.hpp"
|
||||||
@ -88,6 +90,84 @@ bool deserializeVector(std::istream &stream, std::vector<simple_type> &data)
|
|||||||
return static_cast<bool>(stream);
|
return static_cast<bool>(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// serializes a vector of vectors into an adjacency array (creates a copy of the data internally)
|
||||||
|
template <typename simple_type>
|
||||||
|
bool serializeVectorIntoAdjacencyArray(const std::string &filename,
|
||||||
|
const std::vector<std::vector<simple_type>> &data)
|
||||||
|
{
|
||||||
|
std::ofstream out_stream(filename, std::ios::binary);
|
||||||
|
std::vector<std::uint32_t> offsets;
|
||||||
|
offsets.reserve(data.size() + 1);
|
||||||
|
std::uint64_t current_offset = 0;
|
||||||
|
offsets.push_back(current_offset);
|
||||||
|
for (auto const &vec : data)
|
||||||
|
{
|
||||||
|
current_offset += vec.size();
|
||||||
|
offsets.push_back(boost::numeric_cast<std::uint32_t>(current_offset));
|
||||||
|
}
|
||||||
|
if (!serializeVector(out_stream, offsets))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::vector<simple_type> all_data;
|
||||||
|
all_data.reserve(offsets.back());
|
||||||
|
for (auto const &vec : data)
|
||||||
|
all_data.insert(all_data.end(), vec.begin(), vec.end());
|
||||||
|
|
||||||
|
if (!serializeVector(out_stream, all_data))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return static_cast<bool>(out_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename simple_type, std::size_t WRITE_BLOCK_BUFFER_SIZE = 1024>
|
||||||
|
bool serializeVector(std::ofstream &out_stream, const stxxl::vector<simple_type> &data)
|
||||||
|
{
|
||||||
|
const std::uint64_t size = data.size();
|
||||||
|
out_stream.write(reinterpret_cast<const char *>(&size), sizeof(size));
|
||||||
|
|
||||||
|
simple_type write_buffer[WRITE_BLOCK_BUFFER_SIZE];
|
||||||
|
std::size_t buffer_len = 0;
|
||||||
|
|
||||||
|
for (const auto entry : data)
|
||||||
|
{
|
||||||
|
write_buffer[buffer_len++] = entry;
|
||||||
|
|
||||||
|
if (buffer_len >= WRITE_BLOCK_BUFFER_SIZE)
|
||||||
|
{
|
||||||
|
out_stream.write(reinterpret_cast<const char *>(write_buffer),
|
||||||
|
WRITE_BLOCK_BUFFER_SIZE * sizeof(simple_type));
|
||||||
|
buffer_len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write remaining entries
|
||||||
|
if (buffer_len > 0)
|
||||||
|
out_stream.write(reinterpret_cast<const char *>(write_buffer),
|
||||||
|
buffer_len * sizeof(simple_type));
|
||||||
|
|
||||||
|
return static_cast<bool>(out_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename simple_type>
|
||||||
|
bool deserializeAdjacencyArray(const std::string &filename,
|
||||||
|
std::vector<std::uint32_t> &offsets,
|
||||||
|
std::vector<simple_type>& data)
|
||||||
|
{
|
||||||
|
std::ifstream in_stream(filename, std::ios::binary);
|
||||||
|
|
||||||
|
if (!deserializeVector(in_stream, offsets))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!deserializeVector(in_stream, data))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// offsets have to match up with the size of the data
|
||||||
|
if (offsets.empty() || (offsets.back() != boost::numeric_cast<std::uint32_t>(data.size())))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return static_cast<bool>(in_stream);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool serializeFlags(const boost::filesystem::path &path, const std::vector<bool> &flags)
|
inline bool serializeFlags(const boost::filesystem::path &path, const std::vector<bool> &flags)
|
||||||
{
|
{
|
||||||
// TODO this should be replaced with a FILE-based write using error checking
|
// TODO this should be replaced with a FILE-based write using error checking
|
||||||
|
@ -21,7 +21,7 @@ struct NodeBasedEdgeData
|
|||||||
: distance(INVALID_EDGE_WEIGHT), edge_id(SPECIAL_NODEID),
|
: distance(INVALID_EDGE_WEIGHT), edge_id(SPECIAL_NODEID),
|
||||||
name_id(std::numeric_limits<unsigned>::max()), access_restricted(false), reversed(false),
|
name_id(std::numeric_limits<unsigned>::max()), access_restricted(false), reversed(false),
|
||||||
roundabout(false), travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
roundabout(false), travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
||||||
lane_string_id(INVALID_LANE_STRINGID)
|
lane_description_id(INVALID_LANE_DESCRIPTIONID)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,10 +33,10 @@ struct NodeBasedEdgeData
|
|||||||
bool roundabout,
|
bool roundabout,
|
||||||
bool startpoint,
|
bool startpoint,
|
||||||
extractor::TravelMode travel_mode,
|
extractor::TravelMode travel_mode,
|
||||||
const LaneStringID lane_string_id)
|
const LaneDescriptionID lane_description_id)
|
||||||
: distance(distance), edge_id(edge_id), name_id(name_id),
|
: distance(distance), edge_id(edge_id), name_id(name_id),
|
||||||
access_restricted(access_restricted), reversed(reversed), roundabout(roundabout),
|
access_restricted(access_restricted), reversed(reversed), roundabout(roundabout),
|
||||||
startpoint(startpoint), travel_mode(travel_mode), lane_string_id(lane_string_id)
|
startpoint(startpoint), travel_mode(travel_mode), lane_description_id(lane_description_id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ struct NodeBasedEdgeData
|
|||||||
bool roundabout : 1;
|
bool roundabout : 1;
|
||||||
bool startpoint : 1;
|
bool startpoint : 1;
|
||||||
extractor::TravelMode travel_mode : 4;
|
extractor::TravelMode travel_mode : 4;
|
||||||
LaneStringID lane_string_id;
|
LaneDescriptionID lane_description_id;
|
||||||
extractor::guidance::RoadClassificationData road_classification;
|
extractor::guidance::RoadClassificationData road_classification;
|
||||||
|
|
||||||
bool IsCompatibleTo(const NodeBasedEdgeData &other) const
|
bool IsCompatibleTo(const NodeBasedEdgeData &other) const
|
||||||
@ -83,7 +83,7 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
|||||||
output_edge.data.travel_mode = input_edge.travel_mode;
|
output_edge.data.travel_mode = input_edge.travel_mode;
|
||||||
output_edge.data.startpoint = input_edge.startpoint;
|
output_edge.data.startpoint = input_edge.startpoint;
|
||||||
output_edge.data.road_classification = input_edge.road_classification;
|
output_edge.data.road_classification = input_edge.road_classification;
|
||||||
output_edge.data.lane_string_id = input_edge.lane_string_id;
|
output_edge.data.lane_description_id = input_edge.lane_description_id;
|
||||||
});
|
});
|
||||||
|
|
||||||
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
||||||
|
@ -59,12 +59,12 @@ using EdgeID = std::uint32_t;
|
|||||||
using NameID = std::uint32_t;
|
using NameID = std::uint32_t;
|
||||||
using EdgeWeight = std::int32_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;
|
using LaneID = std::uint8_t;
|
||||||
static const LaneID INVALID_LANEID = std::numeric_limits<LaneID>::max();
|
static const LaneID INVALID_LANEID = std::numeric_limits<LaneID>::max();
|
||||||
using LaneDataID = std::uint16_t;
|
using LaneDataID = std::uint16_t;
|
||||||
static const LaneDataID INVALID_LANE_DATAID = std::numeric_limits<LaneStringID>::max();
|
static const LaneDataID INVALID_LANE_DATAID = std::numeric_limits<LaneDataID>::max();
|
||||||
|
using LaneDescriptionID = std::uint16_t;
|
||||||
|
static const LaneDescriptionID INVALID_LANE_DESCRIPTIONID = std::numeric_limits<LaneDescriptionID>::max();
|
||||||
|
|
||||||
using BearingClassID = std::uint32_t;
|
using BearingClassID = std::uint32_t;
|
||||||
static const BearingClassID INVALID_BEARING_CLASSID = std::numeric_limits<BearingClassID>::max();
|
static const BearingClassID INVALID_BEARING_CLASSID = std::numeric_limits<BearingClassID>::max();
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/tokenizer.hpp>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
@ -76,23 +75,18 @@ util::json::Array lanesFromManeuver(const guidance::StepManeuver &maneuver)
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(maneuver.lanes.lanes_in_turn >= 1);
|
BOOST_ASSERT(maneuver.lanes.lanes_in_turn >= 1);
|
||||||
util::json::Array result;
|
util::json::Array result;
|
||||||
LaneID lane_id = 0;
|
LaneID lane_id = maneuver.lane_description.size();
|
||||||
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 (const auto &lane_desc : maneuver.lane_description)
|
||||||
|
|
||||||
for (auto iter = tokens.begin(); iter != tokens.end(); ++iter)
|
|
||||||
{
|
{
|
||||||
--lane_id;
|
--lane_id;
|
||||||
util::json::Object lane;
|
util::json::Object lane;
|
||||||
lane.values["marked"] = (iter->empty() ? "none" : *iter);
|
lane.values["indications"] = extractor::guidance::TurnLaneType::toJsonArray(lane_desc);
|
||||||
if (lane_id >= maneuver.lanes.first_lane_from_the_right &&
|
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_id < maneuver.lanes.first_lane_from_the_right + maneuver.lanes.lanes_in_turn)
|
||||||
lane.values["take"] = util::json::True();
|
lane.values["valid"] = util::json::True();
|
||||||
else
|
else
|
||||||
lane.values["take"] = util::json::False();
|
lane.values["valid"] = util::json::False();
|
||||||
|
|
||||||
result.values.push_back(lane);
|
result.values.push_back(lane);
|
||||||
}
|
}
|
||||||
|
@ -140,8 +140,6 @@ RouteStep forwardInto(RouteStep destination, const RouteStep &source)
|
|||||||
|
|
||||||
destination.geometry_begin = std::min(destination.geometry_begin, source.geometry_begin);
|
destination.geometry_begin = std::min(destination.geometry_begin, source.geometry_begin);
|
||||||
destination.geometry_end = std::max(destination.geometry_end, source.geometry_end);
|
destination.geometry_end = std::max(destination.geometry_end, source.geometry_end);
|
||||||
destination.maneuver.exit = source.maneuver.exit;
|
|
||||||
|
|
||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,6 +222,7 @@ void closeOffRoundabout(const bool on_roundabout,
|
|||||||
const std::size_t step_index)
|
const std::size_t step_index)
|
||||||
{
|
{
|
||||||
auto &step = steps[step_index];
|
auto &step = steps[step_index];
|
||||||
|
step.maneuver.exit += 1;
|
||||||
if (!on_roundabout)
|
if (!on_roundabout)
|
||||||
{
|
{
|
||||||
// We reached a special case that requires the addition of a special route step in the
|
// We reached a special case that requires the addition of a special route step in the
|
||||||
@ -257,7 +256,6 @@ void closeOffRoundabout(const bool on_roundabout,
|
|||||||
if (steps[1].maneuver.instruction.type == TurnType::EnterRotary)
|
if (steps[1].maneuver.instruction.type == TurnType::EnterRotary)
|
||||||
steps[1].rotary_name = steps[0].name;
|
steps[1].rotary_name = steps[0].name;
|
||||||
}
|
}
|
||||||
step.maneuver.exit += 1;
|
|
||||||
|
|
||||||
// Normal exit from the roundabout, or exit from a previously fixed roundabout. Propagate the
|
// Normal exit from the roundabout, or exit from a previously fixed roundabout. Propagate the
|
||||||
// index back to the entering location and prepare the current silent set of instructions for
|
// index back to the entering location and prepare the current silent set of instructions for
|
||||||
@ -280,7 +278,6 @@ void closeOffRoundabout(const bool on_roundabout,
|
|||||||
propagation_step = forwardInto(propagation_step, steps[propagation_index + 1]);
|
propagation_step = forwardInto(propagation_step, steps[propagation_index + 1]);
|
||||||
if (entersRoundabout(propagation_step.maneuver.instruction))
|
if (entersRoundabout(propagation_step.maneuver.instruction))
|
||||||
{
|
{
|
||||||
propagation_step.maneuver.exit = step.maneuver.exit;
|
|
||||||
const auto entry_intersection = propagation_step.intersections.front();
|
const auto entry_intersection = propagation_step.intersections.front();
|
||||||
|
|
||||||
// remember rotary name
|
// remember rotary name
|
||||||
@ -412,7 +409,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
|||||||
else if (one_back_step.distance <= MAX_COLLAPSE_DISTANCE &&
|
else if (one_back_step.distance <= MAX_COLLAPSE_DISTANCE &&
|
||||||
isCollapsableInstruction(current_step.maneuver.instruction))
|
isCollapsableInstruction(current_step.maneuver.instruction))
|
||||||
{
|
{
|
||||||
// TODO check for lanes
|
// TODO check for lanes (https://github.com/Project-OSRM/osrm-backend/issues/2553)
|
||||||
if (compatible(one_back_step, current_step))
|
if (compatible(one_back_step, current_step))
|
||||||
{
|
{
|
||||||
steps[one_back_index] = elongate(std::move(steps[one_back_index]), steps[step_index]);
|
steps[one_back_index] = elongate(std::move(steps[one_back_index]), steps[step_index]);
|
||||||
@ -583,8 +580,6 @@ std::vector<RouteStep> postProcess(std::vector<RouteStep> steps)
|
|||||||
has_entered_roundabout = false;
|
has_entered_roundabout = false;
|
||||||
on_roundabout = false;
|
on_roundabout = false;
|
||||||
}
|
}
|
||||||
else if (has_entered_roundabout)
|
|
||||||
steps[step_index + 1].maneuver.exit = step.maneuver.exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unterminated roundabout
|
// unterminated roundabout
|
||||||
@ -864,7 +859,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
|||||||
// we need to make this conform with the intersection format for the first intersection
|
// we need to make this conform with the intersection format for the first intersection
|
||||||
auto &first_intersection = designated_depart.intersections.front();
|
auto &first_intersection = designated_depart.intersections.front();
|
||||||
designated_depart.maneuver.lanes = util::guidance::LaneTupel();
|
designated_depart.maneuver.lanes = util::guidance::LaneTupel();
|
||||||
designated_depart.maneuver.turn_lane_string = "";
|
designated_depart.maneuver.lane_description.clear();
|
||||||
first_intersection.bearings = {first_intersection.bearings[first_intersection.out]};
|
first_intersection.bearings = {first_intersection.bearings[first_intersection.out]};
|
||||||
first_intersection.entry = {true};
|
first_intersection.entry = {true};
|
||||||
first_intersection.in = Intersection::NO_INDEX;
|
first_intersection.in = Intersection::NO_INDEX;
|
||||||
@ -932,7 +927,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
|||||||
next_to_last_step.maneuver.instruction = TurnInstruction::NO_TURN();
|
next_to_last_step.maneuver.instruction = TurnInstruction::NO_TURN();
|
||||||
next_to_last_step.maneuver.bearing_after = 0;
|
next_to_last_step.maneuver.bearing_after = 0;
|
||||||
next_to_last_step.maneuver.lanes = util::guidance::LaneTupel();
|
next_to_last_step.maneuver.lanes = util::guidance::LaneTupel();
|
||||||
next_to_last_step.maneuver.turn_lane_string = "";
|
next_to_last_step.maneuver.lane_description.clear();
|
||||||
BOOST_ASSERT(next_to_last_step.intersections.size() == 1);
|
BOOST_ASSERT(next_to_last_step.intersections.size() == 1);
|
||||||
auto &last_intersection = next_to_last_step.intersections.back();
|
auto &last_intersection = next_to_last_step.intersections.back();
|
||||||
last_intersection.bearings = {last_intersection.bearings[last_intersection.in]};
|
last_intersection.bearings = {last_intersection.bearings[last_intersection.in]};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "extractor/edge_based_graph_factory.hpp"
|
|
||||||
#include "extractor/edge_based_edge.hpp"
|
#include "extractor/edge_based_edge.hpp"
|
||||||
|
#include "extractor/edge_based_graph_factory.hpp"
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
#include "util/coordinate_calculation.hpp"
|
#include "util/coordinate_calculation.hpp"
|
||||||
#include "util/exception.hpp"
|
#include "util/exception.hpp"
|
||||||
@ -41,13 +41,14 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
|||||||
const std::vector<QueryNode> &node_info_list,
|
const std::vector<QueryNode> &node_info_list,
|
||||||
ProfileProperties profile_properties,
|
ProfileProperties profile_properties,
|
||||||
const util::NameTable &name_table,
|
const util::NameTable &name_table,
|
||||||
const util::NameTable &turn_lanes)
|
const std::vector<std::uint32_t> &turn_lane_offsets,
|
||||||
|
const std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks)
|
||||||
: m_max_edge_id(0), m_node_info_list(node_info_list),
|
: m_max_edge_id(0), m_node_info_list(node_info_list),
|
||||||
m_node_based_graph(std::move(node_based_graph)),
|
m_node_based_graph(std::move(node_based_graph)),
|
||||||
m_restriction_map(std::move(restriction_map)), m_barrier_nodes(barrier_nodes),
|
m_restriction_map(std::move(restriction_map)), m_barrier_nodes(barrier_nodes),
|
||||||
m_traffic_lights(traffic_lights), m_compressed_edge_container(compressed_edge_container),
|
m_traffic_lights(traffic_lights), m_compressed_edge_container(compressed_edge_container),
|
||||||
profile_properties(std::move(profile_properties)), name_table(name_table),
|
profile_properties(std::move(profile_properties)), name_table(name_table),
|
||||||
turn_lanes(turn_lanes)
|
turn_lane_offsets(turn_lane_offsets), turn_lane_masks(turn_lane_masks)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,7 +347,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table);
|
street_name_suffix_table);
|
||||||
guidance::lanes::TurnLaneHandler turn_lane_handler(
|
guidance::lanes::TurnLaneHandler turn_lane_handler(
|
||||||
*m_node_based_graph, turn_lanes, m_node_info_list, turn_analysis);
|
*m_node_based_graph, turn_lane_offsets, turn_lane_masks, m_node_info_list, turn_analysis);
|
||||||
|
|
||||||
bearing_class_by_node_based_node.resize(m_node_based_graph->GetNumberOfNodes(),
|
bearing_class_by_node_based_node.resize(m_node_based_graph->GetNumberOfNodes(),
|
||||||
std::numeric_limits<std::uint32_t>::max());
|
std::numeric_limits<std::uint32_t>::max());
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "util/exception.hpp"
|
#include "util/exception.hpp"
|
||||||
#include "util/fingerprint.hpp"
|
#include "util/fingerprint.hpp"
|
||||||
|
#include "util/io.hpp"
|
||||||
#include "util/lua_util.hpp"
|
#include "util/lua_util.hpp"
|
||||||
#include "util/simple_logger.hpp"
|
#include "util/simple_logger.hpp"
|
||||||
#include "util/timing_util.hpp"
|
#include "util/timing_util.hpp"
|
||||||
@ -51,7 +52,11 @@ 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);
|
name_lengths.push_back(0);
|
||||||
turn_lane_lengths.push_back(0);
|
|
||||||
|
// the offsets have to be initialized with two values, since we have the empty turn string for
|
||||||
|
// the first id
|
||||||
|
turn_lane_offsets.push_back(0);
|
||||||
|
turn_lane_offsets.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,7 +91,7 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
|
|||||||
WriteRestrictions(restrictions_file_name);
|
WriteRestrictions(restrictions_file_name);
|
||||||
|
|
||||||
WriteCharData(name_file_name, name_lengths, name_char_data);
|
WriteCharData(name_file_name, name_lengths, name_char_data);
|
||||||
WriteCharData(turn_lane_file_name, turn_lane_lengths, turn_lane_char_data);
|
WriteTurnLaneMasks(turn_lane_file_name, turn_lane_offsets, turn_lane_masks);
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
@ -94,6 +99,32 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExtractionContainers::WriteTurnLaneMasks(
|
||||||
|
const std::string &file_name,
|
||||||
|
const stxxl::vector<std::uint32_t> &offsets,
|
||||||
|
const stxxl::vector<guidance::TurnLaneType::Mask> &masks) const
|
||||||
|
{
|
||||||
|
util::SimpleLogger().Write() << "Writing turn lane masks...";
|
||||||
|
TIMER_START(turn_lane_timer);
|
||||||
|
|
||||||
|
std::ofstream ofs(file_name, std::ios::binary);
|
||||||
|
|
||||||
|
if (!util::serializeVector(ofs, offsets))
|
||||||
|
{
|
||||||
|
util::SimpleLogger().Write(logWARNING) << "Error while writing.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!util::serializeVector(ofs, masks))
|
||||||
|
{
|
||||||
|
util::SimpleLogger().Write(logWARNING) << "Error while writing.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TIMER_STOP(turn_lane_timer);
|
||||||
|
util::SimpleLogger().Write() << "done (" << TIMER_SEC(turn_lane_timer) << ")";
|
||||||
|
}
|
||||||
|
|
||||||
void ExtractionContainers::WriteCharData(const std::string &file_name,
|
void ExtractionContainers::WriteCharData(const std::string &file_name,
|
||||||
const stxxl::vector<unsigned> &offsets,
|
const stxxl::vector<unsigned> &offsets,
|
||||||
const stxxl::vector<char> &char_data) const
|
const stxxl::vector<char> &char_data) const
|
||||||
|
@ -239,7 +239,7 @@ int Extractor::run()
|
|||||||
extraction_containers.PrepareData(config.output_file_name,
|
extraction_containers.PrepareData(config.output_file_name,
|
||||||
config.restriction_file_name,
|
config.restriction_file_name,
|
||||||
config.names_file_name,
|
config.names_file_name,
|
||||||
config.turn_lane_strings_file_name,
|
config.turn_lane_descriptions_file_name,
|
||||||
main_context.state);
|
main_context.state);
|
||||||
|
|
||||||
WriteProfileProperties(config.profile_properties_output_path, main_context.properties);
|
WriteProfileProperties(config.profile_properties_output_path, main_context.properties);
|
||||||
@ -504,7 +504,14 @@ Extractor::BuildEdgeExpandedGraph(lua_State *lua_state,
|
|||||||
compressed_edge_container.SerializeInternalVector(config.geometry_output_path);
|
compressed_edge_container.SerializeInternalVector(config.geometry_output_path);
|
||||||
|
|
||||||
util::NameTable name_table(config.names_file_name);
|
util::NameTable name_table(config.names_file_name);
|
||||||
util::NameTable turn_lanes(config.turn_lane_strings_file_name);
|
|
||||||
|
std::vector<std::uint32_t> turn_lane_offsets;
|
||||||
|
std::vector<guidance::TurnLaneType::Mask> turn_lane_masks;
|
||||||
|
if( !util::deserializeAdjacencyArray(
|
||||||
|
config.turn_lane_descriptions_file_name, turn_lane_offsets, turn_lane_masks) )
|
||||||
|
{
|
||||||
|
util::SimpleLogger().Write(logWARNING) << "Reading Turn Lane Masks failed.";
|
||||||
|
}
|
||||||
|
|
||||||
EdgeBasedGraphFactory edge_based_graph_factory(
|
EdgeBasedGraphFactory edge_based_graph_factory(
|
||||||
node_based_graph,
|
node_based_graph,
|
||||||
@ -515,7 +522,8 @@ Extractor::BuildEdgeExpandedGraph(lua_State *lua_state,
|
|||||||
internal_to_external_node_map,
|
internal_to_external_node_map,
|
||||||
profile_properties,
|
profile_properties,
|
||||||
name_table,
|
name_table,
|
||||||
turn_lanes);
|
turn_lane_offsets,
|
||||||
|
turn_lane_masks);
|
||||||
|
|
||||||
edge_based_graph_factory.Run(config.edge_output_path,
|
edge_based_graph_factory.Run(config.edge_output_path,
|
||||||
config.turn_lane_data_file_name,
|
config.turn_lane_data_file_name,
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
#include "extractor/extractor_callbacks.hpp"
|
#include "extractor/external_memory_node.hpp"
|
||||||
#include "extractor/extraction_containers.hpp"
|
#include "extractor/extraction_containers.hpp"
|
||||||
#include "extractor/extraction_node.hpp"
|
#include "extractor/extraction_node.hpp"
|
||||||
#include "extractor/extraction_way.hpp"
|
#include "extractor/extraction_way.hpp"
|
||||||
|
#include "extractor/extractor_callbacks.hpp"
|
||||||
#include "extractor/external_memory_node.hpp"
|
|
||||||
#include "extractor/restriction.hpp"
|
#include "extractor/restriction.hpp"
|
||||||
|
|
||||||
#include "util/for_each_pair.hpp"
|
#include "util/for_each_pair.hpp"
|
||||||
#include "util/guidance/turn_lanes.hpp"
|
#include "util/guidance/turn_lanes.hpp"
|
||||||
#include "util/simple_logger.hpp"
|
#include "util/simple_logger.hpp"
|
||||||
|
|
||||||
#include "extractor/extractor_callbacks.hpp"
|
|
||||||
#include <boost/numeric/conversion/cast.hpp>
|
#include <boost/numeric/conversion/cast.hpp>
|
||||||
#include <boost/optional/optional.hpp>
|
#include <boost/optional/optional.hpp>
|
||||||
|
#include <boost/tokenizer.hpp>
|
||||||
|
|
||||||
#include <osmium/osm.hpp>
|
#include <osmium/osm.hpp>
|
||||||
|
|
||||||
@ -27,12 +27,15 @@ namespace osrm
|
|||||||
namespace extractor
|
namespace extractor
|
||||||
{
|
{
|
||||||
|
|
||||||
|
using TurnLaneDescription = guidance::TurnLaneDescription;
|
||||||
|
namespace TurnLaneType = guidance::TurnLaneType;
|
||||||
|
|
||||||
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers)
|
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers)
|
||||||
: external_memory(extraction_containers)
|
: external_memory(extraction_containers)
|
||||||
{
|
{
|
||||||
// we reserved 0, 1, 2 for the empty case
|
// we reserved 0, 1, 2 for the empty case
|
||||||
string_map[MapKey("", "")] = 0;
|
string_map[MapKey("", "")] = 0;
|
||||||
lane_map[""] = 0;
|
lane_description_map[TurnLaneDescription()] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -144,44 +147,109 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
road_classification.road_class = guidance::functionalRoadClassFromTag(data);
|
road_classification.road_class = guidance::functionalRoadClassFromTag(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deduplicates street names and street destination names based on the street_map map.
|
const auto laneStringToDescription = [](std::string lane_string) -> TurnLaneDescription {
|
||||||
// In case we do not already store the name, inserts (name, id) tuple and return id.
|
if (lane_string.empty())
|
||||||
// Otherwise fetches the id based on the name and returns it without insertion.
|
return {};
|
||||||
|
|
||||||
const constexpr auto MAX_STRING_LENGTH = 255u;
|
TurnLaneDescription lane_description;
|
||||||
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
|
typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
|
||||||
// remove this handling when the issue is contained
|
boost::char_separator<char> sep("|&", "", boost::keep_empty_tokens);
|
||||||
std::string turn_lane_string = turn_lane_string_;
|
boost::char_separator<char> inner_sep(";", "");
|
||||||
for (auto &val : turn_lane_string)
|
tokenizer tokens(lane_string, sep);
|
||||||
if (val == '&')
|
|
||||||
val = '|';
|
|
||||||
|
|
||||||
const auto &lane_map_iterator = lane_map.find(turn_lane_string);
|
const constexpr std::size_t num_osm_tags = 11;
|
||||||
if (lane_map.end() == lane_map_iterator)
|
const constexpr char *osm_lane_strings[num_osm_tags] = {"none",
|
||||||
|
"through",
|
||||||
|
"sharp_left",
|
||||||
|
"left",
|
||||||
|
"slight_left",
|
||||||
|
"slight_right",
|
||||||
|
"right",
|
||||||
|
"sharp_right",
|
||||||
|
"reverse",
|
||||||
|
"merge_to_left",
|
||||||
|
"merge_to_right"};
|
||||||
|
const constexpr TurnLaneType::Mask masks_by_osm_string[num_osm_tags + 1] = {
|
||||||
|
TurnLaneType::none,
|
||||||
|
TurnLaneType::straight,
|
||||||
|
TurnLaneType::sharp_left,
|
||||||
|
TurnLaneType::left,
|
||||||
|
TurnLaneType::slight_left,
|
||||||
|
TurnLaneType::slight_right,
|
||||||
|
TurnLaneType::right,
|
||||||
|
TurnLaneType::sharp_right,
|
||||||
|
TurnLaneType::uturn,
|
||||||
|
TurnLaneType::merge_to_left,
|
||||||
|
TurnLaneType::merge_to_right,
|
||||||
|
TurnLaneType::empty}; // fallback, if string not found
|
||||||
|
|
||||||
|
for (auto iter = tokens.begin(); iter != tokens.end(); ++iter)
|
||||||
{
|
{
|
||||||
LaneStringID turn_lane_id =
|
tokenizer inner_tokens(*iter, inner_sep);
|
||||||
boost::numeric_cast<LaneStringID>(external_memory.turn_lane_lengths.size());
|
guidance::TurnLaneType::Mask lane_mask = inner_tokens.begin() == inner_tokens.end()
|
||||||
auto turn_lane_length = std::min<unsigned>(MAX_STRING_LENGTH, turn_lane_string.size());
|
? TurnLaneType::none
|
||||||
std::copy(turn_lane_string.c_str(),
|
: TurnLaneType::empty;
|
||||||
turn_lane_string.c_str() + turn_lane_length,
|
for (auto token_itr = inner_tokens.begin(); token_itr != inner_tokens.end();
|
||||||
std::back_inserter(external_memory.turn_lane_char_data));
|
++token_itr)
|
||||||
external_memory.turn_lane_lengths.push_back(turn_lane_length);
|
{
|
||||||
lane_map.insert(std::make_pair(turn_lane_string, turn_lane_id));
|
auto position = std::find(osm_lane_strings, osm_lane_strings + num_osm_tags, *token_itr);
|
||||||
return turn_lane_id;
|
const auto translated_mask =
|
||||||
|
masks_by_osm_string[std::distance(osm_lane_strings, position)];
|
||||||
|
if (translated_mask == TurnLaneType::empty)
|
||||||
|
{
|
||||||
|
// if we have unsupported tags, don't handle them
|
||||||
|
util::SimpleLogger().Write(logDEBUG) << "Unsupported lane tag found: \""
|
||||||
|
<< *token_itr << "\"";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
BOOST_ASSERT((lane_mask & translated_mask) == 0); // make sure the mask is valid
|
||||||
|
lane_mask |= translated_mask;
|
||||||
|
}
|
||||||
|
// add the lane to the description
|
||||||
|
lane_description.push_back(lane_mask);
|
||||||
|
}
|
||||||
|
return lane_description;
|
||||||
|
};
|
||||||
|
|
||||||
|
// convert the lane description into an ID and, if necessary, remembr the description in the
|
||||||
|
// description_map
|
||||||
|
const auto requestId = [&](std::string lane_string) {
|
||||||
|
if( lane_string.empty() )
|
||||||
|
return INVALID_LANE_DESCRIPTIONID;
|
||||||
|
TurnLaneDescription lane_description = laneStringToDescription(std::move(lane_string));
|
||||||
|
|
||||||
|
const auto lane_description_itr = lane_description_map.find(lane_description);
|
||||||
|
if (lane_description_itr == lane_description_map.end())
|
||||||
|
{
|
||||||
|
const LaneDescriptionID new_id =
|
||||||
|
boost::numeric_cast<LaneDescriptionID>(lane_description_map.size());
|
||||||
|
lane_description_map[lane_description] = new_id;
|
||||||
|
|
||||||
|
// since we are getting a new ID, we can augment the current offsets
|
||||||
|
|
||||||
|
// and store the turn lane masks, sadly stxxl does not support insert
|
||||||
|
for (const auto mask : lane_description)
|
||||||
|
external_memory.turn_lane_masks.push_back(mask);
|
||||||
|
|
||||||
|
external_memory.turn_lane_offsets.push_back(external_memory.turn_lane_offsets.back() +
|
||||||
|
lane_description.size());
|
||||||
|
|
||||||
|
return new_id;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return lane_map_iterator->second;
|
return lane_description_itr->second;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Deduplicates street names and street destination names based on the street_map map.
|
||||||
|
// In case we do not already store the name, inserts (name, id) tuple and return id.
|
||||||
|
// Otherwise fetches the id based on the name and returns it without insertion.
|
||||||
const auto turn_lane_id_forward = requestId(parsed_way.turn_lanes_forward);
|
const auto turn_lane_id_forward = requestId(parsed_way.turn_lanes_forward);
|
||||||
const auto turn_lane_id_backward = requestId(parsed_way.turn_lanes_backward);
|
const auto turn_lane_id_backward = requestId(parsed_way.turn_lanes_backward);
|
||||||
|
|
||||||
|
const constexpr auto MAX_STRING_LENGTH = 255u;
|
||||||
// Get the unique identifier for the street name
|
// Get the unique identifier for the street name
|
||||||
// Get the unique identifier for the street name and destination
|
// Get the unique identifier for the street name and destination
|
||||||
const auto name_iterator = string_map.find(MapKey(parsed_way.name, parsed_way.destinations));
|
const auto name_iterator = string_map.find(MapKey(parsed_way.name, parsed_way.destinations));
|
||||||
|
@ -160,18 +160,18 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
|||||||
* turn-lanes. Without this,we would have to treat any turn-lane beginning/ending just
|
* turn-lanes. Without this,we would have to treat any turn-lane beginning/ending just
|
||||||
* like a barrier.
|
* like a barrier.
|
||||||
*/
|
*/
|
||||||
const auto selectLaneID = [](const LaneStringID front, const LaneStringID back) {
|
const auto selectLaneID = [](const LaneDescriptionID front, const LaneDescriptionID back) {
|
||||||
// A lane has tags: u - (front) - v - (back) - w
|
// A lane has tags: u - (front) - v - (back) - w
|
||||||
// During contraction, we keep only one of the tags. Usually the one closer to the
|
// During contraction, we keep only one of the tags. Usually the one closer to the
|
||||||
// intersection is preferred. If its empty, however, we keep the non-empty one
|
// intersection is preferred. If its empty, however, we keep the non-empty one
|
||||||
if (back == INVALID_LANE_STRINGID)
|
if (back == INVALID_LANE_DESCRIPTIONID)
|
||||||
return front;
|
return front;
|
||||||
return back;
|
return back;
|
||||||
};
|
};
|
||||||
graph.GetEdgeData(forward_e1).lane_string_id = selectLaneID(
|
graph.GetEdgeData(forward_e1).lane_description_id = selectLaneID(
|
||||||
graph.GetEdgeData(forward_e1).lane_string_id, fwd_edge_data2.lane_string_id);
|
graph.GetEdgeData(forward_e1).lane_description_id, fwd_edge_data2.lane_description_id);
|
||||||
graph.GetEdgeData(reverse_e1).lane_string_id = selectLaneID(
|
graph.GetEdgeData(reverse_e1).lane_description_id = selectLaneID(
|
||||||
graph.GetEdgeData(reverse_e1).lane_string_id, rev_edge_data2.lane_string_id);
|
graph.GetEdgeData(reverse_e1).lane_description_id, rev_edge_data2.lane_description_id);
|
||||||
|
|
||||||
// remove e2's (if bidir, otherwise only one)
|
// remove e2's (if bidir, otherwise only one)
|
||||||
graph.DeleteEdge(node_v, forward_e2);
|
graph.DeleteEdge(node_v, forward_e2);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "extractor/guidance/turn_lane_augmentation.hpp"
|
#include "extractor/guidance/turn_lane_augmentation.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
#include "util/simple_logger.hpp"
|
#include "util/simple_logger.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -18,14 +19,14 @@ namespace lanes
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
const constexpr char *tag_by_modifier[] = {"reverse",
|
const constexpr TurnLaneType::Mask tag_by_modifier[] = {TurnLaneType::uturn,
|
||||||
"sharp_right",
|
TurnLaneType::sharp_right,
|
||||||
"right",
|
TurnLaneType::right,
|
||||||
"slight_right",
|
TurnLaneType::slight_right,
|
||||||
"through",
|
TurnLaneType::straight,
|
||||||
"slight_left",
|
TurnLaneType::slight_left,
|
||||||
"left",
|
TurnLaneType::left,
|
||||||
"sharp_left"};
|
TurnLaneType::sharp_left};
|
||||||
|
|
||||||
std::size_t getNumberOfTurns(const Intersection &intersection)
|
std::size_t getNumberOfTurns(const Intersection &intersection)
|
||||||
{
|
{
|
||||||
@ -126,7 +127,6 @@ LaneDataVector augmentMultiple(const std::size_t none_index,
|
|||||||
// This handles situations like "left | | | right".
|
// This handles situations like "left | | | right".
|
||||||
LaneDataVector mergeNoneTag(const std::size_t none_index, LaneDataVector lane_data)
|
LaneDataVector mergeNoneTag(const std::size_t none_index, LaneDataVector lane_data)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (none_index == 0 || none_index + 1 == lane_data.size())
|
if (none_index == 0 || none_index + 1 == lane_data.size())
|
||||||
{
|
{
|
||||||
if (none_index == 0)
|
if (none_index == 0)
|
||||||
@ -175,11 +175,11 @@ LaneDataVector handleRenamingSituations(const std::size_t none_index,
|
|||||||
if (none_index == 0)
|
if (none_index == 0)
|
||||||
{
|
{
|
||||||
if (has_right &&
|
if (has_right &&
|
||||||
(lane_data.size() == 1 || (lane_data[none_index + 1].tag != "sharp_right" &&
|
(lane_data.size() == 1 || (lane_data[none_index + 1].tag != TurnLaneType::sharp_right &&
|
||||||
lane_data[none_index + 1].tag != "right")))
|
lane_data[none_index + 1].tag != TurnLaneType::right)))
|
||||||
{
|
{
|
||||||
lane_data[none_index].tag = "right";
|
lane_data[none_index].tag = TurnLaneType::right;
|
||||||
if (lane_data.size() > 1 && lane_data[none_index + 1].tag == "through")
|
if (lane_data.size() > 1 && lane_data[none_index + 1].tag == TurnLaneType::straight)
|
||||||
{
|
{
|
||||||
lane_data[none_index + 1].from = lane_data[none_index].from;
|
lane_data[none_index + 1].from = lane_data[none_index].from;
|
||||||
// turning right through a possible through lane is not possible
|
// turning right through a possible through lane is not possible
|
||||||
@ -187,39 +187,39 @@ LaneDataVector handleRenamingSituations(const std::size_t none_index,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (has_through &&
|
else if (has_through &&
|
||||||
(lane_data.size() == 1 || lane_data[none_index + 1].tag != "through"))
|
(lane_data.size() == 1 || lane_data[none_index + 1].tag != TurnLaneType::straight))
|
||||||
{
|
{
|
||||||
lane_data[none_index].tag = "through";
|
lane_data[none_index].tag = TurnLaneType::straight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (none_index + 1 == lane_data.size())
|
else if (none_index + 1 == lane_data.size())
|
||||||
{
|
{
|
||||||
if (has_left && ((lane_data[none_index - 1].tag != "sharp_left" &&
|
if (has_left && ((lane_data[none_index - 1].tag != TurnLaneType::sharp_left &&
|
||||||
lane_data[none_index - 1].tag != "left")))
|
lane_data[none_index - 1].tag != TurnLaneType::left)))
|
||||||
{
|
{
|
||||||
lane_data[none_index].tag = "left";
|
lane_data[none_index].tag = TurnLaneType::left;
|
||||||
if (lane_data[none_index - 1].tag == "through")
|
if (lane_data[none_index - 1].tag == TurnLaneType::straight)
|
||||||
{
|
{
|
||||||
lane_data[none_index - 1].to = lane_data[none_index].to;
|
lane_data[none_index - 1].to = lane_data[none_index].to;
|
||||||
// turning left through a possible through lane is not possible
|
// turning left through a possible through lane is not possible
|
||||||
lane_data[none_index].from = lane_data[none_index].to;
|
lane_data[none_index].from = lane_data[none_index].to;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (has_through && lane_data[none_index - 1].tag != "through")
|
else if (has_through && lane_data[none_index - 1].tag != TurnLaneType::straight)
|
||||||
{
|
{
|
||||||
lane_data[none_index].tag = "through";
|
lane_data[none_index].tag = TurnLaneType::straight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((lane_data[none_index + 1].tag == "left" ||
|
if ((lane_data[none_index + 1].tag == TurnLaneType::left ||
|
||||||
lane_data[none_index + 1].tag == "slight_left" ||
|
lane_data[none_index + 1].tag == TurnLaneType::slight_left ||
|
||||||
lane_data[none_index + 1].tag == "sharp_left") &&
|
lane_data[none_index + 1].tag == TurnLaneType::sharp_left) &&
|
||||||
(lane_data[none_index - 1].tag == "right" ||
|
(lane_data[none_index - 1].tag == TurnLaneType::right ||
|
||||||
lane_data[none_index - 1].tag == "slight_right" ||
|
lane_data[none_index - 1].tag == TurnLaneType::slight_right ||
|
||||||
lane_data[none_index - 1].tag == "sharp_right"))
|
lane_data[none_index - 1].tag == TurnLaneType::sharp_right))
|
||||||
{
|
{
|
||||||
lane_data[none_index].tag = "through";
|
lane_data[none_index].tag = TurnLaneType::straight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::move(lane_data);
|
return std::move(lane_data);
|
||||||
@ -236,7 +236,7 @@ LaneDataVector handleNoneValueAtSimpleTurn(LaneDataVector lane_data,
|
|||||||
const Intersection &intersection)
|
const Intersection &intersection)
|
||||||
{
|
{
|
||||||
const bool needs_no_processing =
|
const bool needs_no_processing =
|
||||||
(intersection.empty() || lane_data.empty() || !hasTag("none", lane_data));
|
(intersection.empty() || lane_data.empty() || !hasTag(TurnLaneType::none, lane_data));
|
||||||
|
|
||||||
if (needs_no_processing)
|
if (needs_no_processing)
|
||||||
return std::move(lane_data);
|
return std::move(lane_data);
|
||||||
@ -265,10 +265,10 @@ LaneDataVector handleNoneValueAtSimpleTurn(LaneDataVector lane_data,
|
|||||||
|
|
||||||
const std::size_t connection_count =
|
const std::size_t connection_count =
|
||||||
getNumberOfTurns(intersection) -
|
getNumberOfTurns(intersection) -
|
||||||
((intersection[0].entry_allowed && lane_data.back().tag != "reverse") ? 1 : 0);
|
((intersection[0].entry_allowed && lane_data.back().tag != TurnLaneType::uturn) ? 1 : 0);
|
||||||
|
|
||||||
// TODO check for impossible turns to see whether the turn lane is at the correct place
|
// TODO check for impossible turns to see whether the turn lane is at the correct place
|
||||||
const std::size_t none_index = std::distance(lane_data.begin(), findTag("none", lane_data));
|
const std::size_t none_index = std::distance(lane_data.begin(), findTag(TurnLaneType::none, lane_data));
|
||||||
BOOST_ASSERT(none_index != lane_data.size());
|
BOOST_ASSERT(none_index != lane_data.size());
|
||||||
// we have to create multiple turns
|
// we have to create multiple turns
|
||||||
if (connection_count > lane_data.size())
|
if (connection_count > lane_data.size())
|
||||||
@ -279,7 +279,7 @@ LaneDataVector handleNoneValueAtSimpleTurn(LaneDataVector lane_data,
|
|||||||
// we have to reduce it, assigning it to neighboring turns
|
// we have to reduce it, assigning it to neighboring turns
|
||||||
else if (connection_count < lane_data.size())
|
else if (connection_count < lane_data.size())
|
||||||
{
|
{
|
||||||
// a prerequisite is simple turns. Larger differences should not end up here
|
// a pgerequisite is simple turns. Larger differences should not end up here
|
||||||
// an additional line at the side is only reasonable if it is targeting public
|
// an additional line at the side is only reasonable if it is targeting public
|
||||||
// service vehicles. Otherwise, we should not have it
|
// service vehicles. Otherwise, we should not have it
|
||||||
BOOST_ASSERT(connection_count + 1 == lane_data.size());
|
BOOST_ASSERT(connection_count + 1 == lane_data.size());
|
||||||
|
@ -30,55 +30,69 @@ bool TurnLaneData::operator<(const TurnLaneData &other) const
|
|||||||
if (to > other.to)
|
if (to > other.to)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const constexpr char *tag_by_modifier[] = {"sharp_right",
|
const constexpr TurnLaneType::Mask tag_by_modifier[] = {TurnLaneType::sharp_right,
|
||||||
"right",
|
TurnLaneType::right,
|
||||||
"slight_right",
|
TurnLaneType::slight_right,
|
||||||
"through",
|
TurnLaneType::straight,
|
||||||
"slight_left",
|
TurnLaneType::slight_left,
|
||||||
"left",
|
TurnLaneType::left,
|
||||||
"sharp_left",
|
TurnLaneType::sharp_left,
|
||||||
"reverse"};
|
TurnLaneType::uturn};
|
||||||
return std::find(tag_by_modifier, tag_by_modifier + 8, this->tag) <
|
return std::find(tag_by_modifier, tag_by_modifier + 8, this->tag) <
|
||||||
std::find(tag_by_modifier, tag_by_modifier + 8, other.tag);
|
std::find(tag_by_modifier, tag_by_modifier + 8, other.tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
LaneDataVector laneDataFromString(std::string turn_lane_string)
|
LaneDataVector laneDataFromDescription(const TurnLaneDescription &turn_lane_description)
|
||||||
{
|
{
|
||||||
typedef std::unordered_map<std::string, std::pair<LaneID, LaneID>> LaneMap;
|
typedef std::unordered_map<TurnLaneType::Mask, std::pair<LaneID, LaneID>> LaneMap;
|
||||||
|
|
||||||
// FIXME this is a workaround due to https://github.com/cucumber/cucumber-js/issues/417,
|
// FIXME this is a workaround due to https://github.com/cucumber/cucumber-js/issues/417,
|
||||||
// need to switch statements when fixed
|
// need to switch statements when fixed
|
||||||
// const auto num_lanes = std::count(turn_lane_string.begin(), turn_lane_string.end(), '|') + 1;
|
// const auto num_lanes = std::count(turn_lane_string.begin(), turn_lane_string.end(), '|') + 1;
|
||||||
// count the number of lanes
|
// count the number of lanes
|
||||||
const auto num_lanes = [](const std::string &turn_lane_string) {
|
const auto num_lanes = boost::numeric_cast<LaneID>(turn_lane_description.size());
|
||||||
return boost::numeric_cast<LaneID>(
|
const auto setLaneData = [&](
|
||||||
std::count(turn_lane_string.begin(), turn_lane_string.end(), '|') + 1);
|
LaneMap &map, TurnLaneType::Mask full_mask, const LaneID current_lane) {
|
||||||
}(turn_lane_string);
|
const auto isSet = [&](const TurnLaneType::Mask test_mask) -> bool {
|
||||||
|
return (test_mask & full_mask) == test_mask;
|
||||||
|
};
|
||||||
|
|
||||||
const auto getNextTag = [](std::string &string, const char *separators) {
|
for (std::size_t shift = 0; shift < TurnLaneType::detail::num_supported_lane_types; ++shift)
|
||||||
auto pos = string.find_last_of(separators);
|
|
||||||
auto result = pos != std::string::npos ? string.substr(pos + 1) : string;
|
|
||||||
|
|
||||||
string.resize(pos == std::string::npos ? 0 : pos);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto setLaneData = [&](LaneMap &map, std::string lane, const LaneID current_lane) {
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
auto identifier = getNextTag(lane, ";");
|
TurnLaneType::Mask mask = 1 << shift;
|
||||||
if (identifier.empty())
|
if (isSet(mask))
|
||||||
identifier = "none";
|
|
||||||
auto map_iterator = map.find(identifier);
|
|
||||||
if (map_iterator == map.end())
|
|
||||||
map[identifier] = std::make_pair(current_lane, current_lane);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
map_iterator->second.second = current_lane;
|
auto map_iterator = map.find(mask);
|
||||||
|
if (map_iterator == map.end())
|
||||||
|
map[mask] = std::make_pair(current_lane, current_lane);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
map_iterator->second.first = current_lane;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (!lane.empty());
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
LaneMap lane_map;
|
||||||
|
LaneID lane_nr = num_lanes - 1;
|
||||||
|
if (turn_lane_description.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
for (auto full_mask : turn_lane_description)
|
||||||
|
{
|
||||||
|
setLaneData(lane_map, full_mask, lane_nr);
|
||||||
|
--lane_nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// transform the map into the lane data vector
|
||||||
|
LaneDataVector lane_data;
|
||||||
|
for (const auto tag : lane_map)
|
||||||
|
{
|
||||||
|
lane_data.push_back({tag.first, tag.second.first, tag.second.second});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(lane_data.begin(), lane_data.end());
|
||||||
|
|
||||||
// check whether a given turn lane string resulted in valid lane data
|
// check whether a given turn lane string resulted in valid lane data
|
||||||
const auto hasValidOverlaps = [](const LaneDataVector &lane_data) {
|
const auto hasValidOverlaps = [](const LaneDataVector &lane_data) {
|
||||||
// Allow an overlap of at most one. Larger overlaps would result in crossing another turn,
|
// Allow an overlap of at most one. Larger overlaps would result in crossing another turn,
|
||||||
@ -91,50 +105,26 @@ LaneDataVector laneDataFromString(std::string turn_lane_string)
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
LaneMap lane_map;
|
|
||||||
LaneID lane_nr = 0;
|
|
||||||
LaneDataVector lane_data;
|
|
||||||
if (turn_lane_string.empty())
|
|
||||||
return lane_data;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// 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, "|");
|
|
||||||
setLaneData(lane_map, lane, lane_nr);
|
|
||||||
++lane_nr;
|
|
||||||
} while (lane_nr < num_lanes);
|
|
||||||
|
|
||||||
for (const auto tag : lane_map)
|
|
||||||
{
|
|
||||||
lane_data.push_back({tag.first, tag.second.first, tag.second.second});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(lane_data.begin(), lane_data.end());
|
|
||||||
if (!hasValidOverlaps(lane_data))
|
if (!hasValidOverlaps(lane_data))
|
||||||
{
|
|
||||||
lane_data.clear();
|
lane_data.clear();
|
||||||
}
|
|
||||||
|
|
||||||
return lane_data;
|
return lane_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
LaneDataVector::iterator findTag(const std::string &tag, LaneDataVector &data)
|
LaneDataVector::iterator findTag(const TurnLaneType::Mask tag, LaneDataVector &data)
|
||||||
{
|
{
|
||||||
return std::find_if(data.begin(), data.end(), [&](const TurnLaneData &lane_data) {
|
return std::find_if(data.begin(), data.end(), [&](const TurnLaneData &lane_data) {
|
||||||
return tag == lane_data.tag;
|
return (tag & lane_data.tag) != TurnLaneType::empty;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
LaneDataVector::const_iterator findTag(const std::string &tag, const LaneDataVector &data)
|
LaneDataVector::const_iterator findTag(const TurnLaneType::Mask tag, const LaneDataVector &data)
|
||||||
{
|
{
|
||||||
return std::find_if(data.cbegin(), data.cend(), [&](const TurnLaneData &lane_data) {
|
return std::find_if(data.cbegin(), data.cend(), [&](const TurnLaneData &lane_data) {
|
||||||
return tag == lane_data.tag;
|
return (tag & lane_data.tag) != TurnLaneType::empty;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasTag(const std::string &tag, const LaneDataVector &data)
|
bool hasTag(const TurnLaneType::Mask tag, const LaneDataVector &data)
|
||||||
{
|
{
|
||||||
return findTag(tag, data) != data.cend();
|
return findTag(tag, data) != data.cend();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "extractor/guidance/turn_lane_handler.hpp"
|
|
||||||
#include "extractor/guidance/constants.hpp"
|
#include "extractor/guidance/constants.hpp"
|
||||||
#include "extractor/guidance/turn_discovery.hpp"
|
#include "extractor/guidance/turn_discovery.hpp"
|
||||||
#include "extractor/guidance/turn_lane_augmentation.hpp"
|
#include "extractor/guidance/turn_lane_augmentation.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_handler.hpp"
|
||||||
#include "extractor/guidance/turn_lane_matcher.hpp"
|
#include "extractor/guidance/turn_lane_matcher.hpp"
|
||||||
#include "util/simple_logger.hpp"
|
#include "util/simple_logger.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
@ -31,11 +31,12 @@ std::size_t getNumberOfTurns(const Intersection &intersection)
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const util::NameTable &turn_lane_strings,
|
const std::vector<std::uint32_t> &turn_lane_offsets,
|
||||||
|
const std::vector<TurnLaneType::Mask> &turn_lane_masks,
|
||||||
const std::vector<QueryNode> &node_info_list,
|
const std::vector<QueryNode> &node_info_list,
|
||||||
const TurnAnalysis &turn_analysis)
|
const TurnAnalysis &turn_analysis)
|
||||||
: node_based_graph(node_based_graph), turn_lane_strings(turn_lane_strings),
|
: node_based_graph(node_based_graph), turn_lane_offsets(turn_lane_offsets),
|
||||||
node_info_list(node_info_list), turn_analysis(turn_analysis)
|
turn_lane_masks(turn_lane_masks), node_info_list(node_info_list), turn_analysis(turn_analysis)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_g
|
|||||||
Turn lanes are given in the form of strings that closely correspond to the direction modifiers
|
Turn lanes are given in the form of strings that closely correspond to the direction modifiers
|
||||||
we use for our turn types. However, we still cannot simply perform a 1:1 assignment.
|
we use for our turn types. However, we still cannot simply perform a 1:1 assignment.
|
||||||
|
|
||||||
This function parses the turn_lane_strings of a format that describes an intersection as:
|
This function parses the turn_lane_descriptions of a format that describes an intersection as:
|
||||||
|
|
||||||
----------
|
----------
|
||||||
A -^
|
A -^
|
||||||
@ -53,49 +54,64 @@ TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_g
|
|||||||
C -v
|
C -v
|
||||||
----------
|
----------
|
||||||
|
|
||||||
with a string like |left|through;right|right| and performs an assignment onto the turns:
|
witch is the result of a string like looking |left|through;right|right| and performs an
|
||||||
for example: (130, turn slight right), (180, ramp straight), (320, turn sharp left)
|
assignment onto the turns.
|
||||||
|
For example: (130, turn slight right), (180, ramp straight), (320, turn sharp left).
|
||||||
*/
|
*/
|
||||||
Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
|
Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
Intersection intersection,
|
Intersection intersection,
|
||||||
LaneDataIdMap &id_map) const
|
LaneDataIdMap &id_map) const
|
||||||
{
|
{
|
||||||
|
//if only a uturn exists, there is nothing we can do
|
||||||
|
if( intersection.size() == 1 )
|
||||||
|
return std::move(intersection);
|
||||||
|
|
||||||
const auto &data = node_based_graph.GetEdgeData(via_edge);
|
const auto &data = node_based_graph.GetEdgeData(via_edge);
|
||||||
const auto turn_lane_string = data.lane_string_id != INVALID_LANE_STRINGID
|
// Extract a lane description for the ID
|
||||||
? turn_lane_strings.GetNameForID(data.lane_string_id)
|
|
||||||
: "";
|
const auto turn_lane_description =
|
||||||
|
data.lane_description_id != INVALID_LANE_DESCRIPTIONID
|
||||||
|
? TurnLaneDescription(
|
||||||
|
turn_lane_masks.begin() + turn_lane_offsets[data.lane_description_id],
|
||||||
|
turn_lane_masks.begin() + turn_lane_offsets[data.lane_description_id + 1])
|
||||||
|
: TurnLaneDescription();
|
||||||
|
|
||||||
|
BOOST_ASSERT( turn_lane_description.empty() || turn_lane_description.size() == (turn_lane_offsets[data.lane_description_id+1] - turn_lane_offsets[data.lane_description_id]));
|
||||||
|
|
||||||
// going straight, due to traffic signals, we can have uncompressed geometry
|
// going straight, due to traffic signals, we can have uncompressed geometry
|
||||||
if (intersection.size() == 2 &&
|
if (intersection.size() == 2 &&
|
||||||
((data.lane_string_id != INVALID_LANE_STRINGID &&
|
((data.lane_description_id != INVALID_LANE_DESCRIPTIONID &&
|
||||||
data.lane_string_id ==
|
data.lane_description_id ==
|
||||||
node_based_graph.GetEdgeData(intersection[1].turn.eid).lane_string_id) ||
|
node_based_graph.GetEdgeData(intersection[1].turn.eid).lane_description_id) ||
|
||||||
angularDeviation(intersection[1].turn.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE))
|
angularDeviation(intersection[1].turn.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE))
|
||||||
return std::move(intersection);
|
return std::move(intersection);
|
||||||
|
|
||||||
auto lane_data = laneDataFromString(turn_lane_string);
|
auto lane_data = laneDataFromDescription(turn_lane_description);
|
||||||
|
|
||||||
// if we see an invalid conversion, we stop immediately
|
// if we see an invalid conversion, we stop immediately
|
||||||
if (!turn_lane_string.empty() && lane_data.empty())
|
if (!turn_lane_description.empty() && lane_data.empty())
|
||||||
return std::move(intersection);
|
return std::move(intersection);
|
||||||
|
|
||||||
// might be reasonable to handle multiple turns, if we know of a sequence of lanes
|
// might be reasonable to handle multiple turns, if we know of a sequence of lanes
|
||||||
// e.g. one direction per lane, if three lanes and right, through, left available
|
// e.g. one direction per lane, if three lanes and right, through, left available
|
||||||
if (!turn_lane_string.empty() && lane_data.size() == 1 && lane_data[0].tag == "none")
|
if (!turn_lane_description.empty() && lane_data.size() == 1 &&
|
||||||
|
lane_data[0].tag == TurnLaneType::none)
|
||||||
return std::move(intersection);
|
return std::move(intersection);
|
||||||
|
|
||||||
const std::size_t possible_entries = getNumberOfTurns(intersection);
|
const std::size_t possible_entries = getNumberOfTurns(intersection);
|
||||||
|
|
||||||
// merge does not justify an instruction
|
// merge does not justify an instruction
|
||||||
const bool has_merge_lane =
|
const bool has_merge_lane =
|
||||||
(hasTag("merge_to_left", lane_data) || hasTag("merge_to_right", lane_data));
|
hasTag(TurnLaneType::merge_to_left | TurnLaneType::merge_to_right, lane_data);
|
||||||
|
|
||||||
// Dead end streets that don't have any left-tag. This can happen due to the fallbacks for
|
// Dead end streets that don't have any left-tag. This can happen due to the fallbacks for
|
||||||
// broken data/barriers.
|
// broken data/barriers.
|
||||||
const bool has_non_usable_u_turn =
|
const bool has_non_usable_u_turn = (intersection[0].entry_allowed &&
|
||||||
(intersection[0].entry_allowed && !hasTag("none", lane_data) &&
|
!hasTag(TurnLaneType::none | TurnLaneType::left |
|
||||||
!hasTag("left", lane_data) && !hasTag("sharp_left", lane_data) &&
|
TurnLaneType::sharp_left | TurnLaneType::uturn,
|
||||||
!hasTag("reverse", lane_data) && lane_data.size() + 1 == possible_entries);
|
lane_data) &&
|
||||||
|
lane_data.size() + 1 == possible_entries);
|
||||||
|
|
||||||
if (has_merge_lane || has_non_usable_u_turn)
|
if (has_merge_lane || has_non_usable_u_turn)
|
||||||
return std::move(intersection);
|
return std::move(intersection);
|
||||||
@ -103,19 +119,19 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
|
|||||||
if (!lane_data.empty() && canMatchTrivially(intersection, lane_data) &&
|
if (!lane_data.empty() && canMatchTrivially(intersection, lane_data) &&
|
||||||
lane_data.size() !=
|
lane_data.size() !=
|
||||||
static_cast<std::size_t>(
|
static_cast<std::size_t>(
|
||||||
lane_data.back().tag != "reverse" && intersection[0].entry_allowed ? 1 : 0) +
|
lane_data.back().tag != TurnLaneType::uturn && intersection[0].entry_allowed ? 1
|
||||||
|
: 0) +
|
||||||
possible_entries &&
|
possible_entries &&
|
||||||
intersection[0].entry_allowed && !hasTag("none", lane_data))
|
intersection[0].entry_allowed && !hasTag(TurnLaneType::none, lane_data))
|
||||||
lane_data.push_back({"reverse", lane_data.back().to, lane_data.back().to});
|
lane_data.push_back({TurnLaneType::uturn, lane_data.back().to, lane_data.back().to});
|
||||||
|
|
||||||
bool is_simple = isSimpleIntersection(lane_data, intersection);
|
bool is_simple = isSimpleIntersection(lane_data, intersection);
|
||||||
|
|
||||||
// simple intersections can be assigned directly
|
// simple intersections can be assigned directly
|
||||||
if (is_simple)
|
if (is_simple)
|
||||||
{
|
{
|
||||||
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
|
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
|
||||||
return simpleMatchTuplesToTurns(
|
return simpleMatchTuplesToTurns(
|
||||||
std::move(intersection), lane_data, data.lane_string_id, id_map);
|
std::move(intersection), lane_data, data.lane_description_id, id_map);
|
||||||
}
|
}
|
||||||
// if the intersection is not simple but we have lane data, we check for intersections with
|
// 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
|
// middle islands. We have two cases. The first one is providing lane data on the current
|
||||||
@ -136,13 +152,13 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
|
|||||||
{
|
{
|
||||||
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
|
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
|
||||||
return simpleMatchTuplesToTurns(
|
return simpleMatchTuplesToTurns(
|
||||||
std::move(intersection), lane_data, data.lane_string_id, id_map);
|
std::move(intersection), lane_data, data.lane_description_id, id_map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The second part does not provide lane data on the current segment, but on the segment prior
|
// The second part does not provide lane data on the current segment, but on the segment prior
|
||||||
// to the turn. We try to partition the data and only consider the second part.
|
// to the turn. We try to partition the data and only consider the second part.
|
||||||
else if (turn_lane_string.empty())
|
else if (turn_lane_description.empty())
|
||||||
{
|
{
|
||||||
// acquire the lane data of a previous segment and, if possible, use it for the current
|
// acquire the lane data of a previous segment and, if possible, use it for the current
|
||||||
// intersection.
|
// intersection.
|
||||||
@ -162,10 +178,11 @@ Intersection TurnLaneHandler::handleTurnAtPreviousIntersection(const NodeID at,
|
|||||||
NodeID previous_node = SPECIAL_NODEID;
|
NodeID previous_node = SPECIAL_NODEID;
|
||||||
Intersection previous_intersection;
|
Intersection previous_intersection;
|
||||||
EdgeID previous_id = SPECIAL_EDGEID;
|
EdgeID previous_id = SPECIAL_EDGEID;
|
||||||
|
LaneDataVector lane_data;
|
||||||
|
|
||||||
// Get the previous lane string. We only accept strings that stem from a not-simple intersection
|
// Get the previous lane string. We only accept strings that stem from a not-simple intersection
|
||||||
// and are not empty.
|
// and are not empty.
|
||||||
const auto previous_lane_string = [&]() -> std::string {
|
const auto previous_lane_description = [&]() -> TurnLaneDescription {
|
||||||
if (!findPreviousIntersection(at,
|
if (!findPreviousIntersection(at,
|
||||||
via_edge,
|
via_edge,
|
||||||
intersection,
|
intersection,
|
||||||
@ -174,32 +191,38 @@ Intersection TurnLaneHandler::handleTurnAtPreviousIntersection(const NodeID at,
|
|||||||
previous_node,
|
previous_node,
|
||||||
previous_id,
|
previous_id,
|
||||||
previous_intersection))
|
previous_intersection))
|
||||||
return "";
|
return {};
|
||||||
|
|
||||||
BOOST_ASSERT(previous_id != SPECIAL_EDGEID);
|
BOOST_ASSERT(previous_id != SPECIAL_EDGEID);
|
||||||
|
|
||||||
const auto &previous_data = node_based_graph.GetEdgeData(previous_id);
|
const auto &previous_edge_data = node_based_graph.GetEdgeData(previous_id);
|
||||||
auto previous_string = previous_data.lane_string_id != INVALID_LANE_STRINGID
|
// TODO access correct data
|
||||||
? turn_lane_strings.GetNameForID(previous_data.lane_string_id)
|
const auto previous_description =
|
||||||
: "";
|
previous_edge_data.lane_description_id != INVALID_LANE_DESCRIPTIONID
|
||||||
if (previous_string.empty())
|
? TurnLaneDescription(
|
||||||
return "";
|
turn_lane_masks.begin() +
|
||||||
|
turn_lane_offsets[previous_edge_data.lane_description_id],
|
||||||
|
turn_lane_masks.begin() +
|
||||||
|
turn_lane_offsets[previous_edge_data.lane_description_id + 1])
|
||||||
|
: TurnLaneDescription();
|
||||||
|
if (previous_description.empty())
|
||||||
|
return previous_description;
|
||||||
|
|
||||||
previous_intersection = turn_analysis.assignTurnTypes(
|
previous_intersection = turn_analysis.assignTurnTypes(
|
||||||
previous_node, previous_id, std::move(previous_intersection));
|
previous_node, previous_id, std::move(previous_intersection));
|
||||||
|
|
||||||
auto previous_lane_data = laneDataFromString(previous_string);
|
lane_data = laneDataFromDescription(previous_description);
|
||||||
|
|
||||||
if (isSimpleIntersection(previous_lane_data, previous_intersection))
|
if (isSimpleIntersection(lane_data, previous_intersection))
|
||||||
return "";
|
return {};
|
||||||
return previous_string;
|
else
|
||||||
|
return previous_description;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
// no lane string, no problems
|
// no lane string, no problems
|
||||||
if (previous_lane_string.empty())
|
if (previous_lane_description.empty())
|
||||||
return std::move(intersection);
|
return std::move(intersection);
|
||||||
|
|
||||||
auto lane_data = laneDataFromString(previous_lane_string);
|
|
||||||
|
|
||||||
// stop on invalid lane data conversion
|
// stop on invalid lane data conversion
|
||||||
if (lane_data.empty())
|
if (lane_data.empty())
|
||||||
return std::move(intersection);
|
return std::move(intersection);
|
||||||
@ -210,7 +233,7 @@ Intersection TurnLaneHandler::handleTurnAtPreviousIntersection(const NodeID at,
|
|||||||
{
|
{
|
||||||
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
|
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
|
||||||
return simpleMatchTuplesToTurns(
|
return simpleMatchTuplesToTurns(
|
||||||
std::move(intersection), lane_data, previous_data.lane_string_id, id_map);
|
std::move(intersection), lane_data, previous_data.lane_description_id, id_map);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -230,7 +253,7 @@ Intersection TurnLaneHandler::handleTurnAtPreviousIntersection(const NodeID at,
|
|||||||
{
|
{
|
||||||
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
|
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
|
||||||
return simpleMatchTuplesToTurns(
|
return simpleMatchTuplesToTurns(
|
||||||
std::move(intersection), lane_data, previous_data.lane_string_id, id_map);
|
std::move(intersection), lane_data, previous_data.lane_description_id, id_map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,7 +280,10 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
|
|||||||
return std::count_if(
|
return std::count_if(
|
||||||
lane_data.begin(),
|
lane_data.begin(),
|
||||||
lane_data.end(),
|
lane_data.end(),
|
||||||
[](const TurnLaneData &data) { return boost::starts_with(data.tag, "merge"); }) +
|
[](const TurnLaneData &data) {
|
||||||
|
return ((data.tag & TurnLaneType::merge_to_left) != TurnLaneType::empty) ||
|
||||||
|
((data.tag & TurnLaneType::merge_to_right) != TurnLaneType::empty);
|
||||||
|
}) +
|
||||||
std::size_t{1} >=
|
std::size_t{1} >=
|
||||||
lane_data.size();
|
lane_data.size();
|
||||||
}
|
}
|
||||||
@ -268,7 +294,7 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
|
|||||||
const auto num_turns = [&]() {
|
const auto num_turns = [&]() {
|
||||||
auto count = getNumberOfTurns(intersection);
|
auto count = getNumberOfTurns(intersection);
|
||||||
if (count < lane_data.size() && !intersection[0].entry_allowed &&
|
if (count < lane_data.size() && !intersection[0].entry_allowed &&
|
||||||
lane_data.back().tag == "reverse")
|
lane_data.back().tag == TurnLaneType::uturn)
|
||||||
return count + 1;
|
return count + 1;
|
||||||
return count;
|
return count;
|
||||||
}();
|
}();
|
||||||
@ -281,8 +307,8 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
|
|||||||
|
|
||||||
// single additional lane data entry is alright, if it is none at the side. This usually
|
// single additional lane data entry is alright, if it is none at the side. This usually
|
||||||
// refers to a bus-lane
|
// refers to a bus-lane
|
||||||
if (num_turns + std::size_t{1} == lane_data.size() && lane_data.front().tag != "none" &&
|
if (num_turns + std::size_t{1} == lane_data.size() &&
|
||||||
lane_data.back().tag != "none")
|
lane_data.front().tag != TurnLaneType::none && lane_data.back().tag != TurnLaneType::none)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -291,15 +317,16 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
|
|||||||
if (num_turns > lane_data.size() &&
|
if (num_turns > lane_data.size() &&
|
||||||
lane_data.end() ==
|
lane_data.end() ==
|
||||||
std::find_if(lane_data.begin(), lane_data.end(), [](const TurnLaneData &data) {
|
std::find_if(lane_data.begin(), lane_data.end(), [](const TurnLaneData &data) {
|
||||||
return data.tag == "none";
|
return data.tag == TurnLaneType::none;
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_turns > lane_data.size() && intersection[0].entry_allowed &&
|
if (num_turns > lane_data.size() && intersection[0].entry_allowed &&
|
||||||
!(hasTag("reverse", lane_data) ||
|
!(hasTag(TurnLaneType::uturn, lane_data) ||
|
||||||
(lane_data.back().tag != "left" && lane_data.back().tag != "sharp_left")))
|
(lane_data.back().tag != TurnLaneType::left &&
|
||||||
|
lane_data.back().tag != TurnLaneType::sharp_left)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -310,21 +337,21 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
|
|||||||
std::unordered_set<std::size_t> matched_indices;
|
std::unordered_set<std::size_t> matched_indices;
|
||||||
for (const auto &data : lane_data)
|
for (const auto &data : lane_data)
|
||||||
{
|
{
|
||||||
if (data.tag == "none")
|
if (data.tag == TurnLaneType::none)
|
||||||
{
|
{
|
||||||
has_none = true;
|
has_none = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto best_match = [&]() {
|
const auto best_match = [&]() {
|
||||||
if (data.tag != "reverse" || lane_data.size() == 1)
|
if (data.tag != TurnLaneType::uturn || lane_data.size() == 1)
|
||||||
return findBestMatch(data.tag, intersection);
|
return findBestMatch(data.tag, intersection);
|
||||||
|
|
||||||
// lane_data.size() > 1
|
// lane_data.size() > 1
|
||||||
if (lane_data.back().tag == "reverse")
|
if (lane_data.back().tag == TurnLaneType::uturn)
|
||||||
return findBestMatchForReverse(lane_data[lane_data.size() - 2].tag, intersection);
|
return findBestMatchForReverse(lane_data[lane_data.size() - 2].tag, intersection);
|
||||||
|
|
||||||
BOOST_ASSERT(lane_data.front().tag == "reverse");
|
BOOST_ASSERT(lane_data.front().tag == TurnLaneType::uturn);
|
||||||
return findBestMatchForReverse(lane_data[1].tag, intersection);
|
return findBestMatchForReverse(lane_data[1].tag, intersection);
|
||||||
}();
|
}();
|
||||||
std::size_t match_index = std::distance(intersection.begin(), best_match);
|
std::size_t match_index = std::distance(intersection.begin(), best_match);
|
||||||
@ -396,7 +423,8 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
|
|||||||
std::size_t straightmost_tag_index = turn_lane_data.size();
|
std::size_t straightmost_tag_index = turn_lane_data.size();
|
||||||
for (std::size_t lane = 0; lane < turn_lane_data.size(); ++lane)
|
for (std::size_t lane = 0; lane < turn_lane_data.size(); ++lane)
|
||||||
{
|
{
|
||||||
if (turn_lane_data[lane].tag == "none" || turn_lane_data[lane].tag == "reverse")
|
if ((turn_lane_data[lane].tag & (TurnLaneType::none | TurnLaneType::uturn)) !=
|
||||||
|
TurnLaneType::empty)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto best_match = findBestMatch(turn_lane_data[lane].tag, intersection);
|
const auto best_match = findBestMatch(turn_lane_data[lane].tag, intersection);
|
||||||
@ -419,7 +447,8 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
|
|||||||
return {turn_lane_data, {}};
|
return {turn_lane_data, {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t none_index = std::distance(turn_lane_data.begin(), findTag("none", turn_lane_data));
|
std::size_t none_index =
|
||||||
|
std::distance(turn_lane_data.begin(), findTag(TurnLaneType::none, turn_lane_data));
|
||||||
|
|
||||||
// if the turn lanes are pull forward, we might have to add an additional straight tag
|
// if the turn lanes are pull forward, we might have to add an additional straight tag
|
||||||
// did we find something that matches against the straightmost road?
|
// did we find something that matches against the straightmost road?
|
||||||
@ -477,7 +506,7 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
|
|||||||
std::count(matched_at_second.begin(), matched_at_second.end(), true)) ==
|
std::count(matched_at_second.begin(), matched_at_second.end(), true)) ==
|
||||||
getNumberOfTurns(next_intersection))
|
getNumberOfTurns(next_intersection))
|
||||||
{
|
{
|
||||||
TurnLaneData data = {"through", 255, 0};
|
TurnLaneData data = {TurnLaneType::straight, 255, 0};
|
||||||
augmentEntry(data);
|
augmentEntry(data);
|
||||||
first.push_back(data);
|
first.push_back(data);
|
||||||
std::sort(first.begin(), first.end());
|
std::sort(first.begin(), first.end());
|
||||||
@ -489,19 +518,18 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
|
|||||||
|
|
||||||
Intersection TurnLaneHandler::simpleMatchTuplesToTurns(Intersection intersection,
|
Intersection TurnLaneHandler::simpleMatchTuplesToTurns(Intersection intersection,
|
||||||
const LaneDataVector &lane_data,
|
const LaneDataVector &lane_data,
|
||||||
const LaneStringID lane_string_id,
|
const LaneDescriptionID lane_description_id,
|
||||||
LaneDataIdMap &id_map) const
|
LaneDataIdMap &id_map) const
|
||||||
{
|
{
|
||||||
if (lane_data.empty() || !canMatchTrivially(intersection, lane_data))
|
if (lane_data.empty() || !canMatchTrivially(intersection, lane_data))
|
||||||
return std::move(intersection);
|
return std::move(intersection);
|
||||||
|
|
||||||
BOOST_ASSERT(!hasTag("none", lane_data));
|
BOOST_ASSERT(
|
||||||
BOOST_ASSERT(std::count_if(lane_data.begin(), lane_data.end(), [](const TurnLaneData &data) {
|
!hasTag(TurnLaneType::none | TurnLaneType::merge_to_left | TurnLaneType::merge_to_right,
|
||||||
return boost::starts_with(data.tag, "merge");
|
lane_data));
|
||||||
}) == 0);
|
|
||||||
|
|
||||||
return triviallyMatchLanesToTurns(
|
return triviallyMatchLanesToTurns(
|
||||||
std::move(intersection), lane_data, node_based_graph, lane_string_id, id_map);
|
std::move(intersection), lane_data, node_based_graph, lane_description_id, id_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lanes
|
} // namespace lanes
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "extractor/guidance/turn_lane_matcher.hpp"
|
|
||||||
#include "extractor/guidance/toolkit.hpp"
|
#include "extractor/guidance/toolkit.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_matcher.hpp"
|
||||||
#include "util/guidance/toolkit.hpp"
|
#include "util/guidance/toolkit.hpp"
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
@ -17,18 +17,18 @@ namespace lanes
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Translate Turn Tags into a Matching Direction Modifier
|
// Translate Turn Tags into a Matching Direction Modifier
|
||||||
DirectionModifier::Enum getMatchingModifier(const std::string &tag)
|
DirectionModifier::Enum getMatchingModifier(const TurnLaneType::Mask &tag)
|
||||||
{
|
{
|
||||||
const constexpr char *tag_by_modifier[] = {"reverse",
|
const constexpr TurnLaneType::Mask tag_by_modifier[] = {TurnLaneType::uturn,
|
||||||
"sharp_right",
|
TurnLaneType::sharp_right,
|
||||||
"right",
|
TurnLaneType::right,
|
||||||
"slight_right",
|
TurnLaneType::slight_right,
|
||||||
"through",
|
TurnLaneType::straight,
|
||||||
"slight_left",
|
TurnLaneType::slight_left,
|
||||||
"left",
|
TurnLaneType::left,
|
||||||
"sharp_left",
|
TurnLaneType::sharp_left,
|
||||||
"merge_to_left",
|
TurnLaneType::merge_to_left,
|
||||||
"merge_to_right"};
|
TurnLaneType::merge_to_right};
|
||||||
const auto index =
|
const auto index =
|
||||||
std::distance(tag_by_modifier, std::find(tag_by_modifier, tag_by_modifier + 10, tag));
|
std::distance(tag_by_modifier, std::find(tag_by_modifier, tag_by_modifier + 10, tag));
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ DirectionModifier::Enum getMatchingModifier(const std::string &tag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check whether a match of a given tag and a turn instruction can be seen as valid
|
// check whether a match of a given tag and a turn instruction can be seen as valid
|
||||||
bool isValidMatch(const std::string &tag, const TurnInstruction instruction)
|
bool isValidMatch(const TurnLaneType::Mask &tag, const TurnInstruction instruction)
|
||||||
{
|
{
|
||||||
using util::guidance::hasLeftModifier;
|
using util::guidance::hasLeftModifier;
|
||||||
using util::guidance::hasRightModifier;
|
using util::guidance::hasRightModifier;
|
||||||
@ -59,12 +59,13 @@ bool isValidMatch(const std::string &tag, const TurnInstruction instruction)
|
|||||||
return instruction.type == TurnType::Merge;
|
return instruction.type == TurnType::Merge;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (tag == "reverse")
|
if (tag == TurnLaneType::uturn)
|
||||||
{
|
{
|
||||||
return hasLeftModifier(instruction) ||
|
return hasLeftModifier(instruction) ||
|
||||||
instruction.direction_modifier == DirectionModifier::UTurn;
|
instruction.direction_modifier == DirectionModifier::UTurn;
|
||||||
}
|
}
|
||||||
else if (tag == "sharp_right" || tag == "right" || tag == "slight_right")
|
else if (tag == TurnLaneType::sharp_right || tag == TurnLaneType::right ||
|
||||||
|
tag == TurnLaneType::slight_right)
|
||||||
{
|
{
|
||||||
if (isMirroredModifier(instruction))
|
if (isMirroredModifier(instruction))
|
||||||
return hasLeftModifier(instruction);
|
return hasLeftModifier(instruction);
|
||||||
@ -72,7 +73,7 @@ bool isValidMatch(const std::string &tag, const TurnInstruction instruction)
|
|||||||
// needs to be adjusted for left side driving
|
// needs to be adjusted for left side driving
|
||||||
return leavesRoundabout(instruction) || hasRightModifier(instruction);
|
return leavesRoundabout(instruction) || hasRightModifier(instruction);
|
||||||
}
|
}
|
||||||
else if (tag == "through")
|
else if (tag == TurnLaneType::straight)
|
||||||
{
|
{
|
||||||
return instruction.direction_modifier == DirectionModifier::Straight ||
|
return instruction.direction_modifier == DirectionModifier::Straight ||
|
||||||
instruction.type == TurnType::Suppressed || instruction.type == TurnType::NewName ||
|
instruction.type == TurnType::Suppressed || instruction.type == TurnType::NewName ||
|
||||||
@ -87,7 +88,8 @@ bool isValidMatch(const std::string &tag, const TurnInstruction instruction)
|
|||||||
instruction.direction_modifier == DirectionModifier::SlightRight)) ||
|
instruction.direction_modifier == DirectionModifier::SlightRight)) ||
|
||||||
instruction.type == TurnType::UseLane;
|
instruction.type == TurnType::UseLane;
|
||||||
}
|
}
|
||||||
else if (tag == "slight_left" || tag == "left" || tag == "sharp_left")
|
else if (tag == TurnLaneType::slight_left || tag == TurnLaneType::left ||
|
||||||
|
tag == TurnLaneType::sharp_left)
|
||||||
{
|
{
|
||||||
if (isMirroredModifier(instruction))
|
if (isMirroredModifier(instruction))
|
||||||
return hasRightModifier(instruction);
|
return hasRightModifier(instruction);
|
||||||
@ -100,7 +102,11 @@ bool isValidMatch(const std::string &tag, const TurnInstruction instruction)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
typename Intersection::const_iterator findBestMatch(const std::string &tag,
|
// Every tag is somewhat idealized in form of the expected angle. A through lane should go straight
|
||||||
|
// (or follow a 180 degree turn angle between in/out segments.) The following function tries to find
|
||||||
|
// the best possible match for every tag in a given intersection, considering a few corner cases
|
||||||
|
// introduced to OSRM handling u-turns
|
||||||
|
typename Intersection::const_iterator findBestMatch(const TurnLaneType::Mask &tag,
|
||||||
const Intersection &intersection)
|
const Intersection &intersection)
|
||||||
{
|
{
|
||||||
const constexpr double idealized_turn_angles[] = {0, 35, 90, 135, 180, 225, 270, 315};
|
const constexpr double idealized_turn_angles[] = {0, 35, 90, 135, 180, 225, 270, 315};
|
||||||
@ -122,15 +128,20 @@ typename Intersection::const_iterator findBestMatch(const std::string &tag,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
typename Intersection::const_iterator findBestMatchForReverse(const std::string &leftmost_tag,
|
// Reverse is a special case, because it requires access to the leftmost tag. It has its own
|
||||||
const Intersection &intersection)
|
// matching function as a result of that. The leftmost tag is required, since u-turns are disabled
|
||||||
|
// by default in OSRM. Therefor we cannot check whether a turn is allowed, since it could be
|
||||||
|
// possible that it is forbidden. In addition, the best u-turn angle does not necessarily represent
|
||||||
|
// the u-turn, since it could be a sharp-left turn instead on a road with a middle island.
|
||||||
|
typename Intersection::const_iterator
|
||||||
|
findBestMatchForReverse(const TurnLaneType::Mask &leftmost_tag, const Intersection &intersection)
|
||||||
{
|
{
|
||||||
const auto leftmost_itr = findBestMatch(leftmost_tag, intersection);
|
const auto leftmost_itr = findBestMatch(leftmost_tag, intersection);
|
||||||
if (leftmost_itr + 1 == intersection.cend())
|
if (leftmost_itr + 1 == intersection.cend())
|
||||||
return intersection.begin();
|
return intersection.begin();
|
||||||
|
|
||||||
const constexpr double idealized_turn_angles[] = {0, 35, 90, 135, 180, 225, 270, 315};
|
const constexpr double idealized_turn_angles[] = {0, 35, 90, 135, 180, 225, 270, 315};
|
||||||
const std::string tag = "reverse";
|
const TurnLaneType::Mask tag = TurnLaneType::uturn;
|
||||||
const auto idealized_angle = idealized_turn_angles[getMatchingModifier(tag)];
|
const auto idealized_angle = idealized_turn_angles[getMatchingModifier(tag)];
|
||||||
return std::min_element(
|
return std::min_element(
|
||||||
intersection.begin() + std::distance(intersection.begin(), leftmost_itr),
|
intersection.begin() + std::distance(intersection.begin(), leftmost_itr),
|
||||||
@ -149,6 +160,8 @@ typename Intersection::const_iterator findBestMatchForReverse(const std::string
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a match is trivial if all turns can be associated with their best match in a valid way and the
|
||||||
|
// matches occur in order
|
||||||
bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &lane_data)
|
bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &lane_data)
|
||||||
{
|
{
|
||||||
std::size_t road_index = 1, lane = 0;
|
std::size_t road_index = 1, lane = 0;
|
||||||
@ -163,17 +176,18 @@ bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &l
|
|||||||
if (findBestMatch(lane_data[lane].tag, intersection) !=
|
if (findBestMatch(lane_data[lane].tag, intersection) !=
|
||||||
intersection.begin() + road_index)
|
intersection.begin() + road_index)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
++lane;
|
++lane;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lane == lane_data.size() ||
|
return lane == lane_data.size() ||
|
||||||
(lane + 1 == lane_data.size() && lane_data.back().tag == "reverse");
|
(lane + 1 == lane_data.size() && lane_data.back().tag == TurnLaneType::uturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
||||||
const LaneDataVector &lane_data,
|
const LaneDataVector &lane_data,
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const LaneStringID lane_string_id,
|
const LaneDescriptionID lane_string_id,
|
||||||
LaneDataIdMap &lane_data_to_id)
|
LaneDataIdMap &lane_data_to_id)
|
||||||
{
|
{
|
||||||
std::size_t road_index = 1, lane = 0;
|
std::size_t road_index = 1, lane = 0;
|
||||||
@ -212,7 +226,7 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle reverse tag, if present
|
// handle reverse tag, if present
|
||||||
if (lane + 1 == lane_data.size() && lane_data.back().tag == "reverse")
|
if (lane + 1 == lane_data.size() && lane_data.back().tag == TurnLaneType::uturn)
|
||||||
{
|
{
|
||||||
std::size_t u_turn = 0;
|
std::size_t u_turn = 0;
|
||||||
if (node_based_graph.GetEdgeData(intersection[0].turn.eid).reversed)
|
if (node_based_graph.GetEdgeData(intersection[0].turn.eid).reversed)
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#include "storage/storage.hpp"
|
|
||||||
#include "contractor/query_edge.hpp"
|
#include "contractor/query_edge.hpp"
|
||||||
#include "extractor/compressed_edge_container.hpp"
|
#include "extractor/compressed_edge_container.hpp"
|
||||||
#include "extractor/guidance/turn_instruction.hpp"
|
#include "extractor/guidance/turn_instruction.hpp"
|
||||||
@ -9,6 +8,7 @@
|
|||||||
#include "storage/shared_barriers.hpp"
|
#include "storage/shared_barriers.hpp"
|
||||||
#include "storage/shared_datatype.hpp"
|
#include "storage/shared_datatype.hpp"
|
||||||
#include "storage/shared_memory.hpp"
|
#include "storage/shared_memory.hpp"
|
||||||
|
#include "storage/storage.hpp"
|
||||||
#include "engine/datafacade/datafacade_base.hpp"
|
#include "engine/datafacade/datafacade_base.hpp"
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
#include "util/exception.hpp"
|
#include "util/exception.hpp"
|
||||||
@ -147,25 +147,17 @@ int Storage::Run()
|
|||||||
name_stream.read((char *)&number_of_chars, sizeof(unsigned));
|
name_stream.read((char *)&number_of_chars, sizeof(unsigned));
|
||||||
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::NAME_CHAR_LIST, number_of_chars);
|
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);
|
std::vector<std::uint32_t> lane_description_offsets;
|
||||||
if (!turn_string_stream)
|
std::vector<extractor::guidance::TurnLaneType::Mask> lane_description_masks;
|
||||||
{
|
if (!util::deserializeAdjacencyArray(config.turn_lane_description_path.string(),
|
||||||
throw util::exception("Could not open " + config.turn_lane_string_path.string() +
|
lane_description_offsets,
|
||||||
" for reading.");
|
lane_description_masks))
|
||||||
}
|
throw util::exception("Could not open read lane descriptions from: " +
|
||||||
|
config.turn_lane_description_path.string());
|
||||||
unsigned turn_string_blocks = 0;
|
shared_layout_ptr->SetBlockSize<std::uint32_t>(SharedDataLayout::LANE_DESCRIPTION_OFFSETS,
|
||||||
turn_string_stream.read((char *)&turn_string_blocks, sizeof(unsigned));
|
lane_description_offsets.size());
|
||||||
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::TURN_STRING_OFFSETS,
|
shared_layout_ptr->SetBlockSize<extractor::guidance::TurnLaneType::Mask>(
|
||||||
turn_string_blocks);
|
SharedDataLayout::LANE_DESCRIPTION_MASKS, lane_description_masks.size());
|
||||||
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
|
// Loading information for original edges
|
||||||
boost::filesystem::ifstream edges_input_stream(config.edges_data_path, std::ios::binary);
|
boost::filesystem::ifstream edges_input_stream(config.edges_data_path, std::ios::binary);
|
||||||
@ -454,7 +446,7 @@ int Storage::Run()
|
|||||||
|
|
||||||
char *name_char_ptr = shared_layout_ptr->GetBlockPtr<char, true>(
|
char *name_char_ptr = shared_layout_ptr->GetBlockPtr<char, true>(
|
||||||
shared_memory_ptr, SharedDataLayout::NAME_CHAR_LIST);
|
shared_memory_ptr, SharedDataLayout::NAME_CHAR_LIST);
|
||||||
unsigned temp_length;
|
unsigned temp_length = 0;
|
||||||
name_stream.read((char *)&temp_length, sizeof(unsigned));
|
name_stream.read((char *)&temp_length, sizeof(unsigned));
|
||||||
|
|
||||||
BOOST_ASSERT_MSG(shared_layout_ptr->AlignBlockSize(temp_length) ==
|
BOOST_ASSERT_MSG(shared_layout_ptr->AlignBlockSize(temp_length) ==
|
||||||
@ -468,16 +460,6 @@ int Storage::Run()
|
|||||||
}
|
}
|
||||||
name_stream.close();
|
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...
|
// make sure do write canary...
|
||||||
auto *turn_lane_data_ptr =
|
auto *turn_lane_data_ptr =
|
||||||
shared_layout_ptr->GetBlockPtr<util::guidance::LaneTupelIdPair, true>(
|
shared_layout_ptr->GetBlockPtr<util::guidance::LaneTupelIdPair, true>(
|
||||||
@ -489,30 +471,29 @@ int Storage::Run()
|
|||||||
}
|
}
|
||||||
lane_data_stream.close();
|
lane_data_stream.close();
|
||||||
|
|
||||||
unsigned *turn_string_blocks_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
|
auto *turn_lane_offset_ptr = shared_layout_ptr->GetBlockPtr<std::uint32_t, true>(
|
||||||
shared_memory_ptr, SharedDataLayout::TURN_STRING_BLOCKS);
|
shared_memory_ptr, SharedDataLayout::LANE_DESCRIPTION_OFFSETS);
|
||||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_STRING_BLOCKS) > 0)
|
if (!lane_description_offsets.empty())
|
||||||
{
|
{
|
||||||
turn_string_stream.read(
|
BOOST_ASSERT(shared_layout_ptr->GetBlockSize(SharedDataLayout::LANE_DESCRIPTION_OFFSETS) >=
|
||||||
(char *)turn_string_blocks_ptr,
|
sizeof(lane_description_offsets[0]) * lane_description_offsets.size());
|
||||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_STRING_BLOCKS));
|
std::copy(
|
||||||
|
lane_description_offsets.begin(), lane_description_offsets.end(), turn_lane_offset_ptr);
|
||||||
|
std::vector<std::uint32_t> tmp;
|
||||||
|
lane_description_offsets.swap(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *turn_string_char_ptr = shared_layout_ptr->GetBlockPtr<char, true>(
|
auto *turn_lane_mask_ptr =
|
||||||
shared_memory_ptr, SharedDataLayout::TURN_STRING_CHAR_LIST);
|
shared_layout_ptr->GetBlockPtr<extractor::guidance::TurnLaneType::Mask, true>(
|
||||||
turn_string_stream.read((char *)&temp_length, sizeof(unsigned));
|
shared_memory_ptr, SharedDataLayout::LANE_DESCRIPTION_MASKS);
|
||||||
|
if (!lane_description_masks.empty())
|
||||||
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(
|
BOOST_ASSERT(shared_layout_ptr->GetBlockSize(SharedDataLayout::LANE_DESCRIPTION_MASKS) >=
|
||||||
turn_string_char_ptr,
|
sizeof(lane_description_masks[0]) * lane_description_masks.size());
|
||||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_STRING_CHAR_LIST));
|
std::copy(lane_description_masks.begin(), lane_description_masks.end(), turn_lane_mask_ptr);
|
||||||
|
std::vector<extractor::guidance::TurnLaneType::Mask> tmp;
|
||||||
|
lane_description_masks.swap(tmp);
|
||||||
}
|
}
|
||||||
turn_string_stream.close();
|
|
||||||
|
|
||||||
// load original edge information
|
// load original edge information
|
||||||
NodeID *via_node_ptr = shared_layout_ptr->GetBlockPtr<NodeID, true>(
|
NodeID *via_node_ptr = shared_layout_ptr->GetBlockPtr<NodeID, true>(
|
||||||
@ -595,7 +576,7 @@ int Storage::Run()
|
|||||||
{
|
{
|
||||||
util::SimpleLogger().Write()
|
util::SimpleLogger().Write()
|
||||||
<< "Copying " << (m_datasource_name_data.end() - m_datasource_name_data.begin())
|
<< "Copying " << (m_datasource_name_data.end() - m_datasource_name_data.begin())
|
||||||
<< " chars into name data ptr\n";
|
<< " chars into name data ptr";
|
||||||
std::copy(
|
std::copy(
|
||||||
m_datasource_name_data.begin(), m_datasource_name_data.end(), datasource_name_data_ptr);
|
m_datasource_name_data.begin(), m_datasource_name_data.end(), datasource_name_data_ptr);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ StorageConfig::StorageConfig(const boost::filesystem::path &base)
|
|||||||
datasource_indexes_path{base.string() + ".datasource_indexes"},
|
datasource_indexes_path{base.string() + ".datasource_indexes"},
|
||||||
names_data_path{base.string() + ".names"}, properties_path{base.string() + ".properties"},
|
names_data_path{base.string() + ".names"}, properties_path{base.string() + ".properties"},
|
||||||
intersection_class_path{base.string() + ".icd"}, turn_lane_data_path{base.string() + ".tld"},
|
intersection_class_path{base.string() + ".icd"}, turn_lane_data_path{base.string() + ".tld"},
|
||||||
turn_lane_string_path{base.string() + ".tls"}
|
turn_lane_description_path{base.string() + ".tls"}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{1,
|
{1,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{1,
|
{1,
|
||||||
2,
|
2,
|
||||||
1,
|
1,
|
||||||
@ -62,7 +62,7 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{2,
|
{2,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
@ -73,7 +73,7 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{2,
|
{2,
|
||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
@ -84,7 +84,7 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{3,
|
{3,
|
||||||
2,
|
2,
|
||||||
1,
|
1,
|
||||||
@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{3,
|
{3,
|
||||||
4,
|
4,
|
||||||
1,
|
1,
|
||||||
@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{4,
|
{4,
|
||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
@ -117,7 +117,7 @@ BOOST_AUTO_TEST_CASE(long_road_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID}};
|
INVALID_LANE_DESCRIPTIONID}};
|
||||||
|
|
||||||
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[2].data));
|
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[2].data));
|
||||||
BOOST_ASSERT(edges[2].data.IsCompatibleTo(edges[4].data));
|
BOOST_ASSERT(edges[2].data.IsCompatibleTo(edges[4].data));
|
||||||
@ -159,7 +159,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{0,
|
{0,
|
||||||
5,
|
5,
|
||||||
1,
|
1,
|
||||||
@ -170,7 +170,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{1,
|
{1,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{1,
|
{1,
|
||||||
2,
|
2,
|
||||||
1,
|
1,
|
||||||
@ -192,7 +192,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{2,
|
{2,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{2,
|
{2,
|
||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
@ -214,7 +214,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{3,
|
{3,
|
||||||
2,
|
2,
|
||||||
1,
|
1,
|
||||||
@ -225,7 +225,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{3,
|
{3,
|
||||||
4,
|
4,
|
||||||
1,
|
1,
|
||||||
@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{4,
|
{4,
|
||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
@ -247,7 +247,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{4,
|
{4,
|
||||||
5,
|
5,
|
||||||
1,
|
1,
|
||||||
@ -258,7 +258,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{5,
|
{5,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{5,
|
{5,
|
||||||
4,
|
4,
|
||||||
1,
|
1,
|
||||||
@ -280,7 +280,7 @@ BOOST_AUTO_TEST_CASE(loop_test)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_ASSERT(edges.size() == 12);
|
BOOST_ASSERT(edges.size() == 12);
|
||||||
@ -334,7 +334,7 @@ BOOST_AUTO_TEST_CASE(t_intersection)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{1,
|
{1,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
@ -345,7 +345,7 @@ BOOST_AUTO_TEST_CASE(t_intersection)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{1,
|
{1,
|
||||||
2,
|
2,
|
||||||
1,
|
1,
|
||||||
@ -356,7 +356,7 @@ BOOST_AUTO_TEST_CASE(t_intersection)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{1,
|
{1,
|
||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
@ -367,7 +367,7 @@ BOOST_AUTO_TEST_CASE(t_intersection)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{2,
|
{2,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
@ -378,7 +378,7 @@ BOOST_AUTO_TEST_CASE(t_intersection)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{3,
|
{3,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
@ -389,7 +389,7 @@ BOOST_AUTO_TEST_CASE(t_intersection)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[1].data));
|
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[1].data));
|
||||||
@ -430,7 +430,7 @@ BOOST_AUTO_TEST_CASE(street_name_changes)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{1,
|
{1,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
@ -441,7 +441,7 @@ BOOST_AUTO_TEST_CASE(street_name_changes)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{1,
|
{1,
|
||||||
2,
|
2,
|
||||||
1,
|
1,
|
||||||
@ -452,7 +452,7 @@ BOOST_AUTO_TEST_CASE(street_name_changes)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{2,
|
{2,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
@ -463,7 +463,7 @@ BOOST_AUTO_TEST_CASE(street_name_changes)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[1].data));
|
BOOST_ASSERT(edges[0].data.IsCompatibleTo(edges[1].data));
|
||||||
@ -500,7 +500,7 @@ BOOST_AUTO_TEST_CASE(direction_changes)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{1,
|
{1,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
@ -511,7 +511,7 @@ BOOST_AUTO_TEST_CASE(direction_changes)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{1,
|
{1,
|
||||||
2,
|
2,
|
||||||
1,
|
1,
|
||||||
@ -522,7 +522,7 @@ BOOST_AUTO_TEST_CASE(direction_changes)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
{2,
|
{2,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
@ -533,7 +533,7 @@ BOOST_AUTO_TEST_CASE(direction_changes)
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
TRAVEL_MODE_INACCESSIBLE,
|
TRAVEL_MODE_INACCESSIBLE,
|
||||||
INVALID_LANE_STRINGID},
|
INVALID_LANE_DESCRIPTIONID},
|
||||||
};
|
};
|
||||||
|
|
||||||
Graph graph(5, edges);
|
Graph graph(5, edges);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "contractor/query_edge.hpp"
|
#include "contractor/query_edge.hpp"
|
||||||
#include "extractor/guidance/turn_instruction.hpp"
|
#include "extractor/guidance/turn_instruction.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
#include "engine/datafacade/datafacade_base.hpp"
|
#include "engine/datafacade/datafacade_base.hpp"
|
||||||
#include "util/guidance/bearing_class.hpp"
|
#include "util/guidance/bearing_class.hpp"
|
||||||
#include "util/guidance/entry_class.hpp"
|
#include "util/guidance/entry_class.hpp"
|
||||||
@ -180,9 +181,16 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade
|
|||||||
BearingClassID GetBearingClassID(const NodeID /*id*/) const override { return 0; };
|
BearingClassID GetBearingClassID(const NodeID /*id*/) const override { return 0; };
|
||||||
EntryClassID GetEntryClassID(const EdgeID /*id*/) const override { return 0; }
|
EntryClassID GetEntryClassID(const EdgeID /*id*/) const override { return 0; }
|
||||||
|
|
||||||
bool hasLaneData(const EdgeID /*id*/) const { return true; };
|
bool hasLaneData(const EdgeID /*id*/) const override final { return true; };
|
||||||
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID /*id*/) const { return {{0, 0}, 0}; }
|
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID /*id*/) const override final
|
||||||
std::string GetTurnStringForID(const LaneStringID /*lane_string_id*/) const { return ""; };
|
{
|
||||||
|
return {{0, 0}, 0};
|
||||||
|
}
|
||||||
|
extractor::guidance::TurnLaneDescription
|
||||||
|
GetTurnDescription(const LaneDescriptionID /*lane_description_id*/) const override final
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
util::guidance::BearingClass
|
util::guidance::BearingClass
|
||||||
GetBearingClass(const BearingClassID /*bearing_class_id*/) const override
|
GetBearingClass(const BearingClassID /*bearing_class_id*/) const override
|
||||||
|
Loading…
Reference in New Issue
Block a user