Compare commits

...

19 Commits

Author SHA1 Message Date
Patrick Niklaus cc0c28f366 Fix formating for cherry-picked commit 2017-03-09 12:05:01 +00:00
Michael Krasnyk 66cc99703c Compute correct speed values in tile plugin 2017-03-09 11:49:10 +00:00
Patrick Niklaus f7fbca3e5e Update changelog 2017-03-03 17:27:28 +00:00
Patrick Niklaus 9695eaa28a Fix tile datasize check 2017-03-03 16:03:47 +00:00
Patrick Niklaus 0d7546a510 Only allow restricted access for road of certain highway type 2017-03-03 16:03:36 +00:00
Michael Krasnyk 9dc8136240 Fix incorrect forward datasources getter in facade 2017-03-03 10:52:53 +00:00
Patrick Niklaus a02a83f8bd Other flakey test 2017-03-02 15:24:38 +00:00
Patrick Niklaus 9b18f55d29 Update changelog 2017-03-02 15:00:49 +00:00
Patrick Niklaus a3434e7ae9 Mark test as flaky and track in own issue. 2017-03-02 14:59:10 +00:00
Patrick Niklaus 64b15028e4 Print 0 rate 2017-03-02 14:58:14 +00:00
karenzshea d8e466fdaa simplify test, add intersection turn test 2017-03-02 14:58:01 +00:00
karenzshea 43bbe8f2ae add restricted penalty on NoTurn turns 2017-03-02 14:57:49 +00:00
karenzshea b5c10b1fbf clamp speed value to js max 2017-02-22 16:13:01 +00:00
Daniel J. Hofmann 57d93fc5dc Updates TBB to latest stable version for 5.6 release 2017-02-20 13:55:42 +00:00
karenzshea 3aba2bc2d0 expose data about turning onto restricted roads to turn function 2017-02-20 13:55:19 +00:00
Daniel J. Hofmann c42478f0ee Updates sol2 to v2.15.8, resolves #3733 2017-02-20 10:14:17 +00:00
Moritz Kobitzsch ea583a77ff reduce verbosity of use-lane in combination with lane-anticipation 2017-02-15 21:57:58 +00:00
Kajari Ghosh dd999e112e Update http.md
Clarify where optional rotary properties will be added
2017-02-15 21:56:30 +00:00
Daniel Patterson 69c54bef72 Allow routing on toll roads by default (#3712) 2017-02-14 20:02:15 -08:00
32 changed files with 792 additions and 296 deletions
+17
View File
@@ -1,3 +1,20 @@
# 5.6.3
- Changes from 5.6.0
- Bugfixes
- #3790 Fix incorrect speed values in tile plugin
# 5.6.2
- Changes from 5.6.0
- Bugfixes
- Fix incorrect forward datasources getter in facade
- Fix include `access=private` non-car roads in the car profile
# 5.6.1
- Changes from 5.6.0
- Bugfixes
- Fix #3754 restricted access roads not penalized if restriction begins non at an intersection
# 5.6.0 # 5.6.0
- Changes from 5.5 - Changes from 5.5
- Bugfixes - Bugfixes
+1 -1
View File
@@ -32,7 +32,7 @@ if(ENABLE_MASON)
set(MASON_EXPAT_VERSION "2.2.0") set(MASON_EXPAT_VERSION "2.2.0")
set(MASON_LUA_VERSION "5.2.4") set(MASON_LUA_VERSION "5.2.4")
set(MASON_BZIP2_VERSION "1.0.6") set(MASON_BZIP2_VERSION "1.0.6")
set(MASON_TBB_VERSION "43_20150316") set(MASON_TBB_VERSION "2017_20161128")
message(STATUS "Enabling mason") message(STATUS "Enabling mason")
+5 -3
View File
@@ -576,6 +576,8 @@ step.
- `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 `Intersection` objects 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
- `rotary_name`: The name for the rotary. Optionally included, if the step is a rotary and a rotary name is available.
- `rotary_pronunciation`: The pronunciation hint of the rotary name. Optionally included, if the step is a rotary and a rotary pronunciation is available.
#### Example #### Example
@@ -630,7 +632,7 @@ step.
- `bearing_after`: The clockwise angle from true north to the - `bearing_after`: The clockwise angle from true north to the
direction of travel immediately after the maneuver. Range 0-359. direction of travel immediately after the maneuver. Range 0-359.
- `type` A string indicating the type of maneuver. **new identifiers might be introduced without API change** - `type` A string indicating the type of maneuver. **new identifiers might be introduced without API change**
Types unknown to the client should be handled like the `turn` type, the existance of correct `modifier` values is guranteed. Types unknown to the client should be handled like the `turn` type, the existence of correct `modifier` values is guranteed.
| `type` | Description | | `type` | Description |
|------------------|--------------------------------------------------------------| |------------------|--------------------------------------------------------------|
@@ -646,8 +648,8 @@ step.
| `end of road` | road ends in a T intersection turn in direction of `modifier`| | `end of road` | road ends in a T intersection turn in direction of `modifier`|
| `use lane` | going straight on a specific lane | | `use lane` | going straight on a specific lane |
| `continue` | Turn in direction of `modifier` to stay on the same road | | `continue` | Turn in direction of `modifier` to stay on the same road |
| `roundabout` | traverse roundabout, has additional property `exit` with NR if the roundabout is left. `the modifier specifies the direction of entering the roundabout` | | `roundabout` | traverse roundabout, has additional property `exit` with NR if the roundabout is left. The modifier specifies the direction of entering the roundabout. |
| `rotary` | a traffic circle. While very similar to a larger version of a roundabout, it does not necessarily follow roundabout rules for right of way. It can offer `rotary_name/rotary_pronunciation` in addition to the `exit` parameter. | | `rotary` | a traffic circle. While very similar to a larger version of a roundabout, it does not necessarily follow roundabout rules for right of way. It can offer `rotary_name` and/or `rotary_pronunciation` parameters (located in the RouteStep object) in addition to the `exit` parameter (located on the StepManeuver object). |
| `roundabout turn`| Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. | | `roundabout turn`| Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. |
| `notification` | not an actual turn but a change in the driving conditions. For example the travel mode. If the road takes a turn itself, the `modifier` describes the direction | | `notification` | not an actual turn but a change in the driving conditions. For example the travel mode. If the road takes a turn itself, the `modifier` describes the direction |
+55 -32
View File
@@ -119,12 +119,13 @@ Feature: Car - Restricted access
| permissive | x | | permissive | x |
| designated | x | | designated | x |
| no | | | no | |
| private | | | private | x |
| agricultural | | | agricultural | |
| forestry | | | forestry | |
| psv | | | psv | |
| delivery | | | delivery | x |
| some_tag | x | | some_tag | x |
| destination | x |
Scenario: Car - Access tags on nodes Scenario: Car - Access tags on nodes
@@ -134,11 +135,11 @@ Feature: Car - Restricted access
| permissive | x | | permissive | x |
| designated | x | | designated | x |
| no | | | no | |
| private | | | private | x |
| agricultural | | | agricultural | |
| forestry | | | forestry | |
| psv | | | psv | |
| delivery | | | delivery | x |
| some_tag | x | | some_tag | x |
Scenario: Car - Access tags on both node and way Scenario: Car - Access tags on both node and way
@@ -156,15 +157,15 @@ Feature: Car - Restricted access
Scenario: Car - Access combinations Scenario: Car - Access combinations
Then routability should be Then routability should be
| highway | accesss | vehicle | motor_vehicle | motorcar | bothw | | highway | access | vehicle | motor_vehicle | motorcar | forw | backw | # |
| runway | private | | | permissive | x | | runway | private | | | permissive | x | x | |
| primary | forestry | | yes | | x | | primary | forestry | | yes | | x | x | |
| cycleway | | | designated | | x | | cycleway | | | designated | | x | x | |
| residential | | yes | no | | | | residential | | yes | no | | | | |
| motorway | yes | permissive | | private | | | motorway | yes | permissive | | private | x | | implied oneway |
| trunk | agricultural | designated | permissive | no | | | trunk | agricultural | designated | permissive | no | | | |
| pedestrian | | | | | | | pedestrian | | | | | | | |
| pedestrian | | | | destination | x | | pedestrian | | | | destination | | | temporary disabled #3773 |
Scenario: Car - Ignore access tags for other modes Scenario: Car - Ignore access tags for other modes
Then routability should be Then routability should be
@@ -182,7 +183,7 @@ Feature: Car - Restricted access
Scenario: Car - designated HOV ways are rated low Scenario: Car - designated HOV ways are rated low
Then routability should be Then routability should be
| highway | hov | bothw | forw_rate | backw_rate | | highway | hov | bothw | forw_rate | backw_rate |
| primary | designated | x | 2 | 2 | | primary | designated | x | 18 | 18 |
| primary | yes | x | 18 | 18 | | primary | yes | x | 18 | 18 |
| primary | no | x | 18 | 18 | | primary | no | x | 18 | 18 |
@@ -193,28 +194,29 @@ Feature: Car - Restricted access
Scenario: Car - I-66 use HOV-only roads with heavy penalty Scenario: Car - I-66 use HOV-only roads with heavy penalty
Then routability should be Then routability should be
| highway | hov | hov:lanes | lanes | access | oneway | forw | backw | forw_rate | | highway | hov | hov:lanes | lanes | access | oneway | forw | backw | forw_rate |
| motorway | designated | designated\|designated\|designated | 3 | hov | yes | x | | 3 | | motorway | designated | designated\|designated\|designated | 3 | hov | yes | x | | 25 |
| motorway | lane | | 3 | designated | yes | x | | 25 | | motorway | lane | | 3 | designated | yes | x | | 25 |
@hov @hov
Scenario: Car - a way with all lanes HOV-designated is highly penalized by default (similar to hov=designated) Scenario: Car - a way with all lanes HOV-designated is highly penalized by default (similar to hov=designated)
Then routability should be Then routability should be
| highway | hov:lanes:forward | hov:lanes:backward | hov:lanes | oneway | forw | backw | forw_rate | backw_rate | | highway | hov:lanes:forward | hov:lanes:backward | hov:lanes | oneway | forw | backw | forw_rate | backw_rate |
| primary | designated | designated | | | x | x | 2 | 2 | | primary | designated | designated | | | x | x | 18 | 18 |
| primary | | designated | | | x | x | 18 | 2 | # This test is flaky because non-deterministic turn generation sometimes emits a NoTurn here that is marked as restricted. #3769
| primary | designated | | | | x | x | 2 | 18 | #| primary | | designated | | | x | x | 18 | 18 |
| primary | designated\|designated | designated\|designated | | | x | x | 2 | 2 | #| primary | designated | | | | x | x | 18 | 18 |
| primary | designated\|designated | designated\|designated | | | x | x | 18 | 18 |
| primary | designated\|no | designated\|no | | | x | x | 18 | 18 | | primary | designated\|no | designated\|no | | | x | x | 18 | 18 |
| primary | yes\|no | yes\|no | | | x | x | 18 | 18 | | primary | yes\|no | yes\|no | | | x | x | 18 | 18 |
| primary | | | | | x | x | 18 | 18 | | primary | | | | | x | x | 18 | 18 |
| primary | designated | | | -1 | | x | | 18 | | primary | designated | | | -1 | | x | | 18 |
| primary | | designated | | -1 | | x | | 2 | | primary | | designated | | -1 | | x | | 18 |
| primary | | | designated | yes | x | | 2 | | | primary | | | designated | yes | x | | 18 | |
| primary | | | designated | -1 | | x | | 2 | | primary | | | designated | -1 | | x | | 18 |
| primary | | | designated\| | yes | x | | 18 | | | primary | | | designated\| | yes | x | | 18 | |
| primary | | | designated\| | -1 | | x | | 18 | | primary | | | designated\| | -1 | | x | | 18 |
| primary | | | designated\|designated | yes | x | | 2 | | | primary | | | designated\|designated | yes | x | | 18 | |
| primary | | | designated\|designated | -1 | | x | | 2 | | primary | | | designated\|designated | -1 | | x | | 18 |
| primary | | | designated\|yes | yes | x | | 18 | | | primary | | | designated\|yes | yes | x | | 18 | |
| primary | | | designated\|no | -1 | | x | | 18 | | primary | | | designated\|no | -1 | | x | | 18 |
@@ -224,12 +226,10 @@ Feature: Car - Restricted access
| primary | no | x | | primary | no | x |
| primary | snowmobile | x | | primary | snowmobile | x |
# To test this we need issue #2781 Scenario: Car - toll=yes ways are enabled by default
@todo
Scenario: Car - only toll=yes ways are ignored by default
Then routability should be Then routability should be
| highway | toll | bothw | | highway | toll | bothw |
| primary | yes | | | primary | yes | x |
Scenario: Car - directional access tags Scenario: Car - directional access tags
Then routability should be Then routability should be
@@ -252,7 +252,7 @@ Feature: Car - Restricted access
| gate | yes | x | | gate | yes | x |
| gate | permissive | x | | gate | permissive | x |
| gate | designated | x | | gate | designated | x |
| gate | private | | | gate | private | x |
| gate | garbagetag | x | | gate | garbagetag | x |
Scenario: Car - a way with conditional access Scenario: Car - a way with conditional access
@@ -262,9 +262,11 @@ Feature: Car - Restricted access
Scenario: Car - a way with a list of tags Scenario: Car - a way with a list of tags
Then routability should be Then routability should be
| highway | motor_vehicle | motor_vehicle:forward | motor_vehicle:backward | forw | backw | | highway | motor_vehicle | motor_vehicle:forward | motor_vehicle:backward | forw | backw | # |
| footway | | | destination | | x | | primary | | no | destination | | x | |
| track | destination;agricultural | destination | | x | x | | primary | destination;agricultural | destination | | x | x | |
| footway | | | destination | | | temporary #3373 |
| track | destination;agricultural | destination | | | x | temporary #3373 |
Scenario: Car - Don't route over steps even if marked as accessible Scenario: Car - Don't route over steps even if marked as accessible
Then routability should be Then routability should be
@@ -280,3 +282,24 @@ Feature: Car - Restricted access
| steps | permissive | | | steps | permissive | |
| footway | permissive | x | | footway | permissive | x |
| garbagetag | permissive | x | | garbagetag | permissive | x |
Scenario: Car - Access private blacklist
Then routability should be
| highway | access | bothw |
| footway | yes | x |
| pedestrian | private | |
| footway | private | |
| service | private | |
| cycleway | private | |
| track | private | |
Scenario: Car - Access blacklist
Then routability should be
| highway | access | bothw |
| primary | | x |
| primary | customer | |
| primary | emergency | |
| primary | forestry | |
| primary | agricultural | |
| primary | psv | |
| primary | no | |
+2 -2
View File
@@ -29,14 +29,14 @@ Feature: Car - Barriers
| gate | permissive | x | | gate | permissive | x |
| gate | designated | x | | gate | designated | x |
| gate | no | | | gate | no | |
| gate | private | | | gate | private | x |
| gate | agricultural | | | gate | agricultural | |
| wall | | | | wall | | |
| wall | yes | x | | wall | yes | x |
| wall | permissive | x | | wall | permissive | x |
| wall | designated | x | | wall | designated | x |
| wall | no | | | wall | no | |
| wall | private | | | wall | private | x |
| wall | agricultural | | | wall | agricultural | |
Scenario: Car - Rising bollard exception for barriers Scenario: Car - Rising bollard exception for barriers
+51 -1
View File
@@ -1,4 +1,4 @@
@routing @car @destination @todo @routing @car @destination
Feature: Car - Destination only, no passing through Feature: Car - Destination only, no passing through
Background: Background:
@@ -81,3 +81,53 @@ Feature: Car - Destination only, no passing through
| e | a | de,cd,bc,ab,ab | | e | a | de,cd,bc,ab,ab |
| b | d | bc,cd,cd | | b | d | bc,cd,cd |
| d | b | cd,bc,bc | | d | b | cd,bc,bc |
Scenario: Car - Routing around a way that becomes destination only
Given the node map
"""
b
\
|
e++d++++++c--i
| \
\ h--a
\ |
\___________g
"""
And the ways
| nodes | access | oneway |
| ah | | no |
| ihg | | no |
| eg | | no |
| icde | | no |
| cde | destination | no |
| eb | | no |
When I route I should get
| from | to | route | # |
| i | b | ihg,eg,eb,eb | # goes around access=destination, though restricted way starts at two node intersection |
| b | d | eb,cde,cde | # ends in restricted way correctly |
| b | i | eb,eg,ihg,ihg | # goes around restricted way correctly |
Scenario: Car - Routing around a way that becomes destination only
Given the node map
"""
a---c---b
+ \
+ |
d |
\___e
"""
And the ways
| nodes | access | oneway |
| acbe | | no |
| cd | destination | no |
| de | | no |
When I route I should get
| from | to | route |
| e | a | acbe,acbe |
| d | a | de,acbe,acbe |
| c | d | cd,cd |
+36
View File
@@ -0,0 +1,36 @@
@routing @car @hov
Feature: Car - Handle driving
Background:
Given the profile "car"
And a grid size of 100 meters
Scenario: Car - Avoid hov when not on hov
Given the node map
"""
b=========c========================e====j
~ ~ ~
a ~ f----m
| i |
| | ----------------l
| | /
g_______________h______k_____n
"""
And the ways
| nodes | highway | hov |
| ab | motorway_link | |
| bcej | motorway | designated |
| ag | primary | |
| ghkn | primary | |
| ih | primary | |
| kl | secondary | |
| lf | secondary | |
| ci | motorway_link | |
| ef | motorway_link | |
| fm | secondary | |
When I route I should get
| from | to | route |
| a | m | ag,ghkn,kl,lf,fm,fm |
| c | m | bcej,ef,fm,fm |
+2 -2
View File
@@ -40,13 +40,13 @@ Feature: Car - Surfaces
| highway | access | tracktype | smoothness | surface | forw | backw | | highway | access | tracktype | smoothness | surface | forw | backw |
| motorway | | | | | x | | | motorway | | | | | x | |
| motorway | no | grade1 | excellent | asphalt | | | | motorway | no | grade1 | excellent | asphalt | | |
| motorway | private | grade1 | excellent | asphalt | | | | motorway | private | grade1 | excellent | asphalt | x | |
| motorway | agricultural | grade1 | excellent | asphalt | | | | motorway | agricultural | grade1 | excellent | asphalt | | |
| motorway | forestry | grade1 | excellent | asphalt | | | | motorway | forestry | grade1 | excellent | asphalt | | |
| motorway | emergency | grade1 | excellent | asphalt | | | | motorway | emergency | grade1 | excellent | asphalt | | |
| primary | | | | | x | x | | primary | | | | | x | x |
| primary | private | grade1 | excellent | asphalt | x | x |
| primary | no | grade1 | excellent | asphalt | | | | primary | no | grade1 | excellent | asphalt | | |
| primary | private | grade1 | excellent | asphalt | | |
| primary | agricultural | grade1 | excellent | asphalt | | | | primary | agricultural | grade1 | excellent | asphalt | | |
| primary | forestry | grade1 | excellent | asphalt | | | | primary | forestry | grade1 | excellent | asphalt | | |
| primary | emergency | grade1 | excellent | asphalt | | | | primary | emergency | grade1 | excellent | asphalt | | |
@@ -818,3 +818,37 @@ 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,e | MySt,MySt,MySt,MySt | depart,continue right,turn right,arrive | ,straight:false straight:false right:false right:true,left:false right:true, | | a,e | MySt,MySt,MySt,MySt | depart,continue right,turn right,arrive | ,straight:false straight:false right:false right:true,left:false right:true, |
@anticipate
Scenario: Don't Overdo It
Given the node map
"""
q r s t u v
| | | | | |
a - - - - - - - - - - b - - - - - - - - - - c - - - - - - - - - - d - - - - - - - - - - e - - - - - - - - - - f - - - - - - - - - - g - h - i
| | | | | | |
p o n m l k j
"""
And the ways
| nodes | name | turn:lanes:forward | oneway |
| ab | road | left\|\|\| | yes |
| bc | road | left\|\|\| | yes |
| cd | road | left\|\|\| | yes |
| de | road | left\|\|\| | yes |
| ef | road | left\|\|\| | yes |
| fg | road | left\|\|\| | yes |
| gh | road | \|\|right | yes |
| hi | road | | yes |
| qbp | 1st | | no |
| rco | 2nd | | no |
| sdn | 3rd | | no |
| tem | 4th | | no |
| ufl | 5th | | no |
| vgk | 6th | | no |
| hj | 7th | | no |
When I route I should get
| waypoints | route | turns | locations | lanes |
| a,i | road,road,road | depart,use lane straight,arrive | a,g,i | ,left:false none:true none:true none:false, |
| a,j | road,road,7th,7th | depart,use lane straight,turn right,arrive | a,f,h,j | ,left:false none:false none:false none:true,none:false none:false right:true, |
+2 -1
View File
@@ -28,13 +28,14 @@ module.exports = function () {
directions.filter(d => headers.has(d + '_rate')).forEach((direction) => { directions.filter(d => headers.has(d + '_rate')).forEach((direction) => {
var rate = direction + '_rate'; var rate = direction + '_rate';
var want = row[rate]; var want = row[rate];
switch (true) { switch (true) {
case '' === want: case '' === want:
outputRow[rate] = result[direction].status ? outputRow[rate] = result[direction].status ?
result[direction].status.toString() : ''; result[direction].status.toString() : '';
break; break;
case /^\d+$/.test(want): case /^\d+$/.test(want):
if (result[direction].rate && !isNaN(result[direction].rate)) { if (result[direction].rate !== undefined && !isNaN(result[direction].rate)) {
outputRow[rate] = result[direction].rate.toString(); outputRow[rate] = result[direction].rate.toString();
} else { } else {
outputRow[rate] = ''; outputRow[rate] = '';
+49 -37
View File
@@ -36,15 +36,18 @@ Feature: Traffic - speeds
1,4,27 1,4,27
4,1,27 4,1,27
""" """
And I route I should get And the query options
| from | to | route | speed | weights | | annotations | datasources |
| a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 |
| a | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | When I route I should get
| b | c | bc,bc | 27 km/h | 741.5,0 | | from | to | route | speed | weights | a:datasources |
| a | d | ad,ad | 27 km/h | 1275.7,0 | | a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 | 1:0:0:0 |
| d | c | dc,dc | 36 km/h | 956.8,0 | | a | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | 1:0 |
| g | b | fb,fb | 36 km/h | 164.7,0 | | b | c | bc,bc | 27 km/h | 741.5,0 | 1:0 |
| a | g | ad,df,fb,fb | 30 km/h | 1275.7,487.5,304.7,0 | | a | d | ad,ad | 27 km/h | 1275.7,0 | 1:0 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 |
| a | g | ad,df,fb,fb | 30 km/h | 1275.7,487.5,304.7,0 | 1:0:0 |
Scenario: Weighting based on speed file weights, ETA based on file durations Scenario: Weighting based on speed file weights, ETA based on file durations
@@ -58,15 +61,18 @@ Feature: Traffic - speeds
1,4,27,1275.7 1,4,27,1275.7
4,1,27,1275.7 4,1,27,1275.7
""" """
And I route I should get And the query options
| from | to | route | speed | weights | | annotations | datasources |
| a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 |
| a | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | When I route I should get
| b | c | bc,bc | 27 km/h | 741.5,0 | | from | to | route | speed | weights | a:datasources |
| a | d | ad,ad | 27 km/h | 1275.7,0 | | a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 | 1:0:0:0 |
| d | c | dc,dc | 36 km/h | 956.8,0 | | a | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | 1:0 |
| g | b | ab,ab | 1 km/h | 10010.4,0 | | b | c | bc,bc | 27 km/h | 741.5,0 | 1:0 |
| a | g | ab,ab | 1 km/h | 10010.3,0 | | a | d | ad,ad | 27 km/h | 1275.7,0 | 1:0 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
| g | b | ab,ab | 1 km/h | 10010.4,0 | 1:0 |
| a | g | ab,ab | 1 km/h | 10010.3,0 | 1 |
Scenario: Weighting based on speed file weights, ETA based on file durations Scenario: Weighting based on speed file weights, ETA based on file durations
@@ -87,16 +93,19 @@ Feature: Traffic - speeds
1,4,1,34445.12 1,4,1,34445.12
4,1,1,34445.3 4,1,1,34445.3
""" """
And I route I should get And the query options
| from | to | route | speed | weights | | annotations | datasources |
| a | b | ab,ab | 1 km/h | 20020.789,0 |
| a | c | ab,bc,bc | 2 km/h | 20020.789,741.568,0 | When I route I should get
| b | c | bc,bc | 27 km/h | 741.568,0 | | from | to | route | speed | weights | a:datasources |
| a | d | ab,eb,de,de | 2 km/h | 20020.789,378.169,400.415,0 | | a | b | ab,ab | 1 km/h | 20020.789,0 | 1:0 |
| d | c | dc,dc | 36 km/h | 956.805,0 | | a | c | ab,bc,bc | 2 km/h | 20020.789,741.568,0 | 1:1:0 |
| g | b | ab,ab | 1 km/h | 10010.392,0 | | b | c | bc,bc | 27 km/h | 741.568,0 | 1:0 |
| a | g | ab,ab | 1 km/h | 10010.397,0 | | a | d | ab,eb,de,de | 2 km/h | 20020.789,378.169,400.415,0 | 1:0:0 |
| g | a | ab,ab | 1 km/h | 10010.064,0 | | d | c | dc,dc | 36 km/h | 956.805,0 | 0 |
| g | b | ab,ab | 1 km/h | 10010.392,0 | 1:0 |
| a | g | ab,ab | 1 km/h | 10010.397,0 | 1 |
| g | a | ab,ab | 1 km/h | 10010.064,0 | 1:1 |
Scenario: Speeds that isolate a single node (a) Scenario: Speeds that isolate a single node (a)
@@ -113,15 +122,18 @@ Feature: Traffic - speeds
1,4,0 1,4,0
4,1,0 4,1,0
""" """
And I route I should get And the query options
| from | to | route | speed | weights | | annotations | true |
| a | b | fb,fb | 36 km/h | 329.4,0 |
| a | c | fb,bc,bc | 30 km/h | 329.4,741.5,0 | When I route I should get
| b | c | bc,bc | 27 km/h | 741.5,0 | | from | to | route | speed | weights | a:datasources |
| a | d | fb,df,df | 36 km/h | 140,487.5,0 | | a | b | fb,fb | 36 km/h | 329.4,0 | 0 |
| d | c | dc,dc | 36 km/h | 956.8,0 | | a | c | fb,bc,bc | 30 km/h | 329.4,741.5,0 | 0:1:0 |
| g | b | fb,fb | 36 km/h | 164.7,0 | | b | c | bc,bc | 27 km/h | 741.5,0 | 1:0 |
| a | g | fb,fb | 36 km/h | 164.7,0 | | a | d | fb,df,df | 36 km/h | 140,487.5,0 | 0:0:0 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 |
| a | g | fb,fb | 36 km/h | 164.7,0 | 0 |
Scenario: Verify that negative values cause an error, they're not valid at all Scenario: Verify that negative values cause an error, they're not valid at all
+3 -1
View File
@@ -19,6 +19,7 @@
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/integer_range.hpp" #include "util/integer_range.hpp"
#include "util/json_util.hpp"
#include <iterator> #include <iterator>
#include <vector> #include <vector>
@@ -249,7 +250,8 @@ class RouteAPI : public BaseAPI
{ {
annotation.values["speed"] = GetAnnotations( annotation.values["speed"] = GetAnnotations(
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) { leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return std::round(anno.distance / anno.duration * 10.) / 10.; auto val = std::round(anno.distance / anno.duration * 10.) / 10.;
return util::json::clamp_float(val);
}); });
} }
@@ -865,7 +865,6 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
} }
else else
{ {
result_datasources.resize(end - begin);
std::copy(m_datasource_list.begin() + begin, std::copy(m_datasource_list.begin() + begin,
m_datasource_list.begin() + end, m_datasource_list.begin() + end,
std::back_inserter(result_datasources)); std::back_inserter(result_datasources));
+1 -1
View File
@@ -20,7 +20,7 @@ namespace guidance
// as separate maneuvers. // as separate maneuvers.
OSRM_ATTR_WARN_UNUSED OSRM_ATTR_WARN_UNUSED
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps, std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
const double min_duration_needed_for_lane_change = 15); const double min_duration_needed_for_lane_change = 10);
} // namespace guidance } // namespace guidance
} // namespace engine } // namespace engine
@@ -28,6 +28,7 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps);
// A check whether two instructions can be treated as one. This is only the case for very short // A check whether two instructions can be treated as one. This is only the case for very short
// maneuvers that can, in some form, be seen as one. Lookahead of one step. // maneuvers that can, in some form, be seen as one. Lookahead of one step.
// This is only a pre-check and does not necessarily allow collapsing turns!!!
bool collapsable(const RouteStep &step, const RouteStep &next); bool collapsable(const RouteStep &step, const RouteStep &next);
// trim initial/final segment of very short length. // trim initial/final segment of very short length.
+4 -1
View File
@@ -17,7 +17,8 @@ struct ExtractionTurn
ExtractionTurn(const guidance::ConnectedRoad &turn, bool has_traffic_light) ExtractionTurn(const guidance::ConnectedRoad &turn, bool has_traffic_light)
: angle(180. - turn.angle), turn_type(turn.instruction.type), : angle(180. - turn.angle), turn_type(turn.instruction.type),
direction_modifier(turn.instruction.direction_modifier), direction_modifier(turn.instruction.direction_modifier),
has_traffic_light(has_traffic_light), weight(0.), duration(0.) has_traffic_light(has_traffic_light), weight(0.), duration(0.), source_restricted(false),
target_restricted(false)
{ {
} }
@@ -27,6 +28,8 @@ struct ExtractionTurn
const bool has_traffic_light; const bool has_traffic_light;
double weight; double weight;
double duration; double duration;
bool source_restricted;
bool target_restricted;
}; };
} }
} }
+4
View File
@@ -58,6 +58,8 @@ struct ExtractionWay
turn_lanes_forward.clear(); turn_lanes_forward.clear();
turn_lanes_backward.clear(); turn_lanes_backward.clear();
road_classification = guidance::RoadClassification(); road_classification = guidance::RoadClassification();
backward_restricted = false;
forward_restricted = false;
} }
// These accessors exists because it's not possible to take the address of a bitfield, // These accessors exists because it's not possible to take the address of a bitfield,
@@ -106,6 +108,8 @@ struct ExtractionWay
bool roundabout; bool roundabout;
bool circular; bool circular;
bool is_startpoint; bool is_startpoint;
bool backward_restricted;
bool forward_restricted;
TravelMode forward_travel_mode : 4; TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4; TravelMode backward_travel_mode : 4;
guidance::RoadClassification road_classification; guidance::RoadClassification road_classification;
+10 -5
View File
@@ -70,8 +70,9 @@ struct InternalExtractorEdge
false, // roundabout false, // roundabout
false, // circular false, // circular
true, // can be startpoint true, // can be startpoint
false, // local access only
false, // split edge
TRAVEL_MODE_INACCESSIBLE, TRAVEL_MODE_INACCESSIBLE,
false,
guidance::TurnLaneType::empty, guidance::TurnLaneType::empty,
guidance::RoadClassification()), guidance::RoadClassification()),
weight_data(), duration_data() weight_data(), duration_data()
@@ -88,8 +89,9 @@ struct InternalExtractorEdge
bool roundabout, bool roundabout,
bool circular, bool circular,
bool startpoint, bool startpoint,
TravelMode travel_mode, bool restricted,
bool is_split, bool is_split,
TravelMode travel_mode,
LaneDescriptionID lane_description, LaneDescriptionID lane_description,
guidance::RoadClassification road_classification, guidance::RoadClassification road_classification,
util::Coordinate source_coordinate) util::Coordinate source_coordinate)
@@ -103,8 +105,9 @@ struct InternalExtractorEdge
roundabout, roundabout,
circular, circular,
startpoint, startpoint,
travel_mode, restricted,
is_split, is_split,
travel_mode,
lane_description, lane_description,
std::move(road_classification)), std::move(road_classification)),
weight_data(std::move(weight_data)), duration_data(std::move(duration_data)), weight_data(std::move(weight_data)), duration_data(std::move(duration_data)),
@@ -134,8 +137,9 @@ struct InternalExtractorEdge
false, // roundabout false, // roundabout
false, // circular false, // circular
true, // can be startpoint true, // can be startpoint
false, // local access only
false, // split edge
TRAVEL_MODE_INACCESSIBLE, TRAVEL_MODE_INACCESSIBLE,
false,
INVALID_LANE_DESCRIPTIONID, INVALID_LANE_DESCRIPTIONID,
guidance::RoadClassification(), guidance::RoadClassification(),
util::Coordinate()); util::Coordinate());
@@ -152,8 +156,9 @@ struct InternalExtractorEdge
false, // roundabout false, // roundabout
false, // circular false, // circular
true, // can be startpoint true, // can be startpoint
false, // local access only
false, // split edge
TRAVEL_MODE_INACCESSIBLE, TRAVEL_MODE_INACCESSIBLE,
false,
INVALID_LANE_DESCRIPTIONID, INVALID_LANE_DESCRIPTIONID,
guidance::RoadClassification(), guidance::RoadClassification(),
util::Coordinate()); util::Coordinate());
+27 -21
View File
@@ -25,27 +25,29 @@ struct NodeBasedEdge
bool roundabout, bool roundabout,
bool circular, bool circular,
bool startpoint, bool startpoint,
TravelMode travel_mode, bool restricted,
bool is_split, bool is_split,
TravelMode travel_mode,
const LaneDescriptionID lane_description_id, const LaneDescriptionID lane_description_id,
guidance::RoadClassification road_classification); guidance::RoadClassification road_classification);
bool operator<(const NodeBasedEdge &other) const; bool operator<(const NodeBasedEdge &other) const;
NodeID source; NodeID source; // 32 4
NodeID target; NodeID target; // 32 4
NodeID name_id; NodeID name_id; // 32 4
EdgeWeight weight; EdgeWeight weight; // 32 4
EdgeWeight duration; EdgeWeight duration; // 32 4
std::uint8_t forward : 1; std::uint8_t forward : 1; // 1
std::uint8_t backward : 1; std::uint8_t backward : 1; // 1
std::uint8_t roundabout : 1; std::uint8_t roundabout : 1; // 1
std::uint8_t circular : 1; std::uint8_t circular : 1; // 1
std::uint8_t startpoint : 1; std::uint8_t startpoint : 1; // 1
std::uint8_t is_split : 1; std::uint8_t restricted : 1; // 1
TravelMode travel_mode : 4; std::uint8_t is_split : 1; // 1
LaneDescriptionID lane_description_id; TravelMode travel_mode : 4; // 4
guidance::RoadClassification road_classification; LaneDescriptionID lane_description_id; // 16 2
guidance::RoadClassification road_classification; // 16 2
}; };
struct NodeBasedEdgeWithOSM : NodeBasedEdge struct NodeBasedEdgeWithOSM : NodeBasedEdge
@@ -60,8 +62,9 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
bool roundabout, bool roundabout,
bool circular, bool circular,
bool startpoint, bool startpoint,
TravelMode travel_mode, bool restricted,
bool is_split, bool is_split,
TravelMode travel_mode,
const LaneDescriptionID lane_description_id, const LaneDescriptionID lane_description_id,
guidance::RoadClassification road_classification); guidance::RoadClassification road_classification);
@@ -74,7 +77,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
inline NodeBasedEdge::NodeBasedEdge() inline NodeBasedEdge::NodeBasedEdge()
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), duration(0), : source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), duration(0),
forward(false), backward(false), roundabout(false), circular(false), startpoint(true), forward(false), backward(false), roundabout(false), circular(false), startpoint(true),
is_split(false), travel_mode(TRAVEL_MODE_INACCESSIBLE), restricted(false), is_split(false), travel_mode(TRAVEL_MODE_INACCESSIBLE),
lane_description_id(INVALID_LANE_DESCRIPTIONID) lane_description_id(INVALID_LANE_DESCRIPTIONID)
{ {
} }
@@ -89,13 +92,14 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
bool roundabout, bool roundabout,
bool circular, bool circular,
bool startpoint, bool startpoint,
TravelMode travel_mode, bool restricted,
bool is_split, bool is_split,
TravelMode travel_mode,
const LaneDescriptionID lane_description_id, const LaneDescriptionID lane_description_id,
guidance::RoadClassification road_classification) guidance::RoadClassification road_classification)
: source(source), target(target), name_id(name_id), weight(weight), duration(duration), : source(source), target(target), name_id(name_id), weight(weight), duration(duration),
forward(forward), backward(backward), roundabout(roundabout), circular(circular), forward(forward), backward(backward), roundabout(roundabout), circular(circular),
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode), startpoint(startpoint), restricted(restricted), is_split(is_split), travel_mode(travel_mode),
lane_description_id(lane_description_id), road_classification(std::move(road_classification)) lane_description_id(lane_description_id), road_classification(std::move(road_classification))
{ {
} }
@@ -127,8 +131,9 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
bool roundabout, bool roundabout,
bool circular, bool circular,
bool startpoint, bool startpoint,
TravelMode travel_mode, bool restricted,
bool is_split, bool is_split,
TravelMode travel_mode,
const LaneDescriptionID lane_description_id, const LaneDescriptionID lane_description_id,
guidance::RoadClassification road_classification) guidance::RoadClassification road_classification)
: NodeBasedEdge(SPECIAL_NODEID, : NodeBasedEdge(SPECIAL_NODEID,
@@ -141,8 +146,9 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
roundabout, roundabout,
circular, circular,
startpoint, startpoint,
travel_mode, restricted,
is_split, is_split,
travel_mode,
lane_description_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))
+6 -2
View File
@@ -33,11 +33,12 @@ struct NodeBasedEdgeData
bool roundabout, bool roundabout,
bool circular, bool circular,
bool startpoint, bool startpoint,
bool restricted,
extractor::TravelMode travel_mode, extractor::TravelMode travel_mode,
const LaneDescriptionID lane_description_id) const LaneDescriptionID lane_description_id)
: weight(weight), duration(duration), edge_id(edge_id), name_id(name_id), : weight(weight), duration(duration), edge_id(edge_id), name_id(name_id),
reversed(reversed), roundabout(roundabout), circular(circular), startpoint(startpoint), reversed(reversed), roundabout(roundabout), circular(circular), startpoint(startpoint),
travel_mode(travel_mode), lane_description_id(lane_description_id) restricted(restricted), travel_mode(travel_mode), lane_description_id(lane_description_id)
{ {
} }
@@ -49,6 +50,7 @@ struct NodeBasedEdgeData
bool roundabout : 1; bool roundabout : 1;
bool circular : 1; bool circular : 1;
bool startpoint : 1; bool startpoint : 1;
bool restricted : 1;
extractor::TravelMode travel_mode : 4; extractor::TravelMode travel_mode : 4;
LaneDescriptionID lane_description_id; LaneDescriptionID lane_description_id;
extractor::guidance::RoadClassification road_classification; extractor::guidance::RoadClassification road_classification;
@@ -58,7 +60,8 @@ struct NodeBasedEdgeData
return (reversed == other.reversed) && (roundabout == other.roundabout) && return (reversed == other.reversed) && (roundabout == other.roundabout) &&
(circular == other.circular) && (startpoint == other.startpoint) && (circular == other.circular) && (startpoint == other.startpoint) &&
(travel_mode == other.travel_mode) && (travel_mode == other.travel_mode) &&
(road_classification == other.road_classification); (road_classification == other.road_classification) &&
(restricted == other.restricted);
} }
bool CanCombineWith(const NodeBasedEdgeData &other) const bool CanCombineWith(const NodeBasedEdgeData &other) const
@@ -87,6 +90,7 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
output_edge.data.name_id = input_edge.name_id; output_edge.data.name_id = input_edge.name_id;
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.restricted = input_edge.restricted;
output_edge.data.road_classification = input_edge.road_classification; output_edge.data.road_classification = input_edge.road_classification;
output_edge.data.lane_description_id = input_edge.lane_description_id; output_edge.data.lane_description_id = input_edge.lane_description_id;
+10
View File
@@ -65,6 +65,10 @@ local profile = {
'delivery' 'delivery'
}, },
restricted_access_tag_list = Set { },
restricted_highway_whitelist = Set { },
access_tags_hierarchy = Sequence { access_tags_hierarchy = Sequence {
'bicycle', 'bicycle',
'vehicle', 'vehicle',
@@ -521,4 +525,10 @@ function turn_function(turn)
if turn.has_traffic_light then if turn.has_traffic_light then
turn.duration = turn.duration + profile.traffic_light_penalty turn.duration = turn.duration + profile.traffic_light_penalty
end end
if properties.weight_name == 'cyclability' then
-- penalize turns from non-local access only segments onto local access only tags
if not turn.source_restricted and turn.target_restricted then
turn.weight = turn.weight + 3000
end
end
end end
+38 -7
View File
@@ -34,6 +34,9 @@ local profile = {
speed_reduction = 0.8, speed_reduction = 0.8,
traffic_light_penalty = 2, traffic_light_penalty = 2,
u_turn_penalty = 20, u_turn_penalty = 20,
restricted_penalty = 3000,
-- Note^: abstract value but in seconds correlates approximately to 50 min
-- meaning that a route through a local access way is > 50 min faster than around
-- Note: this biases right-side driving. -- Note: this biases right-side driving.
-- Should be inverted for left-driving countries. -- Should be inverted for left-driving countries.
@@ -63,18 +66,25 @@ local profile = {
'vehicle', 'vehicle',
'permissive', 'permissive',
'designated', 'designated',
'destination', 'hov'
'hov' -- we might filter hov out later depending on the avoid settings or add penalties
}, },
access_tag_blacklist = Set { access_tag_blacklist = Set {
'no', 'no',
'private',
'agricultural', 'agricultural',
'forestry', 'forestry',
'emergency', 'emergency',
'psv', 'psv',
'delivery' 'customer',
'private',
'delivery',
'destination'
},
restricted_access_tag_list = Set {
'private',
'delivery',
'destination'
}, },
access_tags_hierarchy = Sequence { access_tags_hierarchy = Sequence {
@@ -96,7 +106,7 @@ local profile = {
avoid = Set { avoid = Set {
'area', 'area',
'toll', -- 'toll', -- uncomment this to avoid tolls
'reversible', 'reversible',
'impassable', 'impassable',
'hov_lanes', 'hov_lanes',
@@ -131,6 +141,21 @@ local profile = {
["drive-thru"] = 0.5 ["drive-thru"] = 0.5
}, },
restricted_highway_whitelist = Set {
'motorway',
'motorway_link',
'trunk',
'trunk_link',
'primary',
'primary_link',
'secondary',
'secondary_link',
'tertiary',
'tertiary_link',
'residential',
'living_street',
},
route_speeds = { route_speeds = {
ferry = 5, ferry = 5,
shuttle_train = 10 shuttle_train = 10
@@ -253,7 +278,7 @@ function node_function (node, result)
-- parse access and barrier tags -- parse access and barrier tags
local access = find_access_tag(node, profile.access_tags_hierarchy) local access = find_access_tag(node, profile.access_tags_hierarchy)
if access then if access then
if profile.access_tag_blacklist[access] then if profile.access_tag_blacklist[access] and not profile.restricted_access_tag_list[access] then
result.barrier = true result.barrier = true
end end
else else
@@ -331,7 +356,7 @@ function way_function(way, result)
-- handle service road restrictions -- handle service road restrictions
'handle_service', 'handle_service',
-- check high occupancy vehicle restrictions -- handle hov
'handle_hov', 'handle_hov',
-- compute speed taking into account way type, maxspeed tags, etc. -- compute speed taking into account way type, maxspeed tags, etc.
@@ -387,4 +412,10 @@ function turn_function (turn)
turn.weight = turn.duration turn.weight = turn.duration
end end
end end
if properties.weight_name == 'routability' then
-- penalize turns from non-local access only segments onto local access only tags
if not turn.source_restricted and turn.target_restricted then
turn.weight = turn.weight + profile.restricted_penalty
end
end
end end
+13 -2
View File
@@ -12,6 +12,7 @@ properties.max_speed_for_map_matching = 40/3.6 -- kmph -> m/s
properties.use_turn_restrictions = false properties.use_turn_restrictions = false
properties.continue_straight_at_waypoint = false properties.continue_straight_at_waypoint = false
properties.weight_name = 'duration' properties.weight_name = 'duration'
--properties.weight_name = 'routability'
local walking_speed = 5 local walking_speed = 5
@@ -44,12 +45,16 @@ local profile = {
access_tag_blacklist = Set { access_tag_blacklist = Set {
'no', 'no',
'private',
'agricultural', 'agricultural',
'forestry', 'forestry',
'delivery' 'private',
'delivery',
}, },
restricted_access_tag_list = Set { },
restricted_highway_whitelist = Set { },
access_tags_hierarchy = Sequence { access_tags_hierarchy = Sequence {
'foot', 'foot',
'access' 'access'
@@ -244,4 +249,10 @@ function turn_function (turn)
if turn.has_traffic_light then if turn.has_traffic_light then
turn.duration = profile.traffic_light_penalty turn.duration = profile.traffic_light_penalty
end end
if properties.weight_name == 'routability' then
-- penalize turns from non-local access only segments onto local access only tags
if not turn.source_restricted and turn.target_restricted then
turn.weight = turn.weight + 3000
end
end
end end
+36 -31
View File
@@ -177,34 +177,57 @@ function Handlers.handle_hov(way,result,data,profile)
return return
end end
-- in this case we will use penalties instead of filtering out local hov = way:get_value_by_key("hov")
if "designated" == hov then
result.forward_restricted = true
result.backward_restricted = true
end
data.hov_lanes_forward, data.hov_lanes_backward = Tags.get_forward_backward_by_key(way,data,'hov:lanes')
local all_hov_forward = Handlers.has_all_designated_hov_lanes(data.hov_lanes_forward)
local all_hov_backward = Handlers.has_all_designated_hov_lanes(data.hov_lanes_backward)
-- in this case we will use turn penalties instead of filtering out
if properties.weight_name == 'routability' then if properties.weight_name == 'routability' then
if (all_hov_forward) then
result.forward_restricted = true
end
if (all_hov_backward) then
result.backward_restricted = true
end
return return
end end
-- check if all lanes are hov only -- filter out ways where all lanes are hov only
data.hov_lanes_forward, data.hov_lanes_backward = Tags.get_forward_backward_by_key(way,data,'hov:lanes') if all_hov_forward then
local inaccessible_forward = Handlers.has_all_designated_hov_lanes(data.hov_lanes_forward)
local inaccessible_backward = Handlers.has_all_designated_hov_lanes(data.hov_lanes_backward)
if inaccessible_forward then
result.forward_mode = mode.inaccessible result.forward_mode = mode.inaccessible
end end
if inaccessible_backward then if all_hov_backward then
result.backward_mode = mode.inaccessible result.backward_mode = mode.inaccessible
end end
end end
-- check accessibility by traversing our acces tag hierarchy -- check accessibility by traversing our access tag hierarchy
function Handlers.handle_access(way,result,data,profile) function Handlers.handle_access(way,result,data,profile)
data.forward_access, data.backward_access = data.forward_access, data.backward_access =
Tags.get_forward_backward_by_set(way,data,profile.access_tags_hierarchy) Tags.get_forward_backward_by_set(way,data,profile.access_tags_hierarchy)
if profile.access_tag_blacklist[data.forward_access] then -- only allow a subset of roads that are marked as restricted
if profile.restricted_highway_whitelist[data.highway] then
if profile.restricted_access_tag_list[data.forward_access] then
result.forward_restricted = true
end
if profile.restricted_access_tag_list[data.backward_access] then
result.backward_restricted = true
end
end
if profile.access_tag_blacklist[data.forward_access] and not result.forward_restricted then
result.forward_mode = mode.inaccessible result.forward_mode = mode.inaccessible
end end
if profile.access_tag_blacklist[data.backward_access] then if profile.access_tag_blacklist[data.backward_access] and not result.backward_restricted then
result.backward_mode = mode.inaccessible result.backward_mode = mode.inaccessible
end end
@@ -273,24 +296,6 @@ end
function Handlers.handle_penalties(way,result,data,profile) function Handlers.handle_penalties(way,result,data,profile)
-- heavily penalize a way tagged with all HOV lanes -- heavily penalize a way tagged with all HOV lanes
-- in order to only route over them if there is no other option -- in order to only route over them if there is no other option
local forward_hov_penalty = 1.0
local backward_hov_penalty = 1.0
if profile.avoid.hov_lanes then
local hov = way:get_value_by_key("hov")
if "designated" == hov then
forward_hov_penalty = 0.1
backward_hov_penalty = 0.1
else
data.hov_lanes_forward, data.hov_lanes_backward = Tags.get_forward_backward_by_key(way,data,'hov:lanes')
if Handlers.has_all_designated_hov_lanes(data.hov_lanes_forward) then
forward_hov_penalty = 0.1
end
if Handlers.has_all_designated_hov_lanes(data.hov_lanes_backward) then
backward_hov_penalty = 0.1
end
end
end
local service_penalty = 1.0 local service_penalty = 1.0
local service = way:get_value_by_key("service") local service = way:get_value_by_key("service")
if service and profile.service_penalties[service] then if service and profile.service_penalties[service] then
@@ -330,8 +335,8 @@ function Handlers.handle_penalties(way,result,data,profile)
sideroad_penalty = profile.side_road_multiplier sideroad_penalty = profile.side_road_multiplier
end end
local forward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty, forward_hov_penalty) local forward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty)
local backward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty, backward_hov_penalty) local backward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty)
if properties.weight_name == 'routability' then if properties.weight_name == 'routability' then
if result.forward_speed > 0 then if result.forward_speed > 0 then
+29 -14
View File
@@ -74,6 +74,15 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
// We're walking backwards over all adjacent turns: // We're walking backwards over all adjacent turns:
// the current turn lanes constrain the lanes we have to take in the previous turn. // the current turn lanes constrain the lanes we have to take in the previous turn.
// state for the lamda
// the number of lanes we have to change depends on the number of lanes that are allowed for
// a turn (in general) and the set of lanes which would allow for us to do the turn without
// a problem. In a sequence of turns, we have to look at how much time we need to switch the
// sequence. Given the turns in between, we would expect a bit longer than on a straight
// segment for a lane switch, but the total time shouldn't be unlimited.
double time_to_constrained = 0.0;
util::for_each_pair(rev_first, rev_last, [&](RouteStep &current, RouteStep &previous) { util::for_each_pair(rev_first, rev_last, [&](RouteStep &current, RouteStep &previous) {
const auto current_inst = current.maneuver.instruction; const auto current_inst = current.maneuver.instruction;
const auto current_lanes = current.intersections.front().lanes; const auto current_lanes = current.intersections.front().lanes;
@@ -88,7 +97,18 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
const bool lanes_to_constrain = previous_lanes.lanes_in_turn > 1; const bool lanes_to_constrain = previous_lanes.lanes_in_turn > 1;
const bool lanes_fan_in = previous_lanes.lanes_in_turn > current_lanes.lanes_in_turn; const bool lanes_fan_in = previous_lanes.lanes_in_turn > current_lanes.lanes_in_turn;
if (!lanes_to_constrain || !lanes_fan_in) // only prevent use lanes due to making all turns. don't make turns during curvy
// segments
if (previous_inst.type == TurnType::UseLane)
time_to_constrained += previous.duration;
else
time_to_constrained = 0;
const auto lane_delta = previous_lanes.lanes_in_turn - current_lanes.lanes_in_turn;
const auto can_make_all_turns =
time_to_constrained > lane_delta * min_duration_needed_for_lane_change;
if (!lanes_to_constrain || !lanes_fan_in || can_make_all_turns)
return; return;
// We do not have a mapping from lanes to lanes. All we have is the lanes in the turn // We do not have a mapping from lanes to lanes. All we have is the lanes in the turn
@@ -99,9 +119,6 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
const LaneID current_num_lanes_right_of_turn = current.NumLanesToTheRight(); const LaneID current_num_lanes_right_of_turn = current.NumLanesToTheRight();
const LaneID current_num_lanes_left_of_turn = current.NumLanesToTheLeft(); const LaneID current_num_lanes_left_of_turn = current.NumLanesToTheLeft();
const LaneID num_shared_lanes = std::min(current_lanes.lanes_in_turn, //
previous_lanes.lanes_in_turn); //
// 0/ Tag keep straight with the next turn's direction if available // 0/ Tag keep straight with the next turn's direction if available
const auto previous_is_straight = const auto previous_is_straight =
!isLeftTurn(previous_inst) && !isRightTurn(previous_inst); !isLeftTurn(previous_inst) && !isRightTurn(previous_inst);
@@ -121,14 +138,14 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
LaneID new_first_lane_from_the_right = LaneID new_first_lane_from_the_right =
previous_lanes.first_lane_from_the_right // start from rightmost lane previous_lanes.first_lane_from_the_right // start from rightmost lane
+ previous_lanes.lanes_in_turn // one past leftmost lane + previous_lanes.lanes_in_turn // one past leftmost lane
- num_shared_lanes; // back number of new lanes - current_lanes.lanes_in_turn; // back number of new lanes
// The leftmost target lanes might not be involved in the turn. Figure out // The leftmost target lanes might not be involved in the turn. Figure out
// how many lanes are to the left and not in the turn. // how many lanes are to the left and not in the turn.
new_first_lane_from_the_right -= new_first_lane_from_the_right -=
std::min(current_num_lanes_left_of_turn, num_shared_lanes); std::min(current_num_lanes_left_of_turn, current_lanes.lanes_in_turn);
previous_lanes = {num_shared_lanes, new_first_lane_from_the_right}; previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
}; };
const auto anticipate_for_right_turn = [&] { const auto anticipate_for_right_turn = [&] {
@@ -139,9 +156,9 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
// The rightmost target lanes might not be involved in the turn. Figure out // The rightmost target lanes might not be involved in the turn. Figure out
// how many lanes are to the right and not in the turn. // how many lanes are to the right and not in the turn.
new_first_lane_from_the_right += new_first_lane_from_the_right +=
std::min(current_num_lanes_right_of_turn, num_shared_lanes); std::min(current_num_lanes_right_of_turn, current_lanes.lanes_in_turn);
previous_lanes = {num_shared_lanes, new_first_lane_from_the_right}; previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
}; };
// 2/ When to anticipate a left, right turn // 2/ When to anticipate a left, right turn
@@ -179,13 +196,11 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
anticipate_for_right_turn(); anticipate_for_right_turn();
} }
// We might have constrained the previous step in a way that makes it compatible if (previous_inst.type == TurnType::UseLane && current_inst.type == TurnType::UseLane &&
// with the current step. If we did so we collapse it here and mark the current previous.mode == current.mode && previous_lanes == current_lanes)
// step as invalid, scheduled for later removal.
if (collapsable(previous, current))
{ {
previous.ElongateBy(current); previous.ElongateBy(current);
current.maneuver.instruction = TurnInstruction::NO_TURN(); current.Invalidate();
} }
}); });
}; };
+66 -14
View File
@@ -79,9 +79,10 @@ struct TurnData final
TurnData(const util::Coordinate coordinate_, TurnData(const util::Coordinate coordinate_,
const std::size_t _in, const std::size_t _in,
const std::size_t _out, const std::size_t _out,
const std::size_t _weight) const std::size_t _weight,
const std::size_t _duration)
: coordinate(std::move(coordinate_)), in_angle_offset(_in), turn_angle_offset(_out), : coordinate(std::move(coordinate_)), in_angle_offset(_in), turn_angle_offset(_out),
weight_offset(_weight) weight_offset(_weight), duration_offset(_duration)
{ {
} }
@@ -89,6 +90,7 @@ struct TurnData final
const std::size_t in_angle_offset; const std::size_t in_angle_offset;
const std::size_t turn_angle_offset; const std::size_t turn_angle_offset;
const std::size_t weight_offset; const std::size_t weight_offset;
const std::size_t duration_offset;
}; };
using FixedPoint = Point<std::int32_t>; using FixedPoint = Point<std::int32_t>;
@@ -457,6 +459,7 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
// vw is the "exit" // vw is the "exit"
std::vector<contractor::QueryEdge::EdgeData> unpacked_shortcut; std::vector<contractor::QueryEdge::EdgeData> unpacked_shortcut;
std::vector<EdgeWeight> approach_weight_vector; std::vector<EdgeWeight> approach_weight_vector;
std::vector<EdgeWeight> approach_duration_vector;
// Make sure we traverse the startnodes in a consistent order // Make sure we traverse the startnodes in a consistent order
// to ensure identical PBF encoding on all platforms. // to ensure identical PBF encoding on all platforms.
@@ -539,16 +542,26 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
approach_weight_vector = facade->GetUncompressedForwardWeights( approach_weight_vector = facade->GetUncompressedForwardWeights(
edge_based_node_info[approachedge.edge_based_node_id] edge_based_node_info[approachedge.edge_based_node_id]
.packed_geometry_id); .packed_geometry_id);
approach_duration_vector = facade->GetUncompressedForwardDurations(
edge_based_node_info[approachedge.edge_based_node_id]
.packed_geometry_id);
} }
else else
{ {
approach_weight_vector = facade->GetUncompressedReverseWeights( approach_weight_vector = facade->GetUncompressedReverseWeights(
edge_based_node_info[approachedge.edge_based_node_id] edge_based_node_info[approachedge.edge_based_node_id]
.packed_geometry_id); .packed_geometry_id);
approach_duration_vector = facade->GetUncompressedReverseDurations(
edge_based_node_info[approachedge.edge_based_node_id]
.packed_geometry_id);
} }
const auto sum_node_weight = std::accumulate(approach_weight_vector.begin(), const auto sum_node_weight = std::accumulate(approach_weight_vector.begin(),
approach_weight_vector.end(), approach_weight_vector.end(),
EdgeWeight{0}); EdgeWeight{0});
const auto sum_node_duration =
std::accumulate(approach_duration_vector.begin(),
approach_duration_vector.end(),
EdgeWeight{0});
// The edge.weight is the whole edge weight, which includes the turn // The edge.weight is the whole edge weight, which includes the turn
// cost. // cost.
@@ -557,7 +570,8 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
// intersections include stop signs, traffic signals and other // intersections include stop signs, traffic signals and other
// penalties, but at this stage, we can't divide those out, so we just // penalties, but at this stage, we can't divide those out, so we just
// treat the whole lot as the "turn cost" that we'll stick on the map. // treat the whole lot as the "turn cost" that we'll stick on the map.
const auto turn_cost = data.weight - sum_node_weight; const auto turn_weight = data.weight - sum_node_weight;
const auto turn_duration = data.duration - sum_node_duration;
// Find the three nodes that make up the turn movement) // Find the three nodes that make up the turn movement)
const auto node_from = startnode; const auto node_from = startnode;
@@ -598,14 +612,19 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
// And, same for the actual turn cost value - it goes in the lookup // And, same for the actual turn cost value - it goes in the lookup
// table, // table,
// not directly on the feature itself. // not directly on the feature itself.
const auto turn_cost_index = use_point_float_value( const auto turn_weight_index = use_point_float_value(
turn_cost / 10.0); // Note conversion to float here turn_weight / 10.0); // Note conversion to float here
const auto turn_duration_index = use_point_float_value(
turn_duration / 10.0); // Note conversion to float here
// Save everything we need to later add all the points to the tile. // Save everything we need to later add all the points to the tile.
// We need the coordinate of the intersection, the angle in, the turn // We need the coordinate of the intersection, the angle in, the turn
// angle and the turn cost. // angle and the turn cost.
all_turn_data.emplace_back( all_turn_data.emplace_back(coord_via,
coord_via, angle_in_index, turn_angle_index, turn_cost_index); angle_in_index,
turn_angle_index,
turn_weight_index,
turn_duration_index);
} }
} }
} }
@@ -672,6 +691,8 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
for (const auto &edge_index : sorted_edge_indexes) for (const auto &edge_index : sorted_edge_indexes)
{ {
const auto &edge = edges[edge_index]; const auto &edge = edges[edge_index];
// Weight values
const auto forward_weight_vector = const auto forward_weight_vector =
facade->GetUncompressedForwardWeights(edge.packed_geometry_id); facade->GetUncompressedForwardWeights(edge.packed_geometry_id);
const auto reverse_weight_vector = const auto reverse_weight_vector =
@@ -679,8 +700,20 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
const auto forward_weight = forward_weight_vector[edge.fwd_segment_position]; const auto forward_weight = forward_weight_vector[edge.fwd_segment_position];
const auto reverse_weight = reverse_weight_vector[reverse_weight_vector.size() - const auto reverse_weight = reverse_weight_vector[reverse_weight_vector.size() -
edge.fwd_segment_position - 1]; edge.fwd_segment_position - 1];
use_line_value(reverse_weight);
use_line_value(forward_weight); use_line_value(forward_weight);
use_line_value(reverse_weight);
// Duration values
const auto forward_duration_vector =
facade->GetUncompressedForwardDurations(edge.packed_geometry_id);
const auto reverse_duration_vector =
facade->GetUncompressedReverseDurations(edge.packed_geometry_id);
const auto forward_duration = forward_duration_vector[edge.fwd_segment_position];
const auto reverse_duration =
reverse_duration_vector[reverse_duration_vector.size() -
edge.fwd_segment_position - 1];
use_line_value(forward_duration);
use_line_value(reverse_duration);
} }
// Begin the layer features block // Begin the layer features block
@@ -701,6 +734,10 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
facade->GetUncompressedForwardWeights(edge.packed_geometry_id); facade->GetUncompressedForwardWeights(edge.packed_geometry_id);
const auto reverse_weight_vector = const auto reverse_weight_vector =
facade->GetUncompressedReverseWeights(edge.packed_geometry_id); facade->GetUncompressedReverseWeights(edge.packed_geometry_id);
const auto forward_duration_vector =
facade->GetUncompressedForwardDurations(edge.packed_geometry_id);
const auto reverse_duration_vector =
facade->GetUncompressedReverseDurations(edge.packed_geometry_id);
const auto forward_datasource_vector = const auto forward_datasource_vector =
facade->GetUncompressedForwardDatasources(edge.packed_geometry_id); facade->GetUncompressedForwardDatasources(edge.packed_geometry_id);
const auto reverse_datasource_vector = const auto reverse_datasource_vector =
@@ -709,6 +746,11 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
const auto reverse_weight = const auto reverse_weight =
reverse_weight_vector[reverse_weight_vector.size() - reverse_weight_vector[reverse_weight_vector.size() -
edge.fwd_segment_position - 1]; edge.fwd_segment_position - 1];
const auto forward_duration =
forward_duration_vector[edge.fwd_segment_position];
const auto reverse_duration =
reverse_duration_vector[reverse_duration_vector.size() -
edge.fwd_segment_position - 1];
const auto forward_datasource = const auto forward_datasource =
forward_datasource_vector[edge.fwd_segment_position]; forward_datasource_vector[edge.fwd_segment_position];
const auto reverse_datasource = const auto reverse_datasource =
@@ -735,6 +777,7 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
&max_datasource_id, &max_datasource_id,
&used_line_ints](const FixedLine &tile_line, &used_line_ints](const FixedLine &tile_line,
const std::uint32_t speed_kmh, const std::uint32_t speed_kmh,
const std::size_t weight,
const std::size_t duration, const std::size_t duration,
const DatasourceID datasource, const DatasourceID datasource,
const std::size_t name_idx, const std::size_t name_idx,
@@ -770,10 +813,13 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
(edge.component.is_tiny ? 0 : 1)); // is_small feature (edge.component.is_tiny ? 0 : 1)); // is_small feature
field.add_element(2); // "datasource" tag key offset field.add_element(2); // "datasource" tag key offset
field.add_element(130 + datasource); // datasource value offset field.add_element(130 + datasource); // datasource value offset
field.add_element(3); // "duration" tag key offset field.add_element(3); // "weight" tag key offset
field.add_element(130 + max_datasource_id + 1 +
weight); // weight value offset
field.add_element(4); // "duration" tag key offset
field.add_element(130 + max_datasource_id + 1 + field.add_element(130 + max_datasource_id + 1 +
duration); // duration value offset duration); // duration value offset
field.add_element(4); // "name" tag key offset field.add_element(5); // "name" tag key offset
field.add_element(130 + max_datasource_id + 1 + used_line_ints.size() + field.add_element(130 + max_datasource_id + 1 + used_line_ints.size() +
name_idx); // name value offset name_idx); // name value offset
@@ -788,14 +834,14 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
}; };
// If this is a valid forward edge, go ahead and add it to the tile // If this is a valid forward edge, go ahead and add it to the tile
if (forward_weight != 0 && edge.forward_segment_id.enabled) if (forward_duration != 0 && edge.forward_segment_id.enabled)
{ {
std::int32_t start_x = 0; std::int32_t start_x = 0;
std::int32_t start_y = 0; std::int32_t start_y = 0;
// Calculate the speed for this line // Calculate the speed for this line
std::uint32_t speed_kmh = std::uint32_t speed_kmh =
static_cast<std::uint32_t>(round(length / forward_weight * 10 * 3.6)); static_cast<std::uint32_t>(round(length / forward_duration * 10 * 3.6));
auto tile_line = coordinatesToTileLine(a, b, tile_bbox); auto tile_line = coordinatesToTileLine(a, b, tile_bbox);
if (!tile_line.empty()) if (!tile_line.empty())
@@ -803,6 +849,7 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
encode_tile_line(tile_line, encode_tile_line(tile_line,
speed_kmh, speed_kmh,
line_int_offsets[forward_weight], line_int_offsets[forward_weight],
line_int_offsets[forward_duration],
forward_datasource, forward_datasource,
name_offset, name_offset,
start_x, start_x,
@@ -812,14 +859,14 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
// Repeat the above for the coordinates reversed and using the `reverse` // Repeat the above for the coordinates reversed and using the `reverse`
// properties // properties
if (reverse_weight != 0 && edge.reverse_segment_id.enabled) if (reverse_duration != 0 && edge.reverse_segment_id.enabled)
{ {
std::int32_t start_x = 0; std::int32_t start_x = 0;
std::int32_t start_y = 0; std::int32_t start_y = 0;
// Calculate the speed for this line // Calculate the speed for this line
std::uint32_t speed_kmh = std::uint32_t speed_kmh =
static_cast<std::uint32_t>(round(length / reverse_weight * 10 * 3.6)); static_cast<std::uint32_t>(round(length / reverse_duration * 10 * 3.6));
auto tile_line = coordinatesToTileLine(b, a, tile_bbox); auto tile_line = coordinatesToTileLine(b, a, tile_bbox);
if (!tile_line.empty()) if (!tile_line.empty())
@@ -827,6 +874,7 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
encode_tile_line(tile_line, encode_tile_line(tile_line,
speed_kmh, speed_kmh,
line_int_offsets[reverse_weight], line_int_offsets[reverse_weight],
line_int_offsets[reverse_duration],
reverse_datasource, reverse_datasource,
name_offset, name_offset,
start_x, start_x,
@@ -842,6 +890,7 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
line_layer_writer.add_string(util::vector_tile::KEY_TAG, "speed"); line_layer_writer.add_string(util::vector_tile::KEY_TAG, "speed");
line_layer_writer.add_string(util::vector_tile::KEY_TAG, "is_small"); line_layer_writer.add_string(util::vector_tile::KEY_TAG, "is_small");
line_layer_writer.add_string(util::vector_tile::KEY_TAG, "datasource"); line_layer_writer.add_string(util::vector_tile::KEY_TAG, "datasource");
line_layer_writer.add_string(util::vector_tile::KEY_TAG, "weight");
line_layer_writer.add_string(util::vector_tile::KEY_TAG, "duration"); line_layer_writer.add_string(util::vector_tile::KEY_TAG, "duration");
line_layer_writer.add_string(util::vector_tile::KEY_TAG, "name"); line_layer_writer.add_string(util::vector_tile::KEY_TAG, "name");
@@ -938,6 +987,8 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
field.add_element(1); // "turn_angle" tag key offset field.add_element(1); // "turn_angle" tag key offset
field.add_element(point_turn_data.turn_angle_offset); field.add_element(point_turn_data.turn_angle_offset);
field.add_element(2); // "cost" tag key offset field.add_element(2); // "cost" tag key offset
field.add_element(used_point_ints.size() + point_turn_data.duration_offset);
field.add_element(3); // "cost" tag key offset
field.add_element(used_point_ints.size() + point_turn_data.weight_offset); field.add_element(used_point_ints.size() + point_turn_data.weight_offset);
} }
{ {
@@ -965,6 +1016,7 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
point_layer_writer.add_string(util::vector_tile::KEY_TAG, "bearing_in"); point_layer_writer.add_string(util::vector_tile::KEY_TAG, "bearing_in");
point_layer_writer.add_string(util::vector_tile::KEY_TAG, "turn_angle"); point_layer_writer.add_string(util::vector_tile::KEY_TAG, "turn_angle");
point_layer_writer.add_string(util::vector_tile::KEY_TAG, "cost"); point_layer_writer.add_string(util::vector_tile::KEY_TAG, "cost");
point_layer_writer.add_string(util::vector_tile::KEY_TAG, "weight");
// Now, save the lists of integers and floats that our features refer to. // Now, save the lists of integers and floats that our features refer to.
for (const auto &value : used_point_ints) for (const auto &value : used_point_ints)
@@ -526,6 +526,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
// compute weight and duration penalties // compute weight and duration penalties
auto is_traffic_light = m_traffic_lights.count(node_at_center_of_intersection); auto is_traffic_light = m_traffic_lights.count(node_at_center_of_intersection);
ExtractionTurn extracted_turn(turn, is_traffic_light); ExtractionTurn extracted_turn(turn, is_traffic_light);
extracted_turn.source_restricted = edge_data1.restricted;
extracted_turn.target_restricted = edge_data2.restricted;
scripting_environment.ProcessTurn(extracted_turn); scripting_environment.ProcessTurn(extracted_turn);
// turn penalties are limited to [-2^15, 2^15) which roughly // turn penalties are limited to [-2^15, 2^15) which roughly
+7 -2
View File
@@ -121,6 +121,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
const auto toValueByEdgeOrByMeter = [&nodes](const double by_way, const double by_meter) { const auto toValueByEdgeOrByMeter = [&nodes](const double by_way, const double by_meter) {
using Value = detail::ByEdgeOrByMeterValue; using Value = detail::ByEdgeOrByMeterValue;
// get value by weight per edge
if (by_way >= 0) if (by_way >= 0)
{ {
// FIXME We divide by the number of edges here, but should rather consider // FIXME We divide by the number of edges here, but should rather consider
@@ -132,6 +133,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
} }
else else
{ {
// get value by deriving weight from speed per edge
return Value(Value::by_meter, by_meter); return Value(Value::by_meter, by_meter);
} }
}; };
@@ -320,6 +322,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
parsed_way.weight > 0) && parsed_way.weight > 0) &&
(parsed_way.backward_travel_mode != TRAVEL_MODE_INACCESSIBLE); (parsed_way.backward_travel_mode != TRAVEL_MODE_INACCESSIBLE);
// split an edge into two edges if forwards/backwards behavior differ
const bool split_edge = in_forward_direction && in_backward_direction && const bool split_edge = in_forward_direction && in_backward_direction &&
((parsed_way.forward_rate != parsed_way.backward_rate) || ((parsed_way.forward_rate != parsed_way.backward_rate) ||
(parsed_way.forward_speed != parsed_way.backward_speed) || (parsed_way.forward_speed != parsed_way.backward_speed) ||
@@ -343,8 +346,9 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
parsed_way.roundabout, parsed_way.roundabout,
parsed_way.circular, parsed_way.circular,
parsed_way.is_startpoint, parsed_way.is_startpoint,
parsed_way.forward_travel_mode, parsed_way.forward_restricted,
split_edge, split_edge,
parsed_way.forward_travel_mode,
turn_lane_id_forward, turn_lane_id_forward,
road_classification, road_classification,
{})); {}));
@@ -368,8 +372,9 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
parsed_way.roundabout, parsed_way.roundabout,
parsed_way.circular, parsed_way.circular,
parsed_way.is_startpoint, parsed_way.is_startpoint,
parsed_way.backward_travel_mode, parsed_way.backward_restricted,
split_edge, split_edge,
parsed_way.backward_travel_mode,
turn_lane_id_backward, turn_lane_id_backward,
road_classification, road_classification,
{})); {}));
+10 -2
View File
@@ -343,7 +343,11 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"forward_mode", "forward_mode",
sol::property(&ExtractionWay::get_forward_mode, &ExtractionWay::set_forward_mode), sol::property(&ExtractionWay::get_forward_mode, &ExtractionWay::set_forward_mode),
"backward_mode", "backward_mode",
sol::property(&ExtractionWay::get_backward_mode, &ExtractionWay::set_backward_mode)); sol::property(&ExtractionWay::get_backward_mode, &ExtractionWay::set_backward_mode),
"forward_restricted",
&ExtractionWay::forward_restricted,
"backward_restricted",
&ExtractionWay::backward_restricted);
context.state.new_usertype<ExtractionSegment>("ExtractionSegment", context.state.new_usertype<ExtractionSegment>("ExtractionSegment",
"source", "source",
@@ -369,7 +373,11 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"weight", "weight",
&ExtractionTurn::weight, &ExtractionTurn::weight,
"duration", "duration",
&ExtractionTurn::duration); &ExtractionTurn::duration,
"source_restricted",
&ExtractionTurn::source_restricted,
"target_restricted",
&ExtractionTurn::target_restricted);
// Keep in mind .location is undefined since we're not using libosmium's location cache // Keep in mind .location is undefined since we're not using libosmium's location cache
context.state.new_usertype<osmium::NodeRef>("NodeRef", "id", &osmium::NodeRef::ref); context.state.new_usertype<osmium::NodeRef>("NodeRef", "id", &osmium::NodeRef::ref);
+235 -100
View File
@@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script. // This file was generated with a script.
// Generated 2016-12-16 05:28:22.940422 UTC // Generated 2017-02-19 09:59:38.638408 UTC
// This header was generated with sol v2.15.5 (revision bbcbd41) // This header was generated with sol v2.15.8 (revision 0c8ec82)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP #ifndef SOL_SINGLE_INCLUDE_HPP
@@ -47,6 +47,9 @@
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow" #pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wconversion"
#elif defined _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4324 ) // structure was padded due to alignment specifier
#endif // g++ #endif // g++
// beginning of sol/state.hpp // beginning of sol/state.hpp
@@ -790,7 +793,13 @@ namespace sol {
// beginning of sol/compatibility/version.hpp // beginning of sol/compatibility/version.hpp
#ifdef SOL_USING_CXX_LUA
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#else
#include <lua.hpp> #include <lua.hpp>
#endif // C++-compiler Lua
#if defined(_WIN32) || defined(_MSC_VER) #if defined(_WIN32) || defined(_MSC_VER)
#ifndef SOL_CODECVT_SUPPORT #ifndef SOL_CODECVT_SUPPORT
@@ -1022,7 +1031,7 @@ inline const char* kepler_lua_compat_get_string(lua_State* L, void* ud, size_t*
return ls->s; return ls->s;
} }
#if !defined(SOL_LUAJIT) || ((SOL_LUAJIT_VERSION - 20100) <= 0) #if !defined(SOL_LUAJIT) || (SOL_LUAJIT_VERSION < 20100)
inline int luaL_loadbufferx(lua_State* L, const char* buff, size_t size, const char* name, const char*) { inline int luaL_loadbufferx(lua_State* L, const char* buff, size_t size, const char* name, const char*) {
kepler_lua_compat_get_string_view ls; kepler_lua_compat_get_string_view ls;
@@ -1035,7 +1044,8 @@ inline int luaL_loadbufferx(lua_State* L, const char* buff, size_t size, const c
#endif /* Lua 5.1 */ #endif /* Lua 5.1 */
#endif // SOL_5_1_0_H// end of sol/compatibility/5.1.0.h #endif // SOL_5_1_0_H
// end of sol/compatibility/5.1.0.h
// beginning of sol/compatibility/5.0.0.h // beginning of sol/compatibility/5.0.0.h
@@ -2089,8 +2099,8 @@ namespace sol {
}; };
template <class T> template <class T>
struct optional_base { struct alignas(T) optional_base {
char storage_[sizeof(T) + (sizeof(T) % alignof(T))]; char storage_[sizeof(T)];
bool init_; bool init_;
constexpr optional_base() noexcept : storage_(), init_(false) {}; constexpr optional_base() noexcept : storage_(), init_(false) {};
@@ -2137,8 +2147,8 @@ namespace sol {
using constexpr_optional_base = optional_base<T>; using constexpr_optional_base = optional_base<T>;
#else #else
template <class T> template <class T>
struct constexpr_optional_base { struct alignas(T) constexpr_optional_base {
char storage_[sizeof(T) + (sizeof(T) % alignof(T))]; char storage_[sizeof(T)];
bool init_; bool init_;
constexpr constexpr_optional_base() noexcept : storage_(), init_(false) {} constexpr constexpr_optional_base() noexcept : storage_(), init_(false) {}
@@ -3315,7 +3325,7 @@ namespace sol {
memory = LUA_ERRMEM, memory = LUA_ERRMEM,
gc = LUA_ERRGCMM, gc = LUA_ERRGCMM,
handler = LUA_ERRERR, handler = LUA_ERRERR,
dead, dead = -1,
}; };
enum class load_status : int { enum class load_status : int {
@@ -3374,6 +3384,8 @@ namespace sol {
bitwise_and, bitwise_and,
bitwise_or, bitwise_or,
bitwise_xor, bitwise_xor,
pairs,
next
}; };
typedef meta_function meta_method; typedef meta_function meta_method;
@@ -3383,7 +3395,7 @@ namespace sol {
"__newindex", "__newindex",
} }; } };
const std::array<std::string, 21> meta_function_names = { { const std::array<std::string, 29> meta_function_names = { {
"new", "new",
"__index", "__index",
"__newindex", "__newindex",
@@ -3404,6 +3416,17 @@ namespace sol {
"__lt", "__lt",
"__le", "__le",
"__gc", "__gc",
"__idiv",
"__shl",
"__shr",
"__bnot",
"__band",
"__bor",
"__bxor",
"__pairs",
"__next"
} }; } };
inline const std::string& name_of(meta_function mf) { inline const std::string& name_of(meta_function mf) {
@@ -3473,6 +3496,10 @@ namespace sol {
using protected_function = basic_protected_function<reference>; using protected_function = basic_protected_function<reference>;
using stack_function = basic_function<stack_reference>; using stack_function = basic_function<stack_reference>;
using stack_protected_function = basic_protected_function<stack_reference>; using stack_protected_function = basic_protected_function<stack_reference>;
using unsafe_function = basic_function<reference>;
using safe_function = basic_protected_function<reference>;
using stack_unsafe_function = basic_function<stack_reference>;
using stack_safe_function = basic_protected_function<stack_reference>;
template <typename base_t> template <typename base_t>
class basic_object; class basic_object;
template <typename base_t> template <typename base_t>
@@ -3716,11 +3743,15 @@ namespace sol {
template <> template <>
struct is_transparent_argument<variadic_args> : std::true_type {}; struct is_transparent_argument<variadic_args> : std::true_type {};
template <typename T>
struct is_variadic_arguments : std::is_same<T, variadic_args> {};
template <typename Signature> template <typename Signature>
struct lua_bind_traits : meta::bind_traits<Signature> { struct lua_bind_traits : meta::bind_traits<Signature> {
private: private:
typedef meta::bind_traits<Signature> base_t; typedef meta::bind_traits<Signature> base_t;
public: public:
typedef std::integral_constant<bool, meta::count_for<is_transparent_argument, typename base_t::args_list>::value != 0> runtime_variadics_t;
static const std::size_t true_arity = base_t::arity; static const std::size_t true_arity = base_t::arity;
static const std::size_t arity = base_t::arity - meta::count_for<is_transparent_argument, typename base_t::args_list>::value; static const std::size_t arity = base_t::arity - meta::count_for<is_transparent_argument, typename base_t::args_list>::value;
static const std::size_t true_free_arity = base_t::free_arity; static const std::size_t true_free_arity = base_t::free_arity;
@@ -3790,7 +3821,10 @@ namespace sol {
} }
int push(lua_State* Ls) const noexcept { int push(lua_State* Ls) const noexcept {
lua_pushvalue(Ls, index); lua_pushvalue(lua_state(), index);
if (Ls != lua_state()) {
lua_xmove(lua_state(), Ls, 1);
}
return 1; return 1;
} }
@@ -3923,6 +3957,9 @@ namespace sol {
} }
reference& operator=(reference&& o) noexcept { reference& operator=(reference&& o) noexcept {
if (valid()) {
deref();
}
luastate = o.luastate; luastate = o.luastate;
ref = o.ref; ref = o.ref;
@@ -4114,7 +4151,7 @@ namespace sol {
void set_extra(std::true_type, std::index_sequence<I...>, T&& target) { void set_extra(std::true_type, std::index_sequence<I...>, T&& target) {
using std::get; using std::get;
(void)detail::swallow{ 0, (void)detail::swallow{ 0,
(get<I>(*this) = get<I>(types<Tn...>(), target), 0)... (get<I>(static_cast<base_t&>(*this)) = get<I>(types<Tn...>(), target), 0)...
, 0 }; , 0 };
} }
@@ -4122,7 +4159,7 @@ namespace sol {
void set_extra(std::false_type, std::index_sequence<I...>, T&& target) { void set_extra(std::false_type, std::index_sequence<I...>, T&& target) {
using std::get; using std::get;
(void)detail::swallow{ 0, (void)detail::swallow{ 0,
(get<I>(*this) = get<I>(target), 0)... (get<I>(static_cast<base_t&>(*this)) = get<I>(target), 0)...
, 0 }; , 0 };
} }
@@ -4580,7 +4617,39 @@ namespace sol {
namespace sol { namespace sol {
namespace detail { namespace detail {
#ifdef _MSC_VER #if defined(__GNUC__) || defined(__clang__)
template <typename T, class seperator_mark = int>
inline std::string ctti_get_type_name() {
const static std::array<std::string, 2> removals = { { "{anonymous}", "(anonymous namespace)" } };
std::string name = __PRETTY_FUNCTION__;
std::size_t start = name.find_first_of('[');
start = name.find_first_of('=', start);
std::size_t end = name.find_last_of(']');
if (end == std::string::npos)
end = name.size();
if (start == std::string::npos)
start = 0;
if (start < name.size() - 1)
start += 1;
name = name.substr(start, end - start);
start = name.rfind("seperator_mark");
if (start != std::string::npos) {
name.erase(start - 2, name.length());
}
while (!name.empty() && std::isblank(name.front())) name.erase(name.begin());
while (!name.empty() && std::isblank(name.back())) name.pop_back();
for (std::size_t r = 0; r < removals.size(); ++r) {
auto found = name.find(removals[r]);
while (found != std::string::npos) {
name.erase(found, removals[r].size());
found = name.find(removals[r]);
}
}
return name;
}
#elif defined(_MSC_VER)
template <typename T> template <typename T>
inline std::string ctti_get_type_name() { inline std::string ctti_get_type_name() {
const static std::array<std::string, 7> removals = { { "public:", "private:", "protected:", "struct ", "class ", "`anonymous-namespace'", "`anonymous namespace'" } }; const static std::array<std::string, 7> removals = { { "public:", "private:", "protected:", "struct ", "class ", "`anonymous-namespace'", "`anonymous namespace'" } };
@@ -4611,38 +4680,6 @@ namespace sol {
} }
} }
return name;
}
#elif defined(__GNUC__) || defined(__clang__)
template <typename T, class seperator_mark = int>
inline std::string ctti_get_type_name() {
const static std::array<std::string, 2> removals = { { "{anonymous}", "(anonymous namespace)" } };
std::string name = __PRETTY_FUNCTION__;
std::size_t start = name.find_first_of('[');
start = name.find_first_of('=', start);
std::size_t end = name.find_last_of(']');
if (end == std::string::npos)
end = name.size();
if (start == std::string::npos)
start = 0;
if (start < name.size() - 1)
start += 1;
name = name.substr(start, end - start);
start = name.rfind("seperator_mark");
if (start != std::string::npos) {
name.erase(start - 2, name.length());
}
while (!name.empty() && std::isblank(name.front())) name.erase(name.begin());
while (!name.empty() && std::isblank(name.back())) name.pop_back();
for (std::size_t r = 0; r < removals.size(); ++r) {
auto found = name.find(removals[r]);
while (found != std::string::npos) {
name.erase(found, removals[r].size());
found = name.find(removals[r]);
}
}
return name; return name;
} }
#else #else
@@ -5458,7 +5495,7 @@ namespace sol {
if (len < 1) if (len < 1)
return std::wstring(); return std::wstring();
if (sizeof(wchar_t) == 2) { if (sizeof(wchar_t) == 2) {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert; static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
std::wstring r = convert.from_bytes(str, str + len); std::wstring r = convert.from_bytes(str, str + len);
#ifdef __MINGW32__ #ifdef __MINGW32__
// Fuck you, MinGW, and fuck you libstdc++ for introducing this absolutely asinine bug // Fuck you, MinGW, and fuck you libstdc++ for introducing this absolutely asinine bug
@@ -5471,7 +5508,7 @@ namespace sol {
#endif #endif
return r; return r;
} }
std::wstring_convert<std::codecvt_utf8<wchar_t>> convert; static std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
std::wstring r = convert.from_bytes(str, str + len); std::wstring r = convert.from_bytes(str, str + len);
return r; return r;
} }
@@ -5486,12 +5523,12 @@ namespace sol {
if (len < 1) if (len < 1)
return std::u16string(); return std::u16string();
#ifdef _MSC_VER #ifdef _MSC_VER
std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> convert; static std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> convert;
auto intd = convert.from_bytes(str, str + len); auto intd = convert.from_bytes(str, str + len);
std::u16string r(intd.size(), '\0'); std::u16string r(intd.size(), '\0');
std::memcpy(&r[0], intd.data(), intd.size() * sizeof(char16_t)); std::memcpy(&r[0], intd.data(), intd.size() * sizeof(char16_t));
#else #else
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; static std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
std::u16string r = convert.from_bytes(str, str + len); std::u16string r = convert.from_bytes(str, str + len);
#endif // VC++ is a shit #endif // VC++ is a shit
return r; return r;
@@ -5507,12 +5544,12 @@ namespace sol {
if (len < 1) if (len < 1)
return std::u32string(); return std::u32string();
#ifdef _MSC_VER #ifdef _MSC_VER
std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> convert; static std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> convert;
auto intd = convert.from_bytes(str, str + len); auto intd = convert.from_bytes(str, str + len);
std::u32string r(intd.size(), '\0'); std::u32string r(intd.size(), '\0');
std::memcpy(&r[0], intd.data(), r.size() * sizeof(char32_t)); std::memcpy(&r[0], intd.data(), r.size() * sizeof(char32_t));
#else #else
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert; static std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
std::u32string r = convert.from_bytes(str, str + len); std::u32string r = convert.from_bytes(str, str + len);
#endif // VC++ is a shit #endif // VC++ is a shit
return r; return r;
@@ -6394,11 +6431,11 @@ namespace sol {
static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) { static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) {
if (sizeof(wchar_t) == 2) { if (sizeof(wchar_t) == 2) {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert; static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
std::string u8str = convert.to_bytes(strb, stre); std::string u8str = convert.to_bytes(strb, stre);
return stack::push(L, u8str); return stack::push(L, u8str);
} }
std::wstring_convert<std::codecvt_utf8<wchar_t>> convert; static std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
std::string u8str = convert.to_bytes(strb, stre); std::string u8str = convert.to_bytes(strb, stre);
return stack::push(L, u8str); return stack::push(L, u8str);
} }
@@ -6416,10 +6453,10 @@ namespace sol {
static int push(lua_State* L, const char16_t* strb, const char16_t* stre) { static int push(lua_State* L, const char16_t* strb, const char16_t* stre) {
#ifdef _MSC_VER #ifdef _MSC_VER
std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> convert; static std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> convert;
std::string u8str = convert.to_bytes(reinterpret_cast<const int16_t*>(strb), reinterpret_cast<const int16_t*>(stre)); std::string u8str = convert.to_bytes(reinterpret_cast<const int16_t*>(strb), reinterpret_cast<const int16_t*>(stre));
#else #else
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; static std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
std::string u8str = convert.to_bytes(strb, stre); std::string u8str = convert.to_bytes(strb, stre);
#endif // VC++ is a shit #endif // VC++ is a shit
return stack::push(L, u8str); return stack::push(L, u8str);
@@ -6438,10 +6475,10 @@ namespace sol {
static int push(lua_State* L, const char32_t* strb, const char32_t* stre) { static int push(lua_State* L, const char32_t* strb, const char32_t* stre) {
#ifdef _MSC_VER #ifdef _MSC_VER
std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> convert; static std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> convert;
std::string u8str = convert.to_bytes(reinterpret_cast<const int32_t*>(strb), reinterpret_cast<const int32_t*>(stre)); std::string u8str = convert.to_bytes(reinterpret_cast<const int32_t*>(strb), reinterpret_cast<const int32_t*>(stre));
#else #else
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert; static std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
std::string u8str = convert.to_bytes(strb, stre); std::string u8str = convert.to_bytes(strb, stre);
#endif // VC++ is a shit #endif // VC++ is a shit
return stack::push(L, u8str); return stack::push(L, u8str);
@@ -7632,7 +7669,7 @@ namespace sol {
if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) { if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) {
return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...); return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
} }
if (traits::free_arity != fxarity) { if (!traits::runtime_variadics_t::value && traits::free_arity != fxarity) {
return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...); return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
} }
stack::record tracking{}; stack::record tracking{};
@@ -7656,7 +7693,7 @@ namespace sol {
if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) { if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) {
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...); return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
} }
if (traits::free_arity != fxarity) { if (!traits::runtime_variadics_t::value && traits::free_arity != fxarity) {
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...); return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
} }
return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...); return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
@@ -7671,7 +7708,7 @@ namespace sol {
if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) { if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) {
return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...); return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
} }
if (traits::free_arity != fxarity) { if (!traits::runtime_variadics_t::value && traits::free_arity != fxarity) {
return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...); return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
} }
stack::record tracking{}; stack::record tracking{};
@@ -8057,7 +8094,7 @@ namespace sol {
}; };
static int call(lua_State* L, F& fx) { static int call(lua_State* L, F& fx) {
return overload_match_arity<Fs...>(on_match(), L, lua_gettop(L), 1, fx); return overload_match_arity<Fs...>(on_match(), L, lua_gettop(L) - boost, 1 + boost, fx);
} }
}; };
@@ -8498,7 +8535,7 @@ namespace sol {
namespace sol { namespace sol {
namespace function_detail { namespace function_detail {
template <typename... Functions> template <int start_skew = 0, typename... Functions>
struct overloaded_function { struct overloaded_function {
typedef std::tuple<Functions...> overload_list; typedef std::tuple<Functions...> overload_list;
typedef std::make_index_sequence<sizeof...(Functions)> indices; typedef std::make_index_sequence<sizeof...(Functions)> indices;
@@ -8515,12 +8552,12 @@ namespace sol {
template <typename Fx, std::size_t I, typename... R, typename... Args> template <typename Fx, std::size_t I, typename... R, typename... Args>
int call(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int) { int call(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int) {
auto& func = std::get<I>(overloads); auto& func = std::get<I>(overloads);
return call_detail::call_wrapped<void, true, false>(L, func); return call_detail::call_wrapped<void, true, false, start_skew>(L, func);
} }
int operator()(lua_State* L) { int operator()(lua_State* L) {
auto mfx = [&](auto&&... args) { return this->call(std::forward<decltype(args)>(args)...); }; auto mfx = [&](auto&&... args) { return this->call(std::forward<decltype(args)>(args)...); };
return call_detail::overload_match<Functions...>(mfx, L, 1); return call_detail::overload_match<Functions...>(mfx, L, 1 + start_skew);
} }
}; };
} // function_detail } // function_detail
@@ -8531,9 +8568,10 @@ namespace sol {
// beginning of sol/resolve.hpp // beginning of sol/resolve.hpp
namespace sol { namespace sol {
// Clang has distinct problems with constexpr arguments,
// so don't use the constexpr versions inside of clang.
#ifndef __clang__ #ifndef __clang__
// constexpr is fine for not-clang
namespace detail { namespace detail {
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>> template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
inline constexpr auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) { inline constexpr auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
@@ -8600,6 +8638,10 @@ namespace sol {
return detail::resolve_i(types<Sig...>(), std::forward<F>(f)); return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
} }
#else #else
// Clang has distinct problems with constexpr arguments,
// so don't use the constexpr versions inside of clang.
namespace detail { namespace detail {
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>> template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
inline auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) { inline auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
@@ -8665,12 +8707,20 @@ namespace sol {
inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) { inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
return detail::resolve_i(types<Sig...>(), std::forward<F>(f)); return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
} }
#endif #endif
} // sol } // sol
// end of sol/resolve.hpp // end of sol/resolve.hpp
namespace sol { namespace sol {
namespace function_detail {
template<typename T>
struct class_indicator {};
struct call_indicator {};
}
namespace stack { namespace stack {
template<typename... Sigs> template<typename... Sigs>
struct pusher<function_sig<Sigs...>> { struct pusher<function_sig<Sigs...>> {
@@ -8726,12 +8776,19 @@ namespace sol {
select_convertible(types<Sigs...>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...); select_convertible(types<Sigs...>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
} }
template <typename Fx, typename T, typename... Args> template <typename Fx, typename T, typename... Args, meta::disable<meta::is_specialization_of<function_detail::class_indicator, meta::unqualified_t<T>>> = meta::enabler>
static void select_member_variable(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) { static void select_member_variable(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
typedef meta::boolean<meta::is_specialization_of<std::reference_wrapper, meta::unqualified_t<T>>::value || std::is_pointer<T>::value> is_reference; typedef meta::boolean<meta::is_specialization_of<std::reference_wrapper, meta::unqualified_t<T>>::value || std::is_pointer<T>::value> is_reference;
select_reference_member_variable(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...); select_reference_member_variable(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
} }
template <typename Fx, typename C>
static void select_member_variable(std::true_type, lua_State* L, Fx&& fx, function_detail::class_indicator<C>) {
lua_CFunction freefunc = &function_detail::upvalue_this_member_variable<C, Fx>::call;
int upvalues = stack::stack_detail::push_as_upvalues(L, fx);
stack::push(L, c_closure(freefunc, upvalues));
}
template <typename Fx> template <typename Fx>
static void select_member_variable(std::true_type, lua_State* L, Fx&& fx) { static void select_member_variable(std::true_type, lua_State* L, Fx&& fx) {
typedef typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type C; typedef typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type C;
@@ -8764,12 +8821,19 @@ namespace sol {
select_member_variable(std::is_member_object_pointer<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...); select_member_variable(std::is_member_object_pointer<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
} }
template <typename Fx, typename T, typename... Args> template <typename Fx, typename T, typename... Args, meta::disable<meta::is_specialization_of<function_detail::class_indicator, meta::unqualified_t<T>>> = meta::enabler>
static void select_member_function(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) { static void select_member_function(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
typedef meta::boolean<meta::is_specialization_of<std::reference_wrapper, meta::unqualified_t<T>>::value || std::is_pointer<T>::value> is_reference; typedef meta::boolean<meta::is_specialization_of<std::reference_wrapper, meta::unqualified_t<T>>::value || std::is_pointer<T>::value> is_reference;
select_reference_member_function(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...); select_reference_member_function(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
} }
template <typename Fx, typename C>
static void select_member_function(std::true_type, lua_State* L, Fx&& fx, function_detail::class_indicator<C>) {
lua_CFunction freefunc = &function_detail::upvalue_this_member_function<C, Fx>::call;
int upvalues = stack::stack_detail::push_as_upvalues(L, fx);
stack::push(L, c_closure(freefunc, upvalues));
}
template <typename Fx> template <typename Fx>
static void select_member_function(std::true_type, lua_State* L, Fx&& fx) { static void select_member_function(std::true_type, lua_State* L, Fx&& fx) {
typedef typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type C; typedef typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type C;
@@ -8842,9 +8906,9 @@ namespace sol {
template<typename Signature> template<typename Signature>
struct pusher<Signature, std::enable_if_t<std::is_member_pointer<Signature>::value>> { struct pusher<Signature, std::enable_if_t<std::is_member_pointer<Signature>::value>> {
template <typename F> template <typename F, typename... Args>
static int push(lua_State* L, F&& f) { static int push(lua_State* L, F&& f, Args&&... args) {
return pusher<function_sig<>>{}.push(L, std::forward<F>(f)); return pusher<function_sig<>>{}.push(L, std::forward<F>(f), std::forward<Args>(args)...);
} }
}; };
@@ -8859,13 +8923,13 @@ namespace sol {
template<typename... Functions> template<typename... Functions>
struct pusher<overload_set<Functions...>> { struct pusher<overload_set<Functions...>> {
static int push(lua_State* L, overload_set<Functions...>&& set) { static int push(lua_State* L, overload_set<Functions...>&& set) {
typedef function_detail::overloaded_function<Functions...> F; typedef function_detail::overloaded_function<0, Functions...> F;
pusher<function_sig<>>{}.set_fx<F>(L, std::move(set.functions)); pusher<function_sig<>>{}.set_fx<F>(L, std::move(set.functions));
return 1; return 1;
} }
static int push(lua_State* L, const overload_set<Functions...>& set) { static int push(lua_State* L, const overload_set<Functions...>& set) {
typedef function_detail::overloaded_function<Functions...> F; typedef function_detail::overloaded_function<0, Functions...> F;
pusher<function_sig<>>{}.set_fx<F>(L, set.functions); pusher<function_sig<>>{}.set_fx<F>(L, set.functions);
return 1; return 1;
} }
@@ -8929,16 +8993,28 @@ namespace sol {
template <typename... Functions> template <typename... Functions>
struct pusher<factory_wrapper<Functions...>> { struct pusher<factory_wrapper<Functions...>> {
static int push(lua_State* L, const factory_wrapper<Functions...>& fw) { static int push(lua_State* L, const factory_wrapper<Functions...>& fw) {
typedef function_detail::overloaded_function<Functions...> F; typedef function_detail::overloaded_function<0, Functions...> F;
pusher<function_sig<>>{}.set_fx<F>(L, fw.functions); pusher<function_sig<>>{}.set_fx<F>(L, fw.functions);
return 1; return 1;
} }
static int push(lua_State* L, factory_wrapper<Functions...>&& fw) { static int push(lua_State* L, factory_wrapper<Functions...>&& fw) {
typedef function_detail::overloaded_function<Functions...> F; typedef function_detail::overloaded_function<0, Functions...> F;
pusher<function_sig<>>{}.set_fx<F>(L, std::move(fw.functions)); pusher<function_sig<>>{}.set_fx<F>(L, std::move(fw.functions));
return 1; return 1;
} }
static int push(lua_State* L, const factory_wrapper<Functions...>& set, function_detail::call_indicator) {
typedef function_detail::overloaded_function<1, Functions...> F;
pusher<function_sig<>>{}.set_fx<F>(L, set.functions);
return 1;
}
static int push(lua_State* L, factory_wrapper<Functions...>&& set, function_detail::call_indicator) {
typedef function_detail::overloaded_function<1, Functions...> F;
pusher<function_sig<>>{}.set_fx<F>(L, std::move(set.functions));
return 1;
}
}; };
template <typename T, typename... Lists> template <typename T, typename... Lists>
@@ -9653,11 +9729,18 @@ namespace sol {
const_reverse_iterator crend() const { return std::reverse_iterator<const_iterator>(cend()); } const_reverse_iterator crend() const { return std::reverse_iterator<const_iterator>(cend()); }
int push() const { int push() const {
return push(L);
}
int push(lua_State* target) const {
int pushcount = 0; int pushcount = 0;
for (int i = index; i <= stacktop; ++i) { for (int i = index; i <= stacktop; ++i) {
lua_pushvalue(L, i); lua_pushvalue(L, i);
pushcount += 1; pushcount += 1;
} }
if (target != L) {
lua_xmove(L, target, pushcount);
}
return pushcount; return pushcount;
} }
@@ -9687,8 +9770,8 @@ namespace sol {
template <> template <>
struct pusher<variadic_args> { struct pusher<variadic_args> {
static int push(lua_State*, const variadic_args& ref) { static int push(lua_State* L, const variadic_args& ref) {
return ref.push(); return ref.push(L);
} }
}; };
} // stack } // stack
@@ -9906,7 +9989,7 @@ namespace sol {
} }
bool valid() const { bool valid() const {
stack::push_pop(tbl); auto pp = stack::push_pop(tbl);
auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(tbl.lua_state(), key, lua_gettop(tbl.lua_state())); auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(tbl.lua_state(), key, lua_gettop(tbl.lua_state()));
lua_pop(tbl.lua_state(), p.levels); lua_pop(tbl.lua_state(), p.levels);
return p; return p;
@@ -10073,9 +10156,9 @@ namespace sol {
auto maybeaccessor = stack::get<optional<string_detail::string_shim>>(L, is_index ? -1 : -2); auto maybeaccessor = stack::get<optional<string_detail::string_shim>>(L, is_index ? -1 : -2);
string_detail::string_shim accessor = maybeaccessor.value_or(string_detail::string_shim("(unknown)")); string_detail::string_shim accessor = maybeaccessor.value_or(string_detail::string_shim("(unknown)"));
if (is_index) if (is_index)
return luaL_error(L, "sol: attempt to index (get) lua_nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str()); return luaL_error(L, "sol: attempt to index (get) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str());
else else
return luaL_error(L, "sol: attempt to index (set) lua_nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str()); return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str());
} }
template <bool is_index, typename Base> template <bool is_index, typename Base>
@@ -10153,20 +10236,23 @@ namespace sol {
struct verified_tag {} const verified{}; struct verified_tag {} const verified{};
template <typename T> template <typename T>
struct is_constructor : std::false_type {}; struct is_non_factory_constructor : std::false_type {};
template <typename... Args>
struct is_non_factory_constructor<constructors<Args...>> : std::true_type {};
template <typename... Args> template <typename... Args>
struct is_constructor<constructors<Args...>> : std::true_type {}; struct is_non_factory_constructor<constructor_wrapper<Args...>> : std::true_type {};
template <typename... Args> template <>
struct is_constructor<constructor_wrapper<Args...>> : std::true_type {}; struct is_non_factory_constructor<no_construction> : std::true_type {};
template <typename T>
struct is_constructor : is_non_factory_constructor<T> {};
template <typename... Args> template <typename... Args>
struct is_constructor<factory_wrapper<Args...>> : std::true_type {}; struct is_constructor<factory_wrapper<Args...>> : std::true_type {};
template <>
struct is_constructor<no_construction> : std::true_type {};
template <typename... Args> template <typename... Args>
using has_constructor = meta::any<is_constructor<meta::unqualified_t<Args>>...>; using has_constructor = meta::any<is_constructor<meta::unqualified_t<Args>>...>;
@@ -10391,8 +10477,14 @@ namespace sol {
template <std::size_t Idx, bool is_index = true, bool is_variable = false> template <std::size_t Idx, bool is_index = true, bool is_variable = false>
static int real_call_with(lua_State* L, usertype_metatable& um) { static int real_call_with(lua_State* L, usertype_metatable& um) {
typedef meta::unqualified_tuple_element_t<Idx - 1, Tuple> K;
typedef meta::unqualified_tuple_element_t<Idx, Tuple> F;
static const int boost =
!usertype_detail::is_non_factory_constructor<F>::value
&& std::is_same<K, call_construction>::value ?
1 : 0;
auto& f = std::get<Idx>(um.functions); auto& f = std::get<Idx>(um.functions);
return call_detail::call_wrapped<T, is_index, is_variable>(L, f); return call_detail::call_wrapped<T, is_index, is_variable, boost>(L, f);
} }
template <std::size_t Idx, bool is_index = true, bool is_variable = false> template <std::size_t Idx, bool is_index = true, bool is_variable = false>
@@ -10637,10 +10729,13 @@ namespace sol {
lua_settop(L, 0); lua_settop(L, 0);
return 0; return 0;
} }
lua_pop(L, 1);
return indexing_fail<false>(L); return indexing_fail<false>(L);
} }
inline int simple_indexing_fail(lua_State* L) {
return stack::push(L, sol::lua_nil);
}
template <bool is_index, bool toplevel = false> template <bool is_index, bool toplevel = false>
inline int simple_core_indexing_call(lua_State* L) { inline int simple_core_indexing_call(lua_State* L) {
simple_map& sm = toplevel ? stack::get<user<simple_map>>(L, upvalue_index(1)) : stack::pop<user<simple_map>>(L); simple_map& sm = toplevel ? stack::get<user<simple_map>>(L, upvalue_index(1)) : stack::pop<user<simple_map>>(L);
@@ -10747,14 +10842,31 @@ namespace sol {
hint->second = std::move(o); hint->second = std::move(o);
} }
template <typename N, typename F, meta::enable<meta::is_callable<meta::unwrap_unqualified_t<F>>> = meta::enabler> template <typename N, typename F, typename... Args>
void add_function(lua_State* L, N&& n, F&& f) { void insert_prepare(std::true_type, lua_State* L, N&&, F&& f, Args&&... args) {
insert(std::forward<N>(n), make_object(L, as_function_reference(std::forward<F>(f)))); object o = make_object<F>(L, std::forward<F>(f), function_detail::call_indicator(), std::forward<Args>(args)...);
callconstructfunc = std::move(o);
} }
template <typename N, typename F, meta::disable<meta::is_callable<meta::unwrap_unqualified_t<F>>> = meta::enabler> template <typename N, typename F, typename... Args>
void insert_prepare(std::false_type, lua_State* L, N&& n, F&& f, Args&&... args) {
object o = make_object<F>(L, std::forward<F>(f), std::forward<Args>(args)...);
insert(std::forward<N>(n), std::move(o));
}
template <typename N, typename F>
void add_member_function(std::true_type, lua_State* L, N&& n, F&& f) {
insert_prepare(std::is_same<meta::unqualified_t<N>, call_construction>(), L, std::forward<N>(n), std::forward<F>(f), function_detail::class_indicator<T>());
}
template <typename N, typename F>
void add_member_function(std::false_type, lua_State* L, N&& n, F&& f) {
insert_prepare(std::is_same<meta::unqualified_t<N>, call_construction>(), L, std::forward<N>(n), std::forward<F>(f));
}
template <typename N, typename F, meta::enable<meta::is_callable<meta::unwrap_unqualified_t<F>>> = meta::enabler>
void add_function(lua_State* L, N&& n, F&& f) { void add_function(lua_State* L, N&& n, F&& f) {
object o = make_object(L, std::forward<F>(f)); object o = make_object(L, as_function_reference(std::forward<F>(f)));
if (std::is_same<meta::unqualified_t<N>, call_construction>::value) { if (std::is_same<meta::unqualified_t<N>, call_construction>::value) {
callconstructfunc = std::move(o); callconstructfunc = std::move(o);
return; return;
@@ -10762,6 +10874,11 @@ namespace sol {
insert(std::forward<N>(n), std::move(o)); insert(std::forward<N>(n), std::move(o));
} }
template <typename N, typename F, meta::disable<meta::is_callable<meta::unwrap_unqualified_t<F>>> = meta::enabler>
void add_function(lua_State* L, N&& n, F&& f) {
add_member_function(std::is_member_pointer<meta::unwrap_unqualified_t<F>>(), L, std::forward<N>(n), std::forward<F>(f));
}
template <typename N, typename F, meta::disable<is_variable_binding<meta::unqualified_t<F>>> = meta::enabler> template <typename N, typename F, meta::disable<is_variable_binding<meta::unqualified_t<F>>> = meta::enabler>
void add(lua_State* L, N&& n, F&& f) { void add(lua_State* L, N&& n, F&& f) {
add_function(L, std::forward<N>(n), std::forward<F>(f)); add_function(L, std::forward<N>(n), std::forward<F>(f));
@@ -10842,7 +10959,7 @@ namespace sol {
template<std::size_t... I, typename Tuple> template<std::size_t... I, typename Tuple>
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args) simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
: callconstructfunc(lua_nil), : callconstructfunc(lua_nil),
indexfunc(&usertype_detail::indexing_fail<true>), newindexfunc(&usertype_detail::indexing_fail<false>), indexfunc(&usertype_detail::simple_indexing_fail), newindexfunc(&usertype_detail::simple_metatable_newindex<T>),
indexbase(&usertype_detail::simple_core_indexing_call<true>), newindexbase(&usertype_detail::simple_core_indexing_call<false>), indexbase(&usertype_detail::simple_core_indexing_call<true>), newindexbase(&usertype_detail::simple_core_indexing_call<false>),
indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>), indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
baseclasscheck(nullptr), baseclasscast(nullptr), baseclasscheck(nullptr), baseclasscast(nullptr),
@@ -11072,15 +11189,15 @@ namespace sol {
stack::set_field(L, meta_function::index, stack::set_field(L, meta_function::index,
make_closure(&usertype_detail::simple_index_call, make_closure(&usertype_detail::simple_index_call,
make_light(varmap), make_light(varmap),
&usertype_detail::simple_index_call, umx.indexfunc,
&usertype_detail::simple_metatable_newindex<T>, umx.newindexfunc,
usertype_detail::toplevel_magic usertype_detail::toplevel_magic
), metabehind.stack_index()); ), metabehind.stack_index());
stack::set_field(L, meta_function::new_index, stack::set_field(L, meta_function::new_index,
make_closure(&usertype_detail::simple_new_index_call, make_closure(&usertype_detail::simple_new_index_call,
make_light(varmap), make_light(varmap),
&usertype_detail::simple_index_call, umx.indexfunc,
&usertype_detail::simple_metatable_newindex<T>, umx.newindexfunc,
usertype_detail::toplevel_magic usertype_detail::toplevel_magic
), metabehind.stack_index()); ), metabehind.stack_index());
stack::set_field(L, metatable_key, metabehind, t.stack_index()); stack::set_field(L, metatable_key, metabehind, t.stack_index());
@@ -12829,7 +12946,23 @@ namespace sol {
stack::luajit_exception_handler(unique_base::get()); stack::luajit_exception_handler(unique_base::get());
} }
state(const state&) = delete;
state(state&&) = default;
state& operator=(const state&) = delete;
state& operator=(state&& that) {
state_view::operator=(std::move(that));
unique_base::operator=(std::move(that));
return *this;
}
using state_view::get; using state_view::get;
~state() {
auto& handler = protected_function::get_default_handler();
if (handler.lua_state() == this->lua_state()) {
protected_function::set_default_handler(reference());
}
}
}; };
} // sol } // sol
@@ -13079,6 +13212,8 @@ namespace sol {
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#elif defined _MSC_VER
#pragma warning( push )
#endif // g++ #endif // g++
#ifdef SOL_INSIDE_UNREAL #ifdef SOL_INSIDE_UNREAL
+3 -1
View File
@@ -22,7 +22,8 @@ namespace
// creates a default edge of unit weight // creates a default edge of unit weight
inline InputEdge MakeUnitEdge(const NodeID from, const NodeID to) inline InputEdge MakeUnitEdge(const NodeID from, const NodeID to)
{ {
// src, tgt, dist, edge_id, name_id, fwd, bkwd, roundabout, circular, travel_mode // src, tgt, dist, edge_id, name_id, fwd, bkwd, roundabout, circular, startpoint, local access,
// split edge, travel_mode
return {from, return {from,
to, to,
1, 1,
@@ -32,6 +33,7 @@ inline InputEdge MakeUnitEdge(const NodeID from, const NodeID to)
false, false,
false, false,
false, false,
false,
true, true,
TRAVEL_MODE_INACCESSIBLE, TRAVEL_MODE_INACCESSIBLE,
INVALID_LANE_DESCRIPTIONID}; INVALID_LANE_DESCRIPTIONID};
+33 -12
View File
@@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(test_tile)
const auto rc = osrm.Tile(params, result); const auto rc = osrm.Tile(params, result);
BOOST_CHECK(rc == Status::Ok); BOOST_CHECK(rc == Status::Ok);
BOOST_CHECK_EQUAL(result.size(), 113824); BOOST_CHECK(result.size() > 114000);
protozero::pbf_reader tile_message(result); protozero::pbf_reader tile_message(result);
tile_message.next(); tile_message.next();
@@ -54,7 +54,7 @@ BOOST_AUTO_TEST_CASE(test_tile)
auto property_iter_pair = feature_message.get_packed_uint32(); auto property_iter_pair = feature_message.get_packed_uint32();
auto value_begin = property_iter_pair.begin(); auto value_begin = property_iter_pair.begin();
auto value_end = property_iter_pair.end(); auto value_end = property_iter_pair.end();
BOOST_CHECK_EQUAL(std::distance(value_begin, value_end), 10); BOOST_CHECK_EQUAL(std::distance(value_begin, value_end), 12);
auto iter = value_begin; auto iter = value_begin;
BOOST_CHECK_EQUAL(*iter++, 0); // speed key BOOST_CHECK_EQUAL(*iter++, 0); // speed key
BOOST_CHECK_LT(*iter++, 128); // speed value BOOST_CHECK_LT(*iter++, 128); // speed value
@@ -65,10 +65,12 @@ BOOST_AUTO_TEST_CASE(test_tile)
iter++; iter++;
BOOST_CHECK_EQUAL(*iter++, 2); // data source key BOOST_CHECK_EQUAL(*iter++, 2); // data source key
*iter++; // skip value check, can be valud uint32 *iter++; // skip value check, can be valud uint32
BOOST_CHECK_EQUAL(*iter++, 3); // duration key BOOST_CHECK_EQUAL(*iter++, 3); // weight key
BOOST_CHECK_GT(*iter++, 130); // weight value
BOOST_CHECK_EQUAL(*iter++, 4); // duration key
BOOST_CHECK_GT(*iter++, 130); // duration value BOOST_CHECK_GT(*iter++, 130); // duration value
// name // name
BOOST_CHECK_EQUAL(*iter++, 4); BOOST_CHECK_EQUAL(*iter++, 5);
BOOST_CHECK_GT(*iter++, 130); BOOST_CHECK_GT(*iter++, 130);
BOOST_CHECK(iter == value_end); BOOST_CHECK(iter == value_end);
// geometry // geometry
@@ -137,7 +139,7 @@ BOOST_AUTO_TEST_CASE(test_tile)
} }
} }
BOOST_CHECK_EQUAL(number_of_speed_keys, 5); BOOST_CHECK_EQUAL(number_of_speed_keys, 6);
BOOST_CHECK_GT(number_of_speed_values, 128); // speed value resolution BOOST_CHECK_GT(number_of_speed_values, 128); // speed value resolution
tile_message.next(); tile_message.next();
@@ -156,7 +158,7 @@ BOOST_AUTO_TEST_CASE(test_tile)
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::FEATURE_ATTRIBUTES_TAG); BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::FEATURE_ATTRIBUTES_TAG);
// properties // properties
auto feature_iter_pair = feature_message.get_packed_uint32(); auto feature_iter_pair = feature_message.get_packed_uint32();
BOOST_CHECK_EQUAL(std::distance(feature_iter_pair.begin(), feature_iter_pair.end()), 6); BOOST_CHECK_EQUAL(std::distance(feature_iter_pair.begin(), feature_iter_pair.end()), 8);
auto iter = feature_iter_pair.begin(); auto iter = feature_iter_pair.begin();
BOOST_CHECK_EQUAL(*iter++, 0); // bearing_in key BOOST_CHECK_EQUAL(*iter++, 0); // bearing_in key
*iter++; *iter++;
@@ -164,6 +166,8 @@ BOOST_AUTO_TEST_CASE(test_tile)
*iter++; *iter++;
BOOST_CHECK_EQUAL(*iter++, 2); // cost key BOOST_CHECK_EQUAL(*iter++, 2); // cost key
*iter++; // skip value check, can be valud uint32 *iter++; // skip value check, can be valud uint32
BOOST_CHECK_EQUAL(*iter++, 3); // weight key
*iter++; // skip value check, can be valud uint32
BOOST_CHECK(iter == feature_iter_pair.end()); BOOST_CHECK(iter == feature_iter_pair.end());
// geometry // geometry
feature_message.next(); feature_message.next();
@@ -204,8 +208,8 @@ BOOST_AUTO_TEST_CASE(test_tile)
} }
} }
BOOST_CHECK_EQUAL(number_of_turn_keys, 3); BOOST_CHECK_EQUAL(number_of_turn_keys, 4);
BOOST_CHECK_EQUAL(number_of_turns_found, 732); BOOST_CHECK(number_of_turns_found > 700);
} }
BOOST_AUTO_TEST_CASE(test_tile_turns) BOOST_AUTO_TEST_CASE(test_tile_turns)
@@ -236,6 +240,7 @@ BOOST_AUTO_TEST_CASE(test_tile_turns)
std::vector<int> found_bearing_in_indexes; std::vector<int> found_bearing_in_indexes;
std::vector<int> found_turn_angles_indexes; std::vector<int> found_turn_angles_indexes;
std::vector<int> found_penalties_indexes; std::vector<int> found_penalties_indexes;
std::vector<int> found_weight_indexes;
const auto check_turn_feature = [&](protozero::pbf_reader feature_message) { const auto check_turn_feature = [&](protozero::pbf_reader feature_message) {
feature_message.next(); // advance parser to first entry feature_message.next(); // advance parser to first entry
@@ -250,7 +255,7 @@ BOOST_AUTO_TEST_CASE(test_tile_turns)
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::FEATURE_ATTRIBUTES_TAG); BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::FEATURE_ATTRIBUTES_TAG);
// properties // properties
auto feature_iter_pair = feature_message.get_packed_uint32(); auto feature_iter_pair = feature_message.get_packed_uint32();
BOOST_CHECK_EQUAL(std::distance(feature_iter_pair.begin(), feature_iter_pair.end()), 6); BOOST_CHECK_EQUAL(std::distance(feature_iter_pair.begin(), feature_iter_pair.end()), 8);
auto iter = feature_iter_pair.begin(); auto iter = feature_iter_pair.begin();
BOOST_CHECK_EQUAL(*iter++, 0); // bearing_in key BOOST_CHECK_EQUAL(*iter++, 0); // bearing_in key
found_bearing_in_indexes.push_back(*iter++); found_bearing_in_indexes.push_back(*iter++);
@@ -258,6 +263,8 @@ BOOST_AUTO_TEST_CASE(test_tile_turns)
found_turn_angles_indexes.push_back(*iter++); found_turn_angles_indexes.push_back(*iter++);
BOOST_CHECK_EQUAL(*iter++, 2); // cost key BOOST_CHECK_EQUAL(*iter++, 2); // cost key
found_penalties_indexes.push_back(*iter++); // skip value check, can be valud uint32 found_penalties_indexes.push_back(*iter++); // skip value check, can be valud uint32
BOOST_CHECK_EQUAL(*iter++, 3); // weight key
found_weight_indexes.push_back(*iter++); // skip value check, can be valud uint32
BOOST_CHECK(iter == feature_iter_pair.end()); BOOST_CHECK(iter == feature_iter_pair.end());
// geometry // geometry
feature_message.next(); feature_message.next();
@@ -333,6 +340,18 @@ BOOST_AUTO_TEST_CASE(test_tile_turns)
0, 0, 0, 0, 0, 0, .1f, .1f, .3f, .4f, 1.2f, 1.9f, 5.3f, 5.5f, 5.8f, 7.1f, 7.2f, 7.2f}; 0, 0, 0, 0, 0, 0, .1f, .1f, .3f, .4f, 1.2f, 1.9f, 5.3f, 5.5f, 5.8f, 7.1f, 7.2f, 7.2f};
BOOST_CHECK(actual_turn_penalties == expected_turn_penalties); BOOST_CHECK(actual_turn_penalties == expected_turn_penalties);
// Verify that we got the expected turn penalties
std::vector<float> actual_turn_weights;
for (const auto &i : found_weight_indexes)
{
BOOST_CHECK(float_vals.count(i) == 1);
actual_turn_weights.push_back(float_vals[i]);
}
std::sort(actual_turn_weights.begin(), actual_turn_weights.end());
const std::vector<float> expected_turn_weights = {
0, 0, 0, 0, 0, 0, .1f, .1f, .3f, .4f, 1.2f, 1.9f, 5.3f, 5.5f, 5.8f, 7.1f, 7.2f, 7.2f};
BOOST_CHECK(actual_turn_weights == expected_turn_weights);
// Verify the expected turn angles // Verify the expected turn angles
std::vector<std::int64_t> actual_turn_angles; std::vector<std::int64_t> actual_turn_angles;
for (const auto &i : found_turn_angles_indexes) for (const auto &i : found_turn_angles_indexes)
@@ -401,7 +420,7 @@ BOOST_AUTO_TEST_CASE(test_tile_speeds)
auto property_iter_pair = feature_message.get_packed_uint32(); auto property_iter_pair = feature_message.get_packed_uint32();
auto value_begin = property_iter_pair.begin(); auto value_begin = property_iter_pair.begin();
auto value_end = property_iter_pair.end(); auto value_end = property_iter_pair.end();
BOOST_CHECK_EQUAL(std::distance(value_begin, value_end), 10); BOOST_CHECK_EQUAL(std::distance(value_begin, value_end), 12);
auto iter = value_begin; auto iter = value_begin;
BOOST_CHECK_EQUAL(*iter++, 0); // speed key BOOST_CHECK_EQUAL(*iter++, 0); // speed key
found_speed_indexes.push_back(*iter++); found_speed_indexes.push_back(*iter++);
@@ -410,10 +429,12 @@ BOOST_AUTO_TEST_CASE(test_tile_speeds)
found_component_indexes.push_back(*iter++); found_component_indexes.push_back(*iter++);
BOOST_CHECK_EQUAL(*iter++, 2); // data source key BOOST_CHECK_EQUAL(*iter++, 2); // data source key
found_datasource_indexes.push_back(*iter++); found_datasource_indexes.push_back(*iter++);
BOOST_CHECK_EQUAL(*iter++, 3); // duration key BOOST_CHECK_EQUAL(*iter++, 3); // weight key
found_duration_indexes.push_back(*iter++);
BOOST_CHECK_EQUAL(*iter++, 4); // duration key
found_duration_indexes.push_back(*iter++); found_duration_indexes.push_back(*iter++);
// name // name
BOOST_CHECK_EQUAL(*iter++, 4); BOOST_CHECK_EQUAL(*iter++, 5);
found_name_indexes.push_back(*iter++); found_name_indexes.push_back(*iter++);
BOOST_CHECK(iter == value_end); BOOST_CHECK(iter == value_end);
// geometry // geometry