This commit is contained in:
tombay 2024-10-03 06:47:14 +00:00 committed by GitHub
commit e1c3df8345
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
64 changed files with 7334 additions and 7 deletions

View File

@ -1,6 +1,7 @@
# Unreleased # Unreleased
- Changes from 5.27.1 - Changes from 5.27.1
- Features - Features
- ADDED: Routing profiles to support country differences [#7013](https://github.com/Project-OSRM/osrm-backend/pull/7013)
- ADDED: Route pedestrians over highway=platform [#6993](https://github.com/Project-OSRM/osrm-backend/pull/6993) - ADDED: Route pedestrians over highway=platform [#6993](https://github.com/Project-OSRM/osrm-backend/pull/6993)
- REMOVED: Remove all core-CH left-overs [#6920](https://github.com/Project-OSRM/osrm-backend/pull/6920) - REMOVED: Remove all core-CH left-overs [#6920](https://github.com/Project-OSRM/osrm-backend/pull/6920)
- ADDED: Add support for a keepalive_timeout flag. [#6674](https://github.com/Project-OSRM/osrm-backend/pull/6674) - ADDED: Add support for a keepalive_timeout flag. [#6674](https://github.com/Project-OSRM/osrm-backend/pull/6674)

View File

@ -375,3 +375,23 @@ There are a few helper functions defined in the global scope that profiles can u
- `trimLaneString` - `trimLaneString`
- `applyAccessTokens` - `applyAccessTokens`
- `canonicalizeStringList` - `canonicalizeStringList`
### Profiles for country differences
Some countries have differing access rules for different transport types. (https://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Access_restrictions). Profiles countrybicycle and countryfoot may be used as starting points for country support.
To enable support add 'countryspeeds' to the uselocationtags Set. e.g.
uselocationtags = Set
{
'countryspeeds',
}
Country Specific location data (geojson geometry) should be provided to the osrm-extract for example:
osrm-extract --profile ../profiles/countryfoot.lua --location-dependent-data ../data/allthecountries.geojson
osrm-extract --profile ../profiles/countrybicycle.lua --location-dependent-data ../mygeojson/Netherlands.geojson
If you enable the tag but provide no location-dependent-data, the profile will use the 'Worldwide' settings. (https://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Access_restrictions#Worldwide)
It is possible to to include multiple countries in the location data file through the use of a FeatureCollection.

View File

@ -0,0 +1,89 @@
@routing @bicycle @countrybikespeeds
Feature: Testbot - Country Profile Selection
# Check that country data is being selected
# CHE (a) does not support trunk on bike
# FIN (c) does not support trunk on bike
# GRC (m) and IRL (o) support bridleway
# LIU (s) is not a country in list so looks like worldwide
# so
# GRC (m) and LIU (s) support trunk
Scenario: Profile Selection - highway chosen for country
Given the extract extra arguments "--location-dependent-data test/data/countrytest.geojson"
And the partition extra arguments "--threads 1"
And the customize extra arguments "--threads 1"
And the profile file "bicycle" initialized with
"""
profile.uselocationtags.countryspeeds = true
"""
And the node locations
| node | lat | lon |
| a | 9.5 | 5.0 |
| b | 9.5 | 10.0 |
| c | 9.5 | 15.0 |
| d | 9.0 | 5.0 |
| e | 9.0 | 10.0 |
| f | 9.0 | 15.0 |
| g | 8.5 | 5.0 |
| h | 8.5 | 10.0 |
| i | 8.5 | 15.0 |
| j | 8.0 | 5.0 |
| k | 8.0 | 10.0 |
| l | 8.0 | 15.0 |
| m | 7.5 | 5.0 |
| n | 7.5 | 10.0 |
| o | 7.5 | 15.0 |
| p | 7.0 | 5.0 |
| q | 7.0 | 10.0 |
| r | 7.0 | 15.0 |
| s | 6.5 | 5.0 |
| t | 6.5 | 10.0 |
| u | 6.5 | 15.0 |
And the ways
| nodes | highway | comment
| ab | trunk | CHE - FIN no
| bc | trunk |
| cf | trunk | FIN - BEL no
| fi | trunk |
| fl | trunk |
| or | trunk | IRL - world yes
| ru | trunk |
| mn | bridleway | GRC - IRL yes
| no | bridleway |
| mp | trunk | GRC - liu yes
| ps | trunk |
And the partition extra arguments "--threads 1"
And the customize extra arguments "--threads 1"
When I route I should get
| waypoints | route | status | message |
| a,b,c | | 400 | Impossible route between points |
| c,l | | 400 | Impossible route between points |
| g,i | | 400 | Impossible route between points |
| o,u | or,ru,ru | 200 | |
| m,o | mn,no,no | 200 | |
| m,s | mp,ps,ps | 200 | |

View File

@ -0,0 +1,39 @@
@routing @bicycle @countrymotorroad
Feature: Testbot - Country motorroad Selection
# Check that motorroad is avoided
Scenario: bicycle Profile Selection - motorroad avoided
Given the extract extra arguments "--threads 1"
And the partition extra arguments "--threads 1"
And the customize extra arguments "--threads 1"
And the profile file "bicycle" initialized with
"""
profile.uselocationtags.countryspeeds = true
"""
And the node locations
| node | lat | lon |
| a | 9.5 | 5.0 |
| b | 9.5 | 10.0 |
| c | 9.5 | 15.0 |
| d | 9.0 | 5.0 |
| e | 9.0 | 10.0 |
| f | 9.0 | 15.0 |
And the ways
| nodes | highway | motorroad |
| ab | trunk | yes |
| bc | trunk | |
| ad | trunk | |
| de | trunk | |
| ef | trunk | |
| cf | trunk | |
When I route I should get
| waypoints | route | status | message |
| a,c | ad,de,ef,cf,cf | 200 | |
| a,b | ad,de,ef,cf,bc,bc | 200 | |

View File

@ -0,0 +1,42 @@
@routing @foot @countryway
Feature: bicycle - Accessability of different way types with countryspeeds
Background:
Given the profile file "bicycle" initialized with
"""
profile.uselocationtags.countryspeeds = true
"""
Scenario: Countrybicycle - Basic access
Then routability should be
| highway | forw |
| motorway | |
| motorway_link | |
| trunk | x |
| trunk_link | x |
| primary | x |
| primary_link | x |
| secondary | x |
| secondary_link | x |
| tertiary | x |
| tertiary_link | x |
| residential | x |
| service | x |
| unclassified | x |
| living_street | x |
| road | x |
| track | x |
| path | x |
| footway | x |
| pedestrian | x |
| steps | x |
| pier | x |
| cycleway | x |
| bridleway | |
Scenario: Country bicycle - Routability of man_made structures
Then routability should be
| highway | man_made | bothw |
| (nil) | (nil) | |
| (nil) | pier | x |

View File

@ -0,0 +1,186 @@
@routing @countrybicycle @access
Feature: Bike - Access tags on ways
# Reference: http://wiki.openstreetmap.org/wiki/Key:access
Background:
Given the profile "countrybicycle"
Scenario: Bike - Access tag hierarchy on ways
Then routability should be
| highway | access | vehicle | bicycle | bothw |
| primary | | | | cycling |
| primary | yes | | | cycling |
| primary | no | | | |
| primary | | yes | | cycling |
| primary | | no | | |
| primary | no | yes | | cycling |
| primary | yes | no | | |
| primary | | | yes | cycling |
| primary | | | no | |
| primary | no | | yes | cycling |
| primary | yes | | no | |
| primary | | no | yes | cycling |
| primary | | yes | no | |
@todo
Scenario: Bike - Access tag in forward direction
Then routability should be
| highway | access:forward | vehicle:forward | bicycle:forward | forw | backw |
| primary | | | | cycling | |
| primary | yes | | | cycling | |
| primary | no | | | | |
| primary | | yes | | cycling | |
| primary | | no | | | |
| primary | no | yes | | cycling | |
| primary | yes | no | | | |
| primary | | | yes | cycling | |
| primary | | | no | | |
| primary | no | | yes | cycling | |
| primary | yes | | no | | |
| primary | | no | yes | cycling | |
| primary | | yes | no | | |
| runway | | | | cycling | |
| runway | yes | | | cycling | |
| runway | no | | | | |
| runway | | yes | | cycling | |
| runway | | no | | | |
| runway | no | yes | | cycling | |
| runway | yes | no | | | |
| runway | | | yes | cycling | |
| runway | | | no | | |
| runway | no | | yes | cycling | |
| runway | yes | | no | | |
| runway | | no | yes | cycling | |
| runway | | yes | no | | |
@todo
Scenario: Bike - Access tag in backward direction
Then routability should be
| highway | access:forward | vehicle:forward | bicycle:forward | forw | backw |
| primary | | | | | cycling |
| primary | yes | | | | cycling |
| primary | no | | | | |
| primary | | yes | | | cycling |
| primary | | no | | | |
| primary | no | yes | | | cycling |
| primary | yes | no | | | |
| primary | | | yes | | cycling |
| primary | | | no | | |
| primary | no | | yes | | cycling |
| primary | yes | | no | | |
| primary | | no | yes | | cycling |
| primary | | yes | no | | |
| runway | | | | | cycling |
| runway | yes | | | | cycling |
| runway | no | | | | |
| runway | | yes | | | cycling |
| runway | | no | | | |
| runway | no | yes | | | cycling |
| runway | yes | no | | | |
| runway | | | yes | | cycling |
| runway | | | no | | |
| runway | no | | yes | | cycling |
| runway | yes | | no | | |
| runway | | no | yes | | cycling |
| runway | | yes | no | | |
Scenario: Bike - Overwriting implied acccess on ways
Then routability should be
| highway | access | vehicle | bicycle | bothw |
| cycleway | | | | cycling |
| runway | | | | |
| cycleway | no | | | |
| cycleway | | no | | |
| cycleway | | | no | |
| runway | yes | | | cycling |
| runway | | yes | | cycling |
| runway | | | yes | cycling |
Scenario: Bike - Access tags on ways
Then routability should be
| access | vehicle | bicycle | bothw |
| | | | cycling |
| yes | | | cycling |
| permissive | | | cycling |
| designated | | | cycling |
| some_tag | | | cycling |
| no | | | |
| private | | | |
| agricultural | | | |
| forestry | | | |
| delivery | | | |
| | yes | | cycling |
| | permissive | | cycling |
| | designated | | cycling |
| | some_tag | | cycling |
| | no | | |
| | private | | |
| | agricultural | | |
| | forestry | | |
| | delivery | | |
| | | yes | cycling |
| | | permissive | cycling |
| | | designated | cycling |
| | | some_tag | cycling |
| | | no | |
| | | private | |
| | | agricultural | |
| | | forestry | |
| | | delivery | |
| | | use_sidepath | |
Scenario: Bike - Access tags on both node and way
Then routability should be
| access | node/access | bothw |
| yes | yes | cycling |
| yes | no | |
| yes | some_tag | cycling |
| no | yes | |
| no | no | |
| no | some_tag | |
| some_tag | yes | cycling |
| some_tag | no | |
| some_tag | some_tag | cycling |
Scenario: Bike - Access combinations
Then routability should be
| highway | access | vehicle | bicycle | forw | backw |
| runway | private | | yes | cycling | cycling |
| footway | | no | permissive | cycling | cycling |
| motorway | | | yes | cycling | |
| track | forestry | | permissive | cycling | cycling |
| cycleway | yes | designated | no | | |
| primary | | yes | private | | |
| residential | permissive | | no | | |
Scenario: Bike - Ignore access tags for other modes
Then routability should be
| highway | boat | motor_vehicle | moped | bothw |
| river | yes | | | |
| cycleway | no | | | cycling |
| runway | | yes | | |
| cycleway | | no | | cycling |
| runway | | | yes | |
| cycleway | | | no | cycling |
Scenario: Bike - Bridleways when access is explicit
Then routability should be
| highway | horse | foot | bicycle | bothw |
| bridleway | | | yes | cycling |
| bridleway | | yes | | pushing bike |
| bridleway | designated | | | |
| bridleway | | | | |
Scenario: Bike - Tram with oneway when access is implicit
Then routability should be
| highway | railway | access | oneway | forw | backw |
| residential | tram | | yes | cycling | pushing bike |
| service | tram | psv | yes | cycling | pushing bike |
Scenario: Bike - Access combinations
Then routability should be
| highway | access | bothw |
| primary | permissive | cycling |
| steps | permissive | cycling |
| footway | permissive | cycling |
| garbagetag | permissive | cycling |

View File

@ -0,0 +1,68 @@
@routing @countrybicycle @access
Feature: Bike - Access tags on nodes
# Reference: http://wiki.openstreetmap.org/wiki/Key:access
Background:
Given the profile "countrybicycle"
Scenario: Bike - Access tag hierarchy on nodes
Then routability should be
| node/access | node/vehicle | node/bicycle | node/highway | bothw |
| | | | | cycling |
| yes | | | | cycling |
| no | | | | |
| | yes | | | cycling |
| | no | | | |
| no | yes | | | cycling |
| yes | no | | | |
| | | yes | | cycling |
| | | no | | |
| | | no | crossing | cycling |
| no | | yes | | cycling |
| yes | | no | | |
| | no | yes | | cycling |
| | yes | no | | |
Scenario: Bike - Overwriting implied acccess on nodes doesn't overwrite way
Then routability should be
| highway | node/access | node/vehicle | node/bicycle | bothw |
| cycleway | | | | cycling |
| runway | | | | |
| cycleway | no | | | |
| cycleway | | no | | |
| cycleway | | | no | |
| runway | yes | | | |
| runway | | yes | | |
| runway | | | yes | |
Scenario: Bike - Access tags on nodes
Then routability should be
| node/access | node/vehicle | node/bicycle | bothw |
| | | | cycling |
| yes | | | cycling |
| permissive | | | cycling |
| designated | | | cycling |
| some_tag | | | cycling |
| no | | | |
| private | | | |
| agricultural | | | |
| forestry | | | |
| delivery | | | |
| | yes | | cycling |
| | permissive | | cycling |
| | designated | | cycling |
| | some_tag | | cycling |
| | no | | |
| | private | | |
| | agricultural | | |
| | forestry | | |
| | delivery | | |
| | | yes | cycling |
| | | permissive | cycling |
| | | designated | cycling |
| | | some_tag | cycling |
| | | no | |
| | | private | |
| | | agricultural | |
| | | forestry | |
| | | delivery | |

View File

@ -0,0 +1,34 @@
@routing @countrybicycle @alley
Feature: Bicycle - Route around alleys
Background:
Given the profile file "countrybicycle" initialized with
"""
profile.properties.weight_name = 'cyclability'
"""
Scenario: Bicycle - Avoid taking alleys
Given the query options
| annotations | nodes |
Given the node map
"""
a-----b-----c
| : |
d.....e.....f
"""
And the ways
| nodes | highway | service |
| abc | residential | |
| def | service | alley |
| ad | residential | |
| be | service | alley |
| cf | residential | |
When I route I should get
| from | to | a:nodes | weight | # |
| a | f | 1:2:3:6 | 196.2 | Avoids d,e,f |
| a | e | 1:2:5 | 172.2 | Take the alley b,e if neccessary |
| d | f | 4:1:2:3:6 | 248.4 | Avoids the alley d,e,f |

View File

@ -0,0 +1,112 @@
@routing @countrybicycle @area
Feature: Bike - Squares and other areas
Background:
Given the profile "countrybicycle"
@square
Scenario: Bike - Route along edge of a squares
Given the node map
"""
x
a b
d c
"""
And the ways
| nodes | area | highway |
| xa | | primary |
| abcda | yes | residential |
When I route I should get
| from | to | route |
| a | b | abcda,abcda |
| a | d | abcda,abcda |
| b | c | abcda,abcda |
| c | b | abcda,abcda |
| c | d | abcda,abcda |
| d | c | abcda,abcda |
| d | a | abcda,abcda |
| a | d | abcda,abcda |
@building
Scenario: Bike - Don't route on buildings
Given the node map
"""
x
a b
d c
"""
And the ways
| nodes | highway | area | building | access |
| xa | primary | | | |
| abcda | (nil) | yes | yes | yes |
When I route I should get
| from | to | route |
| a | b | xa,xa |
| a | d | xa,xa |
| b | c | xa,xa |
| c | b | xa,xa |
| c | d | xa,xa |
| d | c | xa,xa |
| d | a | xa,xa |
| a | d | xa,xa |
@parking
Scenario: Bike - parking areas
Given the node map
"""
e f
x a b y
d c
"""
And the ways
| nodes | highway | amenity |
| xa | primary | |
| by | primary | |
| xefy | primary | |
| abcda | (nil) | parking |
When I route I should get
| from | to | route |
| x | y | xa,abcda,by |
| y | x | by,abcda,xa |
| a | b | abcda,abcda |
| a | d | abcda,abcda |
| b | c | abcda,abcda |
| c | b | abcda,abcda |
| c | d | abcda,abcda |
| d | c | abcda,abcda |
| d | a | abcda,abcda |
| a | d | abcda,abcda |
@train @platform
Scenario: Bike - railway platforms
Given the node map
"""
x a b y
d c
"""
And the ways
| nodes | highway | railway |
| xa | primary | |
| by | primary | |
| abcda | (nil) | platform |
When I route I should get
| from | to | route |
| x | y | xa,abcda,by |
| y | x | by,abcda,xa |
| a | b | abcda,abcda |
| a | d | abcda,abcda |
| b | c | abcda,abcda |
| c | b | abcda,abcda |
| c | d | abcda,abcda |
| d | c | abcda,abcda |
| d | a | abcda,abcda |
| a | d | abcda,abcda |

View File

@ -0,0 +1,41 @@
@routing @countrybicycle @barrier
Feature: Barriers
Background:
Given the profile "countrybicycle"
Scenario: Bike - Barriers
Then routability should be
| node/barrier | bothw |
| | x |
| bollard | x |
| gate | x |
| lift_gate | x |
| cycle_barrier | x |
| cattle_grid | x |
| border_control | x |
| toll_booth | x |
| sally_port | x |
| entrance | x |
| wall | |
| fence | |
| some_tag | x |
| block | x |
Scenario: Bike - Access tag trumphs barriers
Then routability should be
| node/barrier | node/access | bothw |
| bollard | | x |
| bollard | yes | x |
| bollard | permissive | x |
| bollard | designated | x |
| bollard | no | |
| bollard | private | |
| bollard | agricultural | |
| wall | | |
| wall | yes | x |
| wall | permissive | x |
| wall | designated | x |
| wall | no | |
| wall | private | |
| wall | agricultural | |

View File

@ -0,0 +1,44 @@
@routing @countrybicycle @bridge
Feature: Bicycle - Handle cycling
Background:
Given the profile "bicycle"
Scenario: Bicycle - Use a movable bridge
Given the node map
"""
a b c
d
e f g
"""
And the ways
| nodes | highway | bridge | bicycle |
| abc | primary | | |
| cde | | movable | yes |
| efg | primary | | |
When I route I should get
| from | to | route | modes |
| a | g | abc,cde,efg,efg | cycling,cycling,cycling,cycling |
Scenario: Bicycle - Properly handle durations
Given the node map
"""
a b c
d
e f g
"""
And the ways
| nodes | highway | bridge | duration |
| abc | primary | | |
| cde | | movable | 00:05:00 |
| efg | primary | | |
When I route I should get
| from | to | route | modes | speed |
| a | g | abc,cde,efg,efg | cycling,cycling,cycling,cycling | 6 km/h |
| b | f | abc,cde,efg,efg | cycling,cycling,cycling,cycling | 5 km/h |
| c | e | cde,cde | cycling,cycling | 2 km/h |
| e | c | cde,cde | cycling,cycling | 2 km/h |

View File

@ -0,0 +1,92 @@
@routing @countrybicycle @mode
Feature: Bicycle - Mode flag
Background:
Given the profile "bicycle"
Scenario: Bicycle - We tag ferries with a class
Given the node map
"""
a b
c d
"""
And the ways
| nodes | highway | route |
| ab | primary | |
| bc | | ferry |
| cd | primary | |
When I route I should get
| from | to | route | turns | classes |
| a | d | ab,bc,cd,cd | depart,notification right,notification left,arrive | [()],[(ferry)],[()],[()] |
| d | a | cd,bc,ab,ab | depart,notification right,notification left,arrive | [()],[(ferry)],[()],[()] |
| c | a | bc,ab,ab | depart,notification left,arrive | [(ferry)],[()],[()] |
| d | b | cd,bc,bc | depart,notification right,arrive | [()],[(ferry)],[()] |
| a | c | ab,bc,bc | depart,notification right,arrive | [()],[(ferry)],[()] |
| b | d | bc,cd,cd | depart,notification left,arrive | [(ferry)],[()],[()] |
Scenario: Bicycle - We tag tunnel with a class
Background:
Given a grid size of 200 meters
Given the node map
"""
a b
c d
"""
And the ways
| nodes | tunnel |
| ab | no |
| bc | yes |
| cd | |
When I route I should get
| from | to | route | turns | classes |
| a | d | ab,bc,cd,cd | depart,new name right,new name left,arrive | [()],[(tunnel)],[()],[()] |
Scenario: Bicycle - We tag classes without intersections
Background:
Given a grid size of 200 meters
Given the node map
"""
a b c d
"""
And the ways
| nodes | name | tunnel |
| ab | road | |
| bc | road | yes |
| cd | road | |
When I route I should get
| from | to | route | turns | classes |
| a | d | road,road | depart,arrive | [(),(tunnel),()],[()] |
Scenario: Bicycle - From roundabout on ferry
Given the node map
"""
c
/ \
a---b d---f--h
\ /
e
|
g
"""
And the ways
| nodes | oneway | highway | junction | route |
| ab | yes | service | | |
| cb | yes | service | roundabout | |
| dc | yes | service | roundabout | |
| be | yes | service | roundabout | |
| ed | yes | service | roundabout | |
| eg | yes | service | | |
| df | | | | ferry |
| fh | yes | service | | |
When I route I should get
| from | to | route | turns | classes |
| a | h | ab,df,df,fh,fh | depart,roundabout-exit-2,exit roundabout slight right,notification straight,arrive | [()],[(),()],[(ferry)],[()],[()] |

View File

@ -0,0 +1,89 @@
@routing @countryfoot @countrybikespeeds
Feature: Testbot - Country Profile Selection
# Check that country data is being selected
# CHE (a) does not support trunk on bike
# FIN (c) does not support trunk on bike
# GRC (m) and IRL (o) support bridleway
# LIU (s) is not a country in list so looks like worldwide
# so
# GRC (m) and LIU (s) support trunk
Scenario: Country Profile Selection - highway chosen for country
Given the extract extra arguments "--location-dependent-data test/data/countrytest.geojson"
And the partition extra arguments "--threads 1"
And the customize extra arguments "--threads 1"
And the profile file "countrybicycle" initialized with
"""
profile.uselocationtags.countryspeeds = true
"""
And the node locations
| node | lat | lon |
| a | 9.5 | 5.0 |
| b | 9.5 | 10.0 |
| c | 9.5 | 15.0 |
| d | 9.0 | 5.0 |
| e | 9.0 | 10.0 |
| f | 9.0 | 15.0 |
| g | 8.5 | 5.0 |
| h | 8.5 | 10.0 |
| i | 8.5 | 15.0 |
| j | 8.0 | 5.0 |
| k | 8.0 | 10.0 |
| l | 8.0 | 15.0 |
| m | 7.5 | 5.0 |
| n | 7.5 | 10.0 |
| o | 7.5 | 15.0 |
| p | 7.0 | 5.0 |
| q | 7.0 | 10.0 |
| r | 7.0 | 15.0 |
| s | 6.5 | 5.0 |
| t | 6.5 | 10.0 |
| u | 6.5 | 15.0 |
And the ways
| nodes | highway | comment
| ab | trunk | CHE - FIN no
| bc | trunk |
| cf | trunk | FIN - BEL no
| fi | trunk |
| fl | trunk |
| or | trunk | IRL - world yes
| ru | trunk |
| mn | bridleway | GRC - IRL yes
| no | bridleway |
| mp | trunk | GRC - liu yes
| ps | trunk |
And the partition extra arguments "--threads 1"
And the customize extra arguments "--threads 1"
When I route I should get
| waypoints | route | status | message |
| a,b,c | | 400 | Impossible route between points |
| c,l | | 400 | Impossible route between points |
| g,i | | 400 | Impossible route between points |
| o,u | or,ru,ru | 200 | |
| m,o | mn,no,no | 200 | |
| m,s | mp,ps,ps | 200 | |

View File

@ -0,0 +1,156 @@
@routing @countrybicycle @countryoneway
Feature: Bike - Oneway streets
# Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing
# Usually we can push bikes against oneways, but we use foot=no to prevent this in these tests
Background:
Given the profile file "countrybicycle" initialized with
"""
profile.uselocationtags.countryspeeds = true
"""
Scenario: Bike - Simple oneway
Then routability should be
| highway | foot | oneway | forw | backw |
| primary | no | yes | cycling | |
| primary | | yes | cycling | pushing bike |
Scenario: Simple reverse oneway
Then routability should be
| highway | foot | oneway | forw | backw |
| primary | no | -1 | | cycling |
| primary | | -1 | pushing bike | cycling |
Scenario: Bike - Around the Block
Given the node map
"""
a b
f d c e
"""
And the ways
| nodes | oneway | foot |
| ab | yes | no |
| bc | | no |
| cd | | no |
| da | | no |
| df | | no |
| ce | | no |
When I route I should get
| from | to | route |
| a | b | ab,ab |
| b | a | bc,cd,da,da |
Scenario: Bike - Handle various oneway tag values
Then routability should be
| foot | oneway | forw | backw |
| no | | cycling | cycling |
| no | nonsense | cycling | cycling |
| no | no | cycling | cycling |
| no | false | cycling | cycling |
| no | 0 | cycling | cycling |
| no | yes | cycling | |
| no | true | cycling | |
| no | 1 | cycling | |
| no | -1 | | cycling |
Scenario: Bike - Implied oneways no motorway
Then routability should be
| highway | foot | bicycle | junction | forw | backw | # |
| | no | | | cycling | cycling | |
| | no | | roundabout | cycling | | |
| motorway | no | no | | | | |
| motorway_link | no | no | | | | |
| motorway | no | no | roundabout | | | |
| motorway_link | no | no | roundabout | | | |
Scenario: Bike - Overriding implied oneways
Then routability should be
| highway | foot | junction | oneway | forw | backw |
| primary | no | roundabout | no | cycling | cycling |
| primary | no | roundabout | yes | cycling | |
| motorway_link | no | | -1 | | |
| trunk | no | | -1 | | cycling |
| trunk_link | no | | -1 | | cycling |
| primary | no | roundabout | -1 | | cycling |
Scenario: Bike - Oneway:bicycle should override normal oneways tags
Then routability should be
| foot | oneway:bicycle | oneway | junction | forw | backw |
| no | yes | | | cycling | |
| no | yes | yes | | cycling | |
| no | yes | no | | cycling | |
| no | yes | -1 | | cycling | |
| no | yes | | roundabout | cycling | |
| no | no | | | cycling | cycling |
| no | no | yes | | cycling | cycling |
| no | no | no | | cycling | cycling |
| no | no | -1 | | cycling | cycling |
| no | no | | roundabout | cycling | cycling |
| no | -1 | | | | cycling |
| no | -1 | yes | | | cycling |
| no | -1 | no | | | cycling |
| no | -1 | -1 | | | cycling |
| no | -1 | | roundabout | | cycling |
Scenario: Bike - Contra flow
Then routability should be
| foot | oneway | cycleway | forw | backw |
| no | yes | opposite | cycling | cycling |
| no | yes | opposite_track | cycling | cycling |
| no | yes | opposite_lane | cycling | cycling |
| no | -1 | opposite | cycling | cycling |
| no | -1 | opposite_track | cycling | cycling |
| no | -1 | opposite_lane | cycling | cycling |
| no | no | opposite | cycling | cycling |
| no | no | opposite_track | cycling | cycling |
| no | no | opposite_lane | cycling | cycling |
Scenario: Bike - Should not be affected by car tags
Then routability should be
| foot | junction | oneway | oneway:car | forw | backw |
| no | | yes | yes | cycling | |
| no | | yes | no | cycling | |
| no | | yes | -1 | cycling | |
| no | | no | yes | cycling | cycling |
| no | | no | no | cycling | cycling |
| no | | no | -1 | cycling | cycling |
| no | | -1 | yes | | cycling |
| no | | -1 | no | | cycling |
| no | | -1 | -1 | | cycling |
| no | roundabout | | yes | cycling | |
| no | roundabout | | no | cycling | |
| no | roundabout | | -1 | cycling | |
Scenario: Bike - Two consecutive oneways
Given the node map
"""
a b c
"""
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
When I route I should get
| from | to | route |
| a | c | ab,bc,bc |
Scenario: Bike - Left/right cycleways on oneways
Then routability should be
| highway | oneway | cycleway:left | cycleway:right | forw | backw |
| primary | yes | | | cycling | pushing bike |
| primary | yes | | track | cycling | pushing bike |
| primary | yes | track | | cycling | pushing bike |
| primary | yes | track | track | cycling | pushing bike |
Scenario: Bike - Left/right cycleways on any oneways
Then routability should be
| foot | oneway | cycleway:left | cycleway:right | forw | backw |
| no | yes | track | | cycling | |
| yes | yes | track | | cycling | pushing bike |
| yes | -1 | track | | pushing bike | cycling |

View File

@ -0,0 +1,99 @@
@routing @countrybicycle @cycleway
Feature: Bike - Cycle tracks/lanes
# Reference: http://wiki.openstreetmap.org/wiki/Key:cycleway
Background:
Given the profile "bicycle"
Scenario: Bike - Cycle tracks/lanes should enable biking
Then routability should be
| highway | cycleway | forw | backw |
| motorway | | | |
| motorway | track | x | |
| motorway | lane | x | |
| motorway | shared | x | |
| motorway | share_busway | x | |
| motorway | sharrow | x | |
| some_tag | track | x | x |
| some_tag | lane | x | x |
| some_tag | shared | x | x |
| some_tag | share_busway | x | x |
| some_tag | sharrow | x | x |
| residential | track | x | x |
| residential | lane | x | x |
| residential | shared | x | x |
| residential | share_busway | x | x |
| residential | sharrow | x | x |
Scenario: Bike - Left/right side cycleways on implied bidirectionals
Then routability should be
| highway | cycleway | cycleway:left | cycleway:right | forw | backw |
| primary | | | | x | x |
| primary | track | | | x | x |
| primary | opposite | | | x | x |
| primary | | track | | x | x |
| primary | | opposite | | x | x |
| primary | | | track | x | x |
| primary | | | opposite | x | x |
| primary | | track | track | x | x |
| primary | | opposite | opposite | x | x |
| primary | | track | opposite | x | x |
| primary | | opposite | track | x | x |
Scenario: Bike - Left/right side cycleways on implied oneways
Then routability should be
| highway | cycleway | cycleway:left | cycleway:right | forw | backw |
| primary | | | | x | x |
| motorway | | | | | |
| motorway | track | | | x | |
| motorway | opposite | | | x | x |
| motorway | | track | | x | |
| motorway | | opposite | | x | x |
| motorway | | | track | x | |
| motorway | | | opposite | x | x |
# motorways are implicit oneways and cycleway tracks next to oneways always
# follow the oneway direction (unless tagged as opposite)
| motorway | | track | track | x | |
| motorway | | opposite | opposite | x | x |
| motorway | | track | opposite | x | x |
| motorway | | opposite | track | x | x |
Scenario: Bike - Invalid cycleway tags
Then routability should be
| highway | cycleway | bothw |
| primary | | x |
| primary | yes | x |
| primary | no | x |
| primary | some_track | x |
| motorway | | |
| motorway | yes | |
| motorway | no | |
| motorway | some_track | |
Scenario: Bike - Access tags should overwrite cycleway access
Then routability should be
| highway | cycleway | access | forw | backw |
| motorway | track | no | | |
| residential | track | no | | |
| footway | track | no | | |
| cycleway | track | no | | |
| motorway | lane | yes | x | |
| residential | lane | yes | x | x |
| footway | lane | yes | x | x |
| cycleway | lane | yes | x | x |
Scenario: Bike - Cycleway on oneways, modes
Then routability should be
| highway | cycleway | oneway | forw | backw |
| motorway | track | yes | cycling | |
| residential | track | yes | cycling | pushing bike |
| cycleway | track | yes | cycling | pushing bike |
| footway | track | yes | cycling | pushing bike |
Scenario: Bike - Cycleway on oneways, speeds
Then routability should be
| highway | cycleway | oneway | forw | backw |
| motorway | track | yes | 15 km/h | |
| residential | track | yes | 15 km/h | 4 km/h +-1 |
| cycleway | track | yes | 15 km/h | 4 km/h +-1 |
| footway | track | yes | 15 km/h | 4 km/h +-1 |

View File

@ -0,0 +1,83 @@
@routing @countrybicycle @destination @todo
Feature: Bike - Destination only, no passing through
Background:
Given the profile "bicycle"
Scenario: Bike - Destination only street
Given the node map
"""
a e
b c d
x y
"""
And the ways
| nodes | access |
| ab | |
| bcd | destination |
| de | |
| axye | |
When I route I should get
| from | to | route |
| a | b | ab,ab |
| a | c | ab,bcd |
| a | d | ab,bcd |
| a | e | axye,axye |
| e | d | de,de |
| e | c | de,bcd |
| e | b | de,bcd |
| e | a | axye,axye |
Scenario: Bike - Destination only street
Given the node map
"""
a e
b c d
x y
"""
And the ways
| nodes | access |
| ab | |
| bc | destination |
| cd | destination |
| de | |
| axye | |
When I route I should get
| from | to | route |
| a | b | ab,ab |
| a | c | ab,bc |
| a | d | ab,bc,cd |
| a | e | axye,axye |
| e | d | de,de |
| e | c | de,cd,cd |
| e | b | de,cd,bc |
| e | a | axye,axye |
Scenario: Bike - Routing inside a destination only area
Given the node map
"""
a c e
b d
x y
"""
And the ways
| nodes | access |
| ab | destination |
| bc | destination |
| cd | destination |
| de | destination |
| axye | |
When I route I should get
| from | to | route |
| a | e | ab,bc,cd,de |
| e | a | de,cd,bc,ab |
| b | d | bc,cd |
| d | b | cd,bc |

View File

@ -0,0 +1,35 @@
@routing @countrybicycle
Feature: Bike - Use distance weight
Background:
Given a grid size of 200 meters
Scenario: Bike - Check distance weight
Given the profile file
"""
local functions = require('bicycle')
functions.setup_testbot = functions.setup
functions.setup = function()
local profile = functions.setup_testbot()
profile.properties.weight_name = 'distance'
return profile
end
return functions
"""
Given the node map
"""
a-b-c
"""
And the ways
| nodes | highway |
| abc | residential |
When I route I should get
| from | to | route | weight | time | distance |
| a | b | abc,abc | 200 | 48s | 200m +-1 |
| a | c | abc,abc | 400 | 96s | 400m +-1 |

View File

@ -0,0 +1,55 @@
@routing @countrybicycle @exclude
Feature: Bicycle - Exclude flags
Background:
Given the profile file "countrybicycle" initialized with
"""
profile.excludable = Sequence { Set { 'ferry' } }
"""
Given the node map
"""
a....b~~~~~c...f
: :
d.....e
"""
And the ways
| nodes | highway | route | duration | # |
| ab | service | | | always drivable |
| bc | | ferry | 00:00:01 | not drivable for exclude=ferry, but fast. |
| bd | service | | | always drivable |
| de | service | | | always drivable |
| ec | service | | | always drivable |
| cf | service | | | always drivable |
Scenario: Bicycle - exclude nothing
When I route I should get
| from | to | route |
| a | f | ab,bc,cf,cf |
When I match I should get
| trace | matchings | duration |
| abcf | abcf | 109 |
When I request a travel time matrix I should get
| | a | f |
| a | 0 | 109 |
| f | 109 | 0 |
Scenario: Bicycle - exclude ferry
Given the query options
| exclude | ferry |
When I route I should get
| from | to | route |
| a | f | ab,bd,de,ec,cf,cf |
When I match I should get
| trace | matchings | duration |
| abcf | abcf | 301 |
When I request a travel time matrix I should get
| | a | f |
| a | 0 | 301 +- 1 |
| f | 301.2 +- 1 | 0 |

View File

@ -0,0 +1,63 @@
@routing @countrybicycle @ferry
Feature: Bike - Handle ferry routes
Background:
Given the profile "countrybicycle"
Scenario: Bike - Ferry route
Given the node map
"""
a b c
d
e f g
"""
And the ways
| nodes | highway | route | bicycle |
| abc | primary | | |
| cde | | ferry | yes |
| efg | primary | | |
When I route I should get
| from | to | route |
| a | g | abc,cde,efg,efg |
| c | e | cde,cde |
| c | g | cde,efg,efg |
Scenario: Bike - Ferry duration, single node
Given the node map
"""
a b c d
e f
g h
i j
"""
And the ways
| nodes | highway | route | bicycle | duration |
| ab | primary | | | |
| cd | primary | | | |
| ef | primary | | | |
| gh | primary | | | |
| ij | primary | | | |
| bc | | ferry | yes | 0:01 |
| be | | ferry | yes | 0:10 |
| bg | | ferry | yes | 1:00 |
| bi | | ferry | yes | 10:00 |
Scenario: Bike - Ferry duration, multiple nodes
Given the node map
"""
x a b c d y
"""
And the ways
| nodes | highway | route | bicycle | duration |
| xa | primary | | | |
| yd | primary | | | |
| abcd | | ferry | yes | 1:00 |
When I route I should get
| from | to | route | time |
| a | d | abcd,abcd | 3600s |
| d | a | abcd,abcd | 3600s |

View File

@ -0,0 +1,90 @@
@routing @maxspeed @countrybicycle
Feature: Bike - Max speed restrictions
Background: Use specific speeds
Given the profile "countrybicycle"
And a grid size of 1000 meters
Scenario: Bicycle - Respect maxspeeds when lower that way type speed
Then routability should be
| highway | maxspeed | bothw |
| residential | | 15 km/h |
| residential | 10 | 10 km/h |
Scenario: Bicycle - Ignore maxspeed when higher than way speed
Then routability should be
| highway | maxspeed | bothw |
| residential | | 15 km/h |
| residential | 80 | 15 km/h |
@todo
Scenario: Bicycle - Maxspeed formats
Then routability should be
| highway | maxspeed | bothw |
| residential | | 49s ~10% |
| residential | 5 | 144s ~10% |
| residential | 5mph | 90s ~10% |
| residential | 5 mph | 90s ~10% |
| residential | 5MPH | 90s ~10% |
| residential | 5 MPH | 90s ~10% |
| trunk | 5unknown | 49s ~10% |
| trunk | 5 unknown | 49s ~10% |
@todo
Scenario: Bicycle - Maxspeed special tags
Then routability should be
| highway | maxspeed | bothw |
| residential | | 49s ~10% |
| residential | none | 49s ~10% |
| residential | signals | 49s ~10% |
Scenario: Bike - Do not use maxspeed when higher that way type speed
Given the node map
"""
a b c
"""
And the ways
| nodes | highway | maxspeed |
| ab | residential | |
| bc | residential | 80 |
When I route I should get
| from | to | route | speed |
| a | b | ab,ab | 15 km/h |
| b | c | bc,bc | 15 km/h |
Scenario: Bike - Forward/backward maxspeed
Given the shortcuts
| key | value |
| bike | 49s ~10% |
| run | 73s ~10% |
| walk | 145s ~10% |
| snail | 720s ~10% |
Then routability should be
| maxspeed | maxspeed:forward | maxspeed:backward | forw | backw |
| | | | 15 km/h | 15 km/h |
| 10 | | | 10 km/h | 10 km/h |
| | 10 | | 10 km/h | 15 km/h |
| | | 10 | 15 km/h | 10 km/h |
| 2 | 10 | | 10 km/h | 2 km/h |
| 2 | | 10 | 2 km/h | 10 km/h |
| 2 | 5 | 10 | 5 km/h | 10 km/h |
Scenario: Bike - Maxspeed should not allow routing on unroutable ways
Then routability should be
| highway | railway | access | maxspeed | maxspeed:forward | maxspeed:backward | bothw |
| primary | | | | | | x |
| secondary | | no | | | | |
| secondary | | no | 100 | | | |
| secondary | | no | | 100 | | |
| secondary | | no | | | 100 | |
| (nil) | train | | | | | |
| (nil) | train | | 100 | | | |
| (nil) | train | | | 100 | | |
| (nil) | train | | | | 100 | |
| runway | | | | | | |
| runway | | | 100 | | | |
| runway | | | | 100 | | |
| runway | | | | | 100 | |

View File

@ -0,0 +1,97 @@
@routing @countrybicycle @mode
Feature: Bike - Mode flag
Background:
Given the profile "countrybicycle"
Scenario: Bike - Mode when using a ferry
Given the node map
"""
a b
c d
"""
And the ways
| nodes | highway | route | duration |
| ab | primary | | |
| bc | | ferry | 0:01 |
| cd | primary | | |
When I route I should get
| from | to | route | modes |
| a | d | ab,bc,cd,cd | cycling,ferry,cycling,cycling |
| c | a | bc,ab,ab | ferry,cycling,cycling |
| d | b | cd,bc,bc | cycling,ferry,ferry |
Scenario: Bike - Mode when using a train
Given the node map
"""
a b
c d
"""
And the ways
| nodes | highway | railway | bicycle |
| ab | primary | | |
| bc | | train | yes |
| cd | primary | | |
When I route I should get
| from | to | route | modes |
| a | d | ab,bc,cd,cd | cycling,train,cycling,cycling |
| c | a | bc,ab,ab | train,cycling,cycling |
| d | b | cd,bc,bc | cycling,train,train |
#representative test for all pushes (and mode changes). Where a bike is pushed is tested over in access.feature
Scenario: Bike - Mode when pushing bike against oneways
Given the node map
"""
a b e
f c d
"""
And the ways
| nodes | highway | oneway |
| ab | primary | |
| bc | primary | yes |
| cd | primary | |
| be | primary | |
| cf | primary | |
When I route I should get
| from | to | route | modes |
| a | d | ab,bc,cd,cd | cycling,cycling,cycling,cycling |
| d | a | cd,bc,ab,ab | cycling,pushing bike,cycling,cycling |
| c | a | bc,ab,ab | pushing bike,cycling,cycling |
| d | b | cd,bc,bc | cycling,pushing bike,pushing bike |
Scenario: Bicycle - Modes when starting on forward oneway
Given the node map
"""
a b
"""
And the ways
| nodes | oneway |
| ab | yes |
When I route I should get
| from | to | route | modes |
| a | b | ab,ab | cycling,cycling |
| b | a | ab,ab | pushing bike,pushing bike |
Scenario: Bicycle - Modes when starting on reverse oneway
Given the node map
"""
a b
"""
And the ways
| nodes | oneway |
| ab | -1 |
When I route I should get
| from | to | route | modes |
| a | b | ab,ab | pushing bike,pushing bike |
| b | a | ab,ab | cycling,cycling |

View File

@ -0,0 +1,37 @@
@routing @countrybicycle @names
Feature: Bike - Street names in instructions
Background:
Given the profile "countrybicycle"
Scenario: Bike - A named street
Given the node map
"""
a b
c
"""
And the ways
| nodes | name | ref |
| ab | My Way | A6 |
| bc | Your Way | A7 |
When I route I should get
| from | to | route | ref |
| a | c | My Way,Your Way | A6,A7 |
@unnamed
Scenario: Bike - No longer use way type to describe unnamed ways, see #3231
Given the node map
"""
a b c d
"""
And the ways
| nodes | highway | name |
| ab | cycleway | |
| bcd | track | |
When I route I should get
| from | to | route |
| a | d | , |

View File

@ -0,0 +1,152 @@
@routing @countrybicycle @oneway
Feature: Bike - Oneway streets
# Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing
# Usually we can push bikes against oneways, but we use foot=no to prevent this in these tests
Background:
Given the profile "countrybicycle"
Scenario: Bike - Simple oneway
Then routability should be
| highway | foot | oneway | forw | backw |
| primary | no | yes | cycling | |
| primary | | yes | cycling | pushing bike |
Scenario: Simple reverse oneway
Then routability should be
| highway | foot | oneway | forw | backw |
| primary | no | -1 | | cycling |
| primary | | -1 | pushing bike | cycling |
Scenario: Bike - Around the Block
Given the node map
"""
a b
f d c e
"""
And the ways
| nodes | oneway | foot |
| ab | yes | no |
| bc | | no |
| cd | | no |
| da | | no |
| df | | no |
| ce | | no |
When I route I should get
| from | to | route |
| a | b | ab,ab |
| b | a | bc,cd,da,da |
Scenario: Bike - Handle various oneway tag values
Then routability should be
| foot | oneway | forw | backw |
| no | | cycling | cycling |
| no | nonsense | cycling | cycling |
| no | no | cycling | cycling |
| no | false | cycling | cycling |
| no | 0 | cycling | cycling |
| no | yes | cycling | |
| no | true | cycling | |
| no | 1 | cycling | |
| no | -1 | | cycling |
Scenario: Bike - Implied oneways
Then routability should be
| highway | foot | bicycle | junction | forw | backw | # |
| | no | | | cycling | cycling | |
| | no | | roundabout | cycling | | |
| motorway | no | yes | | cycling | | |
| motorway_link | no | yes | | cycling | cycling | does not imply oneway |
| motorway | no | yes | roundabout | cycling | | |
| motorway_link | no | yes | roundabout | cycling | | |
Scenario: Bike - Overriding implied oneways
Then routability should be
| highway | foot | junction | oneway | forw | backw |
| primary | no | roundabout | no | cycling | cycling |
| primary | no | roundabout | yes | cycling | |
| motorway_link | no | | -1 | | |
| trunk_link | no | | -1 | | |
| primary | no | roundabout | -1 | | cycling |
Scenario: Bike - Oneway:bicycle should override normal oneways tags
Then routability should be
| foot | oneway:bicycle | oneway | junction | forw | backw |
| no | yes | | | cycling | |
| no | yes | yes | | cycling | |
| no | yes | no | | cycling | |
| no | yes | -1 | | cycling | |
| no | yes | | roundabout | cycling | |
| no | no | | | cycling | cycling |
| no | no | yes | | cycling | cycling |
| no | no | no | | cycling | cycling |
| no | no | -1 | | cycling | cycling |
| no | no | | roundabout | cycling | cycling |
| no | -1 | | | | cycling |
| no | -1 | yes | | | cycling |
| no | -1 | no | | | cycling |
| no | -1 | -1 | | | cycling |
| no | -1 | | roundabout | | cycling |
Scenario: Bike - Contra flow
Then routability should be
| foot | oneway | cycleway | forw | backw |
| no | yes | opposite | cycling | cycling |
| no | yes | opposite_track | cycling | cycling |
| no | yes | opposite_lane | cycling | cycling |
| no | -1 | opposite | cycling | cycling |
| no | -1 | opposite_track | cycling | cycling |
| no | -1 | opposite_lane | cycling | cycling |
| no | no | opposite | cycling | cycling |
| no | no | opposite_track | cycling | cycling |
| no | no | opposite_lane | cycling | cycling |
Scenario: Bike - Should not be affected by car tags
Then routability should be
| foot | junction | oneway | oneway:car | forw | backw |
| no | | yes | yes | cycling | |
| no | | yes | no | cycling | |
| no | | yes | -1 | cycling | |
| no | | no | yes | cycling | cycling |
| no | | no | no | cycling | cycling |
| no | | no | -1 | cycling | cycling |
| no | | -1 | yes | | cycling |
| no | | -1 | no | | cycling |
| no | | -1 | -1 | | cycling |
| no | roundabout | | yes | cycling | |
| no | roundabout | | no | cycling | |
| no | roundabout | | -1 | cycling | |
Scenario: Bike - Two consecutive oneways
Given the node map
"""
a b c
"""
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
When I route I should get
| from | to | route |
| a | c | ab,bc,bc |
Scenario: Bike - Left/right cycleways on oneways
Then routability should be
| highway | oneway | cycleway:left | cycleway:right | forw | backw |
| primary | yes | | | cycling | pushing bike |
| primary | yes | | track | cycling | pushing bike |
| primary | yes | track | | cycling | pushing bike |
| primary | yes | track | track | cycling | pushing bike |
Scenario: Bike - Left/right cycleways on any oneways
Then routability should be
| foot | oneway | cycleway:left | cycleway:right | forw | backw |
| no | yes | track | | cycling | |
| yes | yes | track | | cycling | pushing bike |
| yes | -1 | track | | pushing bike | cycling |

View File

@ -0,0 +1,127 @@
@routing @countrybicycle @pushing
Feature: Bike - Accessability of different way types
Background:
Given the profile "countrybicycle"
Scenario: Bike - Pushing bikes on pedestrian-only ways
Then routability should be
| highway | oneway | forw | backw |
| (nil) | | | |
| cycleway | | cycling | cycling |
| primary | | cycling | cycling |
| pedestrian | | pushing bike | pushing bike |
| cycleway | | cycling | cycling |
| primary | yes | cycling | pushing bike |
Scenario: Bike - Pushing bikes against normal oneways
Then routability should be
| highway | oneway | forw | backw |
| (nil) | | | |
| primary | yes | cycling | pushing bike |
| pedestrian | yes | pushing bike | pushing bike |
Scenario: Bike - Pushing bikes against reverse oneways
Then routability should be
| highway | oneway | forw | backw |
| (nil) | | | |
| primary | -1 | pushing bike | cycling |
| pedestrian | -1 | pushing bike | pushing bike |
@square
Scenario: Bike - Push bikes on pedestrian areas
Given the node map
"""
x
a b
d c
"""
And the ways
| nodes | area | highway |
| xa | | primary |
| abcda | yes | pedestrian |
When I route I should get
| from | to | route |
| a | b | abcda,abcda |
| a | d | abcda,abcda |
| b | c | abcda,abcda |
| c | b | abcda,abcda |
| c | d | abcda,abcda |
| d | c | abcda,abcda |
| d | a | abcda,abcda |
| a | d | abcda,abcda |
Scenario: Bike - Pushing bikes on ways with foot=yes
Then routability should be
| highway | foot | forw | backw |
| motorway | | | |
| motorway | yes | pushing bike | |
| runway | | | |
| runway | yes | pushing bike | pushing bike |
@todo
Scenario: Bike - Pushing bikes on ways with foot=yes in one direction
Then routability should be
| highway | foot:forward | foot:backward | forw | backw |
| motorway | | | | |
| motorway | yes | | pushing bike | |
| motorway | | yes | | pushing bike |
@construction
Scenario: Bike - Don't allow routing on ways still under construction
Then routability should be
| highway | foot | bicycle | bothw |
| primary | | | x |
| construction | | | |
| construction | yes | | |
| construction | | yes | |
@roundabout
Scenario: Bike - Don't push bikes against oneway flow on roundabouts
Then routability should be
| junction | forw | backw |
| roundabout | x | |
Scenario: Bike - Instructions when pushing bike on oneways
Given the node map
"""
a b e
f c d
"""
And the ways
| nodes | highway | oneway |
| ab | primary | |
| bc | primary | yes |
| cd | primary | |
| be | primary | |
| cf | primary | |
When I route I should get
| from | to | route | modes |
| a | d | ab,bc,cd,cd | cycling,cycling,cycling,cycling |
| d | a | cd,bc,ab,ab | cycling,pushing bike,cycling,cycling |
| c | a | bc,ab,ab | pushing bike,cycling,cycling |
| d | b | cd,bc,bc | cycling,pushing bike,pushing bike |
Scenario: Bike - Instructions when pushing bike on footway/pedestrian, etc.
Given the node map
"""
a b
c d
"""
And the ways
| nodes | highway |
| ab | primary |
| bc | footway |
| cd | primary |
When I route I should get
| from | to | route | modes |
| a | d | ab,bc,cd,cd | cycling,pushing bike,cycling,cycling |
| d | a | cd,bc,ab,ab | cycling,pushing bike,cycling,cycling |
| c | a | bc,ab,ab | pushing bike,cycling,cycling |
| d | b | cd,bc,bc | cycling,pushing bike,pushing bike |

View File

@ -0,0 +1,133 @@
@routing @countrybicycle @restrictions
Feature: Bike - Turn restrictions
# Ignore turn restrictions on bicycle, since you always become a temporary pedestrian.
# Note that if u-turns are allowed, turn restrictions can lead to suprising, but correct, routes.
Background:
Given the profile "countrybicycle"
Given a grid size of 200 meters
# check to see if bicycle profiles handle relations. The code path is the same as in cars.
# If relations are passed, all variants tested in car also work for bike
@no_turning
Scenario: Bike - No left turn
Given the node map
"""
n
w j e
s
"""
And the ways
| nodes | oneway | foot |
| sj | yes | no |
| nj | -1 | no |
| wj | -1 | no |
| ej | -1 | no |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | sj | wj | j | no_left_turn |
When I route I should get
| from | to | route |
| s | w | sj,wj,wj |
| s | n | sj,nj,nj |
| s | e | sj,ej,ej |
## exceptions are different for bike over car and need to be tested here
@except
Scenario: Bike - Except tag and on no_ restrictions
Given the node map
"""
b x c
a j d
s
"""
And the ways
| nodes | oneway | foot |
| sj | no | no |
| xj | -1 | no |
| aj | -1 | no |
| bj | no | no |
| cj | -1 | no |
| dj | -1 | no |
And the relations
| type | way:from | way:to | node:via | restriction | except |
| restriction | sj | aj | j | no_left_turn | bicycle |
| restriction | sj | bj | j | no_left_turn | |
| restriction | sj | cj | j | no_right_turn | |
| restriction | sj | dj | j | no_right_turn | bicycle |
When I route I should get
| from | to | route |
| s | a | sj,aj,aj |
| s | b | sj,bj,bj |
| s | c | sj,cj,cj |
| s | d | sj,dj,dj |
@except
Scenario: Bike - Except tag and on only_ restrictions
Given the node map
"""
a b
j
s
"""
And the ways
| nodes | oneway | foot |
| sj | yes | no |
| aj | no | no |
| bj | no | no |
And the relations
| type | way:from | way:to | node:via | restriction | except |
| restriction | sj | aj | j | only_straight_on | bicycle |
When I route I should get
| from | to | route |
| s | a | sj,aj,aj |
| s | b | sj,bj,bj |
@except
Scenario: Bike - Multiple except tag values
Given the node map
"""
s j a
b
c
d
e
f
"""
And the ways
| nodes | oneway | foot |
| sj | yes | no |
| ja | yes | no |
| jb | yes | no |
| jc | yes | no |
| jd | yes | no |
| je | yes | no |
| jf | yes | no |
And the relations
| type | way:from | way:to | node:via | restriction | except |
| restriction | sj | ja | j | no_straight_on | |
| restriction | sj | jb | j | no_straight_on | bicycle |
| restriction | sj | jc | j | no_straight_on | bus; bicycle |
| restriction | sj | jd | j | no_straight_on | bicycle; motocar |
| restriction | sj | je | j | no_straight_on | bus, bicycle |
| restriction | sj | jf | j | no_straight_on | bicycle, bus |
When I route I should get
| from | to | route |
| s | a | sj,ja,ja |
| s | b | sj,jb,jb |
| s | c | sj,jc,jc |
| s | d | sj,jd,jd |
| s | e | sj,je,je |
| s | f | sj,jf,jf |

View File

@ -0,0 +1,104 @@
@routing @countrybicycle @safety
Feature: Bicycle - Adds penalties to unsafe roads
Background:
Given the profile file "countrybicycle" initialized with
"""
profile.properties.weight_name = 'cyclability'
"""
Scenario: Bike - Apply penalties to ways without cycleways
Then routability should be
| highway | cycleway | forw | backw | forw_rate | backw_rate |
| motorway | | | | | |
| primary | | 15 km/h | 15 km/h | 2.1 | 2.1 |
| secondary | | 15 km/h | 15 km/h | 2.7 | 2.7 |
| tertiary | | 15 km/h | 15 km/h | 3.3 | 3.3 |
| primary_link | | 15 km/h | 15 km/h | 2.1 | 2.1 |
| secondary_link | | 15 km/h | 15 km/h | 2.7 | 2.7 |
| tertiary_link | | 15 km/h | 15 km/h | 3.3 | 3.3 |
| residential | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | | 4 km/h +-1 | 4 km/h +-1 | 1.1 | 1.1 |
Scenario: Bike - Apply no penalties to ways with cycleways
Then routability should be
| highway | cycleway | forw | backw | forw_rate | backw_rate |
| motorway | track | 15 km/h | | 4.2 | |
| primary | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| secondary | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| primary_link | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| secondary_link | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary_link | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| residential | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | track | 14 km/h | 14 km/h | 4.2 | 4.2 |
| motorway | lane | 15 km/h | | 4.2 | |
| primary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| secondary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| primary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| secondary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| residential | lane | 14 km/h | 14 km/h | 4.2 | 4.2 |
| cycleway | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| motorway | shared_lane | 15 km/h | | 4.2 | |
| primary | shared_lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
Scenario: Bike - Apply no penalties to ways in direction of cycleways
Then routability should be
| highway | cycleway:right | cycleway:left | forw | backw | forw_rate | backw_rate |
| motorway | track | | 15 km/h | | 4.2 | |
| primary | track | | 15 km/h | 15 km/h | 4.2 | 2.1 |
| secondary | track | | 15 km/h | 15 km/h | 4.2 | 2.7 |
| tertiary | track | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| primary_link | track | | 15 km/h | 15 km/h | 4.2 | 2.1 |
| secondary_link | track | | 15 km/h | 15 km/h | 4.2 | 2.7 |
| tertiary_link | track | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| residential | track | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | track | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | track | | 14 km/h | 4 km/h +-1 | 4.2 | 1.1 |
| motorway | | track | 15 km/h | | 4.2 | |
| primary | | track | 15 km/h | 15 km/h | 2.1 | 4.2 |
| secondary | | track | 15 km/h | 15 km/h | 2.7 | 4.2 |
| tertiary | | track | 15 km/h | 15 km/h | 3.3 | 4.2 |
| primary_link | | track | 15 km/h | 15 km/h | 2.1 | 4.2 |
| secondary_link | | track | 15 km/h | 15 km/h | 2.7 | 4.2 |
| tertiary_link | | track | 15 km/h | 15 km/h | 3.3 | 4.2 |
| residential | | track | 14 km/h | 14 km/h | 4.2 | 4.2 |
| cycleway | | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | | track | 4 km/h +-1 | 15 km/h | 1.1 | 4.2 |
| motorway | lane | | 15 km/h | | 4.2 | |
| primary | lane | | 15 km/h | 15 km/h | 4.2 | 2.1 |
| secondary | lane | | 15 km/h | 15 km/h | 4.2 | 2.7 |
| tertiary | lane | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| primary_link | lane | | 15 km/h | 15 km/h | 4.2 | 2.1 |
| secondary_link | lane | | 14 km/h | 14 km/h | 4.2 | 2.7 |
| tertiary_link | lane | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| residential | lane | | 15 km/h +-1 | 15 km/h +-1 | 4.2 | 4.2 |
| cycleway | lane | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | lane | | 15 km/h | 4 km/h +-1 | 4.2 | 1.1 |
| motorway | | lane | 15 km/h | | 4.2 | |
| primary | | lane | 15 km/h | 15 km/h | 2.1 | 4.2 |
| secondary | | lane | 15 km/h +-1 | 15 km/h +-1 | 2.7 | 4.2 |
| tertiary | | lane | 15 km/h | 15 km/h | 3.3 | 4.2 |
| primary_link | | lane | 14 km/h | 14 km/h | 2.1 | 4.2 |
| secondary_link | | lane | 15 km/h | 15 km/h | 2.7 | 4.2 |
| tertiary_link | | lane | 15 km/h | 15 km/h | 3.3 | 4.2 |
| residential | | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | | lane | 4 km/h +-1 | 15 km/h | 1.1 | 4.2 |
| motorway | shared_lane | | 15 km/h | | 4.2 | |
| primary | shared_lane | | 15 km/h | 15 km/h | 4.2 | 2.1 |
| motorway | | shared_lane | 14 km/h | | 4.2 | |
| primary | | shared_lane | 15 km/h | 15 km/h | 2.1 | 4.2 |
Scenario: Bike - Don't apply penalties for all kind of cycleways
Then routability should be
| highway | cycleway | forw | backw | forw_rate | backw_rate |
| tertiary | shared_lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary | opposite | 15 km/h | 15 km/h | 3.3 | 3.3 |

View File

@ -0,0 +1,53 @@
@routing @countrybicycle @startpoint
Feature: Bike - Allowed start/end modes
Background:
Given the profile "countrybicycle"
Scenario: Bike - Don't start/stop on ferries
Given the node map
"""
a 1 b 2 c
"""
And the ways
| nodes | highway | route | bicycle |
| ab | primary | | |
| bc | | ferry | yes |
When I route I should get
| from | to | route | modes |
| 1 | 2 | ab,ab | cycling,cycling |
| 2 | 1 | ab,ab | cycling,cycling |
Scenario: Bike - Don't start/stop on trains
Given the node map
"""
a 1 b 2 c
"""
And the ways
| nodes | highway | railway | bicycle |
| ab | primary | | |
| bc | | train | yes |
When I route I should get
| from | to | route | modes |
| 1 | 2 | ab,ab | cycling,cycling |
| 2 | 1 | ab,ab | cycling,cycling |
Scenario: Bike - OK to start pushing bike
Given the node map
"""
a 1 b 2 c
"""
And the ways
| nodes | highway |
| ab | primary |
| bc | steps |
When I route I should get
| from | to | route | modes |
| 1 | 2 | ab,bc,bc | cycling,pushing bike,pushing bike |
| 2 | 1 | bc,ab,ab | pushing bike,cycling,cycling |

View File

@ -0,0 +1,39 @@
@routing @countrybicycle @stop_area @todo
Feature: Bike - Stop areas for public transport
# Platforms and railway/bus lines are connected using a relation rather that a way, as specified in:
# http://wiki.openstreetmap.org/wiki/Tag:public_transport%3Dstop_area
Background:
Given the profile "countrybicycle"
Scenario: Bike - Platforms tagged using public_transport
Then routability should be
| highway | public_transport | bicycle | bothw |
| primary | | | x |
| (nil) | platform | | x |
Scenario: Bike - railway platforms
Given the node map
"""
a b c d
s t
"""
And the nodes
| node | public_transport |
| c | stop_position |
And the ways
| nodes | highway | railway | bicycle | public_transport |
| abcd | (nil) | train | yes | |
| st | (nil) | (nil) | | platform |
And the relations
| type | public_transport | node:stop | way:platform |
| public_transport | stop_area | c | st |
When I route I should get
| from | to | route |
| a | d | abcd,abcd |
| s | t | st,st |
| s | d | /st,.+,abcd/,abcd/ |

View File

@ -0,0 +1,68 @@
@routing @surface @countrybicycle
Feature: Bike - Surfaces
Background:
Given the profile "countrybicycle"
Scenario: Bicycle - Slow surfaces
Then routability should be
| highway | surface | bothw |
| cycleway | | 48 s |
| cycleway | asphalt | 47.9 s |
| cycleway | chipseal | 48 s |
| cycleway | concrete | 48 s |
| cycleway | concrete_lanes | 48 s |
| cycleway | cobblestone:flattened | 72 s |
| cycleway | paving_stones | 72 s |
| cycleway | wood | 72 s |
| cycleway | metal | 72 s |
| cycleway | compacted | 72 s |
| cycleway | fine_gravel | 72 s |
| cycleway | ground | 72 s |
| cycleway | dirt | 90 s |
| cycleway | cobblestone | 102.9 s |
| cycleway | gravel | 120 s |
| cycleway | pebblestone | 120 s |
| cycleway | grass_paver | 120 s |
| cycleway | dirt | 90 s |
| cycleway | earth | 120 s |
| cycleway | grass | 120 s |
| cycleway | mud | 240 s |
| cycleway | sand | 240 s |
| cycleway | woodchips | 240 s |
| cycleway | sett | 80 s |
Scenario: Bicycle - Good surfaces on small paths
Then routability should be
| highway | surface | bothw |
| cycleway | | 48 s |
| path | | 55.3 s |
| track | | 60 s |
| track | asphalt | 60 s |
| path | asphalt | 55.4 s |
Scenario: Bicycle - Surfaces should not make unknown ways routable
Then routability should be
| highway | surface | bothw |
| cycleway | | 48 s |
| nosense | | |
| nosense | asphalt | |
Scenario: Bicycle - Surfaces should not increase speed when pushing bikes
Given the node map
"""
a b
c d
"""
And the ways
| nodes | highway | oneway | surface |
| ab | primary | yes | asphalt |
| cd | footway | | asphalt |
When I route I should get
| from | to | route | modes | speed |
| a | b | ab,ab | cycling,cycling | 15 km/h |
| b | a | ab,ab | pushing bike,pushing bike | 4 km/h |
| c | d | cd,cd | pushing bike,pushing bike | 4 km/h |
| d | c | cd,cd | pushing bike,pushing bike | 4 km/h |

View File

@ -0,0 +1,71 @@
@routing @bicycle @train
Feature: Bike - Handle ferry routes
# Bringing bikes on trains and subways
# We cannot currently use a 'routability' type test, since the bike
# profile does not allow starting/stopping on trains, and
# it's not possible to modify the bicycle profile table because it's
# defined as local.
Background:
Given the profile "bicycle"
Scenario: Bike - Bringing bikes on trains
Given the node map
"""
a 1 b c 2 d e 3 f g 4 h
"""
And the ways
| nodes | highway | railway | bicycle |
| ab | primary | | |
| cd | primary | | |
| ef | primary | | |
| gh | primary | | |
| bc | | train | |
| de | | train | yes |
| fg | | train | no |
When I route I should get
| from | to | route |
| 1 | 2 | |
| 2 | 3 | cd,de,ef,ef |
| 3 | 4 | |
Scenario: Bike - Bringing bikes on trains, invalid railway tag is accepted if access specified
Given the node map
"""
a 1 b c 2 d e 3 f g 4 h
"""
And the ways
| nodes | highway | railway | bicycle |
| ab | primary | | |
| cd | primary | | |
| ef | primary | | |
| gh | primary | | |
| bc | | invalid_tag | |
| de | | invalid_tag | yes |
| fg | | invalid_tag | no |
When I route I should get
| from | to | route |
| 1 | 2 | |
| 2 | 3 | cd,de,ef|
| 3 | 4 | |
@construction
Scenario: Bike - Don't route on railways under construction
Given the node map
"""
a 1 b c 2 d
"""
And the ways
| nodes | highway | railway | bicycle |
| ab | primary | | |
| cd | primary | | |
| bc | | construction | yes |
When I route I should get
| from | to | route |
| 1 | 2 | |

View File

@ -0,0 +1,42 @@
@routing @countrybicycle @turn_penalty
Feature: Turn Penalties
Background:
Given the profile "countrybicycle"
Given a grid size of 200 meters
Scenario: Bicycle - Turn penalties on cyclability
Given the profile file "bicycle" initialized with
"""
profile.properties.weight_name = 'cyclability'
"""
Given the node map
"""
a--b-----c
|
|
d
e--------f-----------g
/
/
/
h
"""
And the ways
| nodes | highway |
| abc | residential |
| bd | residential |
| efg | residential |
| fh | residential |
When I route I should get
| from | to | distance | weight | # |
| a | c | 900m +- 1 | 216 | Going straight has no penalties |
| a | d | 900m +- 1 | 220.2 | Turning right had penalties |
| e | g | 2100m +- 5| 503.9 | Going straght has no penalties |
| e | h | 2100m +- 5| 515.1 | Turn sharp right has even higher penalties|

View File

@ -0,0 +1,42 @@
@routing @countrybicycle @way
Feature: Bike - Accessability of different way types
Background:
Given the profile "countrybicycle"
Scenario: Bike - Routability of way types
# Bikes are allowed on footways etc because you can pull your bike at a lower speed.
# Pier is not allowed, since it's tagged using man_made=pier.
Then routability should be
| highway | bothw |
| (nil) | |
| motorway | |
| motorway_link | |
| trunk | |
| trunk_link | |
| primary | x |
| primary_link | x |
| secondary | x |
| secondary_link | x |
| tertiary | x |
| tertiary_link | x |
| residential | x |
| service | x |
| unclassified | x |
| living_street | x |
| road | x |
| track | x |
| path | x |
| footway | x |
| pedestrian | x |
| steps | x |
| cycleway | x |
| bridleway | |
| pier | |
Scenario: Bike - Routability of man_made structures
Then routability should be
| highway | man_made | bothw |
| (nil) | (nil) | |
| (nil) | pier | x |

View File

@ -0,0 +1,119 @@
@routing @countryfoot @access
Feature: Countryfoot - Access tags on ways
# Reference: http://wiki.openstreetmap.org/wiki/Key:access
Background:
Given the profile "countryfoot"
Scenario: Countryfoot - Access tag hierarchy on ways
Then routability should be
| highway | access | foot | bothw |
| footway | | | x |
| footway | | yes | x |
| footway | | no | |
| footway | yes | | x |
| footway | yes | yes | x |
| footway | yes | no | |
| footway | no | | |
| footway | no | yes | x |
| footway | no | no | |
| motorway | | | |
| motorway | | yes | x |
| motorway | | no | |
| motorway | yes | | x |
| motorway | yes | yes | x |
| motorway | yes | no | |
| motorway | no | | |
| motorway | no | yes | x |
| motorway | no | no | |
Scenario: Countryfoot - Overwriting implied acccess on ways
Then routability should be
| highway | access | foot | bothw |
| footway | | | x |
| motorway | | | |
| footway | no | | |
| footway | | | x |
| footway | | no | |
| motorway | yes | | x |
| motorway | | | |
| motorway | | yes | x |
Scenario: Countryfoot - Access tags on ways
Then routability should be
| access | foot | bothw |
| | | x |
| yes | | x |
| permissive | | x |
| designated | | x |
| some_tag | | x |
| no | | |
| private | | |
| agricultural | | |
| forestry | | |
| delivery | | |
| | yes | x |
| | permissive | x |
| | designated | x |
| | some_tag | x |
| | no | |
| | private | |
| | agricultural | |
| | forestry | |
| | delivery | |
Scenario: Countryfoot - Access tags on both node and way
Then routability should be
| access | node/access | bothw |
| yes | yes | x |
| yes | no | |
| yes | some_tag | x |
| no | yes | |
| no | no | |
| no | some_tag | |
| some_tag | yes | x |
| some_tag | no | |
| some_tag | some_tag | x |
Scenario: Countryfoot - Access combinations
Then routability should be
| highway | access | foot | bothw |
| motorway | private | yes | x |
| footway | | permissive | x |
| track | forestry | permissive | x |
| footway | yes | no | |
| primary | | private | |
| residential | permissive | no | |
Scenario: Countryfoot - Ignore access tags for other modes
Then routability should be
| highway | boat | motor_vehicle | moped | bothw |
| river | yes | | | |
| footway | no | | | x |
| motorway | | yes | | |
| footway | | no | | x |
| motorway | | | yes | |
| footway | | | no | x |
Scenario: Countryfoot - Bridleways when access is explicit
Then routability should be
| highway | horse | bicycle | foot | bothw |
| bridleway | | | yes | x |
| bridleway | | yes | | |
| bridleway | designated | | | |
| bridleway | | | | |
Scenario: Countryfoot - a way with missing :forward tag
Then routability should be
| highway | bicycle:backward | foot:backward | forw | backw |
| cycleway | designated | designated | | x |
Scenario: Countryfoot - Access combinations
Then routability should be
| highway | access | bothw |
| primary | permissive | x |
| steps | permissive | x |
| footway | permissive | x |
| garbagetag | permissive | x |

View File

@ -0,0 +1,52 @@
@routing @countryfoot @access
Feature: Countryfoot - Access tags on nodes
# Reference: http://wiki.openstreetmap.org/wiki/Key:access
Background:
Given the profile "countryfoot"
Scenario: Countryfoot - Access tag hierarchy on nodes
Then routability should be
| node/access | node/foot | bothw |
| | | x |
| | yes | x |
| | no | |
| yes | | x |
| yes | yes | x |
| yes | no | |
| no | | |
| no | yes | x |
| no | no | |
Scenario: Countryfoot - Overwriting implied acccess on nodes doesn't overwrite way
Then routability should be
| highway | node/access | node/foot | bothw |
| footway | | | x |
| footway | no | | |
| footway | | no | |
| motorway | | | |
| motorway | yes | | |
| motorway | | yes | |
Scenario: Countryfoot - Access tags on nodes
Then routability should be
| node/access | node/foot | bothw |
| | | x |
| yes | | x |
| permissive | | x |
| designated | | x |
| some_tag | | x |
| no | | |
| private | | |
| agricultural | | |
| forestry | | |
| delivery | | |
| no | yes | x |
| no | permissive | x |
| no | designated | x |
| no | some_tag | x |
| yes | no | |
| yes | private | |
| yes | agricultural | |
| yes | forestry | |
| yes | delivery | |

View File

@ -0,0 +1,112 @@
@routing @countryfoot @area
Feature: Countryfoot - Squares and other areas
Background:
Given the profile "countryfoot"
Given a grid size of 200 meters
@square
Scenario: Countryfoot - Route along edge of a squares
Given the node map
"""
x
a b
d c
"""
And the ways
| nodes | area | highway |
| xa | | primary |
| abcda | yes | residential |
When I route I should get
| from | to | route |
| a | b | abcda,abcda |
| a | d | abcda,abcda |
| b | c | abcda,abcda |
| c | b | abcda,abcda |
| c | d | abcda,abcda |
| d | c | abcda,abcda |
| d | a | abcda,abcda |
| a | d | abcda,abcda |
@building
Scenario: Countryfoot - Don't route on buildings
Given the node map
"""
x
a b
d c
"""
And the ways
| nodes | highway | area | building | access |
| xa | primary | | | |
| abcda | (nil) | yes | yes | yes |
When I route I should get
| from | to | route |
| a | b | xa,xa |
| a | d | xa,xa |
| b | c | xa,xa |
| c | b | xa,xa |
| c | d | xa,xa |
| d | c | xa,xa |
| d | a | xa,xa |
| a | d | xa,xa |
@parking
Scenario: Countryfoot - parking areas
Given the node map
"""
e f
x a b y
d c
"""
And the ways
| nodes | highway | amenity |
| xa | primary | |
| by | primary | |
| xefy | primary | |
| abcda | (nil) | parking |
When I route I should get
| from | to | route |
| x | y | xa,abcda,by,by |
| y | x | by,abcda,xa,xa |
| a | b | abcda,abcda |
| a | d | abcda,abcda |
| b | c | abcda,abcda |
| c | b | abcda,abcda |
| c | d | abcda,abcda |
| d | c | abcda,abcda |
| d | a | abcda,abcda |
| a | d | abcda,abcda |
@train @platform
Scenario: Countryfoot - railway platforms
Given the node map
"""
x a b y
d c
"""
And the ways
| nodes | highway | railway |
| xa | primary | |
| by | primary | |
| abcda | (nil) | platform |
When I route I should get
| from | to | route |
| x | y | xa,abcda,by,by |
| y | x | by,abcda,xa,xa |
| a | b | abcda,abcda |
| a | d | abcda,abcda |
| b | c | abcda,abcda |
| c | b | abcda,abcda |
| c | d | abcda,abcda |
| d | c | abcda,abcda |
| d | a | abcda,abcda |
| a | d | abcda,abcda |

View File

@ -0,0 +1,41 @@
@routing @countryfoot @barrier
Feature: Barriers
Background:
Given the profile "countryfoot"
Scenario: Countryfoot - Barriers
Then routability should be
| node/barrier | bothw |
| | x |
| bollard | x |
| gate | x |
| lift_gate | x |
| cycle_barrier | x |
| cattle_grid | x |
| border_control | x |
| toll_booth | x |
| sally_port | x |
| entrance | x |
| wall | |
| fence | |
| some_tag | x |
| block | x |
Scenario: Countryfoot - Access tag trumphs barriers
Then routability should be
| node/barrier | node/access | bothw |
| bollard | | x |
| bollard | yes | x |
| bollard | permissive | x |
| bollard | designated | x |
| bollard | no | |
| bollard | private | |
| bollard | agricultural | |
| wall | | |
| wall | yes | x |
| wall | permissive | x |
| wall | designated | x |
| gate | no | |
| gate | private | |
| gate | agricultural | |

View File

@ -0,0 +1,101 @@
@routing @countryfoot @countryspeeds
Feature: Testbot - Country Profile Selection
# Check that country data is being selected
# CHE (a) and FIN (c) support foot on cycleway
# FRA (g) does not support foot on cycleway
# BEL (i) and FIN (c) support foot on cycleway
# BEL (i) and IRL (o) support Bridleway
# GRC (m) and IRL (o) support trunk and bridleway
# LIU (s) is not a country in list so looks like worldwide
# so
# GRC (m) and LIU (s) support trunk
# LIU (s) does not support cycleway or bridleway
# Worldwide (u) is an area without boundaries (so like s)
Scenario: Country Profile Selection - highway chosen for country
Given the extract extra arguments "--location-dependent-data test/data/countrytest.geojson"
And the partition extra arguments "--threads 1"
And the customize extra arguments "--threads 1"
And the profile file "countryfoot" initialized with
"""
profile.uselocationtags.countryspeeds = true
"""
And the node locations
| node | lat | lon |
| a | 9.5 | 5.0 |
| b | 9.5 | 10.0 |
| c | 9.5 | 15.0 |
| d | 9.0 | 5.0 |
| e | 9.0 | 10.0 |
| f | 9.0 | 15.0 |
| g | 8.5 | 5.0 |
| h | 8.5 | 10.0 |
| i | 8.5 | 15.0 |
| j | 8.0 | 5.0 |
| k | 8.0 | 10.0 |
| l | 8.0 | 15.0 |
| m | 7.5 | 5.0 |
| n | 7.5 | 10.0 |
| o | 7.5 | 15.0 |
| p | 7.0 | 5.0 |
| q | 7.0 | 10.0 |
| r | 7.0 | 15.0 |
| s | 6.5 | 5.0 |
| t | 6.5 | 10.0 |
| u | 6.5 | 15.0 |
And the ways
| nodes | highway | comment
| ab | cycleway | CHE - FIN yes
| bc | cycleway |
| ad | cycleway | CHE - FRA no
| dg | cycleway |
| gj | cycleway |
| cf | bridleway | FIN - BEL no
| fi | bridleway |
| gh | trunk | FRA - BEL no
| hi | trunk |
| il | bridleway | BEL - IRL yes
| lo | bridleway |
| or | trunk | IRL - world yes
| ru | trunk |
| mn | trunk | GRC - IRL yes
| no | trunk |
| mp | trunk | GRC - liu yes
| ps | trunk |
And the partition extra arguments "--threads 1"
And the customize extra arguments "--threads 1"
When I route I should get
| waypoints | route | status | message |
| a,c | ab,bc,bc | 200 | |
| a,j | | 400 | Impossible route between points |
| c,i | | 400 | Impossible route between points |
| g,i | | 400 | Impossible route between points |
| i,o | il,lo,lo | 200 | |
| o,u | or,ru,ru | 200 | |
| m,o | mn,no,no | 200 | |
| m,s | mp,ps,ps | 200 | |

View File

@ -0,0 +1,41 @@
@routing @countryfoot @countryway
Feature: Countryfoot - Accessability of different way types with countryspeeds
Background:
Given the profile file "countryfoot" initialized with
"""
profile.uselocationtags.countryspeeds = true
"""
Scenario: Countryfoot - Basic access
Then routability should be
| highway | forw |
| motorway | |
| motorway_link | |
| trunk | x |
| trunk_link | x |
| primary | x |
| primary_link | x |
| secondary | x |
| secondary_link | x |
| tertiary | x |
| tertiary_link | x |
| residential | x |
| service | x |
| unclassified | x |
| living_street | x |
| road | x |
| track | x |
| path | x |
| footway | x |
| pedestrian | x |
| steps | x |
| pier | x |
| cycleway | |
| bridleway | |
Scenario: Countryfoot - Basic access
Then routability should be
| highway | leisure | forw |
| (nil) | track | x |

View File

@ -0,0 +1,35 @@
@routing @countryfoot
Feature: Countryfoot - Use distance weight
Background:
Given a grid size of 200 meters
Scenario: Countryfoot - Check distance weight
Given the profile file
"""
local functions = require('countryfoot')
functions.setup_testbot = functions.setup
functions.setup = function()
local profile = functions.setup_testbot()
profile.properties.weight_name = 'distance'
return profile
end
return functions
"""
Given the node map
"""
a-b-c
"""
And the ways
| nodes | highway |
| abc | residential |
When I route I should get
| from | to | route | weight | time | distance |
| a | b | abc,abc | 200 | 144s | 200m +-1 |
| a | c | abc,abc | 400 | 288s | 400m +-1 |

View File

@ -0,0 +1,63 @@
@routing @countryfoot @ferry
Feature: Countryfoot - Handle ferry routes
Background:
Given the profile "countryfoot"
Scenario: Countryfoot - Ferry route
Given the node map
"""
a b c
d
e f g
"""
And the ways
| nodes | highway | route | foot |
| abc | primary | | |
| cde | | ferry | yes |
| efg | primary | | |
When I route I should get
| from | to | route | modes |
| a | g | abc,cde,efg,efg | walking,ferry,walking,walking |
| e | a | cde,abc,abc | ferry,walking,walking |
Scenario: Countryfoot - Ferry duration, single node
Given the node map
"""
a b c d
e f
g h
i j
"""
And the ways
| nodes | highway | route | foot | duration |
| ab | primary | | | |
| cd | primary | | | |
| ef | primary | | | |
| gh | primary | | | |
| ij | primary | | | |
| bc | | ferry | yes | 0:01 |
| be | | ferry | yes | 0:10 |
| bg | | ferry | yes | 1:00 |
| bi | | ferry | yes | 10:00 |
Scenario: Countryfoot - Ferry duration, multiple nodes
Given the node map
"""
x y
a b c d
"""
And the ways
| nodes | highway | route | foot | duration |
| xa | primary | | | |
| yd | primary | | | |
| abcd | | ferry | yes | 1:00 |
When I route I should get
| from | to | route | time |
| a | d | abcd,abcd | 3600s |
| d | a | abcd,abcd | 3600s |

View File

@ -0,0 +1,31 @@
@routing @countryfoot
Feature: Countryfoot - Intersections
Background:
Given the profile "countryfoot"
Given a grid size of 2 meters
# https://github.com/Project-OSRM/osrm-backend/issues/6218
Scenario: Countryfoot - Handles non-planar intersections
Given the node map
"""
f
|
a
|
b---c---d
|
e
"""
And the ways
| nodes | highway | foot | layer |
| ac | footway | yes | 0 |
| bc | footway | yes | 0 |
| cd | footway | yes | 0 |
| cef | footway | yes | 1 |
When I route I should get
| from | to | route |
| a | d | ac,cd,cd |

View File

@ -0,0 +1,19 @@
@routing @countryfoot @maxspeed
Feature: Countryfoot - Ignore max speed restrictions
Background: Use specific speeds
Given the profile "countryfoot"
Scenario: Countryfoot - Ignore maxspeed
Then routability should be
| highway | maxspeed | bothw |
| residential | | 145 s ~10% |
| residential | 1 | 145 s ~10% |
| residential | 100 | 145 s ~10% |
| residential | 1 | 145 s ~10% |
| residential | 1mph | 145 s ~10% |
| residential | 1 mph | 145 s ~10% |
| residential | 1unknown | 145 s ~10% |
| residential | 1 unknown | 145 s ~10% |
| residential | none | 145 s ~10% |
| residential | signals | 145 s ~10% |

View File

@ -0,0 +1,39 @@
@routing @countryfoot @names
Feature: Countryfoot - Street names in instructions
Background:
Given the profile "countryfoot"
Given a grid size of 200 meters
Scenario: Countryfoot - A named street
Given the node map
"""
a b
c
"""
And the ways
| nodes | name | ref |
| ab | My Way | |
| bc | | A7 |
When I route I should get
| from | to | route | ref |
| a | c | My Way,, | ,A7,A7 |
Scenario: Countryfoot - Combines named roads with suffix changes
Given the node map
"""
a b c d
"""
And the ways
| nodes | name |
| ab | High Street W |
| bc | High Street E |
| cd | Market Street |
When I route I should get
| from | to | route |
| a | d | High Street W,Market Street,Market Street |

View File

@ -0,0 +1,60 @@
@routing @countryfoot @oneway
Feature: Countryfoot - Oneway streets
# Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing
Background:
Given the profile "countryfoot"
Scenario: Countryfoot - Walking should not be affected by oneways
Then routability should be
| oneway | bothw |
| | x |
| nonsense | x |
| no | x |
| false | x |
| 0 | x |
| yes | x |
| true | x |
| 1 | x |
| -1 | x |
Scenario: Countryfoot - Walking and roundabouts
Then routability should be
| junction | bothw |
| roundarout | x |
Scenario: Countryfoot - Oneway:foot tag should not cause walking on big roads
Then routability should be
| highway | oneway:foot | bothw |
| footway | | x |
| motorway | yes | |
| motorway_link | yes | |
| trunk | yes | |
| trunk_link | yes | |
| motorway | no | |
| motorway_link | no | |
| trunk | no | |
| trunk_link | no | |
| motorway | -1 | |
| motorway_link | -1 | |
| trunk | -1 | |
| trunk_link | -1 | |
Scenario: Countryfoot - Walking should respect oneway:foot
Then routability should be
| oneway:foot | oneway | junction | forw | backw |
| yes | | | x | |
| yes | yes | | x | |
| yes | no | | x | |
| yes | -1 | | x | |
| yes | | roundabout | x | |
| no | | | x | x |
| no | yes | | x | x |
| no | no | | x | x |
| no | -1 | | x | x |
| no | | roundabout | x | x |
| -1 | | | | x |
| -1 | yes | | | x |
| -1 | no | | | x |
| -1 | -1 | | | x |
| -1 | | roundabout | | x |

View File

@ -0,0 +1,131 @@
@routing @countryfoot @restrictions
Feature: Countryfoot - Turn restrictions
# Ignore turn restrictions on foot.
Background:
Given the profile "countryfoot"
Given a grid size of 200 meters
@no_turning
Scenario: Countryfoot - No left turn
Given the node map
"""
n
w j e
s
"""
And the ways
| nodes | oneway |
| sj | yes |
| nj | -1 |
| wj | -1 |
| ej | -1 |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | sj | wj | j | no_left_turn |
When I route I should get
| from | to | route |
| s | w | sj,wj,wj |
| s | n | sj,nj |
| s | e | sj,ej,ej |
@only_turning
Scenario: Countryfoot - Only left turn
Given the node map
"""
n
w j e
s
"""
And the ways
| nodes | oneway |
| sj | yes |
| nj | -1 |
| wj | -1 |
| ej | -1 |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | sj | wj | j | only_left_turn |
When I route I should get
| from | to | route |
| s | w | sj,wj,wj |
| s | n | sj,nj |
| s | e | sj,ej,ej |
@except
Scenario: Countryfoot - Except tag and on no_ restrictions
Given the node map
"""
b x c
a j d
s
"""
And the ways
| nodes | oneway |
| sj | no |
| xj | -1 |
| aj | -1 |
| bj | no |
| cj | -1 |
| dj | -1 |
And the relations
| type | way:from | way:to | node:via | restriction | except |
| restriction | sj | aj | j | no_left_turn | foot |
| restriction | sj | bj | j | no_left_turn | |
| restriction | sj | cj | j | no_right_turn | |
| restriction | sj | dj | j | no_right_turn | foot |
When I route I should get
| from | to | route |
| s | a | sj,aj,aj |
| s | b | sj,bj,bj |
| s | c | sj,cj,cj |
| s | d | sj,dj,dj |
@except
Scenario: Countryfoot - Multiple except tag values
Given the node map
"""
s j a
b
c
d
e
f
"""
And the ways
| nodes | oneway |
| sj | yes |
| ja | yes |
| jb | yes |
| jc | yes |
| jd | yes |
| je | yes |
| jf | yes |
And the relations
| type | way:from | way:to | node:via | restriction | except |
| restriction | sj | ja | j | no_straight_on | |
| restriction | sj | jb | j | no_straight_on | foot |
| restriction | sj | jc | j | no_straight_on | bus; foot |
| restriction | sj | jd | j | no_straight_on | foot; motocar |
| restriction | sj | je | j | no_straight_on | bus, foot |
| restriction | sj | jf | j | no_straight_on | foot, bus |
When I route I should get
| from | to | route |
| s | a | sj,ja,ja |
| s | b | sj,jb,jb |
| s | c | sj,jc,jc |
| s | d | sj,jd,jd |
| s | e | sj,je,je |
| s | f | sj,jf,jf |

View File

@ -0,0 +1,35 @@
@routing @countryfoot @roundabout @instruction @todo
Feature: Roundabout Instructions
Background:
Given the profile "countryfoot"
Scenario: Countryfoot - Roundabout instructions
# You can walk in both directions on a roundabout, bu the normal roundabout instructions don't
# make sense when you're going the opposite way around the roundabout.
Given the node map
"""
v
d
s a c u
b
t
"""
And the ways
| nodes | junction |
| sa | |
| tb | |
| uc | |
| vd | |
| abcda | roundabout |
When I route I should get
| from | to | route | turns |
| s | t | sa,tb | depart,roundabout-exit-1,arrive |
| s | u | sa,uc | depart,roundabout-exit-2,arrive |
| s | v | sa,vd | depart,roundabout-exit-3,arrive |
| u | v | uc,vd | depart,roundabout-exit-1,arrive |
| u | s | uc,sa | depart,roundabout-exit-2,arrive |
| u | t | uc,tb | depart,roundabout-exit-3,arrive |

View File

@ -0,0 +1,37 @@
@routing @countryfoot @startpoint
Feature: Countryfoot - Allowed start/end modes
Background:
Given the profile "countryfoot"
Scenario: Countryfoot - Don't start/stop on ferries
Given the node map
"""
a 1 b 2 c
"""
And the ways
| nodes | highway | route | bicycle |
| ab | primary | | |
| bc | | ferry | yes |
When I route I should get
| from | to | route | modes |
| 1 | 2 | ab,ab | walking,walking |
| 2 | 1 | ab,ab | walking,walking |
Scenario: Countryfoot - Don't start/stop on trains
Given the node map
"""
a 1 b 2 c
"""
And the ways
| nodes | highway | railway | bicycle |
| ab | primary | | |
| bc | | train | yes |
When I route I should get
| from | to | route | modes |
| 1 | 2 | ab,ab | walking,walking |
| 2 | 1 | ab,ab | walking,walking |

View File

@ -0,0 +1,15 @@
@routing @countryfoot @surface
Feature: Countryfoot - Surfaces
Background:
Given the profile "countryfoot"
Scenario: Countryfoot - Slow surfaces
Then routability should be
| highway | surface | bothw |
| footway | | 145 s ~10% |
| footway | fine_gravel | 193 s ~10% |
| footway | gravel | 193 s ~10% |
| footway | pebblestone | 193 s ~10% |
| footway | mud | 289 s ~10% |
| footway | sand | 289 s ~10% |

View File

@ -0,0 +1,38 @@
@routing @countryfoot @way
Feature: Countryfoot - Accessability of different way types
Background:
Given the profile "countryfoot"
Scenario: Countryfoot - Basic access
Then routability should be
| highway | forw |
| motorway | |
| motorway_link | |
| trunk | |
| trunk_link | |
| primary | x |
| primary_link | x |
| secondary | x |
| secondary_link | x |
| tertiary | x |
| tertiary_link | x |
| residential | x |
| service | x |
| unclassified | x |
| living_street | x |
| road | x |
| track | x |
| path | x |
| footway | x |
| pedestrian | x |
| steps | x |
| pier | x |
| cycleway | |
| bridleway | |
Scenario: Countryfoot - Basic access
Then routability should be
| highway | leisure | forw |
| (nil) | track | x |

View File

@ -0,0 +1,55 @@
@routing @foot @countrymotorroad
Feature: Testbot - Country motorroad Selection
# Check that motorroad is avoided
Scenario: foot Profile Selection - motorroad avoided
Given the extract extra arguments "--threads 1"
And the partition extra arguments "--threads 1"
And the customize extra arguments "--threads 1"
And the profile file "foot" initialized with
"""
profile.uselocationtags.countryspeeds = true
"""
And the node locations
| node | lat | lon |
| a | 9.5 | 5.0 |
| b | 9.5 | 10.0 |
| c | 9.5 | 15.0 |
| d | 9.0 | 5.0 |
| e | 9.0 | 10.0 |
| f | 9.0 | 15.0 |
And the ways
| nodes | highway | motorroad |
| ab | trunk | yes |
| bc | trunk | |
| ad | trunk | |
| de | trunk | |
| ef | trunk | |
| cf | trunk | |
When I route I should get
| waypoints | route | status | message |
| a,c | ad,de,ef,cf,cf | 200 | |
| a,b | ad,de,ef,cf,bc,bc | 200 | |

View File

@ -0,0 +1,85 @@
@routing @foot @countryspeeds
Feature: Testbot - Country Profile Selection
# Check that country data is being selected
# CHE (a) and FIN (c) support foot on cycleway
# FRA (g) does not support foot on cycleway
# BEL (i) and FIN (c) support foot on cycleway
# BEL (i) and IRL (o) support Bridleway
# GRC (m) and IRL (o) support trunk and bridleway
# LIU (s) is not a country in list so looks like worldwide
# so
# GRC (m) and LIU (s) support trunk
# LIU (s) does not support cycleway or bridleway
# Worldwide (u) is an area without boundaries (so like s)
Scenario: foot Profile Selection - highway chosen for country
Given the extract extra arguments "--threads 1 --location-dependent-data test/data/countrytest.geojson"
And the partition extra arguments "--threads 1"
And the customize extra arguments "--threads 1"
And the profile file "foot" initialized with
"""
profile.uselocationtags.countryspeeds = true
"""
And the node locations
| node | lat | lon |
| a | 9.5 | 5.0 |
| b | 9.5 | 10.0 |
| c | 9.5 | 15.0 |
| d | 9.0 | 5.0 |
| e | 9.0 | 10.0 |
| f | 9.0 | 15.0 |
| g | 8.5 | 5.0 |
| h | 8.5 | 10.0 |
| i | 8.5 | 15.0 |
| j | 8.0 | 5.0 |
| k | 8.0 | 10.0 |
| l | 8.0 | 15.0 |
| m | 7.5 | 5.0 |
| n | 7.5 | 10.0 |
| o | 7.5 | 15.0 |
| p | 7.0 | 5.0 |
| q | 7.0 | 10.0 |
| r | 7.0 | 15.0 |
| s | 6.5 | 5.0 |
| t | 6.5 | 10.0 |
| u | 6.5 | 15.0 |
And the ways
| nodes | highway | comment
| ab | cycleway | CHE - FIN yes
| bc | cycleway |
| ad | cycleway | CHE - FRA no
| dg | cycleway |
| gj | cycleway |
| cf | bridleway | FIN - BEL no
| fi | bridleway |
| gh | trunk | FRA - BEL no
| hi | trunk |
| il | bridleway | BEL - IRL yes
| lo | bridleway |
| or | trunk | IRL - world yes
| ru | trunk |
| mn | trunk | GRC - IRL yes
| no | trunk |
| mp | trunk | GRC - liu yes
| ps | trunk |
And the partition extra arguments "--threads 1"
And the customize extra arguments "--threads 1"
When I route I should get
| waypoints | route | status | message |
| a,c | ab,bc,bc | 200 | |
| a,j | | 400 | Impossible route between points |
| c,i | | 400 | Impossible route between points |
| g,i | | 400 | Impossible route between points |
| i,o | il,lo,lo | 200 | |
| o,u | or,ru,ru | 200 | |
| m,o | mn,no,no | 200 | |
| m,s | mp,ps,ps | 200 | |

View File

@ -0,0 +1,41 @@
@routing @foot @countryway
Feature: foot - Accessability of different way types with countryspeeds
Background:
Given the profile file "foot" initialized with
"""
profile.uselocationtags.countryspeeds = true
"""
Scenario: Countryfoot - Basic access
Then routability should be
| highway | forw |
| motorway | |
| motorway_link | |
| trunk | x |
| trunk_link | x |
| primary | x |
| primary_link | x |
| secondary | x |
| secondary_link | x |
| tertiary | x |
| tertiary_link | x |
| residential | x |
| service | x |
| unclassified | x |
| living_street | x |
| road | x |
| track | x |
| path | x |
| footway | x |
| pedestrian | x |
| steps | x |
| pier | x |
| cycleway | |
| bridleway | |
Scenario: Countryfoot - Basic access
Then routability should be
| highway | leisure | forw |
| (nil) | track | x |

View File

@ -7,6 +7,7 @@ Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers") Handlers = require("lib/way_handlers")
TrafficSignal = require("lib/traffic_signal") TrafficSignal = require("lib/traffic_signal")
find_access_tag = require("lib/access").find_access_tag find_access_tag = require("lib/access").find_access_tag
country_speeds = require("lib/country_speeds")
limit = require("lib/maxspeed").limit limit = require("lib/maxspeed").limit
Measure = require("lib/measure") Measure = require("lib/measure")
@ -27,6 +28,7 @@ function setup()
mode_change_penalty = 30, mode_change_penalty = 30,
}, },
profile = 'bicycle',
default_mode = mode.cycling, default_mode = mode.cycling,
default_speed = default_speed, default_speed = default_speed,
walking_speed = walking_speed, walking_speed = walking_speed,
@ -221,7 +223,13 @@ function setup()
avoid = Set { avoid = Set {
'impassable', 'impassable',
'construction', 'construction',
'proposed' 'proposed',
'motorroad'
},
uselocationtags = Set
{
-- 'countryspeeds'
} }
} }
end end
@ -342,11 +350,23 @@ function handle_bicycle_tags(profile,way,result,data)
safety_handler(profile,way,result,data) safety_handler(profile,way,result,data)
end end
function speed_handler(profile,way,result,data) function speed_handler(profile,way,result,data)
data.way_type_allows_pushing = false data.way_type_allows_pushing = false
local extra_speeds
local extraspeed = false
if profile.uselocationtags and profile.uselocationtags.countryspeeds then
extra_speeds = country_speeds.getAccessProfile(data, profile.profile)
if extra_speeds then
if extra_speeds.highway[data.highway] then
extraspeed = extra_speeds.highway[data.highway]
if extraspeed == -1 then
extraspeed = false
end
end
end
end
-- speed -- speed
local bridge_speed = profile.bridge_speeds[data.bridge] local bridge_speed = profile.bridge_speeds[data.bridge]
@ -389,6 +409,12 @@ function speed_handler(profile,way,result,data)
result.forward_speed = profile.amenity_speeds[data.amenity] result.forward_speed = profile.amenity_speeds[data.amenity]
result.backward_speed = profile.amenity_speeds[data.amenity] result.backward_speed = profile.amenity_speeds[data.amenity]
data.way_type_allows_pushing = true data.way_type_allows_pushing = true
elseif extraspeed then
if extraspeed ~= -1 then
result.forward_speed = extraspeed
result.backward_speed = extraspeed
data.way_type_allows_pushing = true
end
elseif profile.bicycle_speeds[data.highway] then elseif profile.bicycle_speeds[data.highway] then
-- regular ways -- regular ways
result.forward_speed = profile.bicycle_speeds[data.highway] result.forward_speed = profile.bicycle_speeds[data.highway]
@ -654,6 +680,10 @@ function process_way(profile, way, result)
implied_oneway = false implied_oneway = false
} }
if profile.uselocationtags and profile.uselocationtags.countryspeeds then
data.location = country_speeds.getcountrytag(way)
end
local handlers = Sequence { local handlers = Sequence {
-- set the default mode for this profile. if can be changed later -- set the default mode for this profile. if can be changed later
-- in case it turns we're e.g. on a ferry -- in case it turns we're e.g. on a ferry

709
profiles/countrybicycle.lua Normal file
View File

@ -0,0 +1,709 @@
-- Bicycle profile
api_version = 4
Set = require('lib/set')
Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers")
TrafficSignal = require("lib/traffic_signal")
find_access_tag = require("lib/access").find_access_tag
country_speeds = require("lib/country_speeds")
limit = require("lib/maxspeed").limit
Measure = require("lib/measure")
function setup()
local default_speed = 15
local walking_speed = 4
return {
properties = {
u_turn_penalty = 20,
traffic_light_penalty = 2,
--weight_name = 'cyclability',
weight_name = 'duration',
process_call_tagless_node = false,
max_speed_for_map_matching = 110/3.6, -- kmph -> m/s
use_turn_restrictions = false,
continue_straight_at_waypoint = false,
mode_change_penalty = 30,
},
profile = 'bicycle',
default_mode = mode.cycling,
default_speed = default_speed,
walking_speed = walking_speed,
oneway_handling = true,
turn_penalty = 6,
turn_bias = 1.4,
use_public_transport = true,
allowed_start_modes = Set {
mode.cycling,
mode.pushing_bike
},
barrier_blacklist = Set {
'yes',
'wall',
'fence'
},
access_tag_whitelist = Set {
'yes',
'permissive',
'designated'
},
access_tag_blacklist = Set {
'no',
'private',
'agricultural',
'forestry',
'delivery',
-- When a way is tagged with `use_sidepath` a parallel way suitable for
-- cyclists is mapped and must be used instead (by law). This tag is
-- used on ways that normally may be used by cyclists, but not when
-- a signposted parallel cycleway is available. For purposes of routing
-- cyclists, this value should be treated as 'no access for bicycles'.
'use_sidepath'
},
restricted_access_tag_list = Set { },
restricted_highway_whitelist = Set { },
-- tags disallow access to in combination with highway=service
service_access_tag_blacklist = Set { },
construction_whitelist = Set {
'no',
'widening',
'minor',
},
access_tags_hierarchy = Sequence {
'bicycle',
'vehicle',
'access'
},
restrictions = Set {
'bicycle'
},
cycleway_tags = Set {
'track',
'lane',
'share_busway',
'sharrow',
'shared',
'shared_lane'
},
opposite_cycleway_tags = Set {
'opposite',
'opposite_lane',
'opposite_track',
},
-- reduce the driving speed by 30% for unsafe roads
-- only used for cyclability metric
unsafe_highway_list = {
primary = 0.5,
secondary = 0.65,
tertiary = 0.8,
primary_link = 0.5,
secondary_link = 0.65,
tertiary_link = 0.8,
},
service_penalties = {
alley = 0.5,
},
bicycle_speeds = {
cycleway = default_speed,
primary = default_speed,
primary_link = default_speed,
secondary = default_speed,
secondary_link = default_speed,
tertiary = default_speed,
tertiary_link = default_speed,
residential = default_speed,
unclassified = default_speed,
living_street = default_speed,
road = default_speed,
service = default_speed,
track = 12,
path = 13
},
pedestrian_speeds = {
footway = walking_speed,
pedestrian = walking_speed,
steps = 2
},
railway_speeds = {
train = 10,
railway = 10,
subway = 10,
light_rail = 10,
monorail = 10,
tram = 10
},
platform_speeds = {
platform = walking_speed
},
amenity_speeds = {
parking = 10,
parking_entrance = 10
},
man_made_speeds = {
pier = walking_speed
},
route_speeds = {
ferry = 5
},
bridge_speeds = {
movable = 5
},
surface_speeds = {
asphalt = default_speed,
chipseal = default_speed,
concrete = default_speed,
concrete_lanes = default_speed,
wood = 10,
metal = 10,
["cobblestone:flattened"] = 10,
paving_stones = 10,
compacted = 10,
cobblestone = 7,
unpaved = 6,
fine_gravel = 10,
gravel = 6,
pebblestone = 6,
grass_paver = 6,
ground = 10,
dirt = 8,
earth = 6,
grass = 6,
mud = 3,
sand = 3,
woodchips = 3,
sett = 9
},
classes = Sequence {
'ferry', 'tunnel'
},
-- Which classes should be excludable
-- This increases memory usage so its disabled by default.
excludable = Sequence {
-- Set {'ferry'}
},
tracktype_speeds = {
},
smoothness_speeds = {
},
avoid = Set {
'impassable',
'construction',
'proposed',
'motorroad'
},
uselocationtags = Set
{
-- 'countryspeeds',
}
}
end
function process_node(profile, node, result)
-- parse access and barrier tags
local highway = node:get_value_by_key("highway")
local is_crossing = highway and highway == "crossing"
local access = find_access_tag(node, profile.access_tags_hierarchy)
if access and access ~= "" then
-- access restrictions on crossing nodes are not relevant for
-- the traffic on the road
if profile.access_tag_blacklist[access] and not is_crossing then
result.barrier = true
end
else
local barrier = node:get_value_by_key("barrier")
if barrier and "" ~= barrier then
if profile.barrier_blacklist[barrier] then
result.barrier = true
end
end
end
-- check if node is a traffic light
result.traffic_lights = TrafficSignal.get_value(node)
end
function handle_bicycle_tags(profile,way,result,data)
-- initial routability check, filters out buildings, boundaries, etc
data.route = way:get_value_by_key("route")
data.man_made = way:get_value_by_key("man_made")
data.railway = way:get_value_by_key("railway")
data.amenity = way:get_value_by_key("amenity")
data.public_transport = way:get_value_by_key("public_transport")
data.bridge = way:get_value_by_key("bridge")
if (not data.highway or data.highway == '') and
(not data.route or data.route == '') and
(not profile.use_public_transport or not data.railway or data.railway=='') and
(not data.amenity or data.amenity=='') and
(not data.man_made or data.man_made=='') and
(not data.public_transport or data.public_transport=='') and
(not data.bridge or data.bridge=='')
then
return false
end
-- access
data.access = find_access_tag(way, profile.access_tags_hierarchy)
if data.access and profile.access_tag_blacklist[data.access] then
return false
end
-- other tags
data.junction = way:get_value_by_key("junction")
data.maxspeed = Measure.get_max_speed(way:get_value_by_key ("maxspeed")) or 0
data.maxspeed_forward = Measure.get_max_speed(way:get_value_by_key("maxspeed:forward")) or 0
data.maxspeed_backward = Measure.get_max_speed(way:get_value_by_key("maxspeed:backward")) or 0
data.barrier = way:get_value_by_key("barrier")
data.oneway = way:get_value_by_key("oneway")
data.oneway_bicycle = way:get_value_by_key("oneway:bicycle")
data.cycleway = way:get_value_by_key("cycleway")
data.cycleway_left = way:get_value_by_key("cycleway:left")
data.cycleway_right = way:get_value_by_key("cycleway:right")
data.duration = way:get_value_by_key("duration")
data.service = way:get_value_by_key("service")
data.foot = way:get_value_by_key("foot")
data.foot_forward = way:get_value_by_key("foot:forward")
data.foot_backward = way:get_value_by_key("foot:backward")
data.bicycle = way:get_value_by_key("bicycle")
speed_handler(profile,way,result,data)
oneway_handler(profile,way,result,data)
cycleway_handler(profile,way,result,data)
bike_push_handler(profile,way,result,data)
-- maxspeed
limit( result, data.maxspeed, data.maxspeed_forward, data.maxspeed_backward )
-- not routable if no speed assigned
-- this avoid assertions in debug builds
if result.forward_speed <= 0 and result.duration <= 0 then
result.forward_mode = mode.inaccessible
end
if result.backward_speed <= 0 and result.duration <= 0 then
result.backward_mode = mode.inaccessible
end
safety_handler(profile,way,result,data)
end
function speed_handler(profile,way,result,data)
data.way_type_allows_pushing = false
local extra_speeds
local extraspeed
if profile.uselocationtags and profile.uselocationtags.countryspeeds then
extra_speeds = country_speeds.getAccessProfile(data, profile.profile)
if extra_speeds then
if extra_speeds.highway[data.highway] then
extraspeed = extra_speeds.highway[data.highway]
if extraspeed == -1 then
extraspeed = false
end
end
end
end
-- speed
local bridge_speed = profile.bridge_speeds[data.bridge]
if (bridge_speed and bridge_speed > 0) then
data.highway = data.bridge
if data.duration and durationIsValid(data.duration) then
result.duration = math.max( parseDuration(data.duration), 1 )
end
result.forward_speed = bridge_speed
result.backward_speed = bridge_speed
data.way_type_allows_pushing = true
elseif profile.route_speeds[data.route] then
-- ferries (doesn't cover routes tagged using relations)
result.forward_mode = mode.ferry
result.backward_mode = mode.ferry
if data.duration and durationIsValid(data.duration) then
result.duration = math.max( 1, parseDuration(data.duration) )
else
result.forward_speed = profile.route_speeds[data.route]
result.backward_speed = profile.route_speeds[data.route]
end
-- railway platforms (old tagging scheme)
elseif data.railway and profile.platform_speeds[data.railway] then
result.forward_speed = profile.platform_speeds[data.railway]
result.backward_speed = profile.platform_speeds[data.railway]
data.way_type_allows_pushing = true
-- public_transport platforms (new tagging platform)
elseif data.public_transport and profile.platform_speeds[data.public_transport] then
result.forward_speed = profile.platform_speeds[data.public_transport]
result.backward_speed = profile.platform_speeds[data.public_transport]
data.way_type_allows_pushing = true
-- railways
elseif profile.use_public_transport and data.railway and profile.railway_speeds[data.railway] and profile.access_tag_whitelist[data.access] then
result.forward_mode = mode.train
result.backward_mode = mode.train
result.forward_speed = profile.railway_speeds[data.railway]
result.backward_speed = profile.railway_speeds[data.railway]
elseif data.amenity and profile.amenity_speeds[data.amenity] then
-- parking areas
result.forward_speed = profile.amenity_speeds[data.amenity]
result.backward_speed = profile.amenity_speeds[data.amenity]
data.way_type_allows_pushing = true
elseif extraspeed then
if extraspeed ~= -1 then
result.forward_speed = extraspeed
result.backward_speed = extraspeed
data.way_type_allows_pushing = true
end
elseif profile.bicycle_speeds[data.highway] then
-- regular ways
result.forward_speed = profile.bicycle_speeds[data.highway]
result.backward_speed = profile.bicycle_speeds[data.highway]
data.way_type_allows_pushing = true
elseif data.access and profile.access_tag_whitelist[data.access] then
-- unknown way, but valid access tag
result.forward_speed = profile.default_speed
result.backward_speed = profile.default_speed
data.way_type_allows_pushing = true
end
end
function oneway_handler(profile,way,result,data)
-- oneway
data.implied_oneway = data.junction == "roundabout" or data.junction == "circular" or data.highway == "motorway"
data.reverse = false
if data.oneway_bicycle == "yes" or data.oneway_bicycle == "1" or data.oneway_bicycle == "true" then
result.backward_mode = mode.inaccessible
elseif data.oneway_bicycle == "no" or data.oneway_bicycle == "0" or data.oneway_bicycle == "false" then
-- prevent other cases
elseif data.oneway_bicycle == "-1" then
result.forward_mode = mode.inaccessible
data.reverse = true
elseif data.oneway == "yes" or data.oneway == "1" or data.oneway == "true" then
result.backward_mode = mode.inaccessible
elseif data.oneway == "no" or data.oneway == "0" or data.oneway == "false" then
-- prevent other cases
elseif data.oneway == "-1" then
result.forward_mode = mode.inaccessible
data.reverse = true
elseif data.implied_oneway then
result.backward_mode = mode.inaccessible
end
end
function cycleway_handler(profile,way,result,data)
-- cycleway
data.has_cycleway_forward = false
data.has_cycleway_backward = false
data.is_twoway = result.forward_mode ~= mode.inaccessible and result.backward_mode ~= mode.inaccessible and not data.implied_oneway
-- cycleways on normal roads
if data.is_twoway then
if data.cycleway and profile.cycleway_tags[data.cycleway] then
data.has_cycleway_backward = true
data.has_cycleway_forward = true
end
if (data.cycleway_right and profile.cycleway_tags[data.cycleway_right]) or (data.cycleway_left and profile.opposite_cycleway_tags[data.cycleway_left]) then
data.has_cycleway_forward = true
end
if (data.cycleway_left and profile.cycleway_tags[data.cycleway_left]) or (data.cycleway_right and profile.opposite_cycleway_tags[data.cycleway_right]) then
data.has_cycleway_backward = true
end
else
local has_twoway_cycleway = (data.cycleway and profile.opposite_cycleway_tags[data.cycleway]) or (data.cycleway_right and profile.opposite_cycleway_tags[data.cycleway_right]) or (data.cycleway_left and profile.opposite_cycleway_tags[data.cycleway_left])
local has_opposite_cycleway = (data.cycleway_left and profile.opposite_cycleway_tags[data.cycleway_left]) or (data.cycleway_right and profile.opposite_cycleway_tags[data.cycleway_right])
local has_oneway_cycleway = (data.cycleway and profile.cycleway_tags[data.cycleway]) or (data.cycleway_right and profile.cycleway_tags[data.cycleway_right]) or (data.cycleway_left and profile.cycleway_tags[data.cycleway_left])
-- set cycleway even though it is an one-way if opposite is tagged
if has_twoway_cycleway then
data.has_cycleway_backward = true
data.has_cycleway_forward = true
elseif has_opposite_cycleway then
if not data.reverse then
data.has_cycleway_backward = true
else
data.has_cycleway_forward = true
end
elseif has_oneway_cycleway then
if not data.reverse then
data.has_cycleway_forward = true
else
data.has_cycleway_backward = true
end
end
end
if data.has_cycleway_backward then
result.backward_mode = mode.cycling
result.backward_speed = profile.bicycle_speeds["cycleway"]
end
if data.has_cycleway_forward then
result.forward_mode = mode.cycling
result.forward_speed = profile.bicycle_speeds["cycleway"]
end
end
function bike_push_handler(profile,way,result,data)
-- pushing bikes - if no other mode found
if result.forward_mode == mode.inaccessible or result.backward_mode == mode.inaccessible or
result.forward_speed == -1 or result.backward_speed == -1 then
if data.foot ~= 'no' then
local push_forward_speed = nil
local push_backward_speed = nil
if profile.pedestrian_speeds[data.highway] then
push_forward_speed = profile.pedestrian_speeds[data.highway]
push_backward_speed = profile.pedestrian_speeds[data.highway]
elseif data.man_made and profile.man_made_speeds[data.man_made] then
push_forward_speed = profile.man_made_speeds[data.man_made]
push_backward_speed = profile.man_made_speeds[data.man_made]
else
if data.foot == 'yes' then
push_forward_speed = profile.walking_speed
if not data.implied_oneway then
push_backward_speed = profile.walking_speed
end
elseif data.foot_forward == 'yes' then
push_forward_speed = profile.walking_speed
elseif data.foot_backward == 'yes' then
push_backward_speed = profile.walking_speed
elseif data.way_type_allows_pushing then
push_forward_speed = profile.walking_speed
if not data.implied_oneway then
push_backward_speed = profile.walking_speed
end
end
end
if push_forward_speed and (result.forward_mode == mode.inaccessible or result.forward_speed == -1) then
result.forward_mode = mode.pushing_bike
result.forward_speed = push_forward_speed
end
if push_backward_speed and (result.backward_mode == mode.inaccessible or result.backward_speed == -1)then
result.backward_mode = mode.pushing_bike
result.backward_speed = push_backward_speed
end
end
end
-- dismount
if data.bicycle == "dismount" then
result.forward_mode = mode.pushing_bike
result.backward_mode = mode.pushing_bike
result.forward_speed = profile.walking_speed
result.backward_speed = profile.walking_speed
end
end
function safety_handler(profile,way,result,data)
-- convert duration into cyclability
if profile.properties.weight_name == 'cyclability' then
local safety_penalty = profile.unsafe_highway_list[data.highway] or 1.
local is_unsafe = safety_penalty < 1
-- primaries that are one ways are probably huge primaries where the lanes need to be separated
if is_unsafe and data.highway == 'primary' and not data.is_twoway then
safety_penalty = safety_penalty * 0.5
end
if is_unsafe and data.highway == 'secondary' and not data.is_twoway then
safety_penalty = safety_penalty * 0.6
end
local forward_is_unsafe = is_unsafe and not data.has_cycleway_forward
local backward_is_unsafe = is_unsafe and not data.has_cycleway_backward
local is_undesireable = data.highway == "service" and profile.service_penalties[data.service]
local forward_penalty = 1.
local backward_penalty = 1.
if forward_is_unsafe then
forward_penalty = math.min(forward_penalty, safety_penalty)
end
if backward_is_unsafe then
backward_penalty = math.min(backward_penalty, safety_penalty)
end
if is_undesireable then
forward_penalty = math.min(forward_penalty, profile.service_penalties[data.service])
backward_penalty = math.min(backward_penalty, profile.service_penalties[data.service])
end
if result.forward_speed > 0 then
-- convert from km/h to m/s
result.forward_rate = result.forward_speed / 3.6 * forward_penalty
end
if result.backward_speed > 0 then
-- convert from km/h to m/s
result.backward_rate = result.backward_speed / 3.6 * backward_penalty
end
if result.duration > 0 then
result.weight = result.duration / forward_penalty
end
end
end
function process_way(profile, way, result)
-- the initial filtering of ways based on presence of tags
-- affects processing times significantly, because all ways
-- have to be checked.
-- to increase performance, prefetching and initial tag check
-- is done directly instead of via a handler.
-- in general we should try to abort as soon as
-- possible if the way is not routable, to avoid doing
-- unnecessary work. this implies we should check things that
-- commonly forbids access early, and handle edge cases later.
-- data table for storing intermediate values during processing
local data = {
-- prefetch tags
highway = way:get_value_by_key('highway'),
route = nil,
man_made = nil,
railway = nil,
amenity = nil,
public_transport = nil,
bridge = nil,
access = nil,
junction = nil,
maxspeed = nil,
maxspeed_forward = nil,
maxspeed_backward = nil,
barrier = nil,
oneway = nil,
oneway_bicycle = nil,
cycleway = nil,
cycleway_left = nil,
cycleway_right = nil,
duration = nil,
service = nil,
foot = nil,
foot_forward = nil,
foot_backward = nil,
bicycle = nil,
way_type_allows_pushing = false,
has_cycleway_forward = false,
has_cycleway_backward = false,
is_twoway = true,
reverse = false,
implied_oneway = false
}
if profile.uselocationtags and profile.uselocationtags.countryspeeds then
data.location = country_speeds.getcountrytag(way)
end
local handlers = Sequence {
-- set the default mode for this profile. if can be changed later
-- in case it turns we're e.g. on a ferry
WayHandlers.default_mode,
-- check various tags that could indicate that the way is not
-- routable. this includes things like status=impassable,
-- toll=yes and oneway=reversible
WayHandlers.blocked_ways,
-- our main handler
handle_bicycle_tags,
-- compute speed taking into account way type, maxspeed tags, etc.
WayHandlers.surface,
-- handle turn lanes and road classification, used for guidance
WayHandlers.classification,
-- handle allowed start/end modes
WayHandlers.startpoint,
-- handle roundabouts
WayHandlers.roundabouts,
-- set name, ref and pronunciation
WayHandlers.names,
-- set classes
WayHandlers.classes,
-- set weight properties of the way
WayHandlers.weights
}
WayHandlers.run(profile, way, result, data, handlers)
end
function process_turn(profile, turn)
-- compute turn penalty as angle^2, with a left/right bias
local normalized_angle = turn.angle / 90.0
if normalized_angle >= 0.0 then
turn.duration = normalized_angle * normalized_angle * profile.turn_penalty / profile.turn_bias
else
turn.duration = normalized_angle * normalized_angle * profile.turn_penalty * profile.turn_bias
end
if turn.is_u_turn then
turn.duration = turn.duration + profile.properties.u_turn_penalty
end
if turn.has_traffic_light then
turn.duration = turn.duration + profile.properties.traffic_light_penalty
end
if profile.properties.weight_name == 'cyclability' then
turn.weight = turn.duration
end
if turn.source_mode == mode.cycling and turn.target_mode ~= mode.cycling then
turn.weight = turn.weight + profile.properties.mode_change_penalty
end
end
return {
setup = setup,
process_way = process_way,
process_node = process_node,
process_turn = process_turn
}

282
profiles/countryfoot.lua Normal file
View File

@ -0,0 +1,282 @@
-- Foot profile
api_version = 2
Set = require('lib/set')
Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers")
find_access_tag = require("lib/access").find_access_tag
country_speeds = require("lib/country_speeds")
function setup()
local walking_speed = 5
return {
properties = {
weight_name = 'duration',
max_speed_for_map_matching = 40/3.6, -- kmph -> m/s
call_tagless_node_function = false,
traffic_light_penalty = 2,
u_turn_penalty = 2,
continue_straight_at_waypoint = false,
use_turn_restrictions = false,
},
profile = 'foot',
default_mode = mode.walking,
default_speed = walking_speed,
oneway_handling = 'specific', -- respect 'oneway:foot' but not 'oneway'
barrier_blacklist = Set {
'yes',
'wall',
'fence'
},
access_tag_whitelist = Set {
'yes',
'foot',
'permissive',
'designated'
},
access_tag_blacklist = Set {
'no',
'agricultural',
'forestry',
'private',
'delivery',
},
restricted_access_tag_list = Set { },
restricted_highway_whitelist = Set { },
construction_whitelist = Set {},
access_tags_hierarchy = Sequence {
'foot',
'access'
},
-- tags disallow access to in combination with highway=service
service_access_tag_blacklist = Set { },
restrictions = Sequence {
'foot'
},
-- list of suffixes to suppress in name change instructions
suffix_list = Set {
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East'
},
avoid = Set {
'impassable',
'proposed',
'motorroad'
},
hwyspeeds = Sequence {
highway = {
primary = walking_speed,
primary_link = walking_speed,
secondary = walking_speed,
secondary_link = walking_speed,
tertiary = walking_speed,
tertiary_link = walking_speed,
unclassified = walking_speed,
residential = walking_speed,
road = walking_speed,
living_street = walking_speed,
service = walking_speed,
track = walking_speed,
path = walking_speed,
steps = walking_speed,
pedestrian = walking_speed,
footway = walking_speed,
pier = walking_speed,
},
},
otherspeeds = Sequence {
railway = {
platform = walking_speed
},
amenity = {
parking = walking_speed,
parking_entrance= walking_speed
},
man_made = {
pier = walking_speed
},
leisure = {
track = walking_speed
}
},
route_speeds = {
ferry = 5
},
bridge_speeds = {
},
surface_speeds = {
fine_gravel = walking_speed*0.75,
gravel = walking_speed*0.75,
pebblestone = walking_speed*0.75,
mud = walking_speed*0.5,
sand = walking_speed*0.5
},
tracktype_speeds = {
},
smoothness_speeds = {
},
uselocationtags = Set
{
-- 'countryspeeds',
}
}
end
function process_node(profile, node, result)
-- parse access and barrier tags
local access = find_access_tag(node, profile.access_tags_hierarchy)
if access then
if profile.access_tag_blacklist[access] then
result.barrier = true
end
else
local barrier = node:get_value_by_key("barrier")
if barrier then
-- make an exception for rising bollard barriers
local bollard = node:get_value_by_key("bollard")
local rising_bollard = bollard and "rising" == bollard
if profile.barrier_blacklist[barrier] and not rising_bollard then
result.barrier = true
end
end
end
-- check if node is a traffic light
local tag = node:get_value_by_key("highway")
if "traffic_signals" == tag then
-- Direction should only apply to vehicles
result.traffic_lights = true
end
end
-- main entry point for processsing a way
function process_way(profile, way, result)
-- the intial filtering of ways based on presence of tags
-- affects processing times significantly, because all ways
-- have to be checked.
-- to increase performance, prefetching and intial tag check
-- is done in directly instead of via a handler.
-- in general we should try to abort as soon as
-- possible if the way is not routable, to avoid doing
-- unnecessary work. this implies we should check things that
-- commonly forbids access early, and handle edge cases later.
-- data table for storing intermediate values during processing
local data = {
-- prefetch tags
highway = way:get_value_by_key('highway'),
bridge = way:get_value_by_key('bridge'),
route = way:get_value_by_key('route'),
leisure = way:get_value_by_key('leisure'),
man_made = way:get_value_by_key('man_made'),
railway = way:get_value_by_key('railway'),
platform = way:get_value_by_key('platform'),
amenity = way:get_value_by_key('amenity'),
public_transport = way:get_value_by_key('public_transport')
}
-- perform an quick initial check and abort if the way is
-- obviously not routable. here we require at least one
-- of the prefetched tags to be present, ie. the data table
-- cannot be empty
if next(data) == nil then -- is the data table empty?
return
end
if profile.uselocationtags and profile.uselocationtags.countryspeeds then
data.location = country_speeds.getcountrytag(way)
end
local handlers = Sequence {
-- set the default mode for this profile. if can be changed later
-- in case it turns we're e.g. on a ferry
WayHandlers.default_mode,
-- check various tags that could indicate that the way is not
-- routable. this includes things like status=impassable,
-- toll=yes and oneway=reversible
WayHandlers.blocked_ways,
-- determine access status by checking our hierarchy of
-- access tags, e.g: motorcar, motor_vehicle, vehicle
WayHandlers.access,
-- check whether forward/backward directons are routable
WayHandlers.oneway,
-- check whether forward/backward directons are routable
WayHandlers.destinations,
-- check whether we're using a special transport mode
WayHandlers.ferries,
WayHandlers.movables,
-- compute speed taking into account way type, maxspeed tags, etc.
country_speeds.wayspeed,
WayHandlers.surface,
-- handle turn lanes and road classification, used for guidance
WayHandlers.classification,
-- handle various other flags
WayHandlers.roundabouts,
WayHandlers.startpoint,
-- set name, ref and pronunciation
WayHandlers.names,
-- set weight properties of the way
WayHandlers.weights
}
WayHandlers.run(profile, way, result, data, handlers)
end
function process_turn (profile, turn)
turn.duration = 0.
if turn.direction_modifier == direction_modifier.u_turn then
turn.duration = turn.duration + profile.properties.u_turn_penalty
end
if turn.has_traffic_light then
turn.duration = profile.properties.traffic_light_penalty
end
if profile.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
return {
setup = setup,
process_way = process_way,
process_node = process_node,
process_turn = process_turn
}

View File

@ -6,6 +6,7 @@ Set = require('lib/set')
Sequence = require('lib/sequence') Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers") Handlers = require("lib/way_handlers")
find_access_tag = require("lib/access").find_access_tag find_access_tag = require("lib/access").find_access_tag
country_speeds = require("lib/country_speeds")
function setup() function setup()
local walking_speed = 5 local walking_speed = 5
@ -20,6 +21,7 @@ function setup()
use_turn_restrictions = false, use_turn_restrictions = false,
}, },
profile = 'foot',
default_mode = mode.walking, default_mode = mode.walking,
default_speed = walking_speed, default_speed = walking_speed,
oneway_handling = 'specific', -- respect 'oneway:foot' but not 'oneway' oneway_handling = 'specific', -- respect 'oneway:foot' but not 'oneway'
@ -70,10 +72,11 @@ function setup()
avoid = Set { avoid = Set {
'impassable', 'impassable',
'proposed' 'proposed',
'motorroad'
}, },
speeds = Sequence { hwyspeeds = Sequence {
highway = { highway = {
primary = walking_speed, primary = walking_speed,
primary_link = walking_speed, primary_link = walking_speed,
@ -94,6 +97,9 @@ function setup()
footway = walking_speed, footway = walking_speed,
pier = walking_speed, pier = walking_speed,
}, },
},
otherspeeds = Sequence {
railway = { railway = {
platform = walking_speed platform = walking_speed
@ -132,6 +138,11 @@ function setup()
}, },
smoothness_speeds = { smoothness_speeds = {
},
uselocationtags = Set
{
-- 'countryspeeds'
} }
} }
end end
@ -198,6 +209,12 @@ function process_way(profile, way, result)
if next(data) == nil then -- is the data table empty? if next(data) == nil then -- is the data table empty?
return return
end end
local speedhandler = WayHandlers.speed
if profile.uselocationtags and profile.uselocationtags.countryspeeds then
data.location = country_speeds.getcountrytag(way)
speedhandler =country_speeds.wayspeed
end
local handlers = Sequence { local handlers = Sequence {
-- set the default mode for this profile. if can be changed later -- set the default mode for this profile. if can be changed later
@ -224,7 +241,7 @@ function process_way(profile, way, result)
WayHandlers.movables, WayHandlers.movables,
-- compute speed taking into account way type, maxspeed tags, etc. -- compute speed taking into account way type, maxspeed tags, etc.
WayHandlers.speed, speedhandler,
WayHandlers.surface, WayHandlers.surface,
-- handle turn lanes and road classification, used for guidance -- handle turn lanes and road classification, used for guidance

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,116 @@
-- Assigns extra_speeds list based on location tag
-- based on reading https://wiki.openstreetmap.org/wiki/Key:motorroad
-- and https://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Access_restrictions
-- (esp #Alternative_ideas)
-- We treat all cases of motorroad="yes" as no access.
-- pass in way data and speed to set.
--
local Set = require('lib/set')
local Sequence = require('lib/sequence')
local country_data = {}
local clist = Set
{
'Worldwide',
'AUS',
'AUT',
'tyrol',
'BLR',
'BEL',
'BRA',
'CHN',
'DNK',
'FRA',
'FIN',
'DEU',
'GRC',
'HKG',
'HUN',
'ISL',
'IRL',
'ITA',
'NLD',
'NOR',
'OMN',
'PHL',
'POL',
'ROU',
'RUS',
'SVK',
'ESP',
'SWE',
'CHE',
'THA',
'TUR',
'UKR',
'GBR',
'USA'
}
local cnames = Sequence
{
Australia = "AUS",
Austria = "AUT",
Belarus = "BLR",
Belgium = "BEL",
Brazil = "BRA",
China = "CHN",
Denmark = "DNK",
France = "FRA",
Finland = "FIN",
Germany = "DEU",
Greece = "GRC",
Hong_Kong = "HKG",
Hungary = "HUN",
Iceland = "ISL",
Ireland = "IRL",
Italy = "ITA",
Netherlands = "NLD",
Norway = "NOR",
Oman = "OMN",
Philippines = "PHL",
Poland = "POL",
Romania = "ROU",
Russia = "RUS",
Slovakia = "SVK",
Spain = "ESP",
Sweden = "SWE",
Switzerland = "CHE",
Thailand = "THA",
Turkey = "TUR",
Ukraine = "UKR",
United_Kingdom = "GBR",
United_States_of_America = "USA"
}
function country_data.inAccessSet(country)
if clist[country] then
return true
end
return false
end
function country_data.getCnameEntry(country)
if cnames[country] then
return cnames[country]
end
nob = string.gsub(country, ' ', '_')
if cnames[nob] then
return cnames[nob]
end
return false
end
function country_data.getAccessProfile(country, profile)
if clist[country] then
if countries[country][profile] then
return countries[country][profile]
end
end
return countries['Worldwide'][profile]
end
return country_data

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,125 @@
-- Assigns extra_speeds list based on location tag
-- based on reading https://wiki.openstreetmap.org/wiki/Key:motorroad
-- and https://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Access_restrictions
-- (esp #Alternative_ideas)
--
local Set = require('lib/set')
local Sequence = require('lib/sequence')
local country_foot_data = require('lib/country_foot_data')
local country_bicycle_data = require('lib/country_bicycle_data')
local country_data = require('lib/country_data')
local Tags = require('lib/tags')
local country_speeds = {}
function country_speeds.inAccessSet(country)
return country_data.inAccessSet(country)
end
function country_speeds.getCnameEntry(country)
return country_data.getCnameEntry(country)
end
function country_speeds.getcountrytag(way)
local location = way:get_location_tag('iso_a3_eh')
if not location then
location = way:get_location_tag("iso_a3")
end
if not location then
location = way:get_location_tag("ISO_A3")
end
if not location then
location = way:get_location_tag("ISO3_CODE")
end
if not location then
countryname = way:get_location_tag("name_en")
if countryname then
location = country_speeds.getCnameEntry(countryname)
end
end
if country_data.inAccessSet(location) then
return location
end
return 'Worldwide'
end
function country_speeds.getAccessProfile(data, profile)
local country = data.location
local prof = profile
if profile == 'foot' then
return country_foot_data.getAccessProfile(country, prof)
end
if profile == 'bicycle' then
return country_bicycle_data.getAccessProfile(country, prof)
end
return false
end
-- handle speed (excluding maxspeed)
function country_speeds.wayspeed(profile,way,result,data)
if result.forward_speed ~= -1 then
return -- abort if already set, eg. by a route
end
local key,value,speed
if profile.uselocationtags and profile.uselocationtags.countryspeeds then
-- check for location tags to handle speeds
local extra_speeds = country_speeds.getAccessProfile(data, profile.profile)
if extra_speeds then
key,value,speed = Tags.get_constant_by_key_value(way,extra_speeds)
else
key,value,speed = Tags.get_constant_by_key_value(way,profile.hwyspeeds)
end
if speed and speed ~= -1 then
result.forward_speed = speed
result.backward_speed = speed
else
speed = false
end
else
key,value,speed = Tags.get_constant_by_key_value(way,profile.hwyspeeds)
end
if speed then
-- set speed by way type
result.forward_speed = speed
result.backward_speed = speed
else
if profile.otherspeeds then
key,value,speed = Tags.get_constant_by_key_value(way,profile.otherspeeds)
end
end
if speed then
-- set speed by way type
result.forward_speed = speed
result.backward_speed = speed
end
if not speed then
-- Set the avg speed on ways that are marked accessible
if profile.access_tag_whitelist[data.forward_access] then
result.forward_speed = profile.default_speed
elseif data.forward_access and not profile.access_tag_blacklist[data.forward_access] then
result.forward_speed = profile.default_speed -- fallback to the avg speed if access tag is not blacklisted
elseif not data.forward_access and data.backward_access then
result.forward_mode = mode.inaccessible
end
if profile.access_tag_whitelist[data.backward_access] then
result.backward_speed = profile.default_speed
elseif data.backward_access and not profile.access_tag_blacklist[data.backward_access] then
result.backward_speed = profile.default_speed -- fallback to the avg speed if access tag is not blacklisted
elseif not data.backward_access and data.forward_access then
result.backward_mode = mode.inaccessible
end
end
if result.forward_speed == -1 and result.backward_speed == -1 and result.duration <= 0 then
return false
end
end
return country_speeds

View File

@ -274,8 +274,27 @@ function WayHandlers.speed(profile,way,result,data)
return -- abort if already set, eg. by a route return -- abort if already set, eg. by a route
end end
local key,value,speed = Tags.get_constant_by_key_value(way,profile.speeds) local wayspeeds
if profile.speeds then
wayspeeds = profile.speeds
elseif profile.hwyspeeds then
wayspeeds = profile.hwyspeeds
else
return false
end
local key,value,speed = Tags.get_constant_by_key_value(way,wayspeeds)
if speed then
-- set speed by way type
result.forward_speed = speed
result.backward_speed = speed
else
-- check for other speeds
if profile.otherspeeds then
key,value,speed = Tags.get_constant_by_key_value(way,profile.otherspeeds)
end
end
if speed then if speed then
-- set speed by way type -- set speed by way type
result.forward_speed = speed result.forward_speed = speed
@ -613,6 +632,11 @@ end
-- handle various that can block access -- handle various that can block access
function WayHandlers.blocked_ways(profile,way,result,data) function WayHandlers.blocked_ways(profile,way,result,data)
-- motorroad
if profile.avoid.motorroad and way:get_value_by_key("motorroad") == "yes" then
return false
end
-- areas -- areas
if profile.avoid.area and way:get_value_by_key("area") == "yes" then if profile.avoid.area and way:get_value_by_key("area") == "yes" then
return false return false

View File

@ -0,0 +1,12 @@
{
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "properties": { "name_en": "Switzerland", "iso_a3_eh": "CHE", "ISO3_CODE": "CHE"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.0, 10.0 ], [ 10.0, 10.0 ], [ 10.0, 9.0 ], [ 0.0, 9.0 ], [ 0.0, 10.0 ] ] ] } },
{ "type": "Feature", "properties": { "name_en": "Finland", "iso_a3_eh": "FIN", "ISO3_CODE": "FIN"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 10.0, 10.0 ], [ 20.0, 10.0 ], [ 20.0, 9.0 ], [ 10.0, 9.0 ], [ 10.0, 10.0 ] ] ] } },
{ "type": "Feature", "properties": { "name_en": "France", "iso_a3_eh": "FRA", "ISO3_CODE": "FRA"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.0, 9.0 ], [ 10.0, 9.0 ], [ 10.0, 8.0 ], [ 0.0, 8.0 ], [ 0.0, 9.0 ] ] ] } },
{ "type": "Feature", "properties": {"name_en": "Belgium", "iso_a3_eh": "BEL", "ISO3_CODE": "BEL"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 10.0, 9.0 ], [ 20.0, 9.0 ], [ 20.0, 8.0 ], [ 10.0, 8.0 ], [ 10.0, 9.0 ] ] ] } },
{ "type": "Feature", "properties": {"name_en": "Greece", "iso_a3_eh": "GRC", "ISO3_CODE": "GRC" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.0, 8.0 ], [ 10.0, 8.0 ], [ 10.0, 7.0 ], [ 0.0, 7.0 ], [ 0.0, 8.0 ] ] ] } },
{ "type": "Feature", "properties": {"name_en": "Ireland", "iso_a3_eh": "IRL", "ISO3_CODE": "IRL" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 10.0, 8.0 ], [ 20.0, 8.0 ], [ 20.0, 7.0 ], [ 10.0, 7.0 ], [ 10.0, 8.0 ] ] ] } },
{ "type": "Feature", "properties": {"name_en": "Lithuania", "iso_a3_eh": "LIU", "ISO3_CODE": "LIU" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.0, 7.0 ], [ 10.0, 7.0 ], [ 10.0, 6.0 ], [ 0.0, 6.0 ], [ 0.0, 7.0 ] ] ] } }
]
}

File diff suppressed because one or more lines are too long

Binary file not shown.