Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a02a83f8bd | ||
|
9b18f55d29 | ||
|
a3434e7ae9 | ||
|
64b15028e4 | ||
|
d8e466fdaa | ||
|
43bbe8f2ae | ||
|
b5c10b1fbf | ||
|
57d93fc5dc | ||
|
3aba2bc2d0 | ||
|
c42478f0ee | ||
|
ea583a77ff | ||
|
dd999e112e | ||
|
69c54bef72 | ||
|
cfee0f1109 | ||
|
c7ce758e1c | ||
|
3ac4fb5933 | ||
|
2afe5e971b | ||
|
519b744502 | ||
|
d3c2ac671f | ||
|
07a1a907f8 | ||
|
062cae82a0 | ||
|
316c7781a3 | ||
|
e11bcfece5 | ||
|
cb8dee3e60 | ||
|
a1abe71d9f | ||
|
d54c837e51 | ||
|
106d17541d | ||
|
ad29b237e3 | ||
|
febefb4684 |
@ -13,6 +13,7 @@ notifications:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- "5.6"
|
||||
|
||||
cache:
|
||||
ccache: true
|
||||
|
@ -1,3 +1,8 @@
|
||||
# 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
|
||||
- Changes from 5.5
|
||||
- Bugfixes
|
||||
|
@ -32,7 +32,7 @@ if(ENABLE_MASON)
|
||||
set(MASON_EXPAT_VERSION "2.2.0")
|
||||
set(MASON_LUA_VERSION "5.2.4")
|
||||
set(MASON_BZIP2_VERSION "1.0.6")
|
||||
set(MASON_TBB_VERSION "43_20150316")
|
||||
set(MASON_TBB_VERSION "2017_20161128")
|
||||
|
||||
message(STATUS "Enabling mason")
|
||||
|
||||
|
18
docs/http.md
18
docs/http.md
@ -172,7 +172,7 @@ In addition to the [general options](#general-options) the following options are
|
||||
|------------|---------------------------------------------|-------------------------------------------------------------------------------|
|
||||
|alternatives|`true`, `false` (default) |Search for alternative routes and return as well.\* |
|
||||
|steps |`true`, `false` (default) |Return route steps for each route leg |
|
||||
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|
||||
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|
||||
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
||||
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
||||
|continue\_straight |`default` (default), `true`, `false` |Forces the route to keep going straight at waypoints constraining uturns there even if it would be faster. Default value depends on the profile. |
|
||||
@ -275,7 +275,7 @@ In addition to the [general options](#general-options) the following options are
|
||||
|------------|------------------------------------------------|------------------------------------------------------------------------------------------|
|
||||
|steps |`true`, `false` (default) |Return route steps for each route |
|
||||
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
||||
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|
||||
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|
||||
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
||||
|timestamps |`{timestamp};{timestamp}[;{timestamp} ...]` |Timestamps for the input locations in seconds since UNIX epoch. Timestamps need to be monotonically increasing. |
|
||||
|radiuses |`{radius};{radius}[;{radius} ...]` |Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy.|
|
||||
@ -327,7 +327,7 @@ In addition to the [general options](#general-options) the following options are
|
||||
|source |`any` (default), `first` |Return route starts at `any` or `first` coordinate |
|
||||
|destination |`any` (default), `last` |Return route ends at `any` or `last` coordinate |
|
||||
|steps |`true`, `false` (default) |Return route instructions for each trip |
|
||||
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|
||||
|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. |
|
||||
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
||||
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
||||
|
||||
@ -518,7 +518,8 @@ With `steps=false` and `annotations=true`:
|
||||
"distance": [5,5,10,5,5],
|
||||
"duration": [15,15,40,15,15],
|
||||
"datasources": [1,0,0,0,1],
|
||||
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802]
|
||||
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802],
|
||||
"speed": [0.3, 0.3, 0.3, 0.3, 0.3]
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -534,6 +535,7 @@ Annotation of the whole route leg with fine-grained information about each segme
|
||||
- `datasources`: The index of the datasource for the speed between each pair of coordinates. `0` is the default profile, other values are supplied via `--segment-speed-file` to `osrm-contract`
|
||||
- `nodes`: The OSM node ID for each coordinate along the route, excluding the first/last user-supplied coordinates
|
||||
- `weight`: The weights between each pair of coordinates
|
||||
- `speed`: Convenience field, calculation of `distance / duration` rounded to one decimal place
|
||||
|
||||
#### Example
|
||||
|
||||
@ -574,6 +576,8 @@ step.
|
||||
- `mode`: A string signifying the mode of transportation.
|
||||
- `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
|
||||
- `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
|
||||
|
||||
@ -628,7 +632,7 @@ step.
|
||||
- `bearing_after`: The clockwise angle from true north to the
|
||||
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**
|
||||
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 |
|
||||
|------------------|--------------------------------------------------------------|
|
||||
@ -644,8 +648,8 @@ step.
|
||||
| `end of road` | road ends in a T intersection turn in direction of `modifier`|
|
||||
| `use lane` | going straight on a specific lane |
|
||||
| `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` |
|
||||
| `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. |
|
||||
| `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` and/or `rotary_pronunciation` parameters (located in the RouteStep object) in addition to the `exit` parameter (located on the StepManeuver object). |
|
||||
| `roundabout turn`| Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. |
|
||||
| `notification` | not an actual turn but a change in the driving conditions. For example the travel mode. If the road takes a turn itself, the `modifier` describes the direction |
|
||||
|
||||
|
@ -28,6 +28,29 @@ This dataset is a small extract and may not even contain all tags or edge cases.
|
||||
Furthermore this dataset is not in sync with what you see in up-to-date OSM maps or on the demo server.
|
||||
See the library tests for how to add new dataset dependent tests.
|
||||
|
||||
To prepare the test data simply `cd test/data/` and then run `make`.
|
||||
|
||||
### Running Tests
|
||||
|
||||
To build the unit tests:
|
||||
|
||||
```
|
||||
cd build
|
||||
cmake ..
|
||||
make tests
|
||||
```
|
||||
|
||||
You should see the compiled binaries in `build/unit_tests`, you can then run each suite individually:
|
||||
|
||||
```
|
||||
./engine-tests
|
||||
```
|
||||
|
||||
For `library-tests` you will need to provide a path to the test data:
|
||||
|
||||
```
|
||||
./library-tests ../../test/data/monaco.osrm
|
||||
```
|
||||
|
||||
## Cucumber
|
||||
|
||||
|
@ -119,12 +119,13 @@ Feature: Car - Restricted access
|
||||
| permissive | x |
|
||||
| designated | x |
|
||||
| no | |
|
||||
| private | |
|
||||
| private | x |
|
||||
| agricultural | |
|
||||
| forestry | |
|
||||
| psv | |
|
||||
| delivery | |
|
||||
| delivery | x |
|
||||
| some_tag | x |
|
||||
| destination | x |
|
||||
|
||||
|
||||
Scenario: Car - Access tags on nodes
|
||||
@ -134,11 +135,11 @@ Feature: Car - Restricted access
|
||||
| permissive | x |
|
||||
| designated | x |
|
||||
| no | |
|
||||
| private | |
|
||||
| private | x |
|
||||
| agricultural | |
|
||||
| forestry | |
|
||||
| psv | |
|
||||
| delivery | |
|
||||
| delivery | x |
|
||||
| some_tag | x |
|
||||
|
||||
Scenario: Car - Access tags on both node and way
|
||||
@ -156,15 +157,15 @@ Feature: Car - Restricted access
|
||||
|
||||
Scenario: Car - Access combinations
|
||||
Then routability should be
|
||||
| highway | accesss | vehicle | motor_vehicle | motorcar | bothw |
|
||||
| runway | private | | | permissive | x |
|
||||
| primary | forestry | | yes | | x |
|
||||
| cycleway | | | designated | | x |
|
||||
| residential | | yes | no | | |
|
||||
| motorway | yes | permissive | | private | |
|
||||
| trunk | agricultural | designated | permissive | no | |
|
||||
| pedestrian | | | | | |
|
||||
| pedestrian | | | | destination | x |
|
||||
| highway | access | vehicle | motor_vehicle | motorcar | forw | backw | # |
|
||||
| runway | private | | | permissive | x | x | |
|
||||
| primary | forestry | | yes | | x | x | |
|
||||
| cycleway | | | designated | | x | x | |
|
||||
| residential | | yes | no | | | | |
|
||||
| motorway | yes | permissive | | private | x | | implied oneway |
|
||||
| trunk | agricultural | designated | permissive | no | | | |
|
||||
| pedestrian | | | | | | | |
|
||||
| pedestrian | | | | destination | x | x | |
|
||||
|
||||
Scenario: Car - Ignore access tags for other modes
|
||||
Then routability should be
|
||||
@ -182,7 +183,7 @@ Feature: Car - Restricted access
|
||||
Scenario: Car - designated HOV ways are rated low
|
||||
Then routability should be
|
||||
| highway | hov | bothw | forw_rate | backw_rate |
|
||||
| primary | designated | x | 2 | 2 |
|
||||
| primary | designated | x | 18 | 18 |
|
||||
| primary | yes | 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
|
||||
Then routability should be
|
||||
| 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 |
|
||||
|
||||
@hov
|
||||
Scenario: Car - a way with all lanes HOV-designated is highly penalized by default (similar to hov=designated)
|
||||
Then routability should be
|
||||
| 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 | | | x | x | 18 | 2 |
|
||||
| primary | designated | | | | x | x | 2 | 18 |
|
||||
| primary | designated\|designated | designated\|designated | | | x | x | 2 | 2 |
|
||||
| primary | designated | designated | | | x | x | 18 | 18 |
|
||||
# This test is flaky because non-deterministic turn generation sometimes emits a NoTurn here that is marked as restricted. #3769
|
||||
#| primary | | designated | | | x | x | 18 | 18 |
|
||||
#| 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 | yes\|no | yes\|no | | | x | x | 18 | 18 |
|
||||
| primary | | | | | x | x | 18 | 18 |
|
||||
| primary | designated | | | -1 | | x | | 18 |
|
||||
| primary | | designated | | -1 | | x | | 2 |
|
||||
| primary | | | designated | yes | x | | 2 | |
|
||||
| primary | | | designated | -1 | | x | | 2 |
|
||||
| primary | | designated | | -1 | | x | | 18 |
|
||||
| primary | | | designated | yes | x | | 18 | |
|
||||
| primary | | | designated | -1 | | x | | 18 |
|
||||
| primary | | | designated\| | yes | x | | 18 | |
|
||||
| primary | | | designated\| | -1 | | x | | 18 |
|
||||
| primary | | | designated\|designated | yes | x | | 2 | |
|
||||
| primary | | | designated\|designated | -1 | | x | | 2 |
|
||||
| primary | | | designated\|designated | yes | x | | 18 | |
|
||||
| primary | | | designated\|designated | -1 | | x | | 18 |
|
||||
| primary | | | designated\|yes | yes | x | | 18 | |
|
||||
| primary | | | designated\|no | -1 | | x | | 18 |
|
||||
|
||||
@ -224,12 +226,10 @@ Feature: Car - Restricted access
|
||||
| primary | no | x |
|
||||
| primary | snowmobile | x |
|
||||
|
||||
# To test this we need issue #2781
|
||||
@todo
|
||||
Scenario: Car - only toll=yes ways are ignored by default
|
||||
Scenario: Car - toll=yes ways are enabled by default
|
||||
Then routability should be
|
||||
| highway | toll | bothw |
|
||||
| primary | yes | |
|
||||
| primary | yes | x |
|
||||
|
||||
Scenario: Car - directional access tags
|
||||
Then routability should be
|
||||
@ -252,7 +252,7 @@ Feature: Car - Restricted access
|
||||
| gate | yes | x |
|
||||
| gate | permissive | x |
|
||||
| gate | designated | x |
|
||||
| gate | private | |
|
||||
| gate | private | x |
|
||||
| gate | garbagetag | x |
|
||||
|
||||
Scenario: Car - a way with conditional access
|
||||
|
@ -29,14 +29,14 @@ Feature: Car - Barriers
|
||||
| gate | permissive | x |
|
||||
| gate | designated | x |
|
||||
| gate | no | |
|
||||
| gate | private | |
|
||||
| gate | private | x |
|
||||
| gate | agricultural | |
|
||||
| wall | | |
|
||||
| wall | yes | x |
|
||||
| wall | permissive | x |
|
||||
| wall | designated | x |
|
||||
| wall | no | |
|
||||
| wall | private | |
|
||||
| wall | private | x |
|
||||
| wall | agricultural | |
|
||||
|
||||
Scenario: Car - Rising bollard exception for barriers
|
||||
|
@ -1,4 +1,4 @@
|
||||
@routing @car @destination @todo
|
||||
@routing @car @destination
|
||||
Feature: Car - Destination only, no passing through
|
||||
|
||||
Background:
|
||||
@ -81,3 +81,53 @@ Feature: Car - Destination only, no passing through
|
||||
| e | a | de,cd,bc,ab,ab |
|
||||
| b | d | bc,cd,cd |
|
||||
| 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
features/car/hov.feature
Normal file
36
features/car/hov.feature
Normal 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 |
|
@ -45,3 +45,9 @@ Feature: Car - speeds
|
||||
| primary | 60 | 47 km/h | 47 km/h |
|
||||
| primary | 60 | 47 km/h | 47 km/h |
|
||||
| primary | 60 | 47 km/h | 47 km/h |
|
||||
|
||||
Scenario: Car - Side road penalties
|
||||
Then routability should be
|
||||
|
||||
| highway | side_road | forw | backw | forw_rate | backw_rate |
|
||||
| primary | yes | 64 km/h | 64 km/h | 14 | 14 |
|
||||
|
@ -40,13 +40,13 @@ Feature: Car - Surfaces
|
||||
| highway | access | tracktype | smoothness | surface | forw | backw |
|
||||
| motorway | | | | | x | |
|
||||
| motorway | no | grade1 | excellent | asphalt | | |
|
||||
| motorway | private | grade1 | excellent | asphalt | | |
|
||||
| motorway | private | grade1 | excellent | asphalt | x | |
|
||||
| motorway | agricultural | grade1 | excellent | asphalt | | |
|
||||
| motorway | forestry | grade1 | excellent | asphalt | | |
|
||||
| motorway | emergency | grade1 | excellent | asphalt | | |
|
||||
| primary | | | | | x | x |
|
||||
| primary | private | grade1 | excellent | asphalt | x | x |
|
||||
| primary | no | grade1 | excellent | asphalt | | |
|
||||
| primary | private | grade1 | excellent | asphalt | | |
|
||||
| primary | agricultural | grade1 | excellent | asphalt | | |
|
||||
| primary | forestry | grade1 | excellent | asphalt | | |
|
||||
| primary | emergency | grade1 | excellent | asphalt | | |
|
||||
|
@ -818,3 +818,37 @@ Feature: Turn Lane Guidance
|
||||
When I route I should get
|
||||
| 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, |
|
||||
|
||||
@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, |
|
||||
|
@ -1158,3 +1158,45 @@ Feature: Turn Lane Guidance
|
||||
When I route I should get
|
||||
| waypoints | bearings | route | turns |
|
||||
| 1,a | 90,2 180,180 | | |
|
||||
|
||||
@3379
|
||||
Scenario: Don't Turn through potential through lanes
|
||||
Given the node map
|
||||
"""
|
||||
d
|
||||
|
|
||||
a - - - - b - - - - - c
|
||||
|
|
||||
e
|
||||
"""
|
||||
And the ways
|
||||
| nodes | name | oneway | turn:lanes:forward |
|
||||
| ab | road | yes | left\|none\|none |
|
||||
| bc | road | yes | |
|
||||
| ebd | cross | no | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | road,cross,cross | depart,turn right,arrive | ,left:false none:false none:true, |
|
||||
| a,c | road,road | depart,arrive | , |
|
||||
|
||||
@3379
|
||||
Scenario: Don't Turn through potential through lanes
|
||||
Given the node map
|
||||
"""
|
||||
d
|
||||
|
|
||||
a - - - - b - - - - - c
|
||||
|
|
||||
e
|
||||
"""
|
||||
And the ways
|
||||
| nodes | name | oneway | turn:lanes:forward |
|
||||
| ab | road | yes | none\|none\|right |
|
||||
| bc | road | yes | |
|
||||
| ebd | cross | no | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,cross,cross | depart,turn left,arrive | ,none:true none:false right:false, |
|
||||
| a,c | road,road | depart,arrive | , |
|
||||
|
@ -28,3 +28,11 @@ Feature: osrm-contract command line options: datasources
|
||||
When I run "osrm-contract --segment-speed-file {speeds_file} {processed_file}"
|
||||
Then datasource names should contain "lua profile,27_osrmcontract_passing_base_file_speeds"
|
||||
And it should exit successfully
|
||||
|
||||
Scenario: osrm-contract - Passing base file
|
||||
Given the speed file
|
||||
"""
|
||||
"""
|
||||
And the data has been extracted
|
||||
When I run "osrm-contract --segment-speed-file {speeds_file} {processed_file}"
|
||||
Then it should exit successfully
|
||||
|
@ -28,13 +28,14 @@ module.exports = function () {
|
||||
directions.filter(d => headers.has(d + '_rate')).forEach((direction) => {
|
||||
var rate = direction + '_rate';
|
||||
var want = row[rate];
|
||||
|
||||
switch (true) {
|
||||
case '' === want:
|
||||
outputRow[rate] = result[direction].status ?
|
||||
result[direction].status.toString() : '';
|
||||
break;
|
||||
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();
|
||||
} else {
|
||||
outputRow[rate] = '';
|
||||
|
@ -147,7 +147,7 @@ module.exports = function () {
|
||||
// if header matches 'a:*', parse out the values for *
|
||||
// and return in that header
|
||||
headers.forEach((k) => {
|
||||
let whitelist = ['duration', 'distance', 'datasources', 'nodes', 'weight'];
|
||||
let whitelist = ['duration', 'distance', 'datasources', 'nodes', 'weight', 'speed'];
|
||||
if (k.match(/^a:/)) {
|
||||
let a_type = k.slice(2);
|
||||
if (whitelist.indexOf(a_type) == -1)
|
||||
|
@ -39,7 +39,7 @@ Feature: Weight tests
|
||||
# FIXME include/engine/guidance/assemble_geometry.hpp:95
|
||||
Scenario: Start and target on the same and adjacent edge
|
||||
Given the query options
|
||||
| annotations | distance,duration,weight,nodes |
|
||||
| annotations | distance,duration,weight,nodes,speed |
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
@ -53,11 +53,11 @@ Feature: Weight tests
|
||||
| abc |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | distances | weights | times | a:distance | a:duration | a:weight |
|
||||
| s,t | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3 | 3 |
|
||||
| t,s | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3.1 | 3.1 |
|
||||
| s,e | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 30.026527:10.008842 | 3.1:1 | 3.1:1 |
|
||||
| e,s | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 10.008842:30.026527 | 1:3.1 | 1:3.1 |
|
||||
| waypoints | route | distances | weights | times | a:distance | a:duration | a:weight | a:speed |
|
||||
| s,t | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3 | 3 | 6.7 |
|
||||
| t,s | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3.1 | 3.1 | 6.5 |
|
||||
| s,e | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 30.026527:10.008842 | 3.1:1 | 3.1:1 | 9.7:10 |
|
||||
| e,s | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 10.008842:30.026527 | 1:3.1 | 1:3.1 | 10:9.7 |
|
||||
|
||||
|
||||
Scenario: Step weights -- way_function: fail if no weight or weight_per_meter property
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/json_util.hpp"
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
@ -228,42 +229,60 @@ class RouteAPI : public BaseAPI
|
||||
|
||||
std::vector<util::json::Object> annotations;
|
||||
|
||||
if (parameters.annotations_type != RouteParameters::AnnotationsType::None)
|
||||
// To maintain support for uses of the old default constructors, we check
|
||||
// if annotations property was set manually after default construction
|
||||
auto requested_annotations = parameters.annotations_type;
|
||||
if ((parameters.annotations == true) &&
|
||||
(parameters.annotations_type == RouteParameters::AnnotationsType::None))
|
||||
{
|
||||
requested_annotations = RouteParameters::AnnotationsType::All;
|
||||
}
|
||||
|
||||
if (requested_annotations != RouteParameters::AnnotationsType::None)
|
||||
{
|
||||
for (const auto idx : util::irange<std::size_t>(0UL, leg_geometries.size()))
|
||||
{
|
||||
auto &leg_geometry = leg_geometries[idx];
|
||||
util::json::Object annotation;
|
||||
|
||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Duration)
|
||||
// AnnotationsType uses bit flags, & operator checks if a property is set
|
||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Speed)
|
||||
{
|
||||
annotation.values["speed"] = GetAnnotations(
|
||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
auto val = std::round(anno.distance / anno.duration * 10.) / 10.;
|
||||
return util::json::clamp_float(val);
|
||||
});
|
||||
}
|
||||
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
|
||||
{
|
||||
annotation.values["duration"] = GetAnnotations(
|
||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
return anno.duration;
|
||||
});
|
||||
}
|
||||
|
||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Distance)
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
|
||||
{
|
||||
annotation.values["distance"] = GetAnnotations(
|
||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
return anno.distance;
|
||||
});
|
||||
}
|
||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Weight)
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
|
||||
{
|
||||
annotation.values["weight"] = GetAnnotations(
|
||||
leg_geometry,
|
||||
[](const guidance::LegGeometry::Annotation &anno) { return anno.weight; });
|
||||
}
|
||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Datasources)
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
|
||||
{
|
||||
annotation.values["datasources"] = GetAnnotations(
|
||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
return anno.datasource;
|
||||
});
|
||||
}
|
||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Nodes)
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
|
||||
{
|
||||
util::json::Array nodes;
|
||||
nodes.values.reserve(leg_geometry.osm_node_ids.size());
|
||||
|
@ -75,7 +75,8 @@ struct RouteParameters : public BaseParameters
|
||||
Distance = 0x04,
|
||||
Weight = 0x08,
|
||||
Datasources = 0x10,
|
||||
All = Duration | Nodes | Distance | Weight | Datasources
|
||||
Speed = 0x20,
|
||||
All = Duration | Nodes | Distance | Weight | Datasources | Speed
|
||||
};
|
||||
|
||||
RouteParameters() = default;
|
||||
|
@ -20,7 +20,7 @@ namespace guidance
|
||||
// as separate maneuvers.
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
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 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
|
||||
// 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);
|
||||
|
||||
// trim initial/final segment of very short length.
|
||||
|
@ -17,7 +17,8 @@ struct ExtractionTurn
|
||||
ExtractionTurn(const guidance::ConnectedRoad &turn, bool has_traffic_light)
|
||||
: angle(180. - turn.angle), turn_type(turn.instruction.type),
|
||||
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;
|
||||
double weight;
|
||||
double duration;
|
||||
bool source_restricted;
|
||||
bool target_restricted;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,8 @@ struct ExtractionWay
|
||||
turn_lanes_forward.clear();
|
||||
turn_lanes_backward.clear();
|
||||
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,
|
||||
@ -106,6 +108,8 @@ struct ExtractionWay
|
||||
bool roundabout;
|
||||
bool circular;
|
||||
bool is_startpoint;
|
||||
bool backward_restricted;
|
||||
bool forward_restricted;
|
||||
TravelMode forward_travel_mode : 4;
|
||||
TravelMode backward_travel_mode : 4;
|
||||
guidance::RoadClassification road_classification;
|
||||
|
@ -70,8 +70,9 @@ struct InternalExtractorEdge
|
||||
false, // roundabout
|
||||
false, // circular
|
||||
true, // can be startpoint
|
||||
false, // local access only
|
||||
false, // split edge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
false,
|
||||
guidance::TurnLaneType::empty,
|
||||
guidance::RoadClassification()),
|
||||
weight_data(), duration_data()
|
||||
@ -88,8 +89,9 @@ struct InternalExtractorEdge
|
||||
bool roundabout,
|
||||
bool circular,
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
LaneDescriptionID lane_description,
|
||||
guidance::RoadClassification road_classification,
|
||||
util::Coordinate source_coordinate)
|
||||
@ -103,8 +105,9 @@ struct InternalExtractorEdge
|
||||
roundabout,
|
||||
circular,
|
||||
startpoint,
|
||||
travel_mode,
|
||||
restricted,
|
||||
is_split,
|
||||
travel_mode,
|
||||
lane_description,
|
||||
std::move(road_classification)),
|
||||
weight_data(std::move(weight_data)), duration_data(std::move(duration_data)),
|
||||
@ -134,8 +137,9 @@ struct InternalExtractorEdge
|
||||
false, // roundabout
|
||||
false, // circular
|
||||
true, // can be startpoint
|
||||
false, // local access only
|
||||
false, // split edge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
false,
|
||||
INVALID_LANE_DESCRIPTIONID,
|
||||
guidance::RoadClassification(),
|
||||
util::Coordinate());
|
||||
@ -152,8 +156,9 @@ struct InternalExtractorEdge
|
||||
false, // roundabout
|
||||
false, // circular
|
||||
true, // can be startpoint
|
||||
false, // local access only
|
||||
false, // split edge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
false,
|
||||
INVALID_LANE_DESCRIPTIONID,
|
||||
guidance::RoadClassification(),
|
||||
util::Coordinate());
|
||||
|
@ -25,27 +25,29 @@ struct NodeBasedEdge
|
||||
bool roundabout,
|
||||
bool circular,
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification);
|
||||
|
||||
bool operator<(const NodeBasedEdge &other) const;
|
||||
|
||||
NodeID source;
|
||||
NodeID target;
|
||||
NodeID name_id;
|
||||
EdgeWeight weight;
|
||||
EdgeWeight duration;
|
||||
std::uint8_t forward : 1;
|
||||
std::uint8_t backward : 1;
|
||||
std::uint8_t roundabout : 1;
|
||||
std::uint8_t circular : 1;
|
||||
std::uint8_t startpoint : 1;
|
||||
std::uint8_t is_split : 1;
|
||||
TravelMode travel_mode : 4;
|
||||
LaneDescriptionID lane_description_id;
|
||||
guidance::RoadClassification road_classification;
|
||||
NodeID source; // 32 4
|
||||
NodeID target; // 32 4
|
||||
NodeID name_id; // 32 4
|
||||
EdgeWeight weight; // 32 4
|
||||
EdgeWeight duration; // 32 4
|
||||
std::uint8_t forward : 1; // 1
|
||||
std::uint8_t backward : 1; // 1
|
||||
std::uint8_t roundabout : 1; // 1
|
||||
std::uint8_t circular : 1; // 1
|
||||
std::uint8_t startpoint : 1; // 1
|
||||
std::uint8_t restricted : 1; // 1
|
||||
std::uint8_t is_split : 1; // 1
|
||||
TravelMode travel_mode : 4; // 4
|
||||
LaneDescriptionID lane_description_id; // 16 2
|
||||
guidance::RoadClassification road_classification; // 16 2
|
||||
};
|
||||
|
||||
struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
||||
@ -60,8 +62,9 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
||||
bool roundabout,
|
||||
bool circular,
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification);
|
||||
|
||||
@ -74,7 +77,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
||||
inline NodeBasedEdge::NodeBasedEdge()
|
||||
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), duration(0),
|
||||
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)
|
||||
{
|
||||
}
|
||||
@ -89,13 +92,14 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
|
||||
bool roundabout,
|
||||
bool circular,
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification)
|
||||
: source(source), target(target), name_id(name_id), weight(weight), duration(duration),
|
||||
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))
|
||||
{
|
||||
}
|
||||
@ -127,8 +131,9 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
|
||||
bool roundabout,
|
||||
bool circular,
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool restricted,
|
||||
bool is_split,
|
||||
TravelMode travel_mode,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassification road_classification)
|
||||
: NodeBasedEdge(SPECIAL_NODEID,
|
||||
@ -141,8 +146,9 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
|
||||
roundabout,
|
||||
circular,
|
||||
startpoint,
|
||||
travel_mode,
|
||||
restricted,
|
||||
is_split,
|
||||
travel_mode,
|
||||
lane_description_id,
|
||||
std::move(road_classification)),
|
||||
osm_source_id(std::move(source)), osm_target_id(std::move(target))
|
||||
|
@ -42,11 +42,13 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
||||
|
||||
RouteParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_)
|
||||
{
|
||||
using AnnotationsType = engine::api::RouteParameters::AnnotationsType;
|
||||
|
||||
const auto add_annotation = [](engine::api::RouteParameters &route_parameters,
|
||||
engine::api::RouteParameters::AnnotationsType &route_param) {
|
||||
AnnotationsType route_param) {
|
||||
route_parameters.annotations_type = route_parameters.annotations_type | route_param;
|
||||
route_parameters.annotations = route_parameters.annotations_type !=
|
||||
engine::api::RouteParameters::AnnotationsType::None;
|
||||
route_parameters.annotations =
|
||||
route_parameters.annotations_type != AnnotationsType::None;
|
||||
};
|
||||
|
||||
geometries_type.add("geojson", engine::api::RouteParameters::GeometriesType::GeoJSON)(
|
||||
@ -57,13 +59,10 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
||||
"full", engine::api::RouteParameters::OverviewType::Full)(
|
||||
"false", engine::api::RouteParameters::OverviewType::False);
|
||||
|
||||
annotations_type.add("true", engine::api::RouteParameters::AnnotationsType::All)(
|
||||
"false", engine::api::RouteParameters::AnnotationsType::None)(
|
||||
"duration", engine::api::RouteParameters::AnnotationsType::Duration)(
|
||||
"nodes", engine::api::RouteParameters::AnnotationsType::Nodes)(
|
||||
"distance", engine::api::RouteParameters::AnnotationsType::Distance)(
|
||||
"weight", engine::api::RouteParameters::AnnotationsType::Weight)(
|
||||
"datasources", engine::api::RouteParameters::AnnotationsType::Datasources);
|
||||
annotations_type.add("duration", AnnotationsType::Duration)("nodes",
|
||||
AnnotationsType::Nodes)(
|
||||
"distance", AnnotationsType::Distance)("weight", AnnotationsType::Weight)(
|
||||
"datasources", AnnotationsType::Datasources)("speed", AnnotationsType::Speed);
|
||||
|
||||
base_rule =
|
||||
BaseGrammar::base_rule(qi::_r1) |
|
||||
@ -75,7 +74,9 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
||||
(qi::lit("overview=") >
|
||||
overview_type[ph::bind(&engine::api::RouteParameters::overview, qi::_r1) = qi::_1]) |
|
||||
(qi::lit("annotations=") >
|
||||
annotations_type[ph::bind(add_annotation, qi::_r1, qi::_1)] % ',');
|
||||
(qi::lit("true")[ph::bind(add_annotation, qi::_r1, AnnotationsType::All)] |
|
||||
qi::lit("false")[ph::bind(add_annotation, qi::_r1, AnnotationsType::None)] |
|
||||
(annotations_type[ph::bind(add_annotation, qi::_r1, qi::_1)] % ',')));
|
||||
|
||||
query_rule = BaseGrammar::query_rule(qi::_r1);
|
||||
}
|
||||
|
@ -33,11 +33,12 @@ struct NodeBasedEdgeData
|
||||
bool roundabout,
|
||||
bool circular,
|
||||
bool startpoint,
|
||||
bool restricted,
|
||||
extractor::TravelMode travel_mode,
|
||||
const LaneDescriptionID lane_description_id)
|
||||
: weight(weight), duration(duration), edge_id(edge_id), name_id(name_id),
|
||||
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 circular : 1;
|
||||
bool startpoint : 1;
|
||||
bool restricted : 1;
|
||||
extractor::TravelMode travel_mode : 4;
|
||||
LaneDescriptionID lane_description_id;
|
||||
extractor::guidance::RoadClassification road_classification;
|
||||
@ -58,7 +60,8 @@ struct NodeBasedEdgeData
|
||||
return (reversed == other.reversed) && (roundabout == other.roundabout) &&
|
||||
(circular == other.circular) && (startpoint == other.startpoint) &&
|
||||
(travel_mode == other.travel_mode) &&
|
||||
(road_classification == other.road_classification);
|
||||
(road_classification == other.road_classification) &&
|
||||
(restricted == other.restricted);
|
||||
}
|
||||
|
||||
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.travel_mode = input_edge.travel_mode;
|
||||
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.lane_description_id = input_edge.lane_description_id;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "osrm-backend-test-suite",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"description": "The Open Source Routing Machine is a high performance routing engine written in C++11 designed to run on OpenStreetMap data.",
|
||||
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
||||
"dependencies": {
|
||||
"chalk": "^1.1.3",
|
||||
"cucumber": "^1.2.1",
|
||||
|
@ -65,6 +65,8 @@ local profile = {
|
||||
'delivery'
|
||||
},
|
||||
|
||||
restricted_access_tag_list = Set { },
|
||||
|
||||
access_tags_hierarchy = Sequence {
|
||||
'bicycle',
|
||||
'vehicle',
|
||||
@ -521,4 +523,10 @@ function turn_function(turn)
|
||||
if turn.has_traffic_light then
|
||||
turn.duration = turn.duration + profile.traffic_light_penalty
|
||||
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
|
||||
|
@ -34,6 +34,9 @@ local profile = {
|
||||
speed_reduction = 0.8,
|
||||
traffic_light_penalty = 2,
|
||||
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.
|
||||
-- Should be inverted for left-driving countries.
|
||||
@ -63,18 +66,21 @@ local profile = {
|
||||
'vehicle',
|
||||
'permissive',
|
||||
'designated',
|
||||
'destination',
|
||||
'hov' -- we might filter hov out later depending on the avoid settings or add penalties
|
||||
'hov'
|
||||
},
|
||||
|
||||
access_tag_blacklist = Set {
|
||||
'no',
|
||||
'private',
|
||||
'agricultural',
|
||||
'forestry',
|
||||
'emergency',
|
||||
'psv',
|
||||
'delivery'
|
||||
'psv'
|
||||
},
|
||||
|
||||
restricted_access_tag_list = Set {
|
||||
'private',
|
||||
'delivery',
|
||||
'destination'
|
||||
},
|
||||
|
||||
access_tags_hierarchy = Sequence {
|
||||
@ -96,7 +102,7 @@ local profile = {
|
||||
|
||||
avoid = Set {
|
||||
'area',
|
||||
'toll',
|
||||
-- 'toll', -- uncomment this to avoid tolls
|
||||
'reversible',
|
||||
'impassable',
|
||||
'hov_lanes',
|
||||
@ -331,7 +337,7 @@ function way_function(way, result)
|
||||
-- handle service road restrictions
|
||||
'handle_service',
|
||||
|
||||
-- check high occupancy vehicle restrictions
|
||||
-- handle hov
|
||||
'handle_hov',
|
||||
|
||||
-- compute speed taking into account way type, maxspeed tags, etc.
|
||||
@ -387,4 +393,10 @@ function turn_function (turn)
|
||||
turn.weight = turn.duration
|
||||
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
|
||||
|
@ -12,6 +12,7 @@ properties.max_speed_for_map_matching = 40/3.6 -- kmph -> m/s
|
||||
properties.use_turn_restrictions = false
|
||||
properties.continue_straight_at_waypoint = false
|
||||
properties.weight_name = 'duration'
|
||||
--properties.weight_name = 'routability'
|
||||
|
||||
local walking_speed = 5
|
||||
|
||||
@ -44,12 +45,14 @@ local profile = {
|
||||
|
||||
access_tag_blacklist = Set {
|
||||
'no',
|
||||
'private',
|
||||
'agricultural',
|
||||
'forestry',
|
||||
'delivery'
|
||||
'private',
|
||||
'delivery',
|
||||
},
|
||||
|
||||
restricted_access_tag_list = Set { },
|
||||
|
||||
access_tags_hierarchy = Sequence {
|
||||
'foot',
|
||||
'access'
|
||||
@ -244,4 +247,10 @@ function turn_function (turn)
|
||||
if turn.has_traffic_light then
|
||||
turn.duration = profile.traffic_light_penalty
|
||||
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
|
||||
|
@ -177,25 +177,37 @@ function Handlers.handle_hov(way,result,data,profile)
|
||||
return
|
||||
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 (all_hov_forward) then
|
||||
result.forward_restricted = true
|
||||
end
|
||||
if (all_hov_backward) then
|
||||
result.backward_restricted = true
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- check if all lanes are hov only
|
||||
data.hov_lanes_forward, data.hov_lanes_backward = Tags.get_forward_backward_by_key(way,data,'hov:lanes')
|
||||
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
|
||||
-- filter out ways where all lanes are hov only
|
||||
if all_hov_forward then
|
||||
result.forward_mode = mode.inaccessible
|
||||
end
|
||||
if inaccessible_backward then
|
||||
if all_hov_backward then
|
||||
result.backward_mode = mode.inaccessible
|
||||
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)
|
||||
data.forward_access, data.backward_access =
|
||||
Tags.get_forward_backward_by_set(way,data,profile.access_tags_hierarchy)
|
||||
@ -211,6 +223,14 @@ function Handlers.handle_access(way,result,data,profile)
|
||||
if result.forward_mode == mode.inaccessible and result.backward_mode == mode.inaccessible then
|
||||
return false
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
-- handle speed (excluding maxspeed)
|
||||
@ -273,24 +293,6 @@ end
|
||||
function Handlers.handle_penalties(way,result,data,profile)
|
||||
-- heavily penalize a way tagged with all HOV lanes
|
||||
-- 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 = way:get_value_by_key("service")
|
||||
if service and profile.service_penalties[service] then
|
||||
@ -327,11 +329,11 @@ function Handlers.handle_penalties(way,result,data,profile)
|
||||
local sideroad_penalty = 1.0
|
||||
data.sideroad = way:get_value_by_key("side_road")
|
||||
if "yes" == data.sideroad or "rotary" == data.sideroad then
|
||||
sideroad_penalty = side_road_multiplier;
|
||||
sideroad_penalty = profile.side_road_multiplier
|
||||
end
|
||||
|
||||
local forward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty, forward_hov_penalty)
|
||||
local backward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty, backward_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)
|
||||
|
||||
if properties.weight_name == 'routability' then
|
||||
if result.forward_speed > 0 then
|
||||
|
@ -268,7 +268,7 @@ template <typename Key, typename Value> struct CSVFilesParser
|
||||
qi::rule<Iterator, std::pair<Key, Value>()> csv_line =
|
||||
(key_rule >> ',' >> value_source) >> -(',' >> *(qi::char_ - qi::eol));
|
||||
std::vector<std::pair<Key, Value>> result;
|
||||
const auto ok = qi::parse(first, last, (csv_line % qi::eol) >> *qi::eol, result);
|
||||
const auto ok = qi::parse(first, last, -(csv_line % qi::eol) >> *qi::eol, result);
|
||||
|
||||
if (!ok || first != last)
|
||||
{
|
||||
|
@ -74,6 +74,15 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
|
||||
|
||||
// We're walking backwards over all adjacent turns:
|
||||
// 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 ¤t, RouteStep &previous) {
|
||||
const auto current_inst = current.maneuver.instruction;
|
||||
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_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;
|
||||
|
||||
// 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_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
|
||||
const auto previous_is_straight =
|
||||
!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 =
|
||||
previous_lanes.first_lane_from_the_right // start from rightmost 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
|
||||
// how many lanes are to the left and not in the turn.
|
||||
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 = [&] {
|
||||
@ -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
|
||||
// how many lanes are to the right and not in the turn.
|
||||
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
|
||||
@ -179,13 +196,11 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
|
||||
anticipate_for_right_turn();
|
||||
}
|
||||
|
||||
// We might have constrained the previous step in a way that makes it compatible
|
||||
// with the current step. If we did so we collapse it here and mark the current
|
||||
// step as invalid, scheduled for later removal.
|
||||
if (collapsable(previous, current))
|
||||
if (previous_inst.type == TurnType::UseLane && current_inst.type == TurnType::UseLane &&
|
||||
previous.mode == current.mode && previous_lanes == current_lanes)
|
||||
{
|
||||
previous.ElongateBy(current);
|
||||
current.maneuver.instruction = TurnInstruction::NO_TURN();
|
||||
current.Invalidate();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -526,6 +526,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
// compute weight and duration penalties
|
||||
auto is_traffic_light = m_traffic_lights.count(node_at_center_of_intersection);
|
||||
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);
|
||||
|
||||
// turn penalties are limited to [-2^15, 2^15) which roughly
|
||||
|
@ -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) {
|
||||
using Value = detail::ByEdgeOrByMeterValue;
|
||||
// get value by weight per edge
|
||||
if (by_way >= 0)
|
||||
{
|
||||
// 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
|
||||
{
|
||||
// get value by deriving weight from speed per edge
|
||||
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.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 &&
|
||||
((parsed_way.forward_rate != parsed_way.backward_rate) ||
|
||||
(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.circular,
|
||||
parsed_way.is_startpoint,
|
||||
parsed_way.forward_travel_mode,
|
||||
parsed_way.forward_restricted,
|
||||
split_edge,
|
||||
parsed_way.forward_travel_mode,
|
||||
turn_lane_id_forward,
|
||||
road_classification,
|
||||
{}));
|
||||
@ -368,8 +372,9 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
parsed_way.roundabout,
|
||||
parsed_way.circular,
|
||||
parsed_way.is_startpoint,
|
||||
parsed_way.backward_travel_mode,
|
||||
parsed_way.backward_restricted,
|
||||
split_edge,
|
||||
parsed_way.backward_travel_mode,
|
||||
turn_lane_id_backward,
|
||||
road_classification,
|
||||
{}));
|
||||
|
@ -40,7 +40,6 @@ LaneDataVector augmentMultiple(const std::size_t none_index,
|
||||
LaneDataVector lane_data,
|
||||
const Intersection &intersection)
|
||||
{
|
||||
|
||||
// a none-turn is allowing multiple turns. we have to add a lane-data entry for
|
||||
// every possible turn. This should, hopefully, only be the case for single lane
|
||||
// entries?
|
||||
@ -107,20 +106,64 @@ LaneDataVector augmentMultiple(const std::size_t none_index,
|
||||
util::Log(logWARNING) << "Failed lane assignment. Reached bad situation.";
|
||||
return std::make_pair(std::size_t{0}, std::size_t{0});
|
||||
}();
|
||||
for (auto intersection_index = range.first; intersection_index < range.second;
|
||||
++intersection_index)
|
||||
|
||||
const auto intersection_range_first = intersection.begin() + range.first;
|
||||
const auto intersection_range_end = intersection.begin() + range.second;
|
||||
const auto allowed_in_range =
|
||||
std::count_if(intersection_range_first, intersection_range_end, [](const auto &road) {
|
||||
return road.entry_allowed;
|
||||
});
|
||||
|
||||
if (allowed_in_range > 1 && lane_data[none_index].to - lane_data[none_index].from >= 1)
|
||||
{
|
||||
if (intersection[intersection_index].entry_allowed)
|
||||
// check if there is a straight turn
|
||||
auto straight_itr =
|
||||
std::find_if(intersection_range_first, intersection_range_end, [](const auto &road) {
|
||||
return road.instruction.direction_modifier == DirectionModifier::Straight;
|
||||
});
|
||||
|
||||
// we have a straight turn?
|
||||
if (straight_itr != intersection_range_end)
|
||||
{
|
||||
// FIXME this probably can be only a subset of these turns here?
|
||||
lane_data.push_back(
|
||||
{tag_by_modifier[intersection[intersection_index].instruction.direction_modifier],
|
||||
lane_data[none_index].from,
|
||||
lane_data[none_index].to,
|
||||
false});
|
||||
for (auto itr = intersection_range_first; itr != straight_itr; ++itr)
|
||||
{
|
||||
lane_data.push_back({tag_by_modifier[itr->instruction.direction_modifier],
|
||||
lane_data[none_index].from,
|
||||
lane_data[none_index].from,
|
||||
false});
|
||||
}
|
||||
lane_data.push_back({tag_by_modifier[straight_itr->instruction.direction_modifier],
|
||||
lane_data[none_index].from,
|
||||
lane_data[none_index].to,
|
||||
false});
|
||||
for (auto itr = straight_itr + 1; itr != intersection_range_end; ++itr)
|
||||
{
|
||||
lane_data.push_back({tag_by_modifier[itr->instruction.direction_modifier],
|
||||
lane_data[none_index].to,
|
||||
lane_data[none_index].to,
|
||||
false});
|
||||
}
|
||||
|
||||
lane_data.erase(lane_data.begin() + none_index);
|
||||
}
|
||||
return lane_data;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto intersection_index = range.first; intersection_index < range.second;
|
||||
++intersection_index)
|
||||
{
|
||||
if (intersection[intersection_index].entry_allowed)
|
||||
{
|
||||
lane_data.push_back({tag_by_modifier[intersection[intersection_index]
|
||||
.instruction.direction_modifier],
|
||||
lane_data[none_index].from,
|
||||
lane_data[none_index].to,
|
||||
false});
|
||||
}
|
||||
}
|
||||
lane_data.erase(lane_data.begin() + none_index);
|
||||
}
|
||||
lane_data.erase(lane_data.begin() + none_index);
|
||||
return lane_data;
|
||||
}
|
||||
|
||||
|
@ -343,7 +343,11 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
"forward_mode",
|
||||
sol::property(&ExtractionWay::get_forward_mode, &ExtractionWay::set_forward_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",
|
||||
"source",
|
||||
@ -369,7 +373,11 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
"weight",
|
||||
&ExtractionTurn::weight,
|
||||
"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
|
||||
context.state.new_usertype<osmium::NodeRef>("NodeRef", "id", &osmium::NodeRef::ref);
|
||||
|
333
third_party/sol2/sol2/sol.hpp
vendored
333
third_party/sol2/sol2/sol.hpp
vendored
@ -20,8 +20,8 @@
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// This file was generated with a script.
|
||||
// Generated 2016-12-16 05:28:22.940422 UTC
|
||||
// This header was generated with sol v2.15.5 (revision bbcbd41)
|
||||
// Generated 2017-02-19 09:59:38.638408 UTC
|
||||
// This header was generated with sol v2.15.8 (revision 0c8ec82)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||
@ -47,6 +47,9 @@
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#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++
|
||||
|
||||
// beginning of sol/state.hpp
|
||||
@ -790,7 +793,13 @@ namespace sol {
|
||||
|
||||
// beginning of sol/compatibility/version.hpp
|
||||
|
||||
#ifdef SOL_USING_CXX_LUA
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#else
|
||||
#include <lua.hpp>
|
||||
#endif // C++-compiler Lua
|
||||
|
||||
#if defined(_WIN32) || defined(_MSC_VER)
|
||||
#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;
|
||||
}
|
||||
|
||||
#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*) {
|
||||
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 // 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
|
||||
|
||||
@ -2089,8 +2099,8 @@ namespace sol {
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct optional_base {
|
||||
char storage_[sizeof(T) + (sizeof(T) % alignof(T))];
|
||||
struct alignas(T) optional_base {
|
||||
char storage_[sizeof(T)];
|
||||
bool init_;
|
||||
|
||||
constexpr optional_base() noexcept : storage_(), init_(false) {};
|
||||
@ -2137,8 +2147,8 @@ namespace sol {
|
||||
using constexpr_optional_base = optional_base<T>;
|
||||
#else
|
||||
template <class T>
|
||||
struct constexpr_optional_base {
|
||||
char storage_[sizeof(T) + (sizeof(T) % alignof(T))];
|
||||
struct alignas(T) constexpr_optional_base {
|
||||
char storage_[sizeof(T)];
|
||||
bool init_;
|
||||
constexpr constexpr_optional_base() noexcept : storage_(), init_(false) {}
|
||||
|
||||
@ -3315,7 +3325,7 @@ namespace sol {
|
||||
memory = LUA_ERRMEM,
|
||||
gc = LUA_ERRGCMM,
|
||||
handler = LUA_ERRERR,
|
||||
dead,
|
||||
dead = -1,
|
||||
};
|
||||
|
||||
enum class load_status : int {
|
||||
@ -3374,6 +3384,8 @@ namespace sol {
|
||||
bitwise_and,
|
||||
bitwise_or,
|
||||
bitwise_xor,
|
||||
pairs,
|
||||
next
|
||||
};
|
||||
|
||||
typedef meta_function meta_method;
|
||||
@ -3383,7 +3395,7 @@ namespace sol {
|
||||
"__newindex",
|
||||
} };
|
||||
|
||||
const std::array<std::string, 21> meta_function_names = { {
|
||||
const std::array<std::string, 29> meta_function_names = { {
|
||||
"new",
|
||||
"__index",
|
||||
"__newindex",
|
||||
@ -3404,6 +3416,17 @@ namespace sol {
|
||||
"__lt",
|
||||
"__le",
|
||||
"__gc",
|
||||
|
||||
"__idiv",
|
||||
"__shl",
|
||||
"__shr",
|
||||
"__bnot",
|
||||
"__band",
|
||||
"__bor",
|
||||
"__bxor",
|
||||
|
||||
"__pairs",
|
||||
"__next"
|
||||
} };
|
||||
|
||||
inline const std::string& name_of(meta_function mf) {
|
||||
@ -3473,6 +3496,10 @@ namespace sol {
|
||||
using protected_function = basic_protected_function<reference>;
|
||||
using stack_function = basic_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>
|
||||
class basic_object;
|
||||
template <typename base_t>
|
||||
@ -3716,11 +3743,15 @@ namespace sol {
|
||||
template <>
|
||||
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>
|
||||
struct lua_bind_traits : meta::bind_traits<Signature> {
|
||||
private:
|
||||
typedef meta::bind_traits<Signature> base_t;
|
||||
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 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;
|
||||
@ -3790,7 +3821,10 @@ namespace sol {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -3923,6 +3957,9 @@ namespace sol {
|
||||
}
|
||||
|
||||
reference& operator=(reference&& o) noexcept {
|
||||
if (valid()) {
|
||||
deref();
|
||||
}
|
||||
luastate = o.luastate;
|
||||
ref = o.ref;
|
||||
|
||||
@ -4114,7 +4151,7 @@ namespace sol {
|
||||
void set_extra(std::true_type, std::index_sequence<I...>, T&& target) {
|
||||
using std::get;
|
||||
(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 };
|
||||
}
|
||||
|
||||
@ -4122,7 +4159,7 @@ namespace sol {
|
||||
void set_extra(std::false_type, std::index_sequence<I...>, T&& target) {
|
||||
using std::get;
|
||||
(void)detail::swallow{ 0,
|
||||
(get<I>(*this) = get<I>(target), 0)...
|
||||
(get<I>(static_cast<base_t&>(*this)) = get<I>(target), 0)...
|
||||
, 0 };
|
||||
}
|
||||
|
||||
@ -4580,7 +4617,39 @@ namespace sol {
|
||||
|
||||
namespace sol {
|
||||
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>
|
||||
inline std::string ctti_get_type_name() {
|
||||
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;
|
||||
}
|
||||
#else
|
||||
@ -5458,7 +5495,7 @@ namespace sol {
|
||||
if (len < 1)
|
||||
return std::wstring();
|
||||
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);
|
||||
#ifdef __MINGW32__
|
||||
// Fuck you, MinGW, and fuck you libstdc++ for introducing this absolutely asinine bug
|
||||
@ -5471,7 +5508,7 @@ namespace sol {
|
||||
#endif
|
||||
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);
|
||||
return r;
|
||||
}
|
||||
@ -5486,12 +5523,12 @@ namespace sol {
|
||||
if (len < 1)
|
||||
return std::u16string();
|
||||
#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);
|
||||
std::u16string r(intd.size(), '\0');
|
||||
std::memcpy(&r[0], intd.data(), intd.size() * sizeof(char16_t));
|
||||
#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);
|
||||
#endif // VC++ is a shit
|
||||
return r;
|
||||
@ -5507,12 +5544,12 @@ namespace sol {
|
||||
if (len < 1)
|
||||
return std::u32string();
|
||||
#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);
|
||||
std::u32string r(intd.size(), '\0');
|
||||
std::memcpy(&r[0], intd.data(), r.size() * sizeof(char32_t));
|
||||
#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);
|
||||
#endif // VC++ is a shit
|
||||
return r;
|
||||
@ -6394,11 +6431,11 @@ namespace sol {
|
||||
|
||||
static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) {
|
||||
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);
|
||||
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);
|
||||
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) {
|
||||
#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));
|
||||
#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);
|
||||
#endif // VC++ is a shit
|
||||
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) {
|
||||
#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));
|
||||
#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);
|
||||
#endif // VC++ is a shit
|
||||
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) {
|
||||
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)...);
|
||||
}
|
||||
stack::record tracking{};
|
||||
@ -7656,7 +7693,7 @@ namespace sol {
|
||||
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)...);
|
||||
}
|
||||
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 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) {
|
||||
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)...);
|
||||
}
|
||||
stack::record tracking{};
|
||||
@ -8057,7 +8094,7 @@ namespace sol {
|
||||
};
|
||||
|
||||
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 function_detail {
|
||||
template <typename... Functions>
|
||||
template <int start_skew = 0, typename... Functions>
|
||||
struct overloaded_function {
|
||||
typedef std::tuple<Functions...> overload_list;
|
||||
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>
|
||||
int call(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int) {
|
||||
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) {
|
||||
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
|
||||
@ -8531,9 +8568,10 @@ namespace sol {
|
||||
// beginning of sol/resolve.hpp
|
||||
|
||||
namespace sol {
|
||||
// Clang has distinct problems with constexpr arguments,
|
||||
// so don't use the constexpr versions inside of clang.
|
||||
|
||||
#ifndef __clang__
|
||||
// constexpr is fine for not-clang
|
||||
|
||||
namespace detail {
|
||||
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...) {
|
||||
@ -8600,6 +8638,10 @@ namespace sol {
|
||||
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
||||
}
|
||||
#else
|
||||
|
||||
// Clang has distinct problems with constexpr arguments,
|
||||
// so don't use the constexpr versions inside of clang.
|
||||
|
||||
namespace detail {
|
||||
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...) {
|
||||
@ -8665,12 +8707,20 @@ namespace sol {
|
||||
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));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // sol
|
||||
|
||||
// end of sol/resolve.hpp
|
||||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template<typename T>
|
||||
struct class_indicator {};
|
||||
|
||||
struct call_indicator {};
|
||||
}
|
||||
namespace stack {
|
||||
template<typename... 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)...);
|
||||
}
|
||||
|
||||
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) {
|
||||
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)...);
|
||||
}
|
||||
|
||||
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>
|
||||
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;
|
||||
@ -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)...);
|
||||
}
|
||||
|
||||
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) {
|
||||
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)...);
|
||||
}
|
||||
|
||||
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>
|
||||
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;
|
||||
@ -8842,9 +8906,9 @@ namespace sol {
|
||||
|
||||
template<typename Signature>
|
||||
struct pusher<Signature, std::enable_if_t<std::is_member_pointer<Signature>::value>> {
|
||||
template <typename F>
|
||||
static int push(lua_State* L, F&& f) {
|
||||
return pusher<function_sig<>>{}.push(L, std::forward<F>(f));
|
||||
template <typename F, typename... Args>
|
||||
static int push(lua_State* L, F&& f, Args&&... args) {
|
||||
return pusher<function_sig<>>{}.push(L, std::forward<F>(f), std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
@ -8859,13 +8923,13 @@ namespace sol {
|
||||
template<typename... Functions>
|
||||
struct pusher<overload_set<Functions...>> {
|
||||
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));
|
||||
return 1;
|
||||
}
|
||||
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@ -8929,16 +8993,28 @@ namespace sol {
|
||||
template <typename... Functions>
|
||||
struct pusher<factory_wrapper<Functions...>> {
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
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));
|
||||
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>
|
||||
@ -9653,11 +9729,18 @@ namespace sol {
|
||||
const_reverse_iterator crend() const { return std::reverse_iterator<const_iterator>(cend()); }
|
||||
|
||||
int push() const {
|
||||
return push(L);
|
||||
}
|
||||
|
||||
int push(lua_State* target) const {
|
||||
int pushcount = 0;
|
||||
for (int i = index; i <= stacktop; ++i) {
|
||||
lua_pushvalue(L, i);
|
||||
pushcount += 1;
|
||||
}
|
||||
if (target != L) {
|
||||
lua_xmove(L, target, pushcount);
|
||||
}
|
||||
return pushcount;
|
||||
}
|
||||
|
||||
@ -9687,8 +9770,8 @@ namespace sol {
|
||||
|
||||
template <>
|
||||
struct pusher<variadic_args> {
|
||||
static int push(lua_State*, const variadic_args& ref) {
|
||||
return ref.push();
|
||||
static int push(lua_State* L, const variadic_args& ref) {
|
||||
return ref.push(L);
|
||||
}
|
||||
};
|
||||
} // stack
|
||||
@ -9906,7 +9989,7 @@ namespace sol {
|
||||
}
|
||||
|
||||
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()));
|
||||
lua_pop(tbl.lua_state(), p.levels);
|
||||
return p;
|
||||
@ -10073,9 +10156,9 @@ namespace sol {
|
||||
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)"));
|
||||
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
|
||||
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>
|
||||
@ -10153,20 +10236,23 @@ namespace sol {
|
||||
struct verified_tag {} const verified{};
|
||||
|
||||
template <typename T>
|
||||
struct is_constructor : std::false_type {};
|
||||
struct is_non_factory_constructor : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_constructor<constructors<Args...>> : std::true_type {};
|
||||
struct is_non_factory_constructor<constructors<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_constructor<constructor_wrapper<Args...>> : std::true_type {};
|
||||
struct is_non_factory_constructor<constructor_wrapper<Args...>> : std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_non_factory_constructor<no_construction> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_constructor : is_non_factory_constructor<T> {};
|
||||
|
||||
template <typename... Args>
|
||||
struct is_constructor<factory_wrapper<Args...>> : std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_constructor<no_construction> : std::true_type {};
|
||||
|
||||
template <typename... 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>
|
||||
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);
|
||||
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>
|
||||
@ -10637,10 +10729,13 @@ namespace sol {
|
||||
lua_settop(L, 0);
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
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>
|
||||
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);
|
||||
@ -10747,14 +10842,31 @@ namespace sol {
|
||||
hint->second = std::move(o);
|
||||
}
|
||||
|
||||
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) {
|
||||
insert(std::forward<N>(n), make_object(L, as_function_reference(std::forward<F>(f))));
|
||||
template <typename N, typename F, typename... Args>
|
||||
void insert_prepare(std::true_type, lua_State* L, N&&, F&& f, Args&&... args) {
|
||||
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) {
|
||||
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) {
|
||||
callconstructfunc = std::move(o);
|
||||
return;
|
||||
@ -10762,6 +10874,11 @@ namespace sol {
|
||||
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>
|
||||
void add(lua_State* L, N&& n, 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>
|
||||
simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
|
||||
: 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>),
|
||||
indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
|
||||
baseclasscheck(nullptr), baseclasscast(nullptr),
|
||||
@ -11072,15 +11189,15 @@ namespace sol {
|
||||
stack::set_field(L, meta_function::index,
|
||||
make_closure(&usertype_detail::simple_index_call,
|
||||
make_light(varmap),
|
||||
&usertype_detail::simple_index_call,
|
||||
&usertype_detail::simple_metatable_newindex<T>,
|
||||
umx.indexfunc,
|
||||
umx.newindexfunc,
|
||||
usertype_detail::toplevel_magic
|
||||
), metabehind.stack_index());
|
||||
stack::set_field(L, meta_function::new_index,
|
||||
make_closure(&usertype_detail::simple_new_index_call,
|
||||
make_light(varmap),
|
||||
&usertype_detail::simple_index_call,
|
||||
&usertype_detail::simple_metatable_newindex<T>,
|
||||
umx.indexfunc,
|
||||
umx.newindexfunc,
|
||||
usertype_detail::toplevel_magic
|
||||
), metabehind.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());
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
~state() {
|
||||
auto& handler = protected_function::get_default_handler();
|
||||
if (handler.lua_state() == this->lua_state()) {
|
||||
protected_function::set_default_handler(reference());
|
||||
}
|
||||
}
|
||||
};
|
||||
} // sol
|
||||
|
||||
@ -13079,6 +13212,8 @@ namespace sol {
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined _MSC_VER
|
||||
#pragma warning( push )
|
||||
#endif // g++
|
||||
|
||||
#ifdef SOL_INSIDE_UNREAL
|
||||
|
@ -22,7 +22,8 @@ namespace
|
||||
// creates a default edge of unit weight
|
||||
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,
|
||||
to,
|
||||
1,
|
||||
@ -32,6 +33,7 @@ inline InputEdge MakeUnitEdge(const NodeID from, const NodeID to)
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
INVALID_LANE_DESCRIPTIONID};
|
||||
|
@ -1,11 +1,27 @@
|
||||
#ifndef OSRM_UNIT_TEST_ARGS
|
||||
#define OSRM_UNIT_TEST_ARGS
|
||||
|
||||
#include "util/log.hpp"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <iostream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
inline std::vector<std::string> get_args()
|
||||
{
|
||||
osrm::util::LogPolicy::GetInstance().Unmute();
|
||||
if ((boost::unit_test::framework::master_test_suite().argc != 2) ||
|
||||
(!boost::filesystem::is_regular_file(
|
||||
boost::unit_test::framework::master_test_suite().argv[1])))
|
||||
{
|
||||
osrm::util::Log(logERROR) << "Please provide valid input osrm file";
|
||||
osrm::util::Log(logERROR) << "Usage: "
|
||||
<< boost::unit_test::framework::master_test_suite().argv[0]
|
||||
<< " /path/to/input_osrm_file" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Split off argv[0], store actual positional arguments in args
|
||||
const auto argc = boost::unit_test::framework::master_test_suite().argc - 1;
|
||||
const auto argv = boost::unit_test::framework::master_test_suite().argv + 1;
|
||||
|
@ -387,4 +387,72 @@ BOOST_AUTO_TEST_CASE(test_route_user_disables_generating_hints)
|
||||
BOOST_CHECK_EQUAL(waypoint.get<json::Object>().values.count("hint"), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(speed_annotation_matches_duration_and_distance)
|
||||
{
|
||||
const auto args = get_args();
|
||||
auto osrm = getOSRM(args.at(0));
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
RouteParameters params;
|
||||
params.annotations_type = RouteParameters::AnnotationsType::Duration |
|
||||
RouteParameters::AnnotationsType::Distance |
|
||||
RouteParameters::AnnotationsType::Speed;
|
||||
params.coordinates.push_back(get_dummy_location());
|
||||
params.coordinates.push_back(get_dummy_location());
|
||||
|
||||
json::Object result;
|
||||
const auto rc = osrm.Route(params, result);
|
||||
BOOST_CHECK(rc == Status::Ok);
|
||||
|
||||
const auto &routes = result.values["routes"].get<json::Array>().values;
|
||||
const auto &legs = routes[0].get<json::Object>().values.at("legs").get<json::Array>().values;
|
||||
const auto &annotation =
|
||||
legs[0].get<json::Object>().values.at("annotation").get<json::Object>();
|
||||
const auto &speeds = annotation.values.at("speed").get<json::Array>().values;
|
||||
const auto &durations = annotation.values.at("duration").get<json::Array>().values;
|
||||
const auto &distances = annotation.values.at("distance").get<json::Array>().values;
|
||||
int length = speeds.size();
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
auto speed = speeds[i].get<json::Number>().value;
|
||||
auto duration = durations[i].get<json::Number>().value;
|
||||
auto distance = distances[i].get<json::Number>().value;
|
||||
BOOST_CHECK_EQUAL(speed, std::round(distance / duration * 10.) / 10.);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_manual_setting_of_annotations_property)
|
||||
{
|
||||
const auto args = get_args();
|
||||
auto osrm = getOSRM(args.at(0));
|
||||
|
||||
using namespace osrm;
|
||||
|
||||
RouteParameters params{};
|
||||
params.annotations = true;
|
||||
params.coordinates.push_back(get_dummy_location());
|
||||
params.coordinates.push_back(get_dummy_location());
|
||||
|
||||
json::Object result;
|
||||
const auto rc = osrm.Route(params, result);
|
||||
BOOST_CHECK(rc == Status::Ok);
|
||||
|
||||
const auto code = result.values.at("code").get<json::String>().value;
|
||||
BOOST_CHECK_EQUAL(code, "Ok");
|
||||
|
||||
auto annotations = result.values["routes"]
|
||||
.get<json::Array>()
|
||||
.values[0]
|
||||
.get<json::Object>()
|
||||
.values["legs"]
|
||||
.get<json::Array>()
|
||||
.values[0]
|
||||
.get<json::Object>()
|
||||
.values["annotation"]
|
||||
.get<json::Object>()
|
||||
.values;
|
||||
BOOST_CHECK_EQUAL(annotations.size(), 5);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(test_tile)
|
||||
const auto rc = osrm.Tile(params, result);
|
||||
BOOST_CHECK(rc == Status::Ok);
|
||||
|
||||
BOOST_CHECK_EQUAL(result.size(), 113824);
|
||||
BOOST_CHECK(result.size() > 115000);
|
||||
|
||||
protozero::pbf_reader tile_message(result);
|
||||
tile_message.next();
|
||||
@ -205,7 +205,7 @@ BOOST_AUTO_TEST_CASE(test_tile)
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(number_of_turn_keys, 3);
|
||||
BOOST_CHECK_EQUAL(number_of_turns_found, 732);
|
||||
BOOST_CHECK(number_of_turns_found > 700);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_tile_turns)
|
||||
|
@ -67,6 +67,7 @@ BOOST_AUTO_TEST_CASE(invalid_route_urls)
|
||||
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(std::string{"1,2;3,"} + '\0'), 6);
|
||||
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations=distances"), 28UL);
|
||||
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations="), 20UL);
|
||||
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?annotations=true,false"), 24UL);
|
||||
BOOST_CHECK_EQUAL(
|
||||
testInvalidOptions<RouteParameters>("1,2;3,4?annotations=&overview=simplified"), 20UL);
|
||||
|
||||
@ -349,6 +350,22 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
|
||||
true);
|
||||
BOOST_CHECK_EQUAL(result_15->annotations, true);
|
||||
|
||||
RouteParameters reference_speed{};
|
||||
reference_speed.annotations_type = RouteParameters::AnnotationsType::Duration;
|
||||
reference_speed.coordinates = coords_1;
|
||||
auto result_speed =
|
||||
parseParameters<RouteParameters>("1,2;3,4?geometries=polyline&"
|
||||
"overview=simplified&annotations=duration,distance,speed");
|
||||
BOOST_CHECK(result_speed);
|
||||
BOOST_CHECK_EQUAL(reference_speed.geometries, result_speed->geometries);
|
||||
BOOST_CHECK_EQUAL(reference_speed.overview, result_speed->overview);
|
||||
BOOST_CHECK_EQUAL(result_speed->annotations_type ==
|
||||
(RouteParameters::AnnotationsType::Duration |
|
||||
RouteParameters::AnnotationsType::Distance |
|
||||
RouteParameters::AnnotationsType::Speed),
|
||||
true);
|
||||
BOOST_CHECK_EQUAL(result_speed->annotations, true);
|
||||
|
||||
// parse multiple annotations correctly
|
||||
RouteParameters reference_16{};
|
||||
reference_16.annotations_type = RouteParameters::AnnotationsType::Duration |
|
||||
|
Loading…
Reference in New Issue
Block a user