Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1fd02bb8d | ||
|
|
54d02fac15 | ||
|
|
0a1418c766 | ||
|
|
1d367ccc0d | ||
|
|
860c452b83 | ||
|
|
3b096963a0 | ||
|
|
7154ed9d59 | ||
|
|
8f633e61bf | ||
|
|
86dd319d29 | ||
|
|
89d32eca94 | ||
|
|
f5120d1cec | ||
|
|
d30d28cf4a | ||
|
|
87de37168b | ||
|
|
658b8ef738 | ||
|
|
a2c7f82ec8 | ||
|
|
be49ed3e91 | ||
|
|
6763d4c097 | ||
|
|
6d2860e909 | ||
|
|
d2764bc405 | ||
|
|
005a146223 | ||
|
|
02754647f4 | ||
|
|
82cebfa1f8 | ||
|
|
986bb6f93d | ||
|
|
0c0ab78f13 | ||
|
|
99cda66b58 | ||
|
|
27fa2fc1d0 | ||
|
|
7434f18d04 | ||
|
|
7d1a12a12d | ||
|
|
6d7420e4e5 | ||
|
|
8a44660102 |
@ -13,6 +13,7 @@ notifications:
|
|||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
- "5.16"
|
||||||
# enable building tags
|
# enable building tags
|
||||||
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||||
|
|
||||||
@ -161,6 +162,14 @@ matrix:
|
|||||||
after_success:
|
after_success:
|
||||||
- ./scripts/travis/publish.sh
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode9.2
|
||||||
|
compiler: "mason-osx-release-node-4"
|
||||||
|
# we use the xcode provides clang and don't install our own
|
||||||
|
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="4"
|
||||||
|
after_success:
|
||||||
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
# Shared Library
|
# Shared Library
|
||||||
- os: linux
|
- os: linux
|
||||||
compiler: "gcc-7-release-shared"
|
compiler: "gcc-7-release-shared"
|
||||||
|
|||||||
44
CHANGELOG.md
44
CHANGELOG.md
@ -1,13 +1,51 @@
|
|||||||
# UNRELEASED
|
# 5.16.5
|
||||||
- Changes from 5.15.1:
|
- Changes from 5.16.4:
|
||||||
|
- Debug:
|
||||||
|
- ADDED: Made toEdges allocation more robust and add better memory usage debugging.
|
||||||
|
|
||||||
|
# 5.16.4
|
||||||
|
- Changes from 5.16.3:
|
||||||
|
- Bugfixes:
|
||||||
|
- FIXED: Properly calculate annotations for speeds, durations and distances when waypoints are used with mapmatching [#4949](https://github.com/Project-OSRM/osrm-backend/pull/4949)
|
||||||
|
|
||||||
|
# 5.16.3
|
||||||
|
- Changes from 5.16.2:
|
||||||
|
- FIXED: Remove the last short annotation segment in `trimShortSegments` [#4946](https://github.com/Project-OSRM/osrm-backend/pull/4946)
|
||||||
|
- Performance
|
||||||
|
- FIXED: Speed up response time when lots of legs exist and geojson is used with `steps=true` [#4936](https://github.com/Project-OSRM/osrm-backend/pull/4936)
|
||||||
|
|
||||||
|
# 5.16.2
|
||||||
|
- Changes from 5.16.1:
|
||||||
|
- Bugfixes:
|
||||||
|
- FIXED #4920: Use smaller range for U-turn angles in map-matching [#4920](https://github.com/Project-OSRM/osrm-backend/pull/4920)
|
||||||
|
|
||||||
|
# 5.16.1
|
||||||
|
- Changes from 5.16.0:
|
||||||
|
- Bugfixes
|
||||||
|
- FIXED #4909: deduplication of route steps when waypoints are used [#4909](https://github.com/Project-OSRM/osrm-backend/issues/4909)
|
||||||
|
|
||||||
|
# 5.16.0
|
||||||
|
- Changes from 5.15.2:
|
||||||
- Guidance
|
- Guidance
|
||||||
- ADDED #4676: Support for maneuver override relation, allowing data-driven overrides for turn-by-turn instructions [#4676](https://github.com/Project-OSRM/osrm-backend/pull/4676)
|
- ADDED #4676: Support for maneuver override relation, allowing data-driven overrides for turn-by-turn instructions [#4676](https://github.com/Project-OSRM/osrm-backend/pull/4676)
|
||||||
- CHANGED #4830: Announce reference change if names are empty
|
- CHANGED #4830: Announce reference change if names are empty
|
||||||
- CHANGED #4835: MAXIMAL_ALLOWED_SEPARATION_WIDTH increased to 12 meters
|
- CHANGED #4835: MAXIMAL_ALLOWED_SEPARATION_WIDTH increased to 12 meters
|
||||||
|
- CHANGED #4842: Lower priority links from a motorway now are used as motorway links [#4842](https://github.com/Project-OSRM/osrm-backend/pull/4842)
|
||||||
|
- CHANGED #4895: Use ramp bifurcations as fork intersections [#4895](https://github.com/Project-OSRM/osrm-backend/issues/4895)
|
||||||
|
- CHANGED #4893: Handle motorway forks with links as normal motorway intersections[#4893](https://github.com/Project-OSRM/osrm-backend/issues/4893)
|
||||||
|
- FIXED #4905: Check required tags of `maneuver` relations [#4905](https://github.com/Project-OSRM/osrm-backend/pull/4905)
|
||||||
- Profile:
|
- Profile:
|
||||||
- FIXED: `highway=service` will now be used for restricted access, `access=private` is still disabled for snapping.
|
- FIXED: `highway=service` will now be used for restricted access, `access=private` is still disabled for snapping.
|
||||||
- ADDED #4775: Exposes more information to the turn function, now being able to set turn weights with highway and access information of the turn as well as other roads at the intersection [#4775](https://github.com/Project-OSRM/osrm-backend/issues/4775)
|
- ADDED #4775: Exposes more information to the turn function, now being able to set turn weights with highway and access information of the turn as well as other roads at the intersection [#4775](https://github.com/Project-OSRM/osrm-backend/issues/4775)
|
||||||
- FIXED: #4763: Add support for non-numerical units in car profile for maxheight [#4763](https://github.com/Project-OSRM/osrm-backend/issues/4763)
|
- FIXED #4763: Add support for non-numerical units in car profile for maxheight [#4763](https://github.com/Project-OSRM/osrm-backend/issues/4763)
|
||||||
|
- ADDED #4872: Handling of `barrier=height_restrictor` nodes [#4872](https://github.com/Project-OSRM/osrm-backend/pull/4872)
|
||||||
|
|
||||||
|
# 5.15.2
|
||||||
|
- Changes from 5.15.1:
|
||||||
|
- Features:
|
||||||
|
- ADDED: Exposed the waypoints parameter in the node bindings interface
|
||||||
|
- Bugfixes:
|
||||||
|
- FIXED: Segfault causing bug in leg collapsing map matching when traversing edges in reverse
|
||||||
|
|
||||||
# 5.15.1
|
# 5.15.1
|
||||||
- Changes from 5.15.0:
|
- Changes from 5.15.0:
|
||||||
|
|||||||
@ -61,7 +61,7 @@ endif()
|
|||||||
project(OSRM C CXX)
|
project(OSRM C CXX)
|
||||||
set(OSRM_VERSION_MAJOR 5)
|
set(OSRM_VERSION_MAJOR 5)
|
||||||
set(OSRM_VERSION_MINOR 16)
|
set(OSRM_VERSION_MINOR 16)
|
||||||
set(OSRM_VERSION_PATCH 0)
|
set(OSRM_VERSION_PATCH 5)
|
||||||
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
|
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
|
||||||
|
|
||||||
add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
|
add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|||||||
@ -45,3 +45,11 @@ Feature: Car - Barriers
|
|||||||
| bollard | | |
|
| bollard | | |
|
||||||
| bollard | rising | x |
|
| bollard | rising | x |
|
||||||
| bollard | removable | |
|
| bollard | removable | |
|
||||||
|
|
||||||
|
Scenario: Car - Height restrictions
|
||||||
|
Then routability should be
|
||||||
|
| node/barrier | node/maxheight | bothw |
|
||||||
|
| height_restrictor | | x |
|
||||||
|
| height_restrictor | 1 | |
|
||||||
|
| height_restrictor | 3 | x |
|
||||||
|
| height_restrictor | default | x |
|
||||||
|
|||||||
@ -198,11 +198,26 @@ Feature: Maneuver tag support
|
|||||||
| pt | 395 | no | primary |
|
| pt | 395 | no | primary |
|
||||||
|
|
||||||
And the relations
|
And the relations
|
||||||
| type | way:from | node:via | way:via | way:to | maneuver |
|
| type | way:from | node:via | way:via | way:to | maneuver | # |
|
||||||
| maneuver | zy | p | yp | pt | suppress |
|
| maneuver | zy | p | yp | pt | suppress | original: depart,on ramp left,fork slight left,arrive |
|
||||||
|
|
||||||
|
And the relations
|
||||||
|
| type | way:from | way:via | way:to | maneuver | # |
|
||||||
|
| maneuver | zy | yp | pb | suppress | invalid relation: missing node:via |
|
||||||
|
|
||||||
|
And the relations
|
||||||
|
| type | node:via | way:via | way:to | maneuver | # |
|
||||||
|
| maneuver | p | yp | pb | suppress | invalid relation: missing way:from |
|
||||||
|
|
||||||
|
And the relations
|
||||||
|
| type | way:from | node:via | way:via | maneuver | # |
|
||||||
|
| maneuver | zy | p | yp | suppress | invalid relation: missing way:to |
|
||||||
|
|
||||||
|
And the relations
|
||||||
|
| type | way:from | node:via | way:via | way:to | maneuver | # |
|
||||||
|
| maneuver | zy | y, p | yp | pb | suppress | invalid relation: multiple node:via |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns |
|
| waypoints | route | turns |
|
||||||
| z,t | NY Ave,395,395 | depart,on ramp left,arrive |
|
| z,t | NY Ave,395,395 | depart,on ramp left,arrive |
|
||||||
#original | z,t | NY Ave,,395,395 | depart,on ramp left,fork slight left,arrive |
|
| z,b | NY Ave,,4th St,4th St | depart,on ramp left,fork slight right,arrive |
|
||||||
|
|
||||||
|
|||||||
@ -281,3 +281,67 @@ Feature: Motorway Guidance
|
|||||||
| waypoints | route | turns |
|
| waypoints | route | turns |
|
||||||
| a,d | , | depart,arrive |
|
| a,d | , | depart,arrive |
|
||||||
| b,d | , | depart,arrive |
|
| b,d | , | depart,arrive |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Ramp Exit with Lower Priority
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a-b-c-d-e
|
||||||
|
`--f-g
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | oneway |
|
||||||
|
| abcde | trunk | |
|
||||||
|
| bfg | primary_link | yes |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,e | abcde,abcde | depart,arrive |
|
||||||
|
| a,g | abcde,bfg,bfg | depart,off ramp slight right,arrive |
|
||||||
|
|
||||||
|
|
||||||
|
# https://www.openstreetmap.org/node/67366428#map=18/33.64613/-84.44425
|
||||||
|
Scenario: Ramp Bifurcations should not be suppressed
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
/-----------c /-----------e
|
||||||
|
a---b------------------d------------f
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | name | destination |
|
||||||
|
| ab | motorway | | |
|
||||||
|
| bc | motorway_link | | City 17 |
|
||||||
|
| bd | motorway_link | | |
|
||||||
|
| de | motorway_link | | Domestic Terminal;Camp Creek Parkway;Riverdale Road |
|
||||||
|
| df | motorway_link | | Montgomery |
|
||||||
|
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,c | ,, | depart,fork slight left,arrive |
|
||||||
|
| a,e | ,,, | depart,fork slight right,fork slight left,arrive |
|
||||||
|
| a,f | ,,, | depart,fork slight right,fork slight right,arrive |
|
||||||
|
|
||||||
|
|
||||||
|
# https://www.openstreetmap.org/#map=19/53.46186/-2.24509
|
||||||
|
Scenario: Highway Fork with a Link
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
/-----------d
|
||||||
|
a-b-c------------e
|
||||||
|
\-----------f
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abce | motorway |
|
||||||
|
| cf | motorway |
|
||||||
|
| cd | motorway_link |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abce,cd,cd | depart,off ramp slight left,arrive |
|
||||||
|
| a,e | abce,abce | depart,arrive |
|
||||||
|
| a,f | abce,cf,cf | depart,turn slight right,arrive |
|
||||||
|
|||||||
@ -129,8 +129,12 @@ Feature: osrm-extract lua ways:get_nodes()
|
|||||||
"""
|
"""
|
||||||
functions = require('testbot')
|
functions = require('testbot')
|
||||||
|
|
||||||
|
functions.process_node = function(profile, node, result, relations)
|
||||||
|
print ('node ' .. tostring(node:get_location_tag('answer')))
|
||||||
|
end
|
||||||
|
|
||||||
functions.process_way = function(profile, way, result, relations)
|
functions.process_way = function(profile, way, result, relations)
|
||||||
print ('answer ' .. tostring(way:get_location_tag('answer')))
|
print ('way ' .. tostring(way:get_location_tag('answer')))
|
||||||
result.forward_mode = mode.driving
|
result.forward_mode = mode.driving
|
||||||
result.forward_speed = 1
|
result.forward_speed = 1
|
||||||
end
|
end
|
||||||
@ -148,4 +152,5 @@ Feature: osrm-extract lua ways:get_nodes()
|
|||||||
|
|
||||||
When I run "osrm-extract --profile {profile_file} {osm_file} --location-dependent-data test/data/regions/null-island.geojson"
|
When I run "osrm-extract --profile {profile_file} {osm_file} --location-dependent-data test/data/regions/null-island.geojson"
|
||||||
Then it should exit successfully
|
Then it should exit successfully
|
||||||
And stdout should contain "answer 42"
|
And stdout should contain "node 42"
|
||||||
|
And stdout should contain "way 42"
|
||||||
|
|||||||
@ -74,7 +74,7 @@ module.exports = function () {
|
|||||||
|
|
||||||
if (headers.has('turns')) {
|
if (headers.has('turns')) {
|
||||||
if (json.matchings.length != 1) throw new Error('*** Checking turns only supported for matchings with one subtrace');
|
if (json.matchings.length != 1) throw new Error('*** Checking turns only supported for matchings with one subtrace');
|
||||||
turns = this.turnList(json.matchings[0].instructions);
|
turns = this.turnList(json.matchings[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headers.has('route')) {
|
if (headers.has('route')) {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ Feature: Annotations
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
And the query options
|
And the query options
|
||||||
| annotations | duration,speed,weight |
|
| annotations | duration,speed,weight,nodes |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | highway |
|
| nodes | highway |
|
||||||
@ -22,10 +22,10 @@ Feature: Annotations
|
|||||||
| lm | residential |
|
| lm | residential |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | a:speed | a:weight |
|
| from | to | route | a:speed | a:weight | a:nodes |
|
||||||
| h | j | hk,jk,jk | 6.7:6.7 | 15:15 |
|
| h | j | hk,jk,jk | 6.7:6.7 | 15:15 | 1:4:3 |
|
||||||
| i | m | il,lm,lm | 6.7:6.7 | 15:15 |
|
| i | m | il,lm,lm | 6.7:6.7 | 15:15 | 2:5:6 |
|
||||||
| j | m | jk,lm | 6.7:6.7:6.7 | 15:15:15 |
|
| j | m | jk,lm | 6.7:6.7:6.7 | 15:15:15 | 3:4:5:6 |
|
||||||
|
|
||||||
|
|
||||||
Scenario: There should be different forward/reverse datasources
|
Scenario: There should be different forward/reverse datasources
|
||||||
@ -82,4 +82,4 @@ Feature: Annotations
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | a:speed | a:distance | a:duration | a:nodes |
|
| from | to | route | a:speed | a:distance | a:duration | a:nodes |
|
||||||
| a | c | abc,abc | 10:10:10 | 249.998641:299.931643:0 | 25:30:0 | 1:2:3 |
|
| a | c | abc,abc | 10:10 | 249.998641:299.931643 | 25:30 | 1:2:3 |
|
||||||
|
|||||||
@ -626,3 +626,170 @@ Feature: Basic Map Matching
|
|||||||
| trace | timestamps | matchings | code |
|
| trace | timestamps | matchings | code |
|
||||||
| abbecd | 10 11 27 1516914902 1516914913 1516914952 | ab,ecd | Ok |
|
| abbecd | 10 11 27 1516914902 1516914913 1516914952 | ab,ecd | Ok |
|
||||||
|
|
||||||
|
Scenario: Regression test - waypoints trimming too much geometry
|
||||||
|
# fixes bug in map matching collapsing that was dropping path geometries
|
||||||
|
# after segments that had 0 distance in internal route results
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
ad
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|e g
|
||||||
|
b--------------c
|
||||||
|
f h
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
|
||||||
|
Given the query options
|
||||||
|
| waypoints | 0;4 |
|
||||||
|
| overview | full |
|
||||||
|
|
||||||
|
When I match I should get
|
||||||
|
| trace | geometry | code |
|
||||||
|
| defgh | 1,1,1,0.999461,1.000674,0.999461 | Ok |
|
||||||
|
|
||||||
|
@match @testbot
|
||||||
|
Scenario: Regression test - waypoints trimming too much geometry
|
||||||
|
Given the profile "testbot"
|
||||||
|
Given a grid size of 10 meters
|
||||||
|
Given the query options
|
||||||
|
| geometries | geojson |
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
bh
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
c
|
||||||
|
g\
|
||||||
|
\k
|
||||||
|
\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
j f
|
||||||
|
"""
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| hc |
|
||||||
|
| cf |
|
||||||
|
Given the query options
|
||||||
|
| waypoints | 0;3 |
|
||||||
|
| overview | full |
|
||||||
|
When I match I should get
|
||||||
|
| trace | geometry | code |
|
||||||
|
| bgkj | 1.000135,1,1.000135,0.99964,1.000387,0.999137 | Ok |
|
||||||
|
|
||||||
|
|
||||||
|
@match @testbot
|
||||||
|
# Regression test for issue #4919
|
||||||
|
Scenario: Regression test - non-uturn maneuver preferred over uturn
|
||||||
|
Given the profile "testbot"
|
||||||
|
Given a grid size of 10 meters
|
||||||
|
Given the query options
|
||||||
|
| geometries | geojson |
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
e
|
||||||
|
;
|
||||||
|
;
|
||||||
|
a----hb-----c
|
||||||
|
;
|
||||||
|
;
|
||||||
|
d
|
||||||
|
"""
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| abc |
|
||||||
|
| dbe |
|
||||||
|
Given the query options
|
||||||
|
| waypoints | 0;2 |
|
||||||
|
| overview | full |
|
||||||
|
| steps | true |
|
||||||
|
When I match I should get
|
||||||
|
| trace | geometry | turns | code |
|
||||||
|
| abc | 1,0.99973,1.00027,0.99973,1.000539,0.99973 | depart,arrive | Ok |
|
||||||
|
| abd | 1,0.99973,1.00027,0.99973,1.00027,0.999461 | depart,turn right,arrive | Ok |
|
||||||
|
| abe | 1,0.99973,1.00027,0.99973,1.00027,1 | depart,turn left,arrive | Ok |
|
||||||
|
| ahd | 1,0.99973,1.00027,0.99973,1.00027,0.999461 | depart,turn right,arrive | Ok |
|
||||||
|
| ahe | 1,0.99973,1.00027,0.99973,1.00027,1 | depart,turn left,arrive | Ok |
|
||||||
|
|
||||||
|
@match @testbot
|
||||||
|
Scenario: Regression test - add source phantoms properly (one phantom on one edge)
|
||||||
|
Given the profile "testbot"
|
||||||
|
Given a grid size of 10 meters
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a--1-b2-cd3--e
|
||||||
|
"""
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bcd |
|
||||||
|
| de |
|
||||||
|
Given the query options
|
||||||
|
| geometries | geojson |
|
||||||
|
| overview | full |
|
||||||
|
| steps | true |
|
||||||
|
| waypoints | 0;2 |
|
||||||
|
| annotations | duration,weight |
|
||||||
|
| generate_hints | false |
|
||||||
|
When I match I should get
|
||||||
|
| trace | geometry | a:duration | a:weight | duration |
|
||||||
|
| 123 | 1.000135,1,1.000225,1,1.00036,1,1.000405,1,1.00045,1 | 1:1.5:0.5:0.5 | 1:1.5:0.5:0.5 | 3.5 |
|
||||||
|
| 321 | 1.00045,1,1.000405,1,1.00036,1,1.000225,1,1.000135,1 | 0.5:0.5:1.5:1 | 0.5:0.5:1.5:1 | 3.5 |
|
||||||
|
|
||||||
|
@match @testbot
|
||||||
|
Scenario: Regression test - add source phantom properly (two phantoms on one edge)
|
||||||
|
Given the profile "testbot"
|
||||||
|
Given a grid size of 10 meters
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a--1-b23-c4--d
|
||||||
|
"""
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
| cd |
|
||||||
|
Given the query options
|
||||||
|
| geometries | geojson |
|
||||||
|
| overview | full |
|
||||||
|
| steps | true |
|
||||||
|
| waypoints | 0;3 |
|
||||||
|
| annotations | duration,weight |
|
||||||
|
| generate_hints | false |
|
||||||
|
When I match I should get
|
||||||
|
| trace | geometry | a:duration | a:weight | duration |
|
||||||
|
| 1234 | 1.000135,1,1.000225,1,1.000405,1,1.00045,1 | 1:2:0.5 | 1:2:0.5 | 3.5 |
|
||||||
|
| 4321 | 1.00045,1,1.000405,1,1.000225,1,1.000135,1 | 0.5:2:1 | 0.5:2:1 | 3.5 |
|
||||||
|
|
||||||
|
@match @testbot
|
||||||
|
Scenario: Regression test - add source phantom properly (two phantoms on one edge)
|
||||||
|
Given the profile "testbot"
|
||||||
|
Given a grid size of 10 meters
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a--12345-b
|
||||||
|
"""
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
Given the query options
|
||||||
|
| geometries | geojson |
|
||||||
|
| overview | full |
|
||||||
|
| steps | true |
|
||||||
|
| waypoints | 0;3 |
|
||||||
|
| annotations | duration,weight,distance |
|
||||||
|
| generate_hints | false |
|
||||||
|
|
||||||
|
# These should have the same weights/duration in either direction
|
||||||
|
When I match I should get
|
||||||
|
| trace | geometry | a:distance | a:duration | a:weight | duration |
|
||||||
|
| 2345 | 1.00018,1,1.000315,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
|
||||||
|
| 4321 | 1.00027,1,1.000135,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
|
||||||
@ -48,10 +48,10 @@ Feature: Traffic - speeds
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | speed | weights | a:datasources |
|
| from | to | route | speed | weights | a:datasources |
|
||||||
| a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 | 1:0:0:0 |
|
| a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 | 1:0:0 |
|
||||||
| a | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | 1:0 |
|
| a | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | 1:0 |
|
||||||
| b | c | bc,bc | 27 km/h | 741.5,0 | 1:0 |
|
| b | c | bc,bc | 27 km/h | 741.5,0 | 1 |
|
||||||
| a | d | ad,ad | 27 km/h | 1275.7,0 | 1:0 |
|
| a | d | ad,ad | 27 km/h | 1275.7,0 | 1 |
|
||||||
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
|
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
|
||||||
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 |
|
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 |
|
||||||
| a | g | ad,df,fb,fb | 30 km/h | 1275.7,487.5,304.7,0 | 1:0:0 |
|
| a | g | ad,df,fb,fb | 30 km/h | 1275.7,487.5,304.7,0 | 1:0:0 |
|
||||||
@ -74,12 +74,12 @@ Feature: Traffic - speeds
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | speed | weights | a:datasources |
|
| from | to | route | speed | weights | a:datasources |
|
||||||
| a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 | 1:0:0:0 |
|
| a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 | 1:0:0 |
|
||||||
| a | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | 1:0 |
|
| a | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | 1:0 |
|
||||||
| b | c | bc,bc | 27 km/h | 741.5,0 | 1:0 |
|
| b | c | bc,bc | 27 km/h | 741.5,0 | 1 |
|
||||||
| a | d | ad,ad | 27 km/h | 1275.7,0 | 1:0 |
|
| a | d | ad,ad | 27 km/h | 1275.7,0 | 1 |
|
||||||
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
|
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
|
||||||
| g | b | ab,ab | 1 km/h | 10010.4,0 | 1:0 |
|
| g | b | ab,ab | 1 km/h | 10010.4,0 | 1 |
|
||||||
| a | g | ab,ab | 1 km/h | 10010.3,0 | 1 |
|
| a | g | ab,ab | 1 km/h | 10010.3,0 | 1 |
|
||||||
|
|
||||||
|
|
||||||
@ -106,14 +106,14 @@ Feature: Traffic - speeds
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | speed | weights | a:datasources |
|
| from | to | route | speed | weights | a:datasources |
|
||||||
| a | b | ab,ab | 1 km/h | 20020.73,0 | 1:0 |
|
| a | b | ab,ab | 1 km/h | 20020.73,0 | 1 |
|
||||||
| a | c | ab,bc,bc | 2 km/h | 20020.73,741.51,0 | 1:1:0 |
|
| a | c | ab,bc,bc | 2 km/h | 20020.73,741.51,0 | 1:1 |
|
||||||
| b | c | bc,bc | 27 km/h | 741.51,0 | 1:0 |
|
| b | c | bc,bc | 27 km/h | 741.51,0 | 1 |
|
||||||
| a | d | ab,eb,de,de | 2 km/h | 20020.73,378.17,400.41,0 | 1:0:0 |
|
| a | d | ab,eb,de,de | 2 km/h | 20020.73,378.17,400.41,0 | 1:0:0 |
|
||||||
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
|
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
|
||||||
| g | b | ab,ab | 1 km/h | 10010.37,0 | 1:0 |
|
| g | b | ab,ab | 1 km/h | 10010.37,0 | 1 |
|
||||||
| a | g | ab,ab | 1 km/h | 10010.36,0 | 1 |
|
| a | g | ab,ab | 1 km/h | 10010.36,0 | 1 |
|
||||||
| g | a | ab,ab | 1 km/h | 10010.36,0 | 1:1 |
|
| g | a | ab,ab | 1 km/h | 10010.36,0 | 1 |
|
||||||
|
|
||||||
|
|
||||||
Scenario: Speeds that isolate a single node (a)
|
Scenario: Speeds that isolate a single node (a)
|
||||||
@ -135,14 +135,14 @@ Feature: Traffic - speeds
|
|||||||
| annotations | true |
|
| annotations | true |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | speed | weights | a:datasources |
|
| from | to | route | speed | weights | a:datasources | a:speed | a:nodes|
|
||||||
| a | b | fb,fb | 36 km/h | 329.4,0 | 0 |
|
| a | b | fb,fb | 36 km/h | 329.4,0 | 0 | 10 | 6:2 |
|
||||||
| a | c | fb,bc,bc | 30 km/h | 329.4,741.5,0 | 0:1:0 |
|
| a | c | fb,bc,bc | 30 km/h | 329.4,741.5,0 | 0:1 | 10:7.5 | 6:2:3 |
|
||||||
| b | c | bc,bc | 27 km/h | 741.5,0 | 1:0 |
|
| b | c | bc,bc | 27 km/h | 741.5,0 | 1 | 7.5 | 2:3 |
|
||||||
| a | d | fb,df,df | 36 km/h | 140,487.5,0 | 0:0:0 |
|
| a | d | fb,df,df | 36 km/h | 140,487.5,0 | 0:0 | 10:10 | 2:6:4 |
|
||||||
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
|
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 | 10 | 4:3 |
|
||||||
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 |
|
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 | 10 | 6:2 |
|
||||||
| a | g | fb,fb | 36 km/h | 164.7,0 | 0 |
|
| a | g | fb,fb | 36 km/h | 164.7,0 | 0 | 10 | 6:2 |
|
||||||
|
|
||||||
|
|
||||||
Scenario: Verify that negative values cause an error, they're not valid at all
|
Scenario: Verify that negative values cause an error, they're not valid at all
|
||||||
|
|||||||
@ -53,8 +53,8 @@ Feature: Weight tests
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | distances | weights | times | a:distance | a:duration | a:weight | a:speed |
|
| waypoints | route | distances | weights | times | a:distance | a:duration | a:weight | a:speed |
|
||||||
| s,t | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3 | 3 | 6.7 |
|
| s,t | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 2.1 | 2.1 | 9.5 |
|
||||||
| t,s | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 3.1 | 3.1 | 6.5 |
|
| t,s | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 2.1 | 2.1 | 9.5 |
|
||||||
| s,e | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 30.026527:10.008842 | 3.1:1 | 3.1:1 | 9.7:10 |
|
| s,e | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 30.026527:10.008842 | 3.1:1 | 3.1:1 | 9.7:10 |
|
||||||
| e,s | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 10.008842:30.026527 | 1:3.1 | 1:3.1 | 10:9.7 |
|
| e,s | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 10.008842:30.026527 | 1:3.1 | 1:3.1 | 10:9.7 |
|
||||||
|
|
||||||
|
|||||||
@ -128,23 +128,24 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
|||||||
|
|
||||||
template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT graph)
|
template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT graph)
|
||||||
{
|
{
|
||||||
std::vector<Edge> edges;
|
util::Log() << "Converting contracted graph with " << graph.GetNumberOfEdges()
|
||||||
edges.reserve(graph.GetNumberOfEdges());
|
<< " to edge list (" << (graph.GetNumberOfEdges() * sizeof(Edge)) << " bytes)";
|
||||||
|
std::vector<Edge> edges(graph.GetNumberOfEdges());
|
||||||
|
|
||||||
|
{
|
||||||
util::UnbufferedLog log;
|
util::UnbufferedLog log;
|
||||||
log << "Getting edges of minimized graph ";
|
log << "Getting edges of minimized graph ";
|
||||||
util::Percent p(log, graph.GetNumberOfNodes());
|
util::Percent p(log, graph.GetNumberOfNodes());
|
||||||
const NodeID number_of_nodes = graph.GetNumberOfNodes();
|
const NodeID number_of_nodes = graph.GetNumberOfNodes();
|
||||||
if (graph.GetNumberOfNodes())
|
std::size_t edge_index = 0;
|
||||||
{
|
|
||||||
Edge new_edge;
|
|
||||||
for (const auto node : util::irange(0u, number_of_nodes))
|
for (const auto node : util::irange(0u, number_of_nodes))
|
||||||
{
|
{
|
||||||
p.PrintStatus(node);
|
p.PrintStatus(node);
|
||||||
for (auto edge : graph.GetAdjacentEdgeRange(node))
|
for (auto edge : graph.GetAdjacentEdgeRange(node))
|
||||||
{
|
{
|
||||||
const NodeID target = graph.GetTarget(edge);
|
const NodeID target = graph.GetTarget(edge);
|
||||||
const ContractorGraph::EdgeData &data = graph.GetEdgeData(edge);
|
const auto &data = graph.GetEdgeData(edge);
|
||||||
|
auto &new_edge = edges[edge_index++];
|
||||||
new_edge.source = node;
|
new_edge.source = node;
|
||||||
new_edge.target = target;
|
new_edge.target = target;
|
||||||
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid");
|
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid");
|
||||||
@ -156,16 +157,12 @@ template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT g
|
|||||||
"edge id invalid");
|
"edge id invalid");
|
||||||
new_edge.data.forward = data.forward;
|
new_edge.data.forward = data.forward;
|
||||||
new_edge.data.backward = data.backward;
|
new_edge.data.backward = data.backward;
|
||||||
edges.push_back(new_edge);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BOOST_ASSERT(edge_index == edges.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort and remove duplicates
|
|
||||||
tbb::parallel_sort(edges.begin(), edges.end());
|
tbb::parallel_sort(edges.begin(), edges.end());
|
||||||
auto new_end = std::unique(edges.begin(), edges.end());
|
|
||||||
edges.resize(new_end - edges.begin());
|
|
||||||
edges.shrink_to_fit();
|
|
||||||
|
|
||||||
return edges;
|
return edges;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -211,12 +211,16 @@ class RouteAPI : public BaseAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<util::json::Value> step_geometries;
|
std::vector<util::json::Value> step_geometries;
|
||||||
|
const auto total_step_count =
|
||||||
|
std::accumulate(legs.begin(), legs.end(), 0, [](const auto &v, const auto &leg) {
|
||||||
|
return v + leg.steps.size();
|
||||||
|
});
|
||||||
|
step_geometries.reserve(total_step_count);
|
||||||
|
|
||||||
for (const auto idx : util::irange<std::size_t>(0UL, legs.size()))
|
for (const auto idx : util::irange<std::size_t>(0UL, legs.size()))
|
||||||
{
|
{
|
||||||
auto &leg_geometry = leg_geometries[idx];
|
auto &leg_geometry = leg_geometries[idx];
|
||||||
|
|
||||||
step_geometries.reserve(step_geometries.size() + legs[idx].steps.size());
|
|
||||||
|
|
||||||
std::transform(
|
std::transform(
|
||||||
legs[idx].steps.begin(),
|
legs[idx].steps.begin(),
|
||||||
legs[idx].steps.end(),
|
legs[idx].steps.end(),
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#include "util/coordinate_calculation.hpp"
|
#include "util/coordinate_calculation.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -80,7 +81,9 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
|
|||||||
prev_coordinate = coordinate;
|
prev_coordinate = coordinate;
|
||||||
|
|
||||||
const auto osm_node_id = facade.GetOSMNodeIDOfNode(path_point.turn_via_node);
|
const auto osm_node_id = facade.GetOSMNodeIDOfNode(path_point.turn_via_node);
|
||||||
if (osm_node_id != geometry.osm_node_ids.back())
|
|
||||||
|
if (osm_node_id != geometry.osm_node_ids.back() ||
|
||||||
|
path_point.turn_instruction.type != osrm::guidance::TurnType::NoTurn)
|
||||||
{
|
{
|
||||||
geometry.annotations.emplace_back(LegGeometry::Annotation{
|
geometry.annotations.emplace_back(LegGeometry::Annotation{
|
||||||
current_distance,
|
current_distance,
|
||||||
@ -111,15 +114,39 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
|
|||||||
const std::vector<DatasourceID> forward_datasources =
|
const std::vector<DatasourceID> forward_datasources =
|
||||||
facade.GetUncompressedForwardDatasources(target_geometry_id);
|
facade.GetUncompressedForwardDatasources(target_geometry_id);
|
||||||
|
|
||||||
// FIXME if source and target phantoms are on the same segment then duration and weight
|
// This happens when the source/target are on the same edge-based-node
|
||||||
// will be from one projected point till end of segment
|
// There will be no entries in the unpacked path, thus no annotations.
|
||||||
// testbot/weight.feature:Start and target on the same and adjacent edge
|
// We will need to calculate the lone annotation by looking at the position
|
||||||
|
// of the source/target nodes, and calculating their differences.
|
||||||
|
if (geometry.annotations.empty())
|
||||||
|
{
|
||||||
|
auto duration =
|
||||||
|
std::abs(
|
||||||
|
(reversed_target ? target_node.reverse_duration : target_node.forward_duration) -
|
||||||
|
(reversed_source ? source_node.reverse_duration : source_node.forward_duration)) /
|
||||||
|
10.;
|
||||||
|
BOOST_ASSERT(duration >= 0);
|
||||||
|
auto weight =
|
||||||
|
std::abs((reversed_target ? target_node.reverse_weight : target_node.forward_weight) -
|
||||||
|
(reversed_source ? source_node.reverse_weight : source_node.forward_weight)) /
|
||||||
|
facade.GetWeightMultiplier();
|
||||||
|
BOOST_ASSERT(weight >= 0);
|
||||||
|
|
||||||
|
geometry.annotations.emplace_back(
|
||||||
|
LegGeometry::Annotation{current_distance,
|
||||||
|
duration,
|
||||||
|
weight,
|
||||||
|
forward_datasources[target_node.fwd_segment_position]});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
geometry.annotations.emplace_back(LegGeometry::Annotation{
|
geometry.annotations.emplace_back(LegGeometry::Annotation{
|
||||||
current_distance,
|
current_distance,
|
||||||
(reversed_target ? target_node.reverse_duration : target_node.forward_duration) / 10.,
|
(reversed_target ? target_node.reverse_duration : target_node.forward_duration) / 10.,
|
||||||
(reversed_target ? target_node.reverse_weight : target_node.forward_weight) /
|
(reversed_target ? target_node.reverse_weight : target_node.forward_weight) /
|
||||||
facade.GetWeightMultiplier(),
|
facade.GetWeightMultiplier(),
|
||||||
forward_datasources[target_node.fwd_segment_position]});
|
forward_datasources[target_node.fwd_segment_position]});
|
||||||
|
}
|
||||||
|
|
||||||
geometry.segment_offsets.push_back(geometry.locations.size());
|
geometry.segment_offsets.push_back(geometry.locations.size());
|
||||||
geometry.locations.push_back(target_node.location);
|
geometry.locations.push_back(target_node.location);
|
||||||
|
|||||||
@ -139,22 +139,38 @@ inline InternalRouteResult CollapseInternalRouteResult(const InternalRouteResult
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(!collapsed.unpacked_path_segments.empty());
|
BOOST_ASSERT(!collapsed.unpacked_path_segments.empty());
|
||||||
auto &last_segment = collapsed.unpacked_path_segments.back();
|
auto &last_segment = collapsed.unpacked_path_segments.back();
|
||||||
// deduplicate last segment (needs to be checked for empty for the same node query edge
|
|
||||||
// case)
|
|
||||||
if (!last_segment.empty())
|
|
||||||
last_segment.pop_back();
|
|
||||||
// update target phantom node of leg
|
|
||||||
BOOST_ASSERT(!collapsed.segment_end_coordinates.empty());
|
BOOST_ASSERT(!collapsed.segment_end_coordinates.empty());
|
||||||
collapsed.segment_end_coordinates.back().target_phantom =
|
collapsed.segment_end_coordinates.back().target_phantom =
|
||||||
leggy_result.segment_end_coordinates[i].target_phantom;
|
leggy_result.segment_end_coordinates[i].target_phantom;
|
||||||
collapsed.target_traversed_in_reverse.back() =
|
collapsed.target_traversed_in_reverse.back() =
|
||||||
leggy_result.target_traversed_in_reverse[i];
|
leggy_result.target_traversed_in_reverse[i];
|
||||||
// copy path segments into current leg
|
// copy path segments into current leg
|
||||||
|
if (!leggy_result.unpacked_path_segments[i].empty())
|
||||||
|
{
|
||||||
|
auto old_size = last_segment.size();
|
||||||
last_segment.insert(last_segment.end(),
|
last_segment.insert(last_segment.end(),
|
||||||
leggy_result.unpacked_path_segments[i].begin(),
|
leggy_result.unpacked_path_segments[i].begin(),
|
||||||
leggy_result.unpacked_path_segments[i].end());
|
leggy_result.unpacked_path_segments[i].end());
|
||||||
|
|
||||||
|
// The first segment of the unpacked path is missing the weight of the
|
||||||
|
// source phantom. We need to add those values back so that the total
|
||||||
|
// edge weight is correct
|
||||||
|
last_segment[old_size].weight_until_turn +=
|
||||||
|
|
||||||
|
leggy_result.source_traversed_in_reverse[i]
|
||||||
|
? leggy_result.segment_end_coordinates[i].source_phantom.reverse_weight
|
||||||
|
: leggy_result.segment_end_coordinates[i].source_phantom.forward_weight;
|
||||||
|
|
||||||
|
last_segment[old_size].duration_until_turn +=
|
||||||
|
leggy_result.source_traversed_in_reverse[i]
|
||||||
|
? leggy_result.segment_end_coordinates[i].source_phantom.reverse_duration
|
||||||
|
: leggy_result.segment_end_coordinates[i].source_phantom.forward_duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASSERT(collapsed.segment_end_coordinates.size() ==
|
||||||
|
collapsed.unpacked_path_segments.size());
|
||||||
return collapsed;
|
return collapsed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -261,6 +261,29 @@ inline void writeTurnLaneDescriptions(const boost::filesystem::path &path,
|
|||||||
storage::serialization::write(writer, turn_offsets);
|
storage::serialization::write(writer, turn_offsets);
|
||||||
storage::serialization::write(writer, turn_masks);
|
storage::serialization::write(writer, turn_masks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reads .osrm.maneuver_overrides
|
||||||
|
template <typename StorageManeuverOverrideT, typename NodeSequencesT>
|
||||||
|
inline void readManeuverOverrides(const boost::filesystem::path &path,
|
||||||
|
StorageManeuverOverrideT &maneuver_overrides,
|
||||||
|
NodeSequencesT &node_sequences)
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
|
||||||
|
storage::io::FileReader reader{path, fingerprint};
|
||||||
|
|
||||||
|
serialization::read(reader, maneuver_overrides, node_sequences);
|
||||||
|
}
|
||||||
|
|
||||||
|
// writes .osrm.maneuver_overrides
|
||||||
|
inline void writeManeuverOverrides(const boost::filesystem::path &path,
|
||||||
|
const std::vector<StorageManeuverOverride> &maneuver_overrides,
|
||||||
|
const std::vector<NodeID> &node_sequences)
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
|
||||||
|
storage::io::FileWriter writer{path, fingerprint};
|
||||||
|
|
||||||
|
serialization::write(writer, maneuver_overrides, node_sequences);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -304,10 +304,17 @@ inline void write(storage::io::FileWriter &writer,
|
|||||||
const std::vector<StorageManeuverOverride> &maneuver_overrides,
|
const std::vector<StorageManeuverOverride> &maneuver_overrides,
|
||||||
const std::vector<NodeID> &node_sequences)
|
const std::vector<NodeID> &node_sequences)
|
||||||
{
|
{
|
||||||
writer.WriteElementCount64(maneuver_overrides.size());
|
storage::serialization::write(writer, maneuver_overrides);
|
||||||
writer.WriteElementCount64(node_sequences.size());
|
storage::serialization::write(writer, node_sequences);
|
||||||
writer.WriteFrom(maneuver_overrides);
|
}
|
||||||
writer.WriteFrom(node_sequences);
|
|
||||||
|
template <typename ManeuverOverridesT, typename NodeSequenceT>
|
||||||
|
inline void read(storage::io::FileReader &reader,
|
||||||
|
ManeuverOverridesT &maneuver_overrides,
|
||||||
|
NodeSequenceT &node_sequences)
|
||||||
|
{
|
||||||
|
storage::serialization::read(reader, maneuver_overrides);
|
||||||
|
storage::serialization::read(reader, node_sequences);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,10 +16,14 @@ namespace partitioner
|
|||||||
struct PartitionerConfig final : storage::IOConfig
|
struct PartitionerConfig final : storage::IOConfig
|
||||||
{
|
{
|
||||||
PartitionerConfig()
|
PartitionerConfig()
|
||||||
: IOConfig(
|
: IOConfig({".osrm", ".osrm.fileIndex", ".osrm.ebg_nodes"},
|
||||||
{".osrm", ".osrm.fileIndex", ".osrm.ebg_nodes"},
|
|
||||||
{".osrm.hsgr", ".osrm.cnbg"},
|
{".osrm.hsgr", ".osrm.cnbg"},
|
||||||
{".osrm.ebg", ".osrm.cnbg", ".osrm.cnbg_to_ebg", ".osrm.partition", ".osrm.cells"}),
|
{".osrm.ebg",
|
||||||
|
".osrm.cnbg",
|
||||||
|
".osrm.cnbg_to_ebg",
|
||||||
|
".osrm.partition",
|
||||||
|
".osrm.cells",
|
||||||
|
".osrm.maneuver_overrides"}),
|
||||||
requested_num_threads(0), balance(1.2), boundary_factor(0.25), num_optimizing_cuts(10),
|
requested_num_threads(0), balance(1.2), boundary_factor(0.25), num_optimizing_cuts(10),
|
||||||
small_component_size(1000),
|
small_component_size(1000),
|
||||||
max_cell_sizes({128, 128 * 32, 128 * 32 * 16, 128 * 32 * 16 * 32})
|
max_cell_sizes({128, 128 * 32, 128 * 32 * 16, 128 * 32 * 16 * 32})
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#define OSRM_PARTITIONER_RENUMBER_HPP
|
#define OSRM_PARTITIONER_RENUMBER_HPP
|
||||||
|
|
||||||
#include "extractor/edge_based_node_segment.hpp"
|
#include "extractor/edge_based_node_segment.hpp"
|
||||||
|
#include "extractor/maneuver_override.hpp"
|
||||||
#include "extractor/nbg_to_ebg.hpp"
|
#include "extractor/nbg_to_ebg.hpp"
|
||||||
#include "extractor/node_data_container.hpp"
|
#include "extractor/node_data_container.hpp"
|
||||||
|
|
||||||
@ -73,6 +74,25 @@ inline void renumber(std::vector<extractor::NBGToEBG> &mapping,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void renumber(std::vector<NodeID> &node_ids, const std::vector<std::uint32_t> &permutation)
|
||||||
|
{
|
||||||
|
for (auto &node_id : node_ids)
|
||||||
|
{
|
||||||
|
if (node_id != SPECIAL_NODEID)
|
||||||
|
node_id = permutation[node_id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void renumber(std::vector<extractor::StorageManeuverOverride> &maneuver_overrides,
|
||||||
|
const std::vector<std::uint32_t> &permutation)
|
||||||
|
{
|
||||||
|
for (auto &maneuver_override : maneuver_overrides)
|
||||||
|
{
|
||||||
|
if (maneuver_override.start_node != SPECIAL_NODEID)
|
||||||
|
maneuver_override.start_node = permutation[maneuver_override.start_node];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace partitioner
|
} // namespace partitioner
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
|
||||||
|
|||||||
12
package.json
12
package.json
@ -1,12 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "osrm",
|
"name": "osrm",
|
||||||
"version": "5.16.0-latest.1",
|
"version": "5.16.5",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"mkdirp": "^0.5.1",
|
||||||
"nan": "^2.6.2",
|
"nan": "^2.6.2",
|
||||||
"node-cmake": "^2.3.2",
|
"node-cmake": "^2.3.2",
|
||||||
"node-pre-gyp": "^0.6.36"
|
"node-pre-gyp": "^0.6.36",
|
||||||
|
"rimraf": "^2.5.4"
|
||||||
},
|
},
|
||||||
"browserify": {
|
"browserify": {
|
||||||
"transform": [
|
"transform": [
|
||||||
@ -45,18 +47,18 @@
|
|||||||
"documentation": "^4.0.0-rc.1",
|
"documentation": "^4.0.0-rc.1",
|
||||||
"eslint": "^2.4.0",
|
"eslint": "^2.4.0",
|
||||||
"faucet": "^0.0.1",
|
"faucet": "^0.0.1",
|
||||||
"mkdirp": "^0.5.1",
|
|
||||||
"node-timeout": "0.0.4",
|
"node-timeout": "0.0.4",
|
||||||
"polyline": "^0.2.0",
|
"polyline": "^0.2.0",
|
||||||
"request": "^2.69.0",
|
"request": "^2.69.0",
|
||||||
"rimraf": "^2.5.4",
|
|
||||||
"tape": "^4.7.0",
|
"tape": "^4.7.0",
|
||||||
"xmlbuilder": "^4.2.1"
|
"xmlbuilder": "^4.2.1"
|
||||||
},
|
},
|
||||||
"bundleDependencies": [
|
"bundleDependencies": [
|
||||||
|
"mkdirp",
|
||||||
"nan",
|
"nan",
|
||||||
"node-cmake",
|
"node-cmake",
|
||||||
"node-pre-gyp"
|
"node-pre-gyp",
|
||||||
|
"rimraf"
|
||||||
],
|
],
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"binary": {
|
"binary": {
|
||||||
|
|||||||
@ -9,6 +9,7 @@ Relations = require("lib/relations")
|
|||||||
find_access_tag = require("lib/access").find_access_tag
|
find_access_tag = require("lib/access").find_access_tag
|
||||||
limit = require("lib/maxspeed").limit
|
limit = require("lib/maxspeed").limit
|
||||||
Utils = require("lib/utils")
|
Utils = require("lib/utils")
|
||||||
|
Measure = require("lib/measure")
|
||||||
|
|
||||||
function setup()
|
function setup()
|
||||||
return {
|
return {
|
||||||
@ -54,7 +55,8 @@ function setup()
|
|||||||
'gate',
|
'gate',
|
||||||
'lift_gate',
|
'lift_gate',
|
||||||
'no',
|
'no',
|
||||||
'entrance'
|
'entrance',
|
||||||
|
'height_restrictor'
|
||||||
},
|
},
|
||||||
|
|
||||||
access_tag_whitelist = Set {
|
access_tag_whitelist = Set {
|
||||||
@ -320,11 +322,18 @@ function process_node(profile, node, result, relations)
|
|||||||
else
|
else
|
||||||
local barrier = node:get_value_by_key("barrier")
|
local barrier = node:get_value_by_key("barrier")
|
||||||
if barrier then
|
if barrier then
|
||||||
|
-- check height restriction barriers
|
||||||
|
local restricted_by_height = false
|
||||||
|
if barrier == 'height_restrictor' then
|
||||||
|
local maxheight = Measure.get_max_height(node:get_value_by_key("maxheight"), node)
|
||||||
|
restricted_by_height = maxheight and maxheight < profile.vehicle_height
|
||||||
|
end
|
||||||
|
|
||||||
-- make an exception for rising bollard barriers
|
-- make an exception for rising bollard barriers
|
||||||
local bollard = node:get_value_by_key("bollard")
|
local bollard = node:get_value_by_key("bollard")
|
||||||
local rising_bollard = bollard and "rising" == bollard
|
local rising_bollard = bollard and "rising" == bollard
|
||||||
|
|
||||||
if not profile.barrier_whitelist[barrier] and not rising_bollard then
|
if not profile.barrier_whitelist[barrier] and not rising_bollard or restricted_by_height then
|
||||||
result.barrier = true
|
result.barrier = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -62,11 +62,11 @@ local height_non_numerical_values = Set { "default", "none", "no-sign", "unsigne
|
|||||||
|
|
||||||
--- Get maxheight of specified way in meters. If there are no
|
--- Get maxheight of specified way in meters. If there are no
|
||||||
--- max height, then return nil
|
--- max height, then return nil
|
||||||
function Measure.get_max_height(raw_value,way)
|
function Measure.get_max_height(raw_value, element)
|
||||||
if raw_value then
|
if raw_value then
|
||||||
if height_non_numerical_values[raw_value] then
|
if height_non_numerical_values[raw_value] then
|
||||||
if way then
|
if element then
|
||||||
return way:get_location_tag('maxheight') or default_maxheight
|
return element:get_location_tag('maxheight') or default_maxheight
|
||||||
else
|
else
|
||||||
return default_maxheight
|
return default_maxheight
|
||||||
end
|
end
|
||||||
|
|||||||
@ -370,7 +370,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
|||||||
geometry.segment_offsets.pop_back();
|
geometry.segment_offsets.pop_back();
|
||||||
// remove all the last coordinates from the geometry
|
// remove all the last coordinates from the geometry
|
||||||
geometry.locations.resize(geometry.segment_offsets.back() + 1);
|
geometry.locations.resize(geometry.segment_offsets.back() + 1);
|
||||||
geometry.annotations.resize(geometry.segment_offsets.back() + 1);
|
geometry.annotations.resize(geometry.segment_offsets.back());
|
||||||
geometry.osm_node_ids.resize(geometry.segment_offsets.back() + 1);
|
geometry.osm_node_ids.resize(geometry.segment_offsets.back() + 1);
|
||||||
|
|
||||||
BOOST_ASSERT(geometry.segment_distances.back() <= 1);
|
BOOST_ASSERT(geometry.segment_distances.back() <= 1);
|
||||||
@ -429,6 +429,10 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
|||||||
last_step.intersections.front().bearings.front() = util::bearing::reverse(bearing);
|
last_step.intersections.front().bearings.front() = util::bearing::reverse(bearing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_ASSERT(geometry.segment_offsets.back() + 1 == geometry.locations.size());
|
||||||
|
BOOST_ASSERT(geometry.segment_offsets.back() + 1 == geometry.osm_node_ids.size());
|
||||||
|
BOOST_ASSERT(geometry.segment_offsets.back() == geometry.annotations.size());
|
||||||
|
|
||||||
BOOST_ASSERT(steps.back().geometry_end == geometry.locations.size());
|
BOOST_ASSERT(steps.back().geometry_end == geometry.locations.size());
|
||||||
|
|
||||||
BOOST_ASSERT(steps.front().intersections.size() >= 1);
|
BOOST_ASSERT(steps.front().intersections.size() >= 1);
|
||||||
|
|||||||
@ -44,7 +44,7 @@ void filterCandidates(const std::vector<util::Coordinate> &coordinates,
|
|||||||
coordinates[current_coordinate + 1]);
|
coordinates[current_coordinate + 1]);
|
||||||
|
|
||||||
// sharp turns indicate a possible uturn
|
// sharp turns indicate a possible uturn
|
||||||
if (turn_angle <= 90.0 || turn_angle >= 270.0)
|
if (turn_angle <= 45.0 || turn_angle >= 315.0)
|
||||||
{
|
{
|
||||||
allow_uturn = true;
|
allow_uturn = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1106,11 +1106,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
std::sort(storage_maneuver_overrides.begin(),
|
std::sort(storage_maneuver_overrides.begin(),
|
||||||
storage_maneuver_overrides.end(),
|
storage_maneuver_overrides.end(),
|
||||||
[](const auto &a, const auto &b) { return a.start_node < b.start_node; });
|
[](const auto &a, const auto &b) { return a.start_node < b.start_node; });
|
||||||
// write conditional turn penalties into the restrictions file
|
|
||||||
storage::io::FileWriter writer(maneuver_overrides_filename,
|
files::writeManeuverOverrides(
|
||||||
storage::io::FileWriter::GenerateFingerprint);
|
maneuver_overrides_filename, storage_maneuver_overrides, maneuver_override_sequences);
|
||||||
extractor::serialization::write(
|
|
||||||
writer, storage_maneuver_overrides, maneuver_override_sequences);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
util::Log() << "done.";
|
util::Log() << "done.";
|
||||||
|
|||||||
@ -52,8 +52,10 @@ ManeuverOverrideRelationParser::TryParse(const osmium::Relation &relation) const
|
|||||||
maneuver_override.maneuver = relation.tags().get_value_by_key("maneuver", "");
|
maneuver_override.maneuver = relation.tags().get_value_by_key("maneuver", "");
|
||||||
maneuver_override.direction = relation.tags().get_value_by_key("direction", "");
|
maneuver_override.direction = relation.tags().get_value_by_key("direction", "");
|
||||||
|
|
||||||
boost::optional<std::uint64_t> from = boost::none, via = boost::none, to = boost::none;
|
bool valid_relation = true;
|
||||||
std::vector<std::uint64_t> via_ways;
|
OSMNodeID via_node = SPECIAL_OSM_NODEID;
|
||||||
|
OSMWayID from = SPECIAL_OSM_WAYID, to = SPECIAL_OSM_WAYID;
|
||||||
|
std::vector<OSMWayID> via_ways;
|
||||||
|
|
||||||
for (const auto &member : relation.members())
|
for (const auto &member : relation.members())
|
||||||
{
|
{
|
||||||
@ -74,8 +76,9 @@ ManeuverOverrideRelationParser::TryParse(const osmium::Relation &relation) const
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
BOOST_ASSERT(0 == strcmp("via", role));
|
BOOST_ASSERT(0 == strcmp("via", role));
|
||||||
via = static_cast<std::uint64_t>(member.ref());
|
|
||||||
// set via node id
|
// set via node id
|
||||||
|
valid_relation &= via_node == SPECIAL_OSM_NODEID;
|
||||||
|
via_node = OSMNodeID{static_cast<std::uint64_t>(member.ref())};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case osmium::item_type::way:
|
case osmium::item_type::way:
|
||||||
@ -83,15 +86,17 @@ ManeuverOverrideRelationParser::TryParse(const osmium::Relation &relation) const
|
|||||||
0 == strcmp("via", role));
|
0 == strcmp("via", role));
|
||||||
if (0 == strcmp("from", role))
|
if (0 == strcmp("from", role))
|
||||||
{
|
{
|
||||||
from = static_cast<std::uint64_t>(member.ref());
|
valid_relation &= from == SPECIAL_OSM_WAYID;
|
||||||
|
from = OSMWayID{static_cast<std::uint64_t>(member.ref())};
|
||||||
}
|
}
|
||||||
else if (0 == strcmp("to", role))
|
else if (0 == strcmp("to", role))
|
||||||
{
|
{
|
||||||
to = static_cast<std::uint64_t>(member.ref());
|
valid_relation &= to == SPECIAL_OSM_WAYID;
|
||||||
|
to = OSMWayID{static_cast<std::uint64_t>(member.ref())};
|
||||||
}
|
}
|
||||||
else if (0 == strcmp("via", role))
|
else if (0 == strcmp("via", role))
|
||||||
{
|
{
|
||||||
via_ways.push_back(static_cast<std::uint64_t>(member.ref()));
|
via_ways.push_back(OSMWayID{static_cast<std::uint64_t>(member.ref())});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case osmium::item_type::relation:
|
case osmium::item_type::relation:
|
||||||
@ -103,18 +108,17 @@ ManeuverOverrideRelationParser::TryParse(const osmium::Relation &relation) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (from && (via || via_ways.size() > 0) && to)
|
// Check required roles
|
||||||
|
valid_relation &= from != SPECIAL_OSM_WAYID;
|
||||||
|
valid_relation &= to != SPECIAL_OSM_WAYID;
|
||||||
|
valid_relation &= via_node != SPECIAL_OSM_NODEID;
|
||||||
|
|
||||||
|
if (valid_relation)
|
||||||
{
|
{
|
||||||
via_ways.insert(via_ways.begin(), *from);
|
maneuver_override.via_ways.push_back(from);
|
||||||
via_ways.push_back(*to);
|
std::copy(via_ways.begin(), via_ways.end(), std::back_inserter(maneuver_override.via_ways));
|
||||||
if (via)
|
maneuver_override.via_ways.push_back(to);
|
||||||
{
|
maneuver_override.via_node = via_node;
|
||||||
maneuver_override.via_node = {*via};
|
|
||||||
}
|
|
||||||
for (const auto &n : via_ways)
|
|
||||||
{
|
|
||||||
maneuver_override.via_ways.push_back(OSMWayID{n});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -218,6 +218,22 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
|||||||
"valid",
|
"valid",
|
||||||
&osmium::Location::valid);
|
&osmium::Location::valid);
|
||||||
|
|
||||||
|
auto get_location_tag = [](auto &context, const auto &location, const char *key) {
|
||||||
|
if (context.location_dependent_data.empty())
|
||||||
|
return sol::object(sol::nil);
|
||||||
|
|
||||||
|
const LocationDependentData::point_t point{location.lon(), location.lat()};
|
||||||
|
if (!boost::geometry::equals(context.last_location_point, point))
|
||||||
|
{
|
||||||
|
context.last_location_point = point;
|
||||||
|
context.last_location_indexes =
|
||||||
|
context.location_dependent_data.GetPropertyIndexes(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto value = context.location_dependent_data.FindByKey(context.last_location_indexes, key);
|
||||||
|
return boost::apply_visitor(to_lua_object(context.state), value);
|
||||||
|
};
|
||||||
|
|
||||||
context.state.new_usertype<osmium::Way>(
|
context.state.new_usertype<osmium::Way>(
|
||||||
"Way",
|
"Way",
|
||||||
"get_value_by_key",
|
"get_value_by_key",
|
||||||
@ -229,29 +245,17 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
|||||||
"get_nodes",
|
"get_nodes",
|
||||||
[](const osmium::Way &way) { return sol::as_table(way.nodes()); },
|
[](const osmium::Way &way) { return sol::as_table(way.nodes()); },
|
||||||
"get_location_tag",
|
"get_location_tag",
|
||||||
[&context](const osmium::Way &way, const char *key) {
|
[&context, &get_location_tag](const osmium::Way &way, const char *key) {
|
||||||
if (context.location_dependent_data.empty())
|
|
||||||
return sol::object(sol::nil);
|
|
||||||
// HEURISTIC: use a single node (last) of the way to localize the way
|
// HEURISTIC: use a single node (last) of the way to localize the way
|
||||||
// For more complicated scenarios a proper merging of multiple tags
|
// For more complicated scenarios a proper merging of multiple tags
|
||||||
// at one or many locations must be provided
|
// at one or many locations must be provided
|
||||||
const auto &nodes = way.nodes();
|
const auto &nodes = way.nodes();
|
||||||
const auto &location = nodes.back().location();
|
const auto &location = nodes.back().location();
|
||||||
const LocationDependentData::point_t point{location.lon(), location.lat()};
|
return get_location_tag(context, location, key);
|
||||||
|
|
||||||
if (!boost::geometry::equals(context.last_location_point, point))
|
|
||||||
{
|
|
||||||
context.last_location_point = point;
|
|
||||||
context.last_location_indexes =
|
|
||||||
context.location_dependent_data.GetPropertyIndexes(point);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto value =
|
|
||||||
context.location_dependent_data.FindByKey(context.last_location_indexes, key);
|
|
||||||
return boost::apply_visitor(to_lua_object(context.state), value);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
context.state.new_usertype<osmium::Node>("Node",
|
context.state.new_usertype<osmium::Node>(
|
||||||
|
"Node",
|
||||||
"location",
|
"location",
|
||||||
&osmium::Node::location,
|
&osmium::Node::location,
|
||||||
"get_value_by_key",
|
"get_value_by_key",
|
||||||
@ -259,7 +263,11 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
|||||||
"id",
|
"id",
|
||||||
&osmium::Node::id,
|
&osmium::Node::id,
|
||||||
"version",
|
"version",
|
||||||
&osmium::Node::version);
|
&osmium::Node::version,
|
||||||
|
"get_location_tag",
|
||||||
|
[&context, &get_location_tag](const osmium::Node &node, const char *key) {
|
||||||
|
return get_location_tag(context, node.location(), key);
|
||||||
|
});
|
||||||
|
|
||||||
context.state.new_usertype<ExtractionNode>("ResultNode",
|
context.state.new_usertype<ExtractionNode>("ResultNode",
|
||||||
"traffic_lights",
|
"traffic_lights",
|
||||||
|
|||||||
@ -31,9 +31,13 @@ inline extractor::RoadClassification roadClass(const ConnectedRoad &road,
|
|||||||
return graph.GetEdgeData(road.eid).flags.road_classification;
|
return graph.GetEdgeData(road.eid).flags.road_classification;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isRampClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph)
|
inline bool isRampClass(EdgeID eid,
|
||||||
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
|
bool from_motorway = true)
|
||||||
{
|
{
|
||||||
return node_based_graph.GetEdgeData(eid).flags.road_classification.IsRampClass();
|
return node_based_graph.GetEdgeData(eid).flags.road_classification.IsRampClass() ||
|
||||||
|
(from_motorway &&
|
||||||
|
node_based_graph.GetEdgeData(eid).flags.road_classification.IsLinkClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -63,6 +67,8 @@ bool MotorwayHandler::canProcess(const NodeID,
|
|||||||
const EdgeID via_eid,
|
const EdgeID via_eid,
|
||||||
const Intersection &intersection) const
|
const Intersection &intersection) const
|
||||||
{
|
{
|
||||||
|
const bool from_motorway = isMotorwayClass(via_eid, node_based_graph);
|
||||||
|
|
||||||
bool has_motorway = false;
|
bool has_motorway = false;
|
||||||
bool has_normal_roads = false;
|
bool has_normal_roads = false;
|
||||||
|
|
||||||
@ -76,14 +82,14 @@ bool MotorwayHandler::canProcess(const NodeID,
|
|||||||
if (road.entry_allowed)
|
if (road.entry_allowed)
|
||||||
has_motorway = true;
|
has_motorway = true;
|
||||||
}
|
}
|
||||||
else if (!isRampClass(road.eid, node_based_graph))
|
else if (!isRampClass(road.eid, node_based_graph, from_motorway))
|
||||||
has_normal_roads = true;
|
has_normal_roads = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_normal_roads)
|
if (has_normal_roads)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return has_motorway || isMotorwayClass(via_eid, node_based_graph);
|
return has_motorway || from_motorway;
|
||||||
}
|
}
|
||||||
|
|
||||||
Intersection MotorwayHandler::
|
Intersection MotorwayHandler::
|
||||||
@ -112,16 +118,6 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
|
|||||||
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(via_eid).annotation_data);
|
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(via_eid).annotation_data);
|
||||||
BOOST_ASSERT(isMotorwayClass(via_eid, node_based_graph));
|
BOOST_ASSERT(isMotorwayClass(via_eid, node_based_graph));
|
||||||
|
|
||||||
const auto countExitingMotorways = [this](const Intersection &intersection) {
|
|
||||||
unsigned count = 0;
|
|
||||||
for (const auto &road : intersection)
|
|
||||||
{
|
|
||||||
if (road.entry_allowed && isMotorwayClass(road.eid, node_based_graph))
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
};
|
|
||||||
|
|
||||||
// find the angle that continues on our current highway
|
// find the angle that continues on our current highway
|
||||||
const auto getContinueAngle = [this, in_data](const Intersection &intersection) {
|
const auto getContinueAngle = [this, in_data](const Intersection &intersection) {
|
||||||
for (const auto &road : intersection)
|
for (const auto &road : intersection)
|
||||||
@ -213,7 +209,13 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const unsigned exiting_motorways = countExitingMotorways(intersection);
|
const auto valid_exits = std::count_if(intersection.begin(),
|
||||||
|
intersection.end(),
|
||||||
|
[](const auto &road) { return road.entry_allowed; });
|
||||||
|
const auto exiting_motorways =
|
||||||
|
std::count_if(intersection.begin(), intersection.end(), [this](const auto &road) {
|
||||||
|
return road.entry_allowed && isMotorwayClass(road.eid, node_based_graph);
|
||||||
|
});
|
||||||
|
|
||||||
if (exiting_motorways == 0)
|
if (exiting_motorways == 0)
|
||||||
{
|
{
|
||||||
@ -227,7 +229,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (exiting_motorways == 1)
|
else if (exiting_motorways == 1 || exiting_motorways != valid_exits)
|
||||||
{
|
{
|
||||||
// normal motorway passing some ramps or mering onto another motorway
|
// normal motorway passing some ramps or mering onto another motorway
|
||||||
if (intersection.size() == 2)
|
if (intersection.size() == 2)
|
||||||
|
|||||||
@ -249,8 +249,13 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
|
|||||||
OOOOOOO
|
OOOOOOO
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const auto all_ramps =
|
||||||
|
std::all_of(intersection.begin(), intersection.end(), [this](const auto &road) {
|
||||||
|
return node_based_graph.GetEdgeData(road.eid).flags.road_classification.IsRampClass();
|
||||||
|
});
|
||||||
|
|
||||||
auto fork = findFork(via_edge, intersection);
|
auto fork = findFork(via_edge, intersection);
|
||||||
if (fork && obvious_index == 0)
|
if (fork && (all_ramps || obvious_index == 0))
|
||||||
{
|
{
|
||||||
assignFork(via_edge, fork->getLeft(), fork->getRight());
|
assignFork(via_edge, fork->getLeft(), fork->getRight());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -145,6 +145,15 @@ int Partitioner::Run(const PartitionerConfig &config)
|
|||||||
renumber(node_data, permutation);
|
renumber(node_data, permutation);
|
||||||
extractor::files::writeNodeData(config.GetPath(".osrm.ebg_nodes"), node_data);
|
extractor::files::writeNodeData(config.GetPath(".osrm.ebg_nodes"), node_data);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
const auto &filename = config.GetPath(".osrm.maneuver_overrides");
|
||||||
|
std::vector<extractor::StorageManeuverOverride> maneuver_overrides;
|
||||||
|
std::vector<NodeID> node_sequences;
|
||||||
|
extractor::files::readManeuverOverrides(filename, maneuver_overrides, node_sequences);
|
||||||
|
renumber(maneuver_overrides, permutation);
|
||||||
|
renumber(node_sequences, permutation);
|
||||||
|
extractor::files::writeManeuverOverrides(filename, maneuver_overrides, node_sequences);
|
||||||
|
}
|
||||||
if (boost::filesystem::exists(config.GetPath(".osrm.hsgr")))
|
if (boost::filesystem::exists(config.GetPath(".osrm.hsgr")))
|
||||||
{
|
{
|
||||||
util::Log(logWARNING) << "Found existing .osrm.hsgr file, removing. You need to re-run "
|
util::Log(logWARNING) << "Found existing .osrm.hsgr file, removing. You need to re-run "
|
||||||
|
|||||||
@ -445,10 +445,11 @@ void Storage::PopulateLayout(DataLayout &layout)
|
|||||||
{
|
{
|
||||||
io::FileReader maneuver_overrides_file(config.GetPath(".osrm.maneuver_overrides"),
|
io::FileReader maneuver_overrides_file(config.GetPath(".osrm.maneuver_overrides"),
|
||||||
io::FileReader::VerifyFingerprint);
|
io::FileReader::VerifyFingerprint);
|
||||||
const auto number_of_overrides = maneuver_overrides_file.ReadElementCount64();
|
const auto number_of_overrides =
|
||||||
|
maneuver_overrides_file.ReadVectorSize<extractor::StorageManeuverOverride>();
|
||||||
layout.SetBlockSize<extractor::StorageManeuverOverride>(DataLayout::MANEUVER_OVERRIDES,
|
layout.SetBlockSize<extractor::StorageManeuverOverride>(DataLayout::MANEUVER_OVERRIDES,
|
||||||
number_of_overrides);
|
number_of_overrides);
|
||||||
const auto number_of_nodes = maneuver_overrides_file.ReadElementCount64();
|
const auto number_of_nodes = maneuver_overrides_file.ReadVectorSize<NodeID>();
|
||||||
layout.SetBlockSize<NodeID>(DataLayout::MANEUVER_OVERRIDE_NODE_SEQUENCES, number_of_nodes);
|
layout.SetBlockSize<NodeID>(DataLayout::MANEUVER_OVERRIDE_NODE_SEQUENCES, number_of_nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1089,18 +1090,21 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
|||||||
|
|
||||||
// load maneuver overrides
|
// load maneuver overrides
|
||||||
{
|
{
|
||||||
io::FileReader maneuver_overrides_file(config.GetPath(".osrm.maneuver_overrides"),
|
|
||||||
io::FileReader::VerifyFingerprint);
|
|
||||||
const auto number_of_overrides = maneuver_overrides_file.ReadElementCount64();
|
|
||||||
const auto number_of_nodes = maneuver_overrides_file.ReadElementCount64();
|
|
||||||
const auto maneuver_overrides_ptr =
|
const auto maneuver_overrides_ptr =
|
||||||
layout.GetBlockPtr<extractor::StorageManeuverOverride, true>(
|
layout.GetBlockPtr<extractor::StorageManeuverOverride, true>(
|
||||||
memory_ptr, DataLayout::MANEUVER_OVERRIDES);
|
memory_ptr, DataLayout::MANEUVER_OVERRIDES);
|
||||||
maneuver_overrides_file.ReadInto(maneuver_overrides_ptr, number_of_overrides);
|
|
||||||
|
|
||||||
const auto maneuver_override_node_sequences_ptr = layout.GetBlockPtr<NodeID, true>(
|
const auto maneuver_override_node_sequences_ptr = layout.GetBlockPtr<NodeID, true>(
|
||||||
memory_ptr, DataLayout::MANEUVER_OVERRIDE_NODE_SEQUENCES);
|
memory_ptr, DataLayout::MANEUVER_OVERRIDE_NODE_SEQUENCES);
|
||||||
maneuver_overrides_file.ReadInto(maneuver_override_node_sequences_ptr, number_of_nodes);
|
|
||||||
|
util::vector_view<extractor::StorageManeuverOverride> maneuver_overrides(
|
||||||
|
maneuver_overrides_ptr, layout.num_entries[DataLayout::MANEUVER_OVERRIDES]);
|
||||||
|
util::vector_view<NodeID> maneuver_override_node_sequences(
|
||||||
|
maneuver_override_node_sequences_ptr,
|
||||||
|
layout.num_entries[DataLayout::MANEUVER_OVERRIDE_NODE_SEQUENCES]);
|
||||||
|
|
||||||
|
extractor::files::readManeuverOverrides(config.GetPath(".osrm.maneuver_overrides"),
|
||||||
|
maneuver_overrides,
|
||||||
|
maneuver_override_node_sequences);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -139,6 +139,7 @@
|
|||||||
{"key": "access", "value": "emergency"},
|
{"key": "access", "value": "emergency"},
|
||||||
{"key": "access", "value": "psv"},
|
{"key": "access", "value": "psv"},
|
||||||
{"key": "access", "value": "delivery"},
|
{"key": "access", "value": "delivery"},
|
||||||
|
{"key": "maxheight", "object_types": ["node", "way"]},
|
||||||
{"key": "maxspeed", "value": "none"},
|
{"key": "maxspeed", "value": "none"},
|
||||||
{"key": "maxspeed", "value": "urban"},
|
{"key": "maxspeed", "value": "urban"},
|
||||||
{"key": "maxspeed", "value": "rural"},
|
{"key": "maxspeed", "value": "rural"},
|
||||||
|
|||||||
@ -38,6 +38,10 @@ BOOST_AUTO_TEST_CASE(unchanged_collapse_route_result)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(two_legs_to_one_leg)
|
BOOST_AUTO_TEST_CASE(two_legs_to_one_leg)
|
||||||
{
|
{
|
||||||
|
// from_edge_based_node, turn_via_node, name_id, is_segregated, weight_until_turn,
|
||||||
|
// weight_of_turn,
|
||||||
|
// duration_until_turn, duration_of_turn, turn_instruction, lane_data, travel_mode, classes,
|
||||||
|
// entry_class, datasource_id, pre_turn_bearing, post_turn_bearing, left_hand
|
||||||
PathData pathy{0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false};
|
PathData pathy{0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false};
|
||||||
PathData kathy{0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false};
|
PathData kathy{0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false};
|
||||||
PathData cathy{0, 3, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false};
|
PathData cathy{0, 3, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false};
|
||||||
@ -61,10 +65,11 @@ BOOST_AUTO_TEST_CASE(two_legs_to_one_leg)
|
|||||||
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[0].target_phantom.forward_segment_id.id,
|
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[0].target_phantom.forward_segment_id.id,
|
||||||
12);
|
12);
|
||||||
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[0].source_phantom.forward_segment_id.id, 1);
|
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[0].source_phantom.forward_segment_id.id, 1);
|
||||||
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0].size(), 3);
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0].size(), 4);
|
||||||
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][0].turn_via_node, 2);
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][0].turn_via_node, 2);
|
||||||
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][1].turn_via_node, 1);
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][1].turn_via_node, 1);
|
||||||
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][2].turn_via_node, 3);
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][2].turn_via_node, 1);
|
||||||
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][3].turn_via_node, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(three_legs_to_two_legs)
|
BOOST_AUTO_TEST_CASE(three_legs_to_two_legs)
|
||||||
@ -101,13 +106,14 @@ BOOST_AUTO_TEST_CASE(three_legs_to_two_legs)
|
|||||||
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[1].target_phantom.forward_segment_id.id,
|
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[1].target_phantom.forward_segment_id.id,
|
||||||
18);
|
18);
|
||||||
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0].size(), 2);
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0].size(), 2);
|
||||||
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1].size(), 4);
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1].size(), 5);
|
||||||
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][0].turn_via_node, 2);
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][0].turn_via_node, 2);
|
||||||
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][1].turn_via_node, 1);
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][1].turn_via_node, 1);
|
||||||
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1][0].turn_via_node, 1);
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1][0].turn_via_node, 1);
|
||||||
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1][1].turn_via_node, 5);
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1][1].turn_via_node, 5);
|
||||||
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1][2].turn_via_node, 3);
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1][2].turn_via_node, 3);
|
||||||
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1][3].turn_via_node, 4);
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1][3].turn_via_node, 3);
|
||||||
|
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1][4].turn_via_node, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(two_legs_to_two_legs)
|
BOOST_AUTO_TEST_CASE(two_legs_to_two_legs)
|
||||||
|
|||||||
@ -407,12 +407,20 @@ BOOST_AUTO_TEST_CASE(speed_annotation_matches_duration_and_distance)
|
|||||||
const auto &durations = annotation.values.at("duration").get<json::Array>().values;
|
const auto &durations = annotation.values.at("duration").get<json::Array>().values;
|
||||||
const auto &distances = annotation.values.at("distance").get<json::Array>().values;
|
const auto &distances = annotation.values.at("distance").get<json::Array>().values;
|
||||||
int length = speeds.size();
|
int length = speeds.size();
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(length, 1);
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
auto speed = speeds[i].get<json::Number>().value;
|
auto speed = speeds[i].get<json::Number>().value;
|
||||||
auto duration = durations[i].get<json::Number>().value;
|
auto duration = durations[i].get<json::Number>().value;
|
||||||
auto distance = distances[i].get<json::Number>().value;
|
auto distance = distances[i].get<json::Number>().value;
|
||||||
BOOST_CHECK_EQUAL(speed, std::round(distance / duration * 10.) / 10.);
|
auto calc = std::round(distance / duration * 10.) / 10.;
|
||||||
|
BOOST_CHECK_EQUAL(speed, std::isnan(calc) ? 0 : calc);
|
||||||
|
|
||||||
|
// Because we route from/to the same location, all annotations should be 0;
|
||||||
|
BOOST_CHECK_EQUAL(speed, 0);
|
||||||
|
BOOST_CHECK_EQUAL(distance, 0);
|
||||||
|
BOOST_CHECK_EQUAL(duration, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user