Compare commits
43 Commits
v5.2.3
...
v5.3.0-rc.1
| Author | SHA1 | Date | |
|---|---|---|---|
| dc77d02e8a | |||
| 6265b8fa77 | |||
| 311b348d09 | |||
| ec02cdc4cc | |||
| 5905708111 | |||
| 5d91b759d1 | |||
| ec0a1a4ab1 | |||
| efa29edf09 | |||
| 2a05b70dfc | |||
| 8693e68271 | |||
| d21a9a514d | |||
| e03d132823 | |||
| 61ba985bc9 | |||
| 4629a20fe4 | |||
| a28125ee9a | |||
| df877aca1b | |||
| 05dc415aba | |||
| 6dedd9cb72 | |||
| 256d39b572 | |||
| d186ae1863 | |||
| fddc19e98d | |||
| 2592cd2e58 | |||
| 93b6438cea | |||
| f6746d88b7 | |||
| 34ace4dd4b | |||
| 41d0f42ddf | |||
| 2868f702a5 | |||
| ec4dcee8bd | |||
| 8c378191df | |||
| b98431e8e6 | |||
| 3c8781855e | |||
| 27a94f3ca6 | |||
| 04e334e3e2 | |||
| 12d4832037 | |||
| 6e4f6fec91 | |||
| 57c9525e5c | |||
| 543e4fb57d | |||
| 3881ead8e5 | |||
| 911d1e81b6 | |||
| ae06300c17 | |||
| 26879ca91a | |||
| 306744e5cb | |||
| 3ca32898a1 |
+1
-1
@@ -46,7 +46,7 @@ DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
IncludeCategories:
|
||||
- Regex: '^<'
|
||||
Priority: 3
|
||||
- Regex: '^"(osrm|util|engine|extract|contract)/'
|
||||
|
||||
+12
-2
@@ -71,6 +71,14 @@ matrix:
|
||||
packages: ['g++-5', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-5-release-i686"
|
||||
env: TARGET_ARCH='i686' CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-4.8-release-armhf"
|
||||
env: TARGET_ARCH='armhf' CCOMPILER='arm-linux-gnueabihf-gcc-4.8' CXXCOMPILER='arm-linux-gnueabihf-g++-4.8' BUILD_TYPE='Release'
|
||||
|
||||
# Disabled because of CI slowness
|
||||
#- os: linux
|
||||
#- compiler: gcc
|
||||
@@ -114,19 +122,20 @@ matrix:
|
||||
#- env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
|
||||
before_install:
|
||||
- if [[ ! -z $TARGET_ARCH ]] ; then source ./scripts/travis/before_install.$TARGET_ARCH.sh ; fi
|
||||
- if [[ $(uname -s) == 'Darwin' ]]; then sudo mdutil -i off /; fi;
|
||||
- source ./scripts/install_node.sh 4
|
||||
- npm install
|
||||
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
|
||||
- export PATH=${DEPS_DIR}/bin:${PATH} && mkdir -p ${DEPS_DIR}
|
||||
- CMAKE_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/cmake/3.5.2.tar.gz"
|
||||
- travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR}
|
||||
- travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
|
||||
- |
|
||||
if [[ ${CLANG_VERSION:-false} != false ]]; then
|
||||
export CCOMPILER='clang'
|
||||
export CXXCOMPILER='clang++'
|
||||
CLANG_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/clang/${CLANG_VERSION}.tar.gz"
|
||||
travis_retry wget --quiet -O - ${CLANG_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR}
|
||||
travis_retry wget --quiet -O - ${CLANG_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
|
||||
fi
|
||||
- |
|
||||
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
||||
@@ -161,6 +170,7 @@ install:
|
||||
- popd
|
||||
|
||||
script:
|
||||
- if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi
|
||||
- echo "travis_fold:start:BENCHMARK"
|
||||
- make -C test/data benchmark
|
||||
- echo "travis_fold:end:BENCHMARK"
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
# 5.3.0
|
||||
- API
|
||||
- Introduces new `TurnType` in the form of `use lane`. The type indicates that you have to stick to a lane without turning
|
||||
- Introduces lanes to the route response. The lane data contains both the markings at the intersection and a flag indicating their involvement in the turn
|
||||
|
||||
- Infrastructure
|
||||
- BREAKING: The new turn type changes the turn-type order. This breaks the **data format**.
|
||||
- BREAKING: Turn lane data introduces a new file (osrm.tld). This breaks the fileformat for older versions.
|
||||
|
||||
# 5.2.5
|
||||
- Bugfixes
|
||||
- Fixes a segfault caused by incorrect trimming logic for very short steps.
|
||||
|
||||
# 5.2.4
|
||||
- Bugfixes:
|
||||
- Fixed in issue that arised on roundabouts in combination with intermediate intersections and sliproads
|
||||
|
||||
# 5.2.3
|
||||
- Bugfixes:
|
||||
- Fixed an issue with name changes in roundabouts that could result in crashes
|
||||
|
||||
# 5.2.2
|
||||
Changes from 5.2.1
|
||||
- Bugfixes:
|
||||
|
||||
+5
-4
@@ -9,7 +9,7 @@ endif()
|
||||
|
||||
project(OSRM C CXX)
|
||||
set(OSRM_VERSION_MAJOR 5)
|
||||
set(OSRM_VERSION_MINOR 2)
|
||||
set(OSRM_VERSION_MINOR 3)
|
||||
set(OSRM_VERSION_PATCH 0)
|
||||
|
||||
# these two functions build up custom variables:
|
||||
@@ -39,7 +39,7 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(bitness 64)
|
||||
message(STATUS "Building on a 64 bit system")
|
||||
else()
|
||||
message(WARNING "Building on a 32 bit system is unsupported")
|
||||
message(STATUS "Building on a 32 bit system")
|
||||
endif()
|
||||
|
||||
if(WIN32 AND MSVC_VERSION LESS 1900)
|
||||
@@ -53,6 +53,7 @@ option(BUILD_COMPONENTS "Build osrm-components" OFF)
|
||||
option(ENABLE_ASSERTIONS OFF)
|
||||
option(COVERAGE OFF)
|
||||
option(SANITIZER OFF)
|
||||
option(ENABLE_LTO "Use LTO if available" ON)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/)
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
||||
@@ -118,7 +119,7 @@ if(CMAKE_BUILD_TYPE MATCHES Release)
|
||||
message(STATUS "Configuring OSRM in release mode")
|
||||
# Check if LTO is available
|
||||
check_cxx_compiler_flag("-flto" LTO_AVAILABLE)
|
||||
if(LTO_AVAILABLE)
|
||||
if(ENABLE_LTO AND LTO_AVAILABLE)
|
||||
set(OLD_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
# GCC in addition allows parallelizing LTO
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
@@ -319,7 +320,7 @@ include_directories(SYSTEM ${OSRM_INCLUDE_PATHS})
|
||||
# Binaries
|
||||
target_link_libraries(osrm-datastore osrm_store ${Boost_LIBRARIES})
|
||||
target_link_libraries(osrm-extract osrm_extract ${Boost_LIBRARIES})
|
||||
target_link_libraries(osrm-contract osrm_contract ${Boost_LIBRARIES})
|
||||
target_link_libraries(osrm-contract ${Boost_LIBRARIES} ${TBB_LIBRARIES} osrm_contract)
|
||||
target_link_libraries(osrm-routed osrm ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} ${ZLIB_LIBRARY})
|
||||
|
||||
set(EXTRACTOR_LIBRARIES
|
||||
|
||||
+48
-14
@@ -441,7 +441,7 @@ step.
|
||||
- `destinations`: The destinations of the way. Will be `undefined` if there are no destinations.
|
||||
- `mode`: A string signifying the mode of transportation.
|
||||
- `maneuver`: A `StepManeuver` object representing the maneuver.
|
||||
- `intersections`: A list of `Intersections` that are passed along the segment, the very first belonging to the StepManeuver
|
||||
- `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver
|
||||
|
||||
#### Example
|
||||
|
||||
@@ -451,16 +451,20 @@ step.
|
||||
"duration":15.6,
|
||||
"name":"Lortzingstraße",
|
||||
"maneuver":{
|
||||
"type":"depart",
|
||||
"modifier":"left"
|
||||
},
|
||||
"type":"turn",
|
||||
"modifier":"right",
|
||||
"lanes":[
|
||||
{"indications":["left","straight"], "valid":"false"},
|
||||
{"indications":["right"], "valid":"true"}
|
||||
]},
|
||||
"geometry":"{lu_IypwpAVrAvAdI",
|
||||
"mode":"driving",
|
||||
"intersections":[
|
||||
{"location":[13.39677,52.54366],
|
||||
"in":3,
|
||||
"out":1,
|
||||
"bearings":[66,246],
|
||||
"entry":["true","true"]},
|
||||
"bearings":[10,92,184,270],
|
||||
"entry":[false,"true","true"]},
|
||||
{"location":[13.394718,52.543096],
|
||||
"in":0,
|
||||
"out":2,
|
||||
@@ -503,9 +507,8 @@ step.
|
||||
Please note that even though there are `new name` and `notification` instructions, the `mode` and `name` can change
|
||||
between all instructions. They only offer a fallback in case nothing else is to report.
|
||||
|
||||
|
||||
- `modifier` An optional `string` indicating the direction change of the maneuver.
|
||||
|
||||
|
||||
| `modifier` | Description |
|
||||
|-------------------|-------------------------------------------|
|
||||
| uturn | indicates reversal of direction |
|
||||
@@ -516,17 +519,16 @@ step.
|
||||
| slight left | a slight turn to the left |
|
||||
| left | a normal turn to the left |
|
||||
| sharp left | a sharp turn to the left |
|
||||
|
||||
The list of turns without a modifier is limited to: `depart/arrive`. If the source/target location is close enough to the `depart/arrive` location, no modifier will be given.
|
||||
|
||||
The list of turns without a modifier is limited to: `depart/arrive`. If the source/target location is close enough to the `depart/arrive` location, no modifier will be given.
|
||||
|
||||
The meaning depends on the `type` field.
|
||||
|
||||
|
||||
| `type` | Description |
|
||||
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
|
||||
| `turn` | `modifier` indicates the change in direction accomplished through the turn |
|
||||
| `depart`/`arrive` | `modifier` indicates the position of departure point and arrival point in relation to the current direction of travel |
|
||||
|
||||
|
||||
|
||||
- `exit` An optional `integer` indicating number of the exit to take. The field exists for the following `type` field:
|
||||
|
||||
| `type` | Description |
|
||||
@@ -534,10 +536,42 @@ step.
|
||||
| `roundabout` | Number of the roundabout exit to take. If exit is `undefined` the destination is on the roundabout. |
|
||||
| else | Indicates the number of intersections passed until the turn. Example instruction: `at the fourth intersection, turn left` |
|
||||
|
||||
- `lanes`: Array of `Lane` objects that denote the available turn lanes at the turn location
|
||||
|
||||
New properties (potentially depending on `type`) may be introduced in the future without an API version change.
|
||||
|
||||
### Intersections
|
||||
### Lane
|
||||
|
||||
A lane give a representation of turn lane at the corresponding turn location.
|
||||
|
||||
#### Properties
|
||||
|
||||
- `indications`: a indication (e.g. marking on the road) specifying the turn lane. A road can have multiple indications (e.g. an arrow pointing straight and left). The indications are given in an array, each containing one of the following types. Further indications might be added on without an API version change.
|
||||
|
||||
| `value` | Description |
|
||||
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
|
||||
| `none` | No dedicated indication is shown. |
|
||||
| `sharp right` | An indication indicating a sharp right turn (i.e. strongly bend arrow). |
|
||||
| `right` | An indication indicating a right turn (i.e. bend arrow). |
|
||||
| `sharp right` | An indication indicating a slight right turn (i.e. slightly bend arrow). |
|
||||
| `straight` | No dedicated indication is shown (i.e. straight arrow). |
|
||||
| `sharp left` | An indication indicating a sharp left turn (i.e. strongly bend arrow). |
|
||||
| `left` | An indication indicating a left turn (i.e. bend arrow). |
|
||||
| `sharp left` | An indication indicating a slight left turn (i.e. slightly bend arrow). |
|
||||
| `uturn` | An indication signaling the possibility to reverse (i.e. fully bend arrow). |
|
||||
|
||||
- `valid`: a boolean flag indicating whether the lane is a valid choice in the current maneuver
|
||||
|
||||
#### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"indication": ["left", "straight"],
|
||||
"valid": "false"
|
||||
}
|
||||
```
|
||||
|
||||
### Intersection
|
||||
|
||||
An intersection gives a full representation of any cross-way the path passes bay. For every step, the very first intersection (`intersections[0]`) corresponds to the
|
||||
location of the StepManeuver. Further intersections are listed for every cross-way until the next turn instruction.
|
||||
|
||||
+2
-2
@@ -40,8 +40,8 @@ int main(int argc, const char *argv[]) try
|
||||
RouteParameters params;
|
||||
|
||||
// Route in monaco
|
||||
params.coordinates.push_back({util::FloatLongitude(7.419758), util::FloatLatitude(43.731142)});
|
||||
params.coordinates.push_back({util::FloatLongitude(7.419505), util::FloatLatitude(43.736825)});
|
||||
params.coordinates.push_back({util::FloatLongitude{7.419758}, util::FloatLatitude{43.731142}});
|
||||
params.coordinates.push_back({util::FloatLongitude{7.419505}, util::FloatLatitude{43.736825}});
|
||||
|
||||
// Response is in JSON format
|
||||
json::Object result;
|
||||
|
||||
@@ -46,14 +46,17 @@ Feature: Bike - Mode flag
|
||||
|
||||
Scenario: Bike - Mode when pushing bike against oneways
|
||||
Given the node map
|
||||
| a | b | |
|
||||
| | c | d |
|
||||
| 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 |
|
||||
|
||||
@@ -18,8 +18,8 @@ Feature: Bike - Oneway streets
|
||||
|
||||
Scenario: Bike - Around the Block
|
||||
Given the node map
|
||||
| a | b |
|
||||
| d | c |
|
||||
| | a | b | |
|
||||
| f | d | c | e |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway | foot |
|
||||
@@ -27,6 +27,8 @@ Feature: Bike - Oneway streets
|
||||
| bc | | no |
|
||||
| cd | | no |
|
||||
| da | | no |
|
||||
| df | | no |
|
||||
| ce | | no |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
|
||||
@@ -87,14 +87,16 @@ Feature: Bike - Accessability of different way types
|
||||
|
||||
Scenario: Bike - Instructions when pushing bike on oneways
|
||||
Given the node map
|
||||
| a | b | |
|
||||
| | c | d |
|
||||
| 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 |
|
||||
|
||||
@@ -38,3 +38,20 @@ Feature: Bike - Surfaces
|
||||
| cycleway | | 48s |
|
||||
| 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 | 6 km/h |
|
||||
| c | d | cd,cd | pushing bike,pushing bike | 6 km/h |
|
||||
| d | c | cd,cd | pushing bike,pushing bike | 6 km/h |
|
||||
|
||||
@@ -35,8 +35,8 @@ Feature: Car - Oneway streets
|
||||
|
||||
Scenario: Car - Around the Block
|
||||
Given the node map
|
||||
| a | b |
|
||||
| d | c |
|
||||
| | a | b | |
|
||||
| f | d | c | e |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
@@ -44,6 +44,8 @@ Feature: Car - Oneway streets
|
||||
| bc | |
|
||||
| cd | |
|
||||
| da | |
|
||||
| ce | |
|
||||
| df | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
@routing @guidance @turn-lanes
|
||||
Feature: Turn Lane Guidance
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 20 meters
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate Lane Change for subsequent multi-lane intersections
|
||||
Given the node map
|
||||
| a | | b | | x | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | | z |
|
||||
| | | | | | | |
|
||||
| | | y | | e | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward |
|
||||
| ab | through\|right&right&right |
|
||||
| bx | |
|
||||
| bc | left\|left&through |
|
||||
| cd | through\|right |
|
||||
| cy | |
|
||||
| dz | |
|
||||
| de | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes | # |
|
||||
| a,d | ab,bc,cd,cd | depart,turn right,turn left,arrive | ,straight:false right:true right:true right:false,left:true left:true straight:false, | 2 hops |
|
||||
| a,e | ab,bc,cd,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true, | 3 hops |
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate Lane Change for quick same direction turns, staying on the same street
|
||||
Given the node map
|
||||
| a | | b | x |
|
||||
| | | | |
|
||||
| | | c | |
|
||||
| | | | |
|
||||
| e | | d | y |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | turn:lanes:backward | name |
|
||||
| ab | through\|right&right | | MySt |
|
||||
| bx | | | XSt |
|
||||
| bc | | left\|right | MySt |
|
||||
| cd | left\|right | through\|through | MySt |
|
||||
| de | | left\|left&through | MySt |
|
||||
| dy | | | YSt |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | MySt,MySt,MySt,MySt | depart,continue right,turn right,arrive | ,straight:false right:false right:true,left:false right:true, |
|
||||
| e,a | MySt,MySt,MySt,MySt | depart,continue left,turn left,arrive | ,left:true left:false straight:false,left:true right:false, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate Lane Change for quick same direction turns, changing between streets
|
||||
Given the node map
|
||||
| a | | b | x |
|
||||
| | | | |
|
||||
| | | c | |
|
||||
| | | | |
|
||||
| e | | d | y |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | turn:lanes:backward | name |
|
||||
| ab | through\|right&right | | AXSt |
|
||||
| bx | | | AXSt |
|
||||
| bc | | left\|right | BDSt |
|
||||
| cd | left\|right | through\|through | BDSt |
|
||||
| de | | left\|left&through | EYSt |
|
||||
| dy | | | EYSt |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | AXSt,BDSt,EYSt,EYSt | depart,turn right,turn right,arrive | ,straight:false right:false right:true,left:false right:true, |
|
||||
| e,a | EYSt,BDSt,AXSt,AXSt | depart,turn left,turn left,arrive | ,left:true left:false straight:false,left:true right:false, |
|
||||
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate Lane Change for quick turns during a merge
|
||||
Given the node map
|
||||
| a | | | | |
|
||||
| x | b | | c | y |
|
||||
| | | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | name | highway | oneway |
|
||||
| ab | slight_left\|slight_left | On | motorway_link | yes |
|
||||
| xb | | Hwy | motorway | |
|
||||
| bc | through\|slight_right | Hwy | motorway | |
|
||||
| cd | | Off | motorway_link | yes |
|
||||
| cy | | Hwy | motorway | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive | ,slight left:false slight left:true,straight:false slight right:true, |
|
||||
|
||||
|
||||
@anticipate
|
||||
Scenario: Schoenefelder Kreuz
|
||||
# https://www.openstreetmap.org/way/264306388#map=16/52.3202/13.5568
|
||||
Given the node map
|
||||
| a | b | x | | | i |
|
||||
| | | c | d | | |
|
||||
| | | | | | j |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | lanes | highway | oneway | name |
|
||||
| ab | none\|none&none&slight_right&slight_right | 5 | motorway | | abx |
|
||||
| bx | | 3 | motorway | | abx |
|
||||
| bc | | 2 | motorway_link | yes | bcd |
|
||||
| cd | slight_left\|slight_left;slight_right&slight_right | 3 | motorway_link | yes | bcd |
|
||||
| di | slight_left\|slight_right | 2 | motorway_link | yes | di |
|
||||
| dj | | 2 | motorway_link | yes | dj |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,i | abx,bcd,di,di | depart,off ramp right,fork slight left,arrive | ,none:false none:false none:false slight right:true slight right:true,slight left:true slight left;slight right:true slight right:false, |
|
||||
| a,j | abx,bcd,dj,dj | depart,off ramp right,fork slight right,arrive | ,none:false none:false none:false slight right:true slight right:true,slight left:false slight left;slight right:true slight right:true, |
|
||||
|
||||
|
||||
@anticipate
|
||||
Scenario: Kreuz Oranienburg
|
||||
# https://www.openstreetmap.org/way/4484007#map=18/52.70439/13.20269
|
||||
Given the node map
|
||||
| i | | | | | a |
|
||||
| j | | c | b | | x |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | lanes | highway | oneway | name |
|
||||
| ab | | 1 | motorway_link | yes | ab |
|
||||
| xb | | 1 | motorway_link | yes | xbcj |
|
||||
| bc | none\|slight_right | 2 | motorway_link | yes | xbcj |
|
||||
| ci | | 1 | motorway_link | yes | ci |
|
||||
| cj | | 1 | motorway_link | yes | xbcj |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,i | ab,xbcj,ci,ci | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
|
||||
| a,j | ab,xbcj,xbcj,xbcj | depart,merge slight left,use lane straight,arrive | ,,none:true slight right:false, |
|
||||
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for fan-in
|
||||
Given the node map
|
||||
| a | | b | | x | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | | z |
|
||||
| | | | | | | |
|
||||
| | | y | | e | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | name |
|
||||
| ab | through\|right&right&right | abx |
|
||||
| bx | | abx |
|
||||
| bc | left\|left&through | bcy |
|
||||
| cy | | bcy |
|
||||
| cd | through\|right | cdz |
|
||||
| dz | | cdz |
|
||||
| de | | de |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for fan-out
|
||||
Given the node map
|
||||
| a | | b | | x | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | | z |
|
||||
| | | | | | | |
|
||||
| | | y | | e | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | name |
|
||||
| ab | through\|right | abx |
|
||||
| bx | | abx |
|
||||
| bc | left\|left&through | bcy |
|
||||
| cy | | bcy |
|
||||
| cd | through\|right&right&right | cdz |
|
||||
| dz | | cdz |
|
||||
| de | | de |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:true,left:true left:true straight:false,straight:false right:true right:true right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for fan-in followed by fan-out
|
||||
Given the node map
|
||||
| a | | b | | x | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | | z |
|
||||
| | | | | | | |
|
||||
| | | y | | e | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | name |
|
||||
| ab | through\|right&right&right | abx |
|
||||
| bx | | abx |
|
||||
| bc | left\|left&through | bcy |
|
||||
| cy | | bcy |
|
||||
| cd | through\|right&right&right | cdz |
|
||||
| dz | | cdz |
|
||||
| de | | de |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:true right:true right:false,left:true left:true straight:false,straight:false right:true right:true right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for fan-out followed by fan-in
|
||||
Given the node map
|
||||
| a | | b | | x | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | | z |
|
||||
| | | | | | | |
|
||||
| | | y | | e | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | name |
|
||||
| ab | through\|right | abx |
|
||||
| bx | | abx |
|
||||
| bc | left\|left&through | bcy |
|
||||
| cy | | bcy |
|
||||
| cd | through\|right | cdz |
|
||||
| dz | | cdz |
|
||||
| de | | de |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:true,left:false left:true straight:false,straight:false right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for multiple hops with same number of lanes
|
||||
Given the node map
|
||||
| a | | b | | x | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | | z |
|
||||
| | | | | | | |
|
||||
| | | y | | e | | f |
|
||||
| | | | | | | |
|
||||
| | | | | w | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | name |
|
||||
| ab | through\|right&right&right | abx |
|
||||
| bx | | abx |
|
||||
| bc | left\|left&through | bcy |
|
||||
| cy | | bcy |
|
||||
| cd | through\|right&right | cdz |
|
||||
| dz | | cdz |
|
||||
| de | left\|through | dew |
|
||||
| ew | | dew |
|
||||
| ef | | ef |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | abx,bcy,cdz,dew,ef,ef | depart,turn right,turn left,turn right,turn left,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true right:false,left:true straight:false, |
|
||||
|
||||
@anticipate @bug @todo
|
||||
Scenario: Tripple Right keeping Left
|
||||
Given the node map
|
||||
| a | | | | b | | i |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| f | | e | | | | g |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | j | d | | c | | |
|
||||
| | | | | h | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | highway | name |
|
||||
| abi | \|&right&right | primary | start |
|
||||
| bch | \|&right&right | primary | first |
|
||||
| cdj | \|&right&right | primary | second |
|
||||
| de | left\|right&right | secondary | third |
|
||||
| feg | | tertiary | fourth |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,end of road left,arrive | ,none:false none:true right:false right:false,none:false none:true right:false right:false,none:false none:true right:false right:false,left:true right:false right:false, |
|
||||
| a,g | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,end of road right,arrive | ,none:false none:false right:true right:true,none:false none:false right:true right:true,none:false none:false right:true right:true,left:false right:true right:true, |
|
||||
|
||||
@anticipate @bug @todo
|
||||
Scenario: Tripple Left keeping Right
|
||||
Given the node map
|
||||
| i | | b | | | | a |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| g | | | | e | | f |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | j | |
|
||||
| | | h | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | highway | name |
|
||||
| abi | left\|left&& | primary | start |
|
||||
| bch | left\|left&& | primary | first |
|
||||
| cdj | left\|left&& | primary | second |
|
||||
| de | left\|left&right | secondary | third |
|
||||
| feg | | tertiary | fourth |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,end of road right,arrive | ,left:false left:false none:true none:false,left:false left:false none:true none:false,left:false left:false none:true none:false,left:false left:false right:true, |
|
||||
| a,g | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,end of road left,arrive | ,left:true left:true none:false none:false,left:true left:true none:false none:false,left:true left:true none:false none:false,left:true left:true right:false, |
|
||||
@@ -525,9 +525,9 @@ Feature: Collapse
|
||||
| cf | secondary | bottom |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| a,d | depart,continue right,end of road right,arrive | road,road,road,road |
|
||||
| d,a | depart,continue left,end of road left,arrive | road,road,road,road |
|
||||
| waypoints | turns | route |
|
||||
| a,d | depart,continue right,turn right,arrive | road,road,road,road |
|
||||
| d,a | depart,continue left,turn left,arrive | road,road,road,road |
|
||||
|
||||
Scenario: Forking before a turn
|
||||
Given the node map
|
||||
|
||||
@@ -57,20 +57,21 @@ Feature: Slipways and Dedicated Turn Lanes
|
||||
|
||||
Scenario: Inner city expressway with on road
|
||||
Given the node map
|
||||
| a | b | | | | c |
|
||||
| | | | | f | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | d |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | e |
|
||||
| a | b | | | | c | g |
|
||||
| | | | | f | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | d | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | e | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abc | primary | road |
|
||||
| cg | primary | road |
|
||||
| bfd | trunk_link | |
|
||||
| cde | trunk | trunk |
|
||||
|
||||
@@ -123,3 +124,46 @@ Feature: Slipways and Dedicated Turn Lanes
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,f | road,road,road | depart,continue uturn,arrive |
|
||||
|
||||
Scenario: Schwarzwaldstrasse Autobahn
|
||||
Given the node map
|
||||
| | | | | i | | | | | | h | | | | | g |
|
||||
| | | j | | | | | | | | | | | | | |
|
||||
| a | | | | | | | k | | | | | | | | |
|
||||
| | | | b | | r | c | | d | | e | | | | | f |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | l | | | | | | | | | | |
|
||||
| | | | | | m | | | | | | | | | | |
|
||||
| | | | | | | n | | q | | | | | | | |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | | o | | p | | | | | | | |
|
||||
|
||||
And the nodes
|
||||
# the traffic light at `l` is not actually in the data, but necessary for the test to check everything
|
||||
# http://www.openstreetmap.org/#map=19/48.99211/8.40336
|
||||
| node | highway |
|
||||
| r | traffic_signals |
|
||||
| l | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | ref | oneway |
|
||||
| abrcd | secondary | Schwarzwaldstrasse | L561 | yes |
|
||||
| hija | secondary | Schwarzwaldstrasse | L561 | yes |
|
||||
| def | secondary | Ettlinger Strasse | | yes |
|
||||
| gh | secondary | Ettlinger Strasse | | yes |
|
||||
| blmn | secondary_link | | L561 | yes |
|
||||
| hkc | secondary_link | Ettlinger Strasse | | yes |
|
||||
| qdki | secondary_link | Ettlinger Allee | | yes |
|
||||
| cn | secondary_link | Ettlinger Allee | | yes |
|
||||
| no | primary | Ettlinger Allee | | yes |
|
||||
| pq | primary | Ettlinger Allee | | yes |
|
||||
| qe | secondary_link | Ettlinger Allee | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,o | Schwarzwaldstrasse (L561),Ettlinger Allee,Ettlinger Allee | depart,turn right,arrive |
|
||||
|
||||
@@ -8,116 +8,123 @@ Feature: End Of Road Instructions
|
||||
Scenario: End of Road with through street
|
||||
Given the node map
|
||||
| | | c |
|
||||
| a | | b |
|
||||
| | | d |
|
||||
| a | e | b |
|
||||
| | f | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| cbd | primary |
|
||||
| ef | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
|
||||
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,cbd,cbd | depart,end of road left,arrive |
|
||||
| a,d | aeb,cbd,cbd | depart,end of road right,arrive |
|
||||
|
||||
Scenario: End of Road with three streets
|
||||
Given the node map
|
||||
| | | c |
|
||||
| a | | b |
|
||||
| | | d |
|
||||
| a | e | b |
|
||||
| | f | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| cb | primary |
|
||||
| bd | primary |
|
||||
| ef | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,cb,cb | depart,end of road left,arrive |
|
||||
| a,d | ab,bd,bd | depart,end of road right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,cb,cb | depart,end of road left,arrive |
|
||||
| a,d | aeb,bd,bd | depart,end of road right,arrive |
|
||||
|
||||
Scenario: End of Road with three streets, slightly angled
|
||||
Given the node map
|
||||
| a | | | | | c |
|
||||
| | | | | | b |
|
||||
| a | e | | | | c |
|
||||
| | f | | | | b |
|
||||
| | | | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| cb | primary |
|
||||
| bd | primary |
|
||||
| ef | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,cb,cb | depart,end of road left,arrive |
|
||||
| a,d | ab,bd,bd | depart,end of road right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,cb,cb | depart,end of road left,arrive |
|
||||
| a,d | aeb,bd,bd | depart,end of road right,arrive |
|
||||
|
||||
Scenario: End of Road with three streets, slightly angled
|
||||
Given the node map
|
||||
| | | | | | c |
|
||||
| | | | | | b |
|
||||
| a | | | | | d |
|
||||
| | f | | | | b |
|
||||
| a | e | | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| ef | primary |
|
||||
| cb | primary |
|
||||
| bd | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,cb,cb | depart,end of road left,arrive |
|
||||
| a,d | ab,bd,bd | depart,end of road right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,cb,cb | depart,end of road left,arrive |
|
||||
| a,d | aeb,bd,bd | depart,end of road right,arrive |
|
||||
|
||||
Scenario: End of Road with through street, slightly angled
|
||||
Given the node map
|
||||
| a | | | | | c |
|
||||
| | | | | | b |
|
||||
| a | e | | | | c |
|
||||
| | f | | | | b |
|
||||
| | | | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| ef | primary |
|
||||
| cbd | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
|
||||
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,cbd,cbd | depart,end of road left,arrive |
|
||||
| a,d | aeb,cbd,cbd | depart,end of road right,arrive |
|
||||
|
||||
Scenario: End of Road with through street, slightly angled
|
||||
Given the node map
|
||||
| | | | | | c |
|
||||
| | | | | | b |
|
||||
| a | | | | | d |
|
||||
| | f | | | | b |
|
||||
| a | e | | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| ef | primary |
|
||||
| cbd | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
|
||||
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,cbd,cbd | depart,end of road left,arrive |
|
||||
| a,d | aeb,cbd,cbd | depart,end of road right,arrive |
|
||||
|
||||
Scenario: End of Road with two ramps - prefer ramp over end of road
|
||||
Given the node map
|
||||
| | | c |
|
||||
| a | | b |
|
||||
| | | d |
|
||||
| a | e | b |
|
||||
| | f | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| ef | primary |
|
||||
| bc | motorway_link |
|
||||
| bd | motorway_link |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,bc,bc | depart,on ramp left,arrive |
|
||||
| a,d | ab,bd,bd | depart,on ramp right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,bc,bc | depart,on ramp left,arrive |
|
||||
| a,d | aeb,bd,bd | depart,on ramp right,arrive |
|
||||
|
||||
|
||||
@@ -296,3 +296,21 @@ Feature: Fork Instructions
|
||||
| waypoints | route | turns |
|
||||
| a,c | abc,abc | depart,arrive |
|
||||
| a,d | abc,bd,bd | depart,turn slight right,arrive |
|
||||
|
||||
Scenario: Fork on motorway links - don't fork on through
|
||||
Given the node map
|
||||
| i | | | | | a |
|
||||
| j | | c | b | | x |
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway |
|
||||
| xb | xbcj | motorway_link |
|
||||
| bc | xbcj | motorway_link |
|
||||
| cj | xbcj | motorway_link |
|
||||
| ci | off | motorway_link |
|
||||
| ab | on | motorway_link |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,j | on,xbcj,xbcj | depart,merge slight left,arrive |
|
||||
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive |
|
||||
|
||||
@@ -17,8 +17,8 @@ Feature: Intersections Data
|
||||
| bd | corner |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | intersections |
|
||||
| a,c | through,through | depart,arrive | true:90,true:90 true:180 false:270;true:270 |
|
||||
| waypoints | route | intersections |
|
||||
| a,c | through,through | true:90,true:90 true:180 false:270;true:270 |
|
||||
|
||||
Scenario: Passing Three Way North
|
||||
Given the node map
|
||||
@@ -32,8 +32,8 @@ Feature: Intersections Data
|
||||
| bd | corner |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | intersections |
|
||||
| a,c | through,through | depart,arrive | true:90,true:0 true:90 false:270;true:270 |
|
||||
| waypoints | route | intersections |
|
||||
| a,c | through,through | true:90,true:0 true:90 false:270;true:270 |
|
||||
|
||||
Scenario: Passing Oneway Street In
|
||||
Given the node map
|
||||
@@ -47,8 +47,8 @@ Feature: Intersections Data
|
||||
| db | corner | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | intersections |
|
||||
| a,c | through,through | depart,arrive | true:90,false:0 true:90 false:270;true:270 |
|
||||
| waypoints | route | intersections |
|
||||
| a,c | through,through | true:90,false:0 true:90 false:270;true:270 |
|
||||
|
||||
Scenario: Passing Oneway Street Out
|
||||
Given the node map
|
||||
@@ -62,8 +62,8 @@ Feature: Intersections Data
|
||||
| bd | corner | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | intersections |
|
||||
| a,c | through,through | depart,arrive | true:90,true:0 true:90 false:270;true:270 |
|
||||
| waypoints | route | intersections |
|
||||
| a,c | through,through | true:90,true:0 true:90 false:270;true:270 |
|
||||
|
||||
Scenario: Passing Two Intersections
|
||||
Given the node map
|
||||
@@ -80,27 +80,8 @@ Feature: Intersections Data
|
||||
| cf | corner |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | intersections |
|
||||
| a,d | through,through | depart,arrive | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
|
||||
|
||||
Scenario: Regression test #2424
|
||||
Given the node map
|
||||
| | | e | | | | | | i | | | | |
|
||||
| a | | b | | c | | d | | h | | k | | m |
|
||||
| | | | | f | | | | | | l | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name |
|
||||
| abcd | Fritz-Elsas-Straße |
|
||||
| hkm | Fritz-Elsas-Straße |
|
||||
| dhi | Martin-Luther-Straße |
|
||||
| be | corner |
|
||||
| kl | corner |
|
||||
| cf | corner |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,m | Fritz-Elsas-Straße,Fritz-Elsas-Straße| depart,arrive |
|
||||
| waypoints | route | intersections |
|
||||
| a,d | through,through | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
|
||||
|
||||
Scenario: Passing Two Intersections, Collapsing
|
||||
Given the node map
|
||||
@@ -117,9 +98,9 @@ Feature: Intersections Data
|
||||
| cf | corner |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | intersections |
|
||||
| a,d | through,through | depart,arrive | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
|
||||
| f,a | corner,through,through | depart,end of road left,arrive | true:0;true:90 false:180 true:270,true:0 false:90 true:270;true:90 |
|
||||
| waypoints | route | intersections |
|
||||
| a,d | through,through | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
|
||||
| f,a | corner,through,through | true:0;true:90 false:180 true:270,true:0 false:90 true:270;true:90 |
|
||||
|
||||
Scenario: Roundabouts
|
||||
Given the node map
|
||||
@@ -144,10 +125,10 @@ Feature: Intersections Data
|
||||
| hd | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | intersections |
|
||||
| e,f | ea,fb,fb | depart,abcda-exit-1,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 |
|
||||
| e,g | ea,gc,gc | depart,abcda-exit-2,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0|
|
||||
| e,h | ea,hd,hd | depart,abcda-exit-3,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330,true:90 false:210 true:330;true:270 |
|
||||
| e,2 | ea,abcda,abcda | depart,abcda-exit-undefined,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1|
|
||||
| 1,g | abcda,gc,gc | depart,abcda-exit-2,arrive | true:214;true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:0|
|
||||
| 1,3 | abcda,abcda | depart,arrive | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214|
|
||||
| waypoints | route | intersections |
|
||||
| e,f | ea,fb,fb | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 |
|
||||
| e,g | ea,gc,gc | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0 |
|
||||
| e,h | ea,hd,hd | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330,true:90 false:210 true:330;true:270 |
|
||||
| e,2 | ea,abcda,abcda | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1 |
|
||||
| 1,g | abcda,gc,gc | true:214;false:30 true:150 true:270,true:30 true:180 false:330;true:0 |
|
||||
| 1,3 | abcda,abcda | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214 |
|
||||
|
||||
@@ -50,3 +50,27 @@ Feature: Merging
|
||||
| waypoints | route | turns |
|
||||
| d,c | db,abc,abc | depart,merge slight left,arrive |
|
||||
|
||||
Scenario: Merge onto a turning road
|
||||
Given the node map
|
||||
| | | | | | | e |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | d | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | c | | |
|
||||
| | | | b | | | |
|
||||
| a | | | | | | f |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abcde | primary | road |
|
||||
| fd | residential | in |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| f,e | depart,merge slight left,arrive | in,road,road |
|
||||
| f,a | depart,turn sharp left,arrive | in,road,road |
|
||||
|
||||
@@ -216,3 +216,21 @@ Feature: Motorway Guidance
|
||||
| waypoints | route | turns |
|
||||
| d,c | db,abc,abc | depart,merge slight left,arrive |
|
||||
| e,c | eb,abc,abc | depart,merge slight right,arrive |
|
||||
|
||||
Scenario: Handle 90 degree off ramps correctly
|
||||
Given the node map
|
||||
| a | | | | |
|
||||
| x | b | | c | y |
|
||||
| | | | d | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway | oneway |
|
||||
| ab | On | motorway_link | yes |
|
||||
| xb | Hwy | motorway | |
|
||||
| bc | Hwy | motorway | |
|
||||
| cd | Off | motorway_link | yes |
|
||||
| cy | Hwy | motorway | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive |
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
@routing @guidance @post-processing
|
||||
Feature: General Post-Processing related features
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 10 meters
|
||||
|
||||
# this testcase used to crash geometry generation (at that time handled during intersection generation)
|
||||
Scenario: Regression test #2424
|
||||
Given the node map
|
||||
| | | e | | | | | | i | | | | |
|
||||
| a | | b | | c | | d | | h | | k | | m |
|
||||
| | | | | f | | | | | | l | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name |
|
||||
| abcd | Fritz-Elsas-Straße |
|
||||
| hkm | Fritz-Elsas-Straße |
|
||||
| dhi | Martin-Luther-Straße |
|
||||
| be | corner |
|
||||
| kl | corner |
|
||||
| cf | corner |
|
||||
@@ -361,3 +361,79 @@ Feature: Basic Roundabout
|
||||
| a,f | ab,ef,ef | depart,roundabout-exit-2,arrive | 0->180,180->270,180->0 |
|
||||
| a,h | ab,gh,gh | depart,roundabout-exit-1,arrive | 0->180,180->270,270->0 |
|
||||
|
||||
Scenario: Motorway Roundabout
|
||||
#See 39.933742 -75.082345
|
||||
Given the node map
|
||||
| | | | | l | | | | a | | i |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | b | | | | |
|
||||
| | | | c | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | h | | |
|
||||
| n | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | d | | | | | | | | j |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | m | | | g | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | e | | f | | | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | junction | name | highway | oneway | ref |
|
||||
| ab | | crescent | trunk | yes | US 130 |
|
||||
| bcd | roundabout | crescent | trunk | yes | US 130 |
|
||||
| de | | crescent | trunk | yes | US 130 |
|
||||
| fg | | crescent | trunk | yes | US 130 |
|
||||
| gh | roundabout | crescent | trunk | yes | US 130 |
|
||||
| hi | | crescent | trunk | yes | US 130 |
|
||||
| jh | | | trunk_link | yes | NJ 38 |
|
||||
| hb | roundabout | | trunk_link | yes | NJ 38 |
|
||||
| bl | | | trunk_link | yes | NJ 38 |
|
||||
| cnd | | kaighns | trunk_link | yes | |
|
||||
| dmg | roundabout | | trunk_link | yes | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,e | crescent (US 130),crescent (US 130),crescent (US 130) | depart,roundabout-exit-3,arrive |
|
||||
| j,l | NJ 38,NJ 38,NJ 38 | depart,roundabout-exit-2,arrive |
|
||||
|
||||
Scenario: Double Roundabout with through-lane
|
||||
#http://map.project-osrm.org/?z=18¢er=38.911752%2C-77.048667&loc=38.912003%2C-77.050831&loc=38.909277%2C-77.042516&hl=en&alt=0
|
||||
Given the node map
|
||||
| | | | | o | | | | | | | | | | | | n | | | | |
|
||||
| | | | | e | | | | | | | | | | | | j | | | | |
|
||||
| | | | | | | | | | | | | | | | | | | | | |
|
||||
| | | | | | | q | | | | | | | | | | | | | | |
|
||||
| a | | b | | | | | | s | | f | | | | g | | | | i | | k |
|
||||
| | | | | | | r | | | | | | | | | | | p | | | |
|
||||
| | | | | | | | | | | t | | | | | | | | | | |
|
||||
| | | | | c | | d | | | | | | | | | | h | | | | |
|
||||
| | | | | l | | | | | | | | | | | | m | | | | |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| i | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | junction | name | oneway |
|
||||
| bcdrqeb | roundabout | sheridan circle | yes |
|
||||
| ghi | roundabout | dupont circle | yes |
|
||||
| ijg | roundabout | dupont circle | yes |
|
||||
| ab | | massachusetts | no |
|
||||
| sfgpik | | massachusetts | no |
|
||||
| cl | | 23rd street | no |
|
||||
| oe | | r street | no |
|
||||
| jn | | new hampshire | no |
|
||||
| mh | | new hampshire | yes |
|
||||
| rsq | | massachusetts | yes |
|
||||
| ft | | suppressed | no |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | sfgpik | ijg | i | no_left_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,k | massachusetts,massachusetts,massachusetts,massachusetts | depart,sheridan circle-exit-2,dupont circle-exit-1,arrive |
|
||||
|
||||
@@ -0,0 +1,670 @@
|
||||
@routing @guidance @turn-lanes
|
||||
Feature: Turn Lane Guidance
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 20 meters
|
||||
|
||||
#requires https://github.com/cucumber/cucumber-js/issues/417
|
||||
#Due to this, we use & as a pipe character. Switch them out for \| when 417 is fixed
|
||||
@bug @WORKAROUND-FIXME
|
||||
Scenario: Basic Turn Lane 3-way Turn with empty lanes
|
||||
Given the node map
|
||||
| a | | b | | c |
|
||||
| | | d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes | turn:lanes:forward | turn:lanes:backward | name |
|
||||
| ab | | through\|right | | in |
|
||||
| bc | | | left\|through&& | straight |
|
||||
| bd | | | left\|right | right |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,straight:true right:false, |
|
||||
| a,d | in,right,right | depart,turn right,arrive | ,straight:false right:true, |
|
||||
| c,a | straight,in,in | depart,new name straight,arrive | ,left:false straight:true none:true none:true, |
|
||||
| c,d | straight,right,right | depart,turn left,arrive | ,left:true straight:false none:false none:false, |
|
||||
|
||||
Scenario: Basic Turn Lane 4-Way Turn
|
||||
Given the node map
|
||||
| | | e | | |
|
||||
| a | | b | | c |
|
||||
| | | d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes | turn:lanes:forward | turn:lanes:backward | name |
|
||||
| ab | | \|right | | in |
|
||||
| bc | | | | straight |
|
||||
| bd | | | left\| | right |
|
||||
| be | | | | left |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,none:true right:false, |
|
||||
| a,d | in,right,right | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,e | in,left,left | depart,turn left,arrive | ,none:true right:false, |
|
||||
| d,a | right,in,in | depart,turn left,arrive | ,left:true none:false, |
|
||||
| d,e | right,left,left | depart,new name straight,arrive | ,left:false none:true, |
|
||||
| d,c | right,straight,straight | depart,turn right,arrive | ,left:false none:true, |
|
||||
|
||||
Scenario: Basic Turn Lane 4-Way Turn using none
|
||||
Given the node map
|
||||
| | | e | | |
|
||||
| a | | b | | c |
|
||||
| | | d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes | turn:lanes:forward | turn:lanes:backward | name |
|
||||
| ab | | none\|right | | in |
|
||||
| bc | | | | straight |
|
||||
| bd | | | left\|none | right |
|
||||
| be | | | | left |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,none:true right:false, |
|
||||
| a,d | in,right,right | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,e | in,left,left | depart,turn left,arrive | ,none:true right:false, |
|
||||
|
||||
Scenario: Basic Turn Lane 4-Way With U-Turn Lane
|
||||
Given the node map
|
||||
| | | e | | |
|
||||
| a | 1 | b | | c |
|
||||
| | | d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes | turn:lanes:forward | name |
|
||||
| ab | | reverse;left\|through;right | in |
|
||||
| bc | | | straight |
|
||||
| bd | | | right |
|
||||
| be | | | left |
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | turns | lanes |
|
||||
| a | c | 180,180 180,180 | in,straight,straight | depart,new name straight,arrive | ,left;uturn:false straight;right:true, |
|
||||
| a | d | 180,180 180,180 | in,right,right | depart,turn right,arrive | ,left;uturn:false straight;right:true, |
|
||||
| a | e | 180,180 180,180 | in,left,left | depart,turn left,arrive | ,left;uturn:true straight;right:false, |
|
||||
| 1 | a | 90,2 270,2 | in,in,in | depart,turn uturn,arrive | ,left;uturn:true straight;right:false, |
|
||||
|
||||
|
||||
#this next test requires decision on how to announce lanes for going straight if there is no turn
|
||||
@TODO @WORKAROUND-FIXME
|
||||
Scenario: Turn with Bus-Lane
|
||||
Given the node map
|
||||
| a | | b | | c |
|
||||
| | | | | |
|
||||
| | | d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | lanes:psv:forward |
|
||||
| ab | road | through\|right& | 1 |
|
||||
| bc | road | | |
|
||||
| bd | turn | | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
|
||||
| a,c | road,road,road | depart,use lane straight,arrive | ,straight:true right:false, |
|
||||
|
||||
#turn lanes are often drawn at the incoming road, even though the actual turn requires crossing the intersection first
|
||||
@todo @WORKAROUND-FIXME @bug
|
||||
Scenario: Turn Lanes at Segregated Road
|
||||
Given the node map
|
||||
| | | i | l | | |
|
||||
| | | | | | |
|
||||
| h | | g | f | | e |
|
||||
| a | | b | c | | d |
|
||||
| | | | | | |
|
||||
| | | j | k | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|through&right | yes |
|
||||
| bc | road | left\|through | yes |
|
||||
| cd | road | | yes |
|
||||
| ef | road | \|through&through;right | yes |
|
||||
| fg | road | left;through\|through& | yes |
|
||||
| gh | road | | yes |
|
||||
| ig | cross | | yes |
|
||||
| gb | cross | left\|through | yes |
|
||||
| bj | cross | | yes |
|
||||
| kc | cross | left\|through;right | yes |
|
||||
| cf | cross | left\|through | yes |
|
||||
| fl | cross | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,left:false straight:true right:false, |
|
||||
| a,l | road,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,left:true straight:false right:false, |
|
||||
| k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, |
|
||||
| k,l | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight;right:true, |
|
||||
| k,h | cross,road,road | depart,turn left,arrive | ,left:true straight;right:false, |
|
||||
| k,j | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight;right:false, |
|
||||
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, |
|
||||
| e,h | road,road | depart,arrive | ,none:false straight:true straight;right:true |
|
||||
| e,j | road,cross,cross | depart,turn left,arrive | ,none:true straight:false straight;right:false, |
|
||||
| e,d | road,road,road | depart,continue uturn,arrive | ,none:true straight:false straight;right:false, |
|
||||
| i,h | cross,road,road | depart,turn right,arrive | ,, |
|
||||
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight:true, |
|
||||
| i,d | cross,road,road | depart,turn left,arrive | ,left:true straight:false, |
|
||||
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, |
|
||||
|
||||
#copy of former case to prevent further regression
|
||||
Scenario: Turn Lanes at Segregated Road
|
||||
Given the node map
|
||||
| | | i | l | | |
|
||||
| | | | | | |
|
||||
| h | | g | f | | e |
|
||||
| a | | b | c | | d |
|
||||
| | | | | | |
|
||||
| | | j | k | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|through&right | yes |
|
||||
| bc | road | left\|through | yes |
|
||||
| cd | road | | yes |
|
||||
| ef | road | \|through&through;right | yes |
|
||||
| fg | road | left;through\|through& | yes |
|
||||
| gh | road | | yes |
|
||||
| ig | cross | | yes |
|
||||
| gb | cross | left\|through | yes |
|
||||
| bj | cross | | yes |
|
||||
| kc | cross | left\|through;right | yes |
|
||||
| cf | cross | left\|through | yes |
|
||||
| fl | cross | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
|
||||
| k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, |
|
||||
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, |
|
||||
| i,h | cross,road,road | depart,turn right,arrive | ,, |
|
||||
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight:true, |
|
||||
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, |
|
||||
|
||||
Scenario: Turn Lanes at Segregated Road
|
||||
Given the node map
|
||||
| | | g | f | | |
|
||||
| a | | b | c | | d |
|
||||
| | | | | | |
|
||||
| | | j | k | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|through&right | yes |
|
||||
| bc | road | | yes |
|
||||
| cd | road | | yes |
|
||||
| gb | cross | | yes |
|
||||
| bj | cross | | yes |
|
||||
| kc | cross | | yes |
|
||||
| cf | cross | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
|
||||
|
||||
#this can happen due to traffic lights / lanes not drawn up to the intersection itself
|
||||
Scenario: Turn Lanes Given earlier than actual turn
|
||||
Given the node map
|
||||
| a | | b | c | | d |
|
||||
| | | | | | |
|
||||
| | | | e | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward |
|
||||
| ab | road | \|right |
|
||||
| bc | road | |
|
||||
| cd | road | |
|
||||
| ce | turn | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | road,turn,turn | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,none:true right:false, |
|
||||
|
||||
Scenario: Turn Lanes Given earlier than actual turn
|
||||
Given the node map
|
||||
| a | | b | c | d | | e | | f | g | h | | i |
|
||||
| | | j | | | | | | | | k | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | turn:lanes:backward |
|
||||
| abc | road | | |
|
||||
| cd | road | | left\| |
|
||||
| def | road | | |
|
||||
| fg | road | \|right | |
|
||||
| ghi | road | | |
|
||||
| bj | first-turn | | |
|
||||
| hk | second-turn | | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,k | road,second-turn,second-turn | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,i | road,road,road | depart,use lane straight,arrive | ,none:true right:false, |
|
||||
| i,j | road,first-turn,first-turn | depart,turn left,arrive | ,left:true none:false, |
|
||||
| i,a | road,road,road | depart,use lane straight,arrive | ,left:false none:true, |
|
||||
|
||||
Scenario: Passing a one-way street
|
||||
Given the node map
|
||||
| e | | | f | |
|
||||
| a | | b | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|through | no |
|
||||
| bcd | road | | no |
|
||||
| eb | owi | | yes |
|
||||
| cf | turn | | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true straight:false, |
|
||||
|
||||
Scenario: Passing a one-way street, partly pulled back lanes
|
||||
Given the node map
|
||||
| e | | | f | |
|
||||
| a | | b | c | d |
|
||||
| | | g | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|through;right | no |
|
||||
| bcd | road | | no |
|
||||
| eb | owi | | yes |
|
||||
| cf | turn | | no |
|
||||
| bg | right | | no |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true straight;right:false, |
|
||||
| a,g | road,right,right | depart,turn right,arrive | ,left:false straight;right:true, |
|
||||
|
||||
Scenario: Passing a one-way street, partly pulled back lanes, no through
|
||||
Given the node map
|
||||
| e | | | f |
|
||||
| a | | b | c |
|
||||
| | | g | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|right | no |
|
||||
| bc | road | | no |
|
||||
| eb | owi | | yes |
|
||||
| cf | turn | | no |
|
||||
| bg | right | | no |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true right:false, |
|
||||
| a,g | road,right,right | depart,turn right,arrive | ,left:false right:true, |
|
||||
|
||||
@todo @bug
|
||||
Scenario: Narrowing Turn Lanes
|
||||
Given the node map
|
||||
| | | | | g | |
|
||||
| | | | | | |
|
||||
| a | | b | c | d | e |
|
||||
| | | | f | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward |
|
||||
| ab | road | left\|through&right |
|
||||
| bc | road | |
|
||||
| cd | road | left\|through |
|
||||
| de | through | |
|
||||
| dg | left | |
|
||||
| cf | right | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,g | road,left,left | depart,turn left,arrive | ,left:true straight:false right:false, |
|
||||
| a,e | road,through,through | depart,new name straight,arrive | ,left:false straight:true right:false, |
|
||||
| a,f | road,right,right | depart,turn right,arrive | ,left:false straight:false right:true, |
|
||||
|
||||
Scenario: Turn at a traffic light
|
||||
Given the node map
|
||||
| a | b | c | d |
|
||||
| | | e | |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| b | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward |
|
||||
| ab | road | through\|right |
|
||||
| bc | road | |
|
||||
| cd | road | |
|
||||
| ce | turn | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,straight:true right:false, |
|
||||
| a,e | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
|
||||
|
||||
@bug @todo
|
||||
Scenario: Theodor Heuss Platz
|
||||
Given the node map
|
||||
| | | | i | o | | | l | |
|
||||
| | | b | | | | a | | m |
|
||||
| | c | | | | | | | |
|
||||
| | | | | | | | h | |
|
||||
| | | | | | | | | |
|
||||
| j | | | | | | | | |
|
||||
| | | | | | | | g | |
|
||||
| | | | | | | | | |
|
||||
| | d | | | | | | | |
|
||||
| | | e | | | | f | | |
|
||||
| | | | | k | | | | n |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| g | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | junction | oneway | highway |
|
||||
| abcdef | roundabout | | roundabout | yes | primary |
|
||||
| gha | roundabout | | roundabout | yes | primary |
|
||||
| fg | roundabout | slight_left\|slight_left;slight_right&slight_right&slight_right | roundabout | yes | primary |
|
||||
| aoib | top | | | yes | primary |
|
||||
| cjd | left | | | yes | primary |
|
||||
| ekf | bottom | | | yes | primary |
|
||||
| fng | bottom-right | | | yes | primary |
|
||||
| hma | top-right | | | yes | primary |
|
||||
| hl | top-right-out | | | yes | secondary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| i,m | top,top-right,top-right | depart,roundabout-exit-4,arrive | ,slight left:false slight left;slight right:true slight right:true slight right:true, |
|
||||
| i,l | top,top-right-out,top-right-out | depart,roundabout-exit-4,arrive | ,slight left:true slight left;slight right:true slight right:false slight right:false, |
|
||||
| i,o | top,top,top | depart,roundabout-exit-5,arrive | ,, |
|
||||
|
||||
Scenario: Turn Lanes Breaking up
|
||||
Given the node map
|
||||
| | | | g | |
|
||||
| | | | | |
|
||||
| | | | c | |
|
||||
| a | b | | d | e |
|
||||
| | | | | |
|
||||
| | | | f | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway | highway |
|
||||
| ab | road | left\|left&through&through | yes | primary |
|
||||
| bd | road | through\|through | yes | primary |
|
||||
| bc | road | left\|left | yes | primary |
|
||||
| de | road | | yes | primary |
|
||||
| fdcg | cross | | | secondary |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | bd | fdcg | d | no_left_turn |
|
||||
| restriction | bc | fdcg | c | no_right_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,g | road,cross,cross | depart,turn left,arrive | ,left:true left:true straight:false straight:false, |
|
||||
| a,e | road,road,road | depart,use lane straight,arrive | ,left:false left:false straight:true straight:true, |
|
||||
|
||||
Scenario: U-Turn Road at Intersection
|
||||
Given the node map
|
||||
| | | | | | h | |
|
||||
| | | | | f | e | j |
|
||||
| a | b | | | | | |
|
||||
| | | | | c | d | i |
|
||||
| | | | | | g | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway | highway |
|
||||
| ab | road | | no | primary |
|
||||
| di | road | | yes | primary |
|
||||
| bc | road | \|through&right | yes | primary |
|
||||
| cd | road | \|through&right | yes | primary |
|
||||
| fc | road | | no | tertiary |
|
||||
| jefb | road | | yes | primary |
|
||||
| gdeh | cross | | no | primary |
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | turns | lanes |
|
||||
| a | g | 180,180 180,180 | road,cross,cross | depart,turn right,arrive | ,none:false straight:false right:true, |
|
||||
| a | h | 180,180 180,180 | road,cross,cross | depart,turn left,arrive | ,none:true straight:false right:false, |
|
||||
| a | i | 180,180 180,180 | road,road,road | depart,use lane straight,arrive | ,none:true straight:true right:false, |
|
||||
| b | a | 90,2 270,2 | road,road,road | depart,continue uturn,arrive | ,none:true straight:false right:false, |
|
||||
|
||||
Scenario: Segregated Intersection Merges With Lanes
|
||||
Given the node map
|
||||
| | | | | | | f |
|
||||
| | | | | | | |
|
||||
| e | | | d | | | |
|
||||
| | | | | | c | g |
|
||||
| a | | | b | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | h | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway | highway |
|
||||
| abc | road | left\|left&left&through&through | yes | primary |
|
||||
| cde | road | | yes | primary |
|
||||
| hc | cross | | yes | secondary |
|
||||
| cg | straight | | no | tertiary |
|
||||
| cf | left | | yes | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | road,left,left | depart,turn left,arrive | ,left:true left:true left:true straight:false straight:false, |
|
||||
| a,e | road,road,road | depart,turn uturn,arrive | ,left:true left:false left:false straight:false straight:false, |
|
||||
| a,g | road,straight,straight | depart,new name straight,arrive | ,left:false left:false left:false straight:true straight:true, |
|
||||
|
||||
@bug @todo
|
||||
Scenario: Passing Through a Roundabout
|
||||
Given the node map
|
||||
| | | h | | g | | |
|
||||
| | a | | | | f | k |
|
||||
| i | | | | | | |
|
||||
| | | | | | | |
|
||||
| | b | | | | e | |
|
||||
| | | c | | d | | |
|
||||
| | | | | j | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway | highway | junction |
|
||||
| efgha | round | | yes | primary | roundabout |
|
||||
| ab | round | | yes | primary | roundabout |
|
||||
| bc | round | slight_left\|slight_left&slight_right | yes | primary | roundabout |
|
||||
| cd | round | | yes | primary | roundabout |
|
||||
| de | round | slight_left\|slight_right | yes | primary | roundabout |
|
||||
| ib | left | slight_left\|slight_left&slight_right | yes | primary | |
|
||||
| cj | bottom | | yes | primary | |
|
||||
| ek | right | | yes | primary | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| i,j | left,bottom,bottom | depart,round-exit-1,arrive | ,0, |
|
||||
| i,k | left,right,right | depart,round-exit-2,arrive | ,1, |
|
||||
|
||||
Scenario: Crossing Traffic Light
|
||||
Given the node map
|
||||
| a | | b | | c | | d |
|
||||
| | | | | | | e |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| b | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway |
|
||||
| abc | road | through\|through&through;slight_right&slight_right | primary |
|
||||
| cd | road | | primary |
|
||||
| ce | cross | | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,straight:true straight:true straight;slight right:true slight right:false, |
|
||||
| a,e | road,cross,cross | depart,turn slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
|
||||
|
||||
Scenario: Highway Ramp
|
||||
Given the node map
|
||||
| a | | b | | c | | d |
|
||||
| | | | | | | e |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway |
|
||||
| abc | hwy | through\|through&through;slight_right&slight_right | motorway |
|
||||
| cd | hwy | | motorway |
|
||||
| ce | ramp | | motorway_link |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | hwy,hwy,hwy | depart,use lane straight,arrive | ,straight:true straight:true straight;slight right:true slight right:false, |
|
||||
| a,e | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
|
||||
|
||||
@bug @todo
|
||||
Scenario: Turning Off Ramp
|
||||
Given the node map
|
||||
| | a | |
|
||||
| d | c | b |
|
||||
| e | f | g |
|
||||
| | h | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway | oneway |
|
||||
| ac | off | left\|right | motorway_link | yes |
|
||||
| bcd | road | | primary | yes |
|
||||
| cf | road | | primary | |
|
||||
| efg | road | | primary | yes |
|
||||
| fh | on | | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | off,road,road | depart,turn_right,arrive | ,left:false right:true, |
|
||||
| a,g | off,road,road | depart,turn_left,arrive | ,left:true right:false, |
|
||||
| a,h | | | |
|
||||
|
||||
Scenario: Off Ramp In a Turn
|
||||
Given the node map
|
||||
| a | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | |
|
||||
| | | | | | b | | | | | | c |
|
||||
| | | | | | | | | | | d | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway | oneway |
|
||||
| ab | hwy | through\|through&slight_right | motorway | yes |
|
||||
| bc | hwy | | motorway | yes |
|
||||
| bd | ramp | | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | hwy,hwy,hwy | depart,use lane slight left,arrive | ,straight:true straight:true slight right:false, |
|
||||
| a,d | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false slight right:true, |
|
||||
|
||||
Scenario: Reverse Lane in Segregated Road
|
||||
Given the node map
|
||||
| h | | | | | g | | | | | | f |
|
||||
| | | | | | | | e | | | | |
|
||||
| | | | | | | | d | | | | |
|
||||
| a | | | | | b | | | | | | c |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway | oneway |
|
||||
| ab | road | reverse\|through&through | primary | yes |
|
||||
| bc | road | | primary | yes |
|
||||
| bdeg | road | | primary_link | yes |
|
||||
| fgh | road | | primary | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false straight:false,|
|
||||
|
||||
Scenario: Reverse Lane in Segregated Road with none
|
||||
Given the node map
|
||||
| h | | | | | g | | | | | | f |
|
||||
| | | | | | | | e | | | | |
|
||||
| | | | | | | | d | | | | |
|
||||
| a | | | | | b | | | | | | c |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway | oneway |
|
||||
| ab | road | reverse\|through&none | primary | yes |
|
||||
| bc | road | | primary | yes |
|
||||
| bdeg | road | | primary_link | yes |
|
||||
| fgh | road | | primary | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false, |
|
||||
|
||||
Scenario: Reverse Lane in Segregated Road with none, Service Turn Prior
|
||||
Given the node map
|
||||
| h | | | | | g | | | | | | f |
|
||||
| | | | | | | | e | | | | |
|
||||
| | | | | | | | d | | | | |
|
||||
| a | | j | | | b | | | | | | c |
|
||||
| | | i | | | | | | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway | oneway |
|
||||
| ajb | road | reverse\|through&none | primary | yes |
|
||||
| bc | road | | primary | yes |
|
||||
| bdeg | road | | primary_link | yes |
|
||||
| fgh | road | | primary | yes |
|
||||
| ji | park | | service | no |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false, |
|
||||
|
||||
Scenario: Don't collapse everything to u-turn / too wide
|
||||
Given the node map
|
||||
| a | | b | | e |
|
||||
| | | | | |
|
||||
| d | | c | | f |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | turn:lanes:forward |
|
||||
| ab | primary | road | through\|right |
|
||||
| bc | primary | road | |
|
||||
| dc | primary | road | left\|through |
|
||||
| be | secondary | top | |
|
||||
| cf | secondary | bottom | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route | lanes |
|
||||
| a,d | depart,continue right,turn right,arrive | road,road,road,road | ,straight:false right:true,, |
|
||||
| d,a | depart,continue left,turn left,arrive | road,road,road,road | ,left:true straight:false,, |
|
||||
|
||||
Scenario: Merge Lanes Onto Freeway
|
||||
Given the node map
|
||||
| a | | | b | c |
|
||||
| | d | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | turn:lanes:forward |
|
||||
| abc | motorway | Hwy | |
|
||||
| db | motorway_link | ramp | slight_right\|slight_right |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route | lanes |
|
||||
| d,c | depart,merge slight left,arrive | ramp,Hwy,Hwy | ,slight right:true slight right:true, |
|
||||
|
||||
Scenario: Fork on motorway links - don't fork on through but use lane
|
||||
Given the node map
|
||||
| i | | | | | a |
|
||||
| j | | c | b | | x |
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway | turn:lanes:forward |
|
||||
| xb | xbcj | motorway_link | |
|
||||
| bc | xbcj | motorway_link | none\|slight_right |
|
||||
| cj | xbcj | motorway_link | |
|
||||
| ci | off | motorway_link | |
|
||||
| ab | on | motorway_link | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | on,xbcj,xbcj,xbcj | depart,merge slight left,use lane straight,arrive | ,,none:true slight right:false, |
|
||||
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
|
||||
@@ -833,3 +833,23 @@ Feature: Simple Turns
|
||||
| a,d | road,road | depart,arrive |
|
||||
| d,i | road,cross,cross | depart,turn left,arrive |
|
||||
| d,g | road,road | depart,arrive |
|
||||
|
||||
Scenario: Go onto turning major road
|
||||
Given the node map
|
||||
| | | | c |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| a | | | b |
|
||||
| | | | |
|
||||
| | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abc | primary | road |
|
||||
| bd | residential | in |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| a,c | depart,arrive | road,road |
|
||||
| d,a | depart,turn left,arrive | in,road,road |
|
||||
| d,c | depart,new name straight,arrive | in,road,road |
|
||||
|
||||
@@ -17,7 +17,7 @@ module.exports = function () {
|
||||
this.setContractArgs(args, callback);
|
||||
});
|
||||
|
||||
this.Given(/^a grid size of (\d+) meters$/, (meters, callback) => {
|
||||
this.Given(/^a grid size of ([0-9.]+) meters$/, (meters, callback) => {
|
||||
this.setGridSize(meters);
|
||||
callback();
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
var util = require('util');
|
||||
var d3 = require('d3-queue');
|
||||
var polyline = require('polyline');
|
||||
|
||||
module.exports = function () {
|
||||
this.When(/^I match I should get$/, (table, callback) => {
|
||||
@@ -35,6 +36,7 @@ module.exports = function () {
|
||||
route = '',
|
||||
duration = '',
|
||||
annotation = '',
|
||||
geometry = '',
|
||||
OSMIDs = '';
|
||||
|
||||
|
||||
@@ -63,6 +65,11 @@ module.exports = function () {
|
||||
annotation = this.annotationList(json.matchings[0]);
|
||||
}
|
||||
|
||||
if (headers.has('geometry')) {
|
||||
if (json.matchings.length != 1) throw new Error('*** Checking geometry only supported for matchings with one subtrace');
|
||||
geometry = json.matchings[0].geometry;
|
||||
}
|
||||
|
||||
if (headers.has('OSM IDs')) {
|
||||
if (json.matchings.length != 1) throw new Error('*** CHecking annotation only supported for matchings with one subtrace');
|
||||
OSMIDs = this.OSMIDList(json.matchings[0]);
|
||||
@@ -85,6 +92,13 @@ module.exports = function () {
|
||||
got.annotation = annotation.toString();
|
||||
}
|
||||
|
||||
if (headers.has('geometry')) {
|
||||
if (this.queryParams['geometries'] === 'polyline')
|
||||
got.geometry = polyline.decode(geometry).toString();
|
||||
else
|
||||
got.geometry = geometry;
|
||||
}
|
||||
|
||||
if (headers.has('OSM IDs')) {
|
||||
got['OSM IDs'] = OSMIDs;
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ module.exports = function () {
|
||||
};
|
||||
|
||||
['osrm', 'osrm.ebg', 'osrm.edges', 'osrm.enw', 'osrm.fileIndex', 'osrm.geometry', 'osrm.icd',
|
||||
'osrm.names', 'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions'].forEach(file => {
|
||||
'osrm.names', 'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions', 'osrm.tld', 'osrm.tls'].forEach(file => {
|
||||
q.defer(rename, file);
|
||||
});
|
||||
|
||||
@@ -283,7 +283,7 @@ module.exports = function () {
|
||||
|
||||
['osrm', 'osrm.core', 'osrm.datasource_indexes', 'osrm.datasource_names', 'osrm.ebg','osrm.edges',
|
||||
'osrm.enw', 'osrm.fileIndex', 'osrm.geometry', 'osrm.hsgr', 'osrm.icd','osrm.level', 'osrm.names',
|
||||
'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions'].forEach((file) => {
|
||||
'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions', 'osrm.tld', 'osrm.tls'].forEach((file) => {
|
||||
q.defer(rename, file);
|
||||
});
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ module.exports = function () {
|
||||
this.DEFAULT_GRID_SIZE = 100; // meters
|
||||
this.PROFILES_PATH = path.resolve(this.ROOT_FOLDER, 'profiles');
|
||||
this.FIXTURES_PATH = path.resolve(this.ROOT_FOLDER, 'unit_tests/fixtures');
|
||||
this.BIN_PATH = path.resolve(this.ROOT_FOLDER, 'build');
|
||||
this.BIN_PATH = process.env.OSRM_BUILD_DIR && process.env.OSRM_BUILD_DIR || path.resolve(this.ROOT_FOLDER, 'build');
|
||||
this.DEFAULT_INPUT_FORMAT = 'osm';
|
||||
this.DEFAULT_ORIGIN = [1,1];
|
||||
this.DEFAULT_LOAD_METHOD = 'datastore';
|
||||
|
||||
@@ -168,6 +168,17 @@ module.exports = function () {
|
||||
return instructions.legs.map(l => l.annotation.nodes.map(n => n.toString()).join(',')).join(',');
|
||||
};
|
||||
|
||||
this.lanesList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, instruction => {
|
||||
if( 'lanes' in instruction.maneuver )
|
||||
{
|
||||
return instruction.maneuver.lanes.map( p => { return (p.indications).join(';') + ':' + p.valid; } ).join(' ');
|
||||
} else
|
||||
{
|
||||
return '';
|
||||
}});
|
||||
};
|
||||
|
||||
this.turnList = (instructions) => {
|
||||
return instructions.legs.reduce((m, v) => m.concat(v.steps), [])
|
||||
.map(v => {
|
||||
|
||||
@@ -33,7 +33,8 @@ module.exports = function () {
|
||||
var afterRequest = (err, res, body) => {
|
||||
if (err) return cb(err);
|
||||
if (body && body.length) {
|
||||
let destinations, pronunciations, instructions, bearings, turns, modes, times, distances, summary, intersections;
|
||||
let destinations, pronunciations, instructions, bearings, turns, modes, times,
|
||||
distances, summary, intersections, lanes;
|
||||
|
||||
let json = JSON.parse(body);
|
||||
|
||||
@@ -49,6 +50,7 @@ module.exports = function () {
|
||||
modes = this.modeList(json.routes[0]);
|
||||
times = this.timeList(json.routes[0]);
|
||||
distances = this.distanceList(json.routes[0]);
|
||||
lanes = this.lanesList(json.routes[0]);
|
||||
summary = this.summary(json.routes[0]);
|
||||
}
|
||||
|
||||
@@ -102,6 +104,10 @@ module.exports = function () {
|
||||
got.time = instructions ? util.format('%ds', time) : '';
|
||||
}
|
||||
|
||||
if (headers.has('lanes')) {
|
||||
got.lanes = (lanes || '').trim();
|
||||
}
|
||||
|
||||
if (headers.has('speed')) {
|
||||
if (row.speed !== '' && instructions) {
|
||||
if (!row.speed.match(/\d+ km\/h/))
|
||||
|
||||
@@ -59,10 +59,10 @@ Feature: Compass bearing
|
||||
|
||||
Scenario: Bearing in a roundabout
|
||||
Given the node map
|
||||
| | d | c | |
|
||||
| k | d | c | j |
|
||||
| e | | | b |
|
||||
| f | | | a |
|
||||
| | g | h | |
|
||||
| l | g | h | i |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
@@ -74,6 +74,14 @@ Feature: Compass bearing
|
||||
| fg | yes |
|
||||
| gh | yes |
|
||||
| ha | yes |
|
||||
| dk | no |
|
||||
| ke | no |
|
||||
| fl | no |
|
||||
| lg | no |
|
||||
| hi | no |
|
||||
| ia | no |
|
||||
| bj | no |
|
||||
| cj | no |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | bearing |
|
||||
@@ -82,8 +90,10 @@ Feature: Compass bearing
|
||||
|
||||
Scenario: Bearing should stay constant when zig-zagging
|
||||
Given the node map
|
||||
| i | j | k | |
|
||||
| b | d | f | h |
|
||||
| a | c | e | g |
|
||||
| | m | n | o |
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
@@ -94,6 +104,12 @@ Feature: Compass bearing
|
||||
| ef |
|
||||
| fg |
|
||||
| gh |
|
||||
| bi |
|
||||
| cm |
|
||||
| dj |
|
||||
| en |
|
||||
| fk |
|
||||
| go |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | bearing |
|
||||
|
||||
@@ -14,11 +14,11 @@ Feature: Bearing parameter
|
||||
| ad |
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | bearing |
|
||||
| from | to | bearings | route | bearing |
|
||||
| b | c | 90 90 | ad,ad | 0->90,90->0|
|
||||
| b | c | 180 90 | | |
|
||||
| b | c | 180 90 | | |
|
||||
| b | c | 80 100 | ad,ad | 0->90,90->0|
|
||||
| b | c | 79 100 | | |
|
||||
| b | c | 79 100 | | |
|
||||
| b | c | 79,11 100 | ad,ad | 0->90,90->0|
|
||||
|
||||
Scenario: Testbot - Intial bearing in simple case
|
||||
@@ -33,13 +33,13 @@ Feature: Bearing parameter
|
||||
| bc |
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | bearing |
|
||||
| 0 | c | 0 0 | | |
|
||||
| 0 | c | 45 45 | bc,bc | 0->44,44->0 +- 1|
|
||||
| 0 | c | 85 85 | | |
|
||||
| 0 | c | 95 95 | | |
|
||||
| from | to | bearings | route | bearing |
|
||||
| 0 | c | 0 0 | | |
|
||||
| 0 | c | 45 45 | bc,bc | 0->44,44->0 +- 1 |
|
||||
| 0 | c | 85 85 | | |
|
||||
| 0 | c | 95 95 | | |
|
||||
| 0 | c | 135 135 | ac,ac | 0->135,135->0 +- 1|
|
||||
| 0 | c | 180 180 | | |
|
||||
| 0 | c | 180 180 | | |
|
||||
|
||||
Scenario: Testbot - Initial bearing on split way
|
||||
Given the node map
|
||||
@@ -58,21 +58,21 @@ Feature: Bearing parameter
|
||||
| ha | yes |
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | bearing |
|
||||
| 0 | b | 10 10 | bc,bc | 0->0,0->0 |
|
||||
| 0 | b | 90 90 | ab,ab | 0->90,90->0 |
|
||||
| from | to | bearings | route | bearing |
|
||||
| 0 | b | 10 10 | bc,bc | 0->0,0->0 |
|
||||
| 0 | b | 90 90 | ab,ab | 0->90,90->0 |
|
||||
# The returned bearing is wrong here, it's based on the snapped
|
||||
# coordinates, not the acutal edge bearing. This should be
|
||||
# fixed one day, but it's only a problem when we snap two vias
|
||||
# to the same point - DP
|
||||
#| 0 | b | 170 170 | da | 180 |
|
||||
#| 0 | b | 189 189 | da | 180 |
|
||||
| 0 | 1 | 90 270 | ab,bc,cd,cd | 0->90,90->0,0->270,270->0 |
|
||||
| 1 | d | 10 10 | bc,bc | 0->0,0->0 |
|
||||
#| 0 | b | 170 170 | da | 180 |
|
||||
#| 0 | b | 189 189 | da | 180 |
|
||||
| 0 | 1 | 90 270 | ab,bc,cd,cd | 0->90,90->0,0->270,270->0 |
|
||||
| 1 | d | 10 10 | bc,bc | 0->0,0->0 |
|
||||
| 1 | d | 90 90 | ab,bc,cd,da,da | 0->90,90->0,0->270,270->180,180->0 |
|
||||
| 1 | 0 | 189 189 | da,da | 0->180,180->0 |
|
||||
| 1 | d | 270 270 | cd,cd | 0->270,270->0 |
|
||||
| 1 | d | 349 349 | | |
|
||||
| 1 | 0 | 189 189 | da,da | 0->180,180->0 |
|
||||
| 1 | d | 270 270 | cd,cd | 0->270,270->0 |
|
||||
| 1 | d | 349 349 | | |
|
||||
|
||||
Scenario: Testbot - Initial bearing in all direction
|
||||
Given the node map
|
||||
|
||||
@@ -3,7 +3,7 @@ Feature: U-turns at via points
|
||||
|
||||
Background:
|
||||
Given the profile "testbot"
|
||||
Given a grid size of 100 meters
|
||||
Given a grid size of 250 meters
|
||||
|
||||
Scenario: Continue straight at waypoints enabled by default
|
||||
Given the node map
|
||||
|
||||
@@ -24,3 +24,18 @@ Feature: Fixed bugs, kept to check for regressions
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| x | y | abc,abc |
|
||||
|
||||
Scenario: Step trimming with very short segments
|
||||
Given a grid size of 0.1 meters
|
||||
Given the node map
|
||||
| a | 1 | b | c | d | 2 | e |
|
||||
|
||||
Given the ways
|
||||
| nodes | oneway |
|
||||
| ab | yes |
|
||||
| bcd | yes |
|
||||
| de | yes |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| 1 | 2 | bcd,bcd |
|
||||
|
||||
@@ -75,12 +75,12 @@ Feature: Avoid weird loops caused by rounding errors
|
||||
And the node map
|
||||
| a | | |
|
||||
| b | e | |
|
||||
| | | 1 |
|
||||
| h | | 1 |
|
||||
| | | |
|
||||
| | | 2 |
|
||||
| | | |
|
||||
| g | | |
|
||||
| | c | f |
|
||||
| | d | |
|
||||
| d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
@@ -90,6 +90,8 @@ Feature: Avoid weird loops caused by rounding errors
|
||||
| be | primary |
|
||||
| ef | primary |
|
||||
| cf | primary |
|
||||
| cg | primary |
|
||||
| bh | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route |
|
||||
|
||||
@@ -128,3 +128,21 @@ Feature: Basic Map Matching
|
||||
| trace | matchings | OSM IDs |
|
||||
| abeh | abcedgh | 1,2,3,2,3,4,5,4,5,6,7 |
|
||||
| abci | abc,ci | 1,2,3,2,3,8,3,8 |
|
||||
|
||||
Scenario: Testbot - Geometry details
|
||||
Given the query options
|
||||
| overview | full |
|
||||
| geometries | polyline |
|
||||
|
||||
Given the node map
|
||||
| a | b | c |
|
||||
| | d | |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| abc | no |
|
||||
| bd | no |
|
||||
|
||||
When I match I should get
|
||||
| trace | matchings | geometry |
|
||||
| abd | abd | 1,1,1,1.00009,1,1.00009,0.99991,1.00009 |
|
||||
|
||||
@@ -3,6 +3,7 @@ Feature: Testbot - oneways
|
||||
|
||||
Background:
|
||||
Given the profile "testbot"
|
||||
Given a grid size of 250 meters
|
||||
|
||||
Scenario: Routing on a oneway roundabout
|
||||
Given the node map
|
||||
@@ -59,8 +60,8 @@ Feature: Testbot - oneways
|
||||
|
||||
Scenario: Testbot - Around the Block
|
||||
Given the node map
|
||||
| a | b |
|
||||
| d | c |
|
||||
| | a | b | |
|
||||
| e | d | c | f |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway | foot |
|
||||
@@ -68,6 +69,8 @@ Feature: Testbot - oneways
|
||||
| bc | | no |
|
||||
| cd | | no |
|
||||
| da | | no |
|
||||
| de | | no |
|
||||
| cf | | no |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
|
||||
@@ -145,14 +145,16 @@ Feature: Estimation of travel time
|
||||
|
||||
Scenario: Time of travel on a series of ways
|
||||
Given the node map
|
||||
| a | b | |
|
||||
| | c | d |
|
||||
| a | b | e |
|
||||
| f | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| bc | primary |
|
||||
| cd | primary |
|
||||
| be | primary |
|
||||
| cf | primary |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
|
||||
@@ -85,13 +85,16 @@ Feature: Via points
|
||||
Scenario: Via points on ring of oneways
|
||||
# xa it to avoid only having a single ring, which cna trigger edge cases
|
||||
Given the node map
|
||||
| x | | | | | | |
|
||||
| a | 1 | b | 2 | c | 3 | d |
|
||||
| f | | | | | | e |
|
||||
| | x | | | | | | g | |
|
||||
| | a | 1 | b | 2 | c | 3 | d | |
|
||||
| i | f | | | | | | e | h |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| xa | |
|
||||
| if | |
|
||||
| gd | |
|
||||
| eh | |
|
||||
| ab | yes |
|
||||
| bc | yes |
|
||||
| cd | yes |
|
||||
@@ -110,13 +113,16 @@ Feature: Via points
|
||||
Scenario: Via points on ring on the same oneway
|
||||
# xa it to avoid only having a single ring, which cna trigger edge cases
|
||||
Given the node map
|
||||
| x | | | | |
|
||||
| a | 1 | 2 | 3 | b |
|
||||
| d | | | | c |
|
||||
| | x | | | | e | |
|
||||
| | a | 1 | 2 | 3 | b | |
|
||||
| g | d | | | | c | f |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| xa | |
|
||||
| eb | |
|
||||
| cf | |
|
||||
| dg | |
|
||||
| ab | yes |
|
||||
| bc | yes |
|
||||
| cd | yes |
|
||||
|
||||
@@ -78,7 +78,7 @@ class Contractor
|
||||
private:
|
||||
ContractorConfig config;
|
||||
|
||||
std::size_t
|
||||
EdgeID
|
||||
LoadEdgeExpandedGraph(const std::string &edge_based_graph_path,
|
||||
util::DeallocatingVector<extractor::EdgeBasedEdge> &edge_based_edge_list,
|
||||
const std::string &edge_segment_lookup_path,
|
||||
|
||||
@@ -82,6 +82,9 @@ class IteratorbasedCRC32
|
||||
: "0"(crc), "c"(*str));
|
||||
++str;
|
||||
}
|
||||
#else
|
||||
(void)str;
|
||||
(void)len;
|
||||
#endif
|
||||
return crc;
|
||||
}
|
||||
@@ -95,8 +98,11 @@ class IteratorbasedCRC32
|
||||
}
|
||||
|
||||
#if defined(__MINGW64__) || defined(_MSC_VER) || !defined(__x86_64__)
|
||||
inline void
|
||||
__get_cpuid(int param, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) const
|
||||
inline void __get_cpuid(int /*param*/,
|
||||
unsigned * /*eax*/,
|
||||
unsigned * /*ebx*/,
|
||||
unsigned *ecx,
|
||||
unsigned * /*edx*/) const
|
||||
{
|
||||
*ecx = 0;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "engine/guidance/assemble_overview.hpp"
|
||||
#include "engine/guidance/assemble_route.hpp"
|
||||
#include "engine/guidance/assemble_steps.hpp"
|
||||
#include "engine/guidance/lane_processing.hpp"
|
||||
#include "engine/guidance/post_processing.hpp"
|
||||
|
||||
#include "engine/internal_route_result.hpp"
|
||||
@@ -149,6 +150,7 @@ class RouteAPI : public BaseAPI
|
||||
leg_geometry,
|
||||
phantoms.source_phantom,
|
||||
phantoms.target_phantom);
|
||||
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
|
||||
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "extractor/edge_based_node.hpp"
|
||||
#include "extractor/external_memory_node.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "util/exception.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
@@ -138,6 +139,11 @@ class BaseDataFacade
|
||||
const int bearing,
|
||||
const int bearing_range) const = 0;
|
||||
|
||||
virtual bool hasLaneData(const EdgeID id) const = 0;
|
||||
virtual util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const = 0;
|
||||
virtual extractor::guidance::TurnLaneDescription
|
||||
GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0;
|
||||
|
||||
virtual unsigned GetCheckSum() const = 0;
|
||||
|
||||
virtual bool IsCoreNode(const NodeID id) const = 0;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "storage/storage_config.hpp"
|
||||
#include "engine/geospatial_query.hpp"
|
||||
#include "util/graph_loader.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/io.hpp"
|
||||
#include "util/packed_vector.hpp"
|
||||
#include "util/range_table.hpp"
|
||||
@@ -78,6 +79,8 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
util::ShM<NodeID, false>::vector m_via_node_list;
|
||||
util::ShM<unsigned, false>::vector m_name_ID_list;
|
||||
util::ShM<extractor::guidance::TurnInstruction, false>::vector m_turn_instruction_list;
|
||||
util::ShM<LaneDataID, false>::vector m_lane_data_id;
|
||||
util::ShM<util::guidance::LaneTupelIdPair, false>::vector m_lane_tupel_id_pairs;
|
||||
util::ShM<extractor::TravelMode, false>::vector m_travel_mode_list;
|
||||
util::ShM<char, false>::vector m_names_char_list;
|
||||
util::ShM<unsigned, false>::vector m_geometry_indices;
|
||||
@@ -86,6 +89,8 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
util::ShM<unsigned, false>::vector m_segment_weights;
|
||||
util::ShM<uint8_t, false>::vector m_datasource_list;
|
||||
util::ShM<std::string, false>::vector m_datasource_names;
|
||||
util::ShM<std::uint32_t, false>::vector m_lane_description_offsets;
|
||||
util::ShM<extractor::guidance::TurnLaneType::Mask, false>::vector m_lane_description_masks;
|
||||
extractor::ProfileProperties m_profile_properties;
|
||||
|
||||
std::unique_ptr<InternalRTree> m_static_rtree;
|
||||
@@ -118,6 +123,20 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
sizeof(m_profile_properties));
|
||||
}
|
||||
|
||||
void LoadLaneTupelIdPairs(const boost::filesystem::path &lane_data_path)
|
||||
{
|
||||
boost::filesystem::ifstream in_stream(lane_data_path);
|
||||
if (!in_stream)
|
||||
{
|
||||
throw util::exception("Could not open " + lane_data_path.string() + " for reading.");
|
||||
}
|
||||
std::uint64_t size;
|
||||
in_stream.read(reinterpret_cast<char *>(&size), sizeof(size));
|
||||
m_lane_tupel_id_pairs.resize(size);
|
||||
in_stream.read(reinterpret_cast<char *>(&m_lane_tupel_id_pairs[0]),
|
||||
sizeof(m_lane_tupel_id_pairs) * size);
|
||||
}
|
||||
|
||||
void LoadTimestamp(const boost::filesystem::path ×tamp_path)
|
||||
{
|
||||
util::SimpleLogger().Write() << "Loading Timestamp";
|
||||
@@ -173,6 +192,7 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
m_via_node_list.resize(number_of_edges);
|
||||
m_name_ID_list.resize(number_of_edges);
|
||||
m_turn_instruction_list.resize(number_of_edges);
|
||||
m_lane_data_id.resize(number_of_edges);
|
||||
m_travel_mode_list.resize(number_of_edges);
|
||||
m_entry_class_id_list.resize(number_of_edges);
|
||||
|
||||
@@ -184,6 +204,7 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
m_via_node_list[i] = current_edge_data.via_node;
|
||||
m_name_ID_list[i] = current_edge_data.name_id;
|
||||
m_turn_instruction_list[i] = current_edge_data.turn_instruction;
|
||||
m_lane_data_id[i] = current_edge_data.lane_data_id;
|
||||
m_travel_mode_list[i] = current_edge_data.travel_mode;
|
||||
m_entry_class_id_list[i] = current_edge_data.entry_classid;
|
||||
}
|
||||
@@ -251,9 +272,9 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
}
|
||||
BOOST_ASSERT(datasources_stream);
|
||||
|
||||
std::size_t number_of_datasources = 0;
|
||||
std::uint64_t number_of_datasources = 0;
|
||||
datasources_stream.read(reinterpret_cast<char *>(&number_of_datasources),
|
||||
sizeof(std::size_t));
|
||||
sizeof(number_of_datasources));
|
||||
if (number_of_datasources > 0)
|
||||
{
|
||||
m_datasource_list.resize(number_of_datasources);
|
||||
@@ -284,6 +305,15 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
new InternalGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
|
||||
}
|
||||
|
||||
void LoadLaneDescriptions(const boost::filesystem::path &lane_description_file)
|
||||
{
|
||||
if (!util::deserializeAdjacencyArray(lane_description_file.string(),
|
||||
m_lane_description_offsets,
|
||||
m_lane_description_masks))
|
||||
util::SimpleLogger().Write(logWARNING) << "Failed to read turn lane descriptions from "
|
||||
<< lane_description_file.string();
|
||||
}
|
||||
|
||||
void LoadStreetNames(const boost::filesystem::path &names_file)
|
||||
{
|
||||
boost::filesystem::ifstream name_stream(names_file, std::ios::binary);
|
||||
@@ -386,11 +416,17 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
util::SimpleLogger().Write() << "loading street names";
|
||||
LoadStreetNames(config.names_data_path);
|
||||
|
||||
util::SimpleLogger().Write() << "loading lane tags";
|
||||
LoadLaneDescriptions(config.turn_lane_description_path);
|
||||
|
||||
util::SimpleLogger().Write() << "loading rtree";
|
||||
LoadRTree();
|
||||
|
||||
util::SimpleLogger().Write() << "loading intersection class data";
|
||||
LoadIntersectionClasses(config.intersection_class_path);
|
||||
|
||||
util::SimpleLogger().Write() << "Loading Lane Data Pairs";
|
||||
LoadLaneTupelIdPairs(config.turn_lane_data_path);
|
||||
}
|
||||
|
||||
// search graph access
|
||||
@@ -741,6 +777,29 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
{
|
||||
return m_entry_class_table.at(entry_class_id);
|
||||
}
|
||||
|
||||
bool hasLaneData(const EdgeID id) const override final
|
||||
{
|
||||
return m_lane_data_id[id] != INVALID_LANE_DATAID;
|
||||
}
|
||||
|
||||
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const override final
|
||||
{
|
||||
BOOST_ASSERT(hasLaneData(id));
|
||||
return m_lane_tupel_id_pairs[m_lane_data_id[id]];
|
||||
}
|
||||
|
||||
extractor::guidance::TurnLaneDescription
|
||||
GetTurnDescription(const LaneDescriptionID lane_description_id) const override final
|
||||
{
|
||||
if (lane_description_id == INVALID_LANE_DESCRIPTIONID)
|
||||
return {};
|
||||
else
|
||||
return extractor::guidance::TurnLaneDescription(
|
||||
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id],
|
||||
m_lane_description_masks.begin() +
|
||||
m_lane_description_offsets[lane_description_id + 1]);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,11 @@
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include "engine/geospatial_query.hpp"
|
||||
#include "util/make_unique.hpp"
|
||||
@@ -79,6 +81,7 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
util::PackedVector<OSMNodeID, true> m_osmnodeid_list;
|
||||
util::ShM<NodeID, true>::vector m_via_node_list;
|
||||
util::ShM<unsigned, true>::vector m_name_ID_list;
|
||||
util::ShM<LaneDataID, true>::vector m_lane_data_id;
|
||||
util::ShM<extractor::guidance::TurnInstruction, true>::vector m_turn_instruction_list;
|
||||
util::ShM<extractor::TravelMode, true>::vector m_travel_mode_list;
|
||||
util::ShM<char, true>::vector m_names_char_list;
|
||||
@@ -87,10 +90,13 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, true>::vector m_geometry_list;
|
||||
util::ShM<bool, true>::vector m_is_core_node;
|
||||
util::ShM<uint8_t, true>::vector m_datasource_list;
|
||||
util::ShM<std::uint32_t, true>::vector m_lane_description_offsets;
|
||||
util::ShM<extractor::guidance::TurnLaneType::Mask, true>::vector m_lane_description_masks;
|
||||
|
||||
util::ShM<char, true>::vector m_datasource_name_data;
|
||||
util::ShM<std::size_t, true>::vector m_datasource_name_offsets;
|
||||
util::ShM<std::size_t, true>::vector m_datasource_name_lengths;
|
||||
util::ShM<util::guidance::LaneTupelIdPair, true>::vector m_lane_tupel_id_pairs;
|
||||
|
||||
std::unique_ptr<SharedRTree> m_static_rtree;
|
||||
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
|
||||
@@ -177,7 +183,8 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
osmnodeid_list_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::OSM_NODE_ID_LIST]);
|
||||
// We (ab)use the number of coordinates here because we know we have the same amount of ids
|
||||
m_osmnodeid_list.set_number_of_entries(data_layout->num_entries[storage::SharedDataLayout::COORDINATE_LIST]);
|
||||
m_osmnodeid_list.set_number_of_entries(
|
||||
data_layout->num_entries[storage::SharedDataLayout::COORDINATE_LIST]);
|
||||
|
||||
auto travel_mode_list_ptr = data_layout->GetBlockPtr<extractor::TravelMode>(
|
||||
shared_memory, storage::SharedDataLayout::TRAVEL_MODE);
|
||||
@@ -185,6 +192,19 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
travel_mode_list_ptr, data_layout->num_entries[storage::SharedDataLayout::TRAVEL_MODE]);
|
||||
m_travel_mode_list = std::move(travel_mode_list);
|
||||
|
||||
auto lane_data_id_ptr = data_layout->GetBlockPtr<LaneDataID>(
|
||||
shared_memory, storage::SharedDataLayout::LANE_DATA_ID);
|
||||
util::ShM<LaneDataID, true>::vector lane_data_id(
|
||||
lane_data_id_ptr, data_layout->num_entries[storage::SharedDataLayout::LANE_DATA_ID]);
|
||||
m_lane_data_id = std::move(lane_data_id);
|
||||
|
||||
auto lane_tupel_id_pair_ptr = data_layout->GetBlockPtr<util::guidance::LaneTupelIdPair>(
|
||||
shared_memory, storage::SharedDataLayout::TURN_LANE_DATA);
|
||||
util::ShM<util::guidance::LaneTupelIdPair, true>::vector lane_tupel_id_pair(
|
||||
lane_tupel_id_pair_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::TURN_LANE_DATA]);
|
||||
m_lane_tupel_id_pairs = std::move(lane_tupel_id_pair);
|
||||
|
||||
auto turn_instruction_list_ptr =
|
||||
data_layout->GetBlockPtr<extractor::guidance::TurnInstruction>(
|
||||
shared_memory, storage::SharedDataLayout::TURN_INSTRUCTION);
|
||||
@@ -237,6 +257,23 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
m_names_char_list = std::move(names_char_list);
|
||||
}
|
||||
|
||||
void LoadTurnLaneDescriptions()
|
||||
{
|
||||
auto offsets_ptr = data_layout->GetBlockPtr<std::uint32_t>(
|
||||
shared_memory, storage::SharedDataLayout::LANE_DESCRIPTION_OFFSETS);
|
||||
util::ShM<std::uint32_t, true>::vector offsets(
|
||||
offsets_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::LANE_DESCRIPTION_OFFSETS]);
|
||||
m_lane_description_offsets = std::move(offsets);
|
||||
|
||||
auto masks_ptr = data_layout->GetBlockPtr<extractor::guidance::TurnLaneType::Mask>(
|
||||
shared_memory, storage::SharedDataLayout::LANE_DESCRIPTION_MASKS);
|
||||
|
||||
util::ShM<extractor::guidance::TurnLaneType::Mask, true>::vector masks(
|
||||
masks_ptr, data_layout->num_entries[storage::SharedDataLayout::LANE_DESCRIPTION_MASKS]);
|
||||
m_lane_description_masks = std::move(masks);
|
||||
}
|
||||
|
||||
void LoadCoreInformation()
|
||||
{
|
||||
if (data_layout->num_entries[storage::SharedDataLayout::CORE_MARKER] <= 0)
|
||||
@@ -415,6 +452,7 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
LoadTimestamp();
|
||||
LoadViaNodeList();
|
||||
LoadNames();
|
||||
LoadTurnLaneDescriptions();
|
||||
LoadCoreInformation();
|
||||
LoadProfileProperties();
|
||||
LoadRTree();
|
||||
@@ -782,6 +820,28 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
{
|
||||
return m_entry_class_table.at(entry_class_id);
|
||||
}
|
||||
|
||||
bool hasLaneData(const EdgeID id) const override final
|
||||
{
|
||||
return INVALID_LANE_DATAID != m_lane_data_id.at(id);
|
||||
}
|
||||
|
||||
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const override final
|
||||
{
|
||||
BOOST_ASSERT(hasLaneData(id));
|
||||
return m_lane_tupel_id_pairs.at(m_lane_data_id.at(id));
|
||||
}
|
||||
|
||||
extractor::guidance::TurnLaneDescription
|
||||
GetTurnDescription(const LaneDescriptionID lane_description_id) const override final
|
||||
{
|
||||
if (lane_description_id == INVALID_LANE_DESCRIPTIONID)
|
||||
return {};
|
||||
else
|
||||
return extractor::guidance::TurnLaneDescription(
|
||||
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id],
|
||||
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id + 1]);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "engine/guidance/toolkit.hpp"
|
||||
@@ -31,11 +32,10 @@ namespace guidance
|
||||
// |---| segment 1
|
||||
// |---| segment 2
|
||||
// |---| segment 3
|
||||
template <typename DataFacadeT>
|
||||
LegGeometry assembleGeometry(const DataFacadeT &facade,
|
||||
const std::vector<PathData> &leg_data,
|
||||
const PhantomNode &source_node,
|
||||
const PhantomNode &target_node)
|
||||
inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
|
||||
const std::vector<PathData> &leg_data,
|
||||
const PhantomNode &source_node,
|
||||
const PhantomNode &target_node)
|
||||
{
|
||||
LegGeometry geometry;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "engine/guidance/step_maneuver.hpp"
|
||||
@@ -14,6 +16,7 @@
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
@@ -34,14 +37,13 @@ std::pair<short, short> getIntermediateBearings(const LegGeometry &leg_geometry,
|
||||
const std::size_t segment_index);
|
||||
} // ns detail
|
||||
|
||||
template <typename DataFacadeT>
|
||||
std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
const std::vector<PathData> &leg_data,
|
||||
const LegGeometry &leg_geometry,
|
||||
const PhantomNode &source_node,
|
||||
const PhantomNode &target_node,
|
||||
const bool source_traversed_in_reverse,
|
||||
const bool target_traversed_in_reverse)
|
||||
inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &facade,
|
||||
const std::vector<PathData> &leg_data,
|
||||
const LegGeometry &leg_geometry,
|
||||
const PhantomNode &source_node,
|
||||
const PhantomNode &target_node,
|
||||
const bool source_traversed_in_reverse,
|
||||
const bool target_traversed_in_reverse)
|
||||
{
|
||||
const double constexpr ZERO_DURATION = 0., ZERO_DISTANCE = 0.;
|
||||
const constexpr char *NO_ROTARY_NAME = "";
|
||||
@@ -70,7 +72,9 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
bearings.second,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Depart,
|
||||
0};
|
||||
0,
|
||||
util::guidance::LaneTupel(),
|
||||
{}};
|
||||
Intersection intersection{source_node.location,
|
||||
std::vector<short>({bearings.second}),
|
||||
std::vector<bool>({true}),
|
||||
@@ -147,7 +151,11 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
bearings.second,
|
||||
path_point.turn_instruction,
|
||||
WaypointType::None,
|
||||
0};
|
||||
0,
|
||||
path_point.lane_data.first,
|
||||
(path_point.lane_data.second != INVALID_LANE_DESCRIPTIONID
|
||||
? facade.GetTurnDescription(path_point.lane_data.second)
|
||||
: extractor::guidance::TurnLaneDescription())};
|
||||
segment_index++;
|
||||
segment_duration = 0;
|
||||
}
|
||||
@@ -202,7 +210,9 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
bearings.second,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Arrive,
|
||||
0};
|
||||
0,
|
||||
util::guidance::LaneTupel(),
|
||||
{}};
|
||||
intersection = {
|
||||
target_node.location,
|
||||
std::vector<short>({static_cast<short>(util::bearing::reverseBearing(bearings.first))}),
|
||||
@@ -233,6 +243,9 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
BOOST_ASSERT(steps.back().intersections.front().bearings.size() == 1);
|
||||
BOOST_ASSERT(steps.back().intersections.front().entry.size() == 1);
|
||||
BOOST_ASSERT(steps.back().maneuver.waypoint_type == WaypointType::Arrive);
|
||||
BOOST_ASSERT(steps.back().maneuver.lanes.lanes_in_turn == 0);
|
||||
BOOST_ASSERT(steps.back().maneuver.lanes.first_lane_from_the_right == INVALID_LANEID);
|
||||
BOOST_ASSERT(steps.back().maneuver.lane_description.empty());
|
||||
return steps;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
|
||||
#define OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
// Constrains lanes for multi-hop situations where lane changes depend on earlier ones.
|
||||
// Instead of forcing users to change lanes rapidly in a short amount of time,
|
||||
// we anticipate lane changes emitting only matching lanes early on.
|
||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps);
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
#endif /* OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_ */
|
||||
@@ -2,9 +2,12 @@
|
||||
#define ENGINE_GUIDANCE_STEP_MANEUVER_HPP
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
@@ -27,8 +30,12 @@ struct StepManeuver
|
||||
short bearing_before;
|
||||
short bearing_after;
|
||||
extractor::guidance::TurnInstruction instruction;
|
||||
|
||||
WaypointType waypoint_type;
|
||||
unsigned exit;
|
||||
|
||||
util::guidance::LaneTupel lanes;
|
||||
extractor::guidance::TurnLaneDescription lane_description;
|
||||
};
|
||||
|
||||
inline StepManeuver getInvalidStepManeuver()
|
||||
@@ -38,7 +45,9 @@ inline StepManeuver getInvalidStepManeuver()
|
||||
0,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::None,
|
||||
0};
|
||||
0,
|
||||
util::guidance::LaneTupel(),
|
||||
{}};
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
|
||||
@@ -63,12 +63,6 @@ inline extractor::guidance::DirectionModifier::Enum angleToDirectionModifier(con
|
||||
return extractor::guidance::DirectionModifier::Left;
|
||||
}
|
||||
|
||||
inline double angularDeviation(const double angle, const double from)
|
||||
{
|
||||
const double deviation = std::abs(angle - from);
|
||||
return std::min(360 - deviation, deviation);
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "osrm/coordinate.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -27,6 +27,8 @@ struct PathData
|
||||
EdgeWeight duration_until_turn;
|
||||
// instruction to execute at the turn
|
||||
extractor::guidance::TurnInstruction turn_instruction;
|
||||
// turn lane data
|
||||
util::guidance::LaneTupelIdPair lane_data;
|
||||
// travel mode of the street that leads to the turn
|
||||
extractor::TravelMode travel_mode : 4;
|
||||
// entry class of the turn, indicating possibility of turns
|
||||
|
||||
@@ -546,8 +546,8 @@ class AlternativeRouting final
|
||||
}
|
||||
}
|
||||
|
||||
via_path_index = partially_unpacked_via_path.size() - 1;
|
||||
shortest_path_index = partially_unpacked_shortest_path.size() - 1;
|
||||
via_path_index = static_cast<int64_t>(partially_unpacked_via_path.size()) - 1;
|
||||
shortest_path_index = static_cast<int64_t>(partially_unpacked_shortest_path.size()) - 1;
|
||||
for (; via_path_index > 0 && shortest_path_index > 0;
|
||||
--via_path_index, --shortest_path_index)
|
||||
{
|
||||
|
||||
@@ -327,10 +327,14 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
||||
name_index,
|
||||
weight_vector[i],
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
|
||||
travel_mode,
|
||||
INVALID_ENTRY_CLASSID});
|
||||
}
|
||||
BOOST_ASSERT(unpacked_path.size() > 0);
|
||||
if (facade->hasLaneData(ed.id))
|
||||
unpacked_path.back().lane_data = facade->GetLaneData(ed.id);
|
||||
|
||||
unpacked_path.back().entry_classid = facade->GetEntryClassID(ed.id);
|
||||
unpacked_path.back().turn_instruction = turn_instruction;
|
||||
unpacked_path.back().duration_until_turn += (ed.distance - total_weight);
|
||||
@@ -389,6 +393,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
||||
phantom_node_pair.target_phantom.name_id,
|
||||
weight_vector[i],
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
|
||||
target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode
|
||||
: phantom_node_pair.target_phantom.forward_travel_mode,
|
||||
INVALID_ENTRY_CLASSID});
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "extractor/guidance/turn_analysis.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
|
||||
@@ -42,22 +43,54 @@ namespace osrm
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
namespace lookup
|
||||
{
|
||||
// Set to 1 byte alignment
|
||||
struct SegmentHeaderBlock
|
||||
{
|
||||
std::uint32_t num_osm_nodes;
|
||||
OSMNodeID previous_osm_node_id;
|
||||
} __attribute ((packed));
|
||||
static_assert(sizeof(SegmentHeaderBlock) == 12, "SegmentHeaderBlock is not packed correctly");
|
||||
|
||||
struct SegmentBlock
|
||||
{
|
||||
OSMNodeID this_osm_node_id;
|
||||
double segment_length;
|
||||
std::int32_t segment_weight;
|
||||
} __attribute ((packed));
|
||||
static_assert(sizeof(SegmentBlock) == 20, "SegmentBlock is not packed correctly");
|
||||
|
||||
struct PenaltyBlock
|
||||
{
|
||||
std::uint32_t fixed_penalty;
|
||||
OSMNodeID from_id;
|
||||
OSMNodeID via_id;
|
||||
OSMNodeID to_id;
|
||||
} __attribute ((packed));
|
||||
static_assert(sizeof(PenaltyBlock) == 28, "PenaltyBlock is not packed correctly");
|
||||
}
|
||||
|
||||
class EdgeBasedGraphFactory
|
||||
{
|
||||
public:
|
||||
EdgeBasedGraphFactory(const EdgeBasedGraphFactory &) = delete;
|
||||
EdgeBasedGraphFactory &operator=(const EdgeBasedGraphFactory &) = delete;
|
||||
|
||||
explicit EdgeBasedGraphFactory(std::shared_ptr<util::NodeBasedDynamicGraph> node_based_graph,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::unordered_set<NodeID> &traffic_lights,
|
||||
std::shared_ptr<const RestrictionMap> restriction_map,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
ProfileProperties profile_properties,
|
||||
const util::NameTable &name_table);
|
||||
explicit EdgeBasedGraphFactory(
|
||||
std::shared_ptr<util::NodeBasedDynamicGraph> node_based_graph,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::unordered_set<NodeID> &traffic_lights,
|
||||
std::shared_ptr<const RestrictionMap> restriction_map,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
ProfileProperties profile_properties,
|
||||
const util::NameTable &name_table,
|
||||
const std::vector<std::uint32_t> &turn_lane_offsets,
|
||||
const std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks);
|
||||
|
||||
void Run(const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
lua_State *lua_state,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_penalty_filename,
|
||||
@@ -104,7 +137,7 @@ class EdgeBasedGraphFactory
|
||||
//! list of edge based nodes (compressed segments)
|
||||
std::vector<EdgeBasedNode> m_edge_based_node_list;
|
||||
util::DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
|
||||
unsigned m_max_edge_id;
|
||||
EdgeID m_max_edge_id;
|
||||
|
||||
const std::vector<QueryNode> &m_node_info_list;
|
||||
std::shared_ptr<util::NodeBasedDynamicGraph> m_node_based_graph;
|
||||
@@ -117,11 +150,14 @@ class EdgeBasedGraphFactory
|
||||
ProfileProperties profile_properties;
|
||||
|
||||
const util::NameTable &name_table;
|
||||
const std::vector<std::uint32_t> &turn_lane_offsets;
|
||||
const std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks;
|
||||
|
||||
void CompressGeometry();
|
||||
unsigned RenumberEdges();
|
||||
void GenerateEdgeExpandedNodes();
|
||||
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
lua_State *lua_state,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_fixed_penalties_filename,
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
@@ -26,13 +28,13 @@ struct ExternalMemoryNode : QueryNode
|
||||
static ExternalMemoryNode min_value()
|
||||
{
|
||||
return ExternalMemoryNode(
|
||||
util::FixedLongitude(0), util::FixedLatitude(0), MIN_OSM_NODEID, false, false);
|
||||
util::FixedLongitude{0}, util::FixedLatitude{0}, MIN_OSM_NODEID, false, false);
|
||||
}
|
||||
|
||||
static ExternalMemoryNode max_value()
|
||||
{
|
||||
return ExternalMemoryNode(util::FixedLongitude(std::numeric_limits<int>::max()),
|
||||
util::FixedLatitude(std::numeric_limits<int>::max()),
|
||||
return ExternalMemoryNode(util::FixedLongitude{std::numeric_limits<std::int32_t>::max()},
|
||||
util::FixedLatitude{std::numeric_limits<std::int32_t>::max()},
|
||||
MAX_OSM_NODEID,
|
||||
false,
|
||||
false);
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
|
||||
#include "extractor/external_memory_node.hpp"
|
||||
#include "extractor/first_and_last_segment_of_way.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/internal_extractor_edge.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
#include "extractor/scripting_environment.hpp"
|
||||
|
||||
#include <stxxl/vector>
|
||||
#include <unordered_map>
|
||||
#include <cstdint>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -37,7 +39,12 @@ class ExtractionContainers
|
||||
void WriteNodes(std::ofstream &file_out_stream) const;
|
||||
void WriteRestrictions(const std::string &restrictions_file_name) const;
|
||||
void WriteEdges(std::ofstream &file_out_stream) const;
|
||||
void WriteNames(const std::string &names_file_name) const;
|
||||
void WriteCharData(const std::string &file_name,
|
||||
const stxxl::vector<unsigned> &offests,
|
||||
const stxxl::vector<char> &char_data) const;
|
||||
void WriteTurnLaneMasks(const std::string &file_name,
|
||||
const stxxl::vector<std::uint32_t> &turn_lane_offsets,
|
||||
const stxxl::vector<guidance::TurnLaneType::Mask> &turn_lane_masks) const;
|
||||
|
||||
public:
|
||||
using STXXLNodeIDVector = stxxl::vector<OSMNodeID>;
|
||||
@@ -51,6 +58,9 @@ class ExtractionContainers
|
||||
STXXLEdgeVector all_edges_list;
|
||||
stxxl::vector<char> name_char_data;
|
||||
stxxl::vector<unsigned> name_lengths;
|
||||
// an adjacency array containing all turn lane masks
|
||||
stxxl::vector<std::uint32_t> turn_lane_offsets;
|
||||
stxxl::vector<guidance::TurnLaneType::Mask> turn_lane_masks;
|
||||
STXXLRestrictionsVector restrictions_list;
|
||||
STXXLWayIDStartEndVector way_start_end_id_list;
|
||||
std::unordered_map<OSMNodeID, NodeID> external_to_internal_node_id_map;
|
||||
@@ -61,6 +71,7 @@ class ExtractionContainers
|
||||
void PrepareData(const std::string &output_file_name,
|
||||
const std::string &restrictions_file_name,
|
||||
const std::string &names_file_name,
|
||||
const std::string &turn_lane_file_name,
|
||||
lua_State *segment_state);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
@@ -98,6 +100,12 @@ inline unsigned parseDuration(const std::string &s)
|
||||
|
||||
return !s.empty() && iter == s.end() ? duration : std::numeric_limits<unsigned>::max();
|
||||
}
|
||||
|
||||
inline std::string
|
||||
trimLaneString(std::string lane_string, std::int32_t count_left, std::int32_t count_right)
|
||||
{
|
||||
return extractor::guidance::trimLaneString(std::move(lane_string), count_left, count_right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define EXTRACTION_WAY_HPP
|
||||
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <string>
|
||||
@@ -35,6 +36,8 @@ struct ExtractionWay
|
||||
destinations.clear();
|
||||
forward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
|
||||
backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
|
||||
turn_lanes_forward.clear();
|
||||
turn_lanes_backward.clear();
|
||||
}
|
||||
|
||||
// These accessors exists because it's not possible to take the address of a bitfield,
|
||||
@@ -50,6 +53,8 @@ struct ExtractionWay
|
||||
std::string name;
|
||||
std::string pronunciation;
|
||||
std::string destinations;
|
||||
std::string turn_lanes_forward;
|
||||
std::string turn_lanes_backward;
|
||||
bool roundabout;
|
||||
bool is_access_restricted;
|
||||
bool is_startpoint;
|
||||
|
||||
@@ -54,7 +54,7 @@ class Extractor
|
||||
private:
|
||||
ExtractorConfig config;
|
||||
|
||||
std::pair<std::size_t, std::size_t>
|
||||
std::pair<std::size_t, EdgeID>
|
||||
BuildEdgeExpandedGraph(lua_State *lua_state,
|
||||
const ProfileProperties &profile_properties,
|
||||
std::vector<QueryNode> &internal_to_external_node_map,
|
||||
@@ -79,7 +79,7 @@ class Extractor
|
||||
std::vector<QueryNode> &internal_to_external_node_map);
|
||||
|
||||
void WriteEdgeBasedGraph(const std::string &output_file_filename,
|
||||
const size_t max_edge_id,
|
||||
const EdgeID max_edge_id,
|
||||
util::DeallocatingVector<EdgeBasedEdge> const &edge_based_edge_list);
|
||||
|
||||
void WriteIntersectionClassificationData(
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#define EXTRACTOR_CALLBACKS_HPP
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/optional/optional_fwd.hpp>
|
||||
|
||||
@@ -38,6 +40,7 @@ class ExtractorCallbacks
|
||||
using MapKey = std::pair<std::string, std::string>;
|
||||
using MapVal = unsigned;
|
||||
std::unordered_map<MapKey, MapVal, boost::hash<MapKey>> string_map;
|
||||
std::unordered_map<guidance::TurnLaneDescription,LaneDescriptionID,guidance::TurnLaneDescription_hash> lane_description_map;
|
||||
ExtractionContainers &external_memory;
|
||||
|
||||
public:
|
||||
|
||||
@@ -61,6 +61,8 @@ struct ExtractorConfig
|
||||
output_file_name = basepath + ".osrm";
|
||||
restriction_file_name = basepath + ".osrm.restrictions";
|
||||
names_file_name = basepath + ".osrm.names";
|
||||
turn_lane_descriptions_file_name = basepath + ".osrm.tls";
|
||||
turn_lane_data_file_name = basepath + ".osrm.tld";
|
||||
timestamp_file_name = basepath + ".osrm.timestamp";
|
||||
geometry_output_path = basepath + ".osrm.geometry";
|
||||
node_output_path = basepath + ".osrm.nodes";
|
||||
@@ -82,6 +84,8 @@ struct ExtractorConfig
|
||||
std::string output_file_name;
|
||||
std::string restriction_file_name;
|
||||
std::string names_file_name;
|
||||
std::string turn_lane_data_file_name;
|
||||
std::string turn_lane_descriptions_file_name;
|
||||
std::string timestamp_file_name;
|
||||
std::string geometry_output_path;
|
||||
std::string edge_output_path;
|
||||
|
||||
@@ -58,6 +58,12 @@ inline bool isLinkClass(const FunctionalRoadClass road_class)
|
||||
road_class == FunctionalRoadClass::TERTIARY_LINK;
|
||||
}
|
||||
|
||||
// check wheter a class is a motorway like class
|
||||
inline bool isMotorwayClass(const FunctionalRoadClass road_class)
|
||||
{
|
||||
return road_class == FunctionalRoadClass::MOTORWAY || road_class == FunctionalRoadClass::TRUNK;
|
||||
}
|
||||
|
||||
// TODO augment this with all data required for guidance generation
|
||||
struct RoadClassificationData
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ struct TurnOperation final
|
||||
EdgeID eid;
|
||||
double angle;
|
||||
TurnInstruction instruction;
|
||||
LaneDataID lane_data_id;
|
||||
};
|
||||
|
||||
// A Connected Road is the internal representation of a potential turn. Internally, we require
|
||||
@@ -59,6 +60,9 @@ std::string toString(const ConnectedRoad &road);
|
||||
|
||||
typedef std::vector<ConnectedRoad> Intersection;
|
||||
|
||||
Intersection::const_iterator findClosestTurn(const Intersection &intersection, const double angle);
|
||||
Intersection::iterator findClosestTurn(Intersection &intersection, const double angle);
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/restriction_map.hpp"
|
||||
#include "util/name_table.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_MOTORWAY_HANDLER_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/intersection_generator.hpp"
|
||||
#include "extractor/guidance/intersection_handler.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
|
||||
@@ -26,8 +25,7 @@ class MotorwayHandler : public IntersectionHandler
|
||||
MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const util::NameTable &name_table,
|
||||
const SuffixTable &street_name_suffix_table,
|
||||
const IntersectionGenerator &intersection_generator);
|
||||
const SuffixTable &street_name_suffix_table);
|
||||
~MotorwayHandler() override final;
|
||||
|
||||
// check whether the handler can actually handle the intersection
|
||||
@@ -47,8 +45,6 @@ class MotorwayHandler : public IntersectionHandler
|
||||
Intersection fromRamp(const EdgeID via_edge, Intersection intersection) const;
|
||||
|
||||
Intersection fallback(Intersection intersection) const;
|
||||
|
||||
const IntersectionGenerator &intersection_generator;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
@@ -20,10 +22,12 @@
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -32,6 +36,9 @@ namespace extractor
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
using util::guidance::LaneTupelIdPair;
|
||||
using LaneDataIdMap = std::unordered_map<LaneTupelIdPair, LaneDataID, boost::hash<LaneTupelIdPair>>;
|
||||
|
||||
using util::guidance::angularDeviation;
|
||||
|
||||
namespace detail
|
||||
@@ -405,10 +412,10 @@ inline bool requiresNameAnnounced(const std::string &from,
|
||||
(from_ref.find(to_ref) != std::string::npos || to_ref.find(from_ref) != std::string::npos);
|
||||
const auto ref_is_removed = !from_ref.empty() && to_ref.empty();
|
||||
|
||||
const auto obvious_change = (names_are_empty && refs_are_empty) ||
|
||||
(names_are_equal && ref_is_contained) ||
|
||||
(names_are_equal && refs_are_empty) || name_is_removed ||
|
||||
ref_is_removed || is_suffix_change;
|
||||
const auto obvious_change =
|
||||
(names_are_empty && refs_are_empty) || (names_are_equal && ref_is_contained) ||
|
||||
(names_are_equal && refs_are_empty) || (ref_is_contained && name_is_removed) ||
|
||||
(names_are_equal && ref_is_removed) || is_suffix_change;
|
||||
|
||||
return !obvious_change;
|
||||
}
|
||||
@@ -456,6 +463,97 @@ inline ConnectedRoad mirror(ConnectedRoad road)
|
||||
return road;
|
||||
}
|
||||
|
||||
inline bool hasRoundaboutType(const TurnInstruction instruction)
|
||||
{
|
||||
using namespace extractor::guidance::TurnType;
|
||||
const constexpr TurnType::Enum valid_types[] = {TurnType::EnterRoundabout,
|
||||
TurnType::EnterAndExitRoundabout,
|
||||
TurnType::EnterRotary,
|
||||
TurnType::EnterAndExitRotary,
|
||||
TurnType::EnterRoundaboutIntersection,
|
||||
TurnType::EnterAndExitRoundaboutIntersection,
|
||||
TurnType::EnterRoundaboutAtExit,
|
||||
TurnType::ExitRoundabout,
|
||||
TurnType::EnterRotaryAtExit,
|
||||
TurnType::ExitRotary,
|
||||
TurnType::EnterRoundaboutIntersectionAtExit,
|
||||
TurnType::ExitRoundaboutIntersection,
|
||||
TurnType::StayOnRoundabout};
|
||||
const auto valid_end = valid_types + 13;
|
||||
return std::find(valid_types, valid_end, instruction.type) != valid_end;
|
||||
}
|
||||
|
||||
// Public service vehicle lanes and similar can introduce additional lanes into the lane string that
|
||||
// are not specifically marked for left/right turns. This function can be used from the profile to
|
||||
// trim the lane string appropriately
|
||||
//
|
||||
// left|throught|
|
||||
// in combination with lanes:psv:forward=1
|
||||
// will be corrected to left|throught, since the final lane is not drivable.
|
||||
// This is in contrast to a situation with lanes:psv:forward=0 (or not set) where left|through|
|
||||
// represents left|through|through
|
||||
inline std::string
|
||||
trimLaneString(std::string lane_string, std::int32_t count_left, std::int32_t count_right)
|
||||
{
|
||||
if (count_left)
|
||||
{
|
||||
bool sane = count_left < static_cast<std::int32_t>(lane_string.size());
|
||||
for (std::int32_t i = 0; i < count_left; ++i)
|
||||
// this is adjusted for our fake pipe. The moment cucumber can handle multiple escaped
|
||||
// pipes, the '&' part can be removed
|
||||
if (lane_string[i] != '|' && lane_string[i] != '&')
|
||||
{
|
||||
sane = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sane)
|
||||
{
|
||||
lane_string.erase(lane_string.begin(), lane_string.begin() + count_left);
|
||||
}
|
||||
}
|
||||
if (count_right)
|
||||
{
|
||||
bool sane = count_right < static_cast<std::int32_t>(lane_string.size());
|
||||
for (auto itr = lane_string.rbegin();
|
||||
itr != lane_string.rend() && itr != lane_string.rbegin() + count_right;
|
||||
++itr)
|
||||
{
|
||||
if (*itr != '|' && *itr != '&')
|
||||
{
|
||||
sane = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sane)
|
||||
lane_string.resize(lane_string.size() - count_right);
|
||||
}
|
||||
return lane_string;
|
||||
}
|
||||
|
||||
inline bool entersRoundabout(const extractor::guidance::TurnInstruction instruction)
|
||||
{
|
||||
return (instruction.type == extractor::guidance::TurnType::EnterRoundabout ||
|
||||
instruction.type == extractor::guidance::TurnType::EnterRotary ||
|
||||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutIntersection ||
|
||||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutAtExit ||
|
||||
instruction.type == extractor::guidance::TurnType::EnterRotaryAtExit ||
|
||||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutIntersectionAtExit ||
|
||||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout ||
|
||||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary ||
|
||||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary);
|
||||
}
|
||||
|
||||
inline bool leavesRoundabout(const extractor::guidance::TurnInstruction instruction)
|
||||
{
|
||||
return (instruction.type == extractor::guidance::TurnType::ExitRoundabout ||
|
||||
instruction.type == extractor::guidance::TurnType::ExitRotary ||
|
||||
instruction.type == extractor::guidance::TurnType::ExitRoundaboutIntersection ||
|
||||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout ||
|
||||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary ||
|
||||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundaboutIntersection);
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
@@ -44,10 +44,14 @@ class TurnAnalysis
|
||||
const SuffixTable &street_name_suffix_table);
|
||||
|
||||
// the entry into the turn analysis
|
||||
std::vector<TurnOperation> getTurns(const NodeID from_node, const EdgeID via_eid) const;
|
||||
|
||||
// access to the intersection representation for classification purposes
|
||||
Intersection getIntersection(const NodeID from_node, const EdgeID via_eid) const;
|
||||
Intersection
|
||||
assignTurnTypes(const NodeID from_node, const EdgeID via_eid, Intersection intersection) const;
|
||||
|
||||
std::vector<TurnOperation>
|
||||
transformIntersectionIntoTurns(const Intersection &intersection) const;
|
||||
|
||||
const IntersectionGenerator &getGenerator() const;
|
||||
|
||||
private:
|
||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_TURN_DISCOVERY_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_TURN_DISCOVERY_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/turn_analysis.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
namespace lanes
|
||||
{
|
||||
|
||||
// OSRM processes edges by looking at a via_edge, coming into an intersection. For turn lanes, we
|
||||
// might require to actually look back a turn. We do so in the hope that the turn lanes match up at
|
||||
// the previous intersection for all incoming lanes.
|
||||
bool findPreviousIntersection(
|
||||
const NodeID node,
|
||||
const EdgeID via_edge,
|
||||
const Intersection intersection,
|
||||
const TurnAnalysis &turn_analysis, // to generate other intersections
|
||||
const util::NodeBasedDynamicGraph &node_based_graph, // query edge data
|
||||
// output parameters, will be in an arbitrary state on failure
|
||||
NodeID &result_node,
|
||||
EdgeID &result_via_edge,
|
||||
Intersection &result_intersection);
|
||||
|
||||
} // namespace lanes
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /*OSRM_EXTRACTOR_GUIDANCE_TURN_DISCOVERY_HPP_*/
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include "extractor/guidance/roundabout_type.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -53,48 +55,45 @@ const constexpr Enum EnterRotary = 12; // Enter a rotary
|
||||
const constexpr Enum EnterAndExitRotary = 13; // Touching a rotary
|
||||
const constexpr Enum EnterRoundaboutIntersection = 14; // Entering a small Roundabout
|
||||
const constexpr Enum EnterAndExitRoundaboutIntersection = 15; // Touching a roundabout
|
||||
const constexpr Enum UseLane = 16; // No Turn, but you need to stay on a given lane!
|
||||
|
||||
// Values below here are silent instructions
|
||||
const constexpr Enum NoTurn = 16; // end of segment without turn/middle of a segment
|
||||
const constexpr Enum Suppressed = 17; // location that suppresses a turn
|
||||
const constexpr Enum EnterRoundaboutAtExit = 18; // Entering a small Roundabout at a countable exit
|
||||
const constexpr Enum ExitRoundabout = 19; // Exiting a small Roundabout
|
||||
const constexpr Enum EnterRotaryAtExit = 20; // Enter A Rotary at a countable exit
|
||||
const constexpr Enum ExitRotary = 21; // Exit a rotary
|
||||
const constexpr Enum NoTurn = 17; // end of segment without turn/middle of a segment
|
||||
const constexpr Enum Suppressed = 18; // location that suppresses a turn
|
||||
const constexpr Enum EnterRoundaboutAtExit = 19; // Entering a small Roundabout at a countable exit
|
||||
const constexpr Enum ExitRoundabout = 20; // Exiting a small Roundabout
|
||||
const constexpr Enum EnterRotaryAtExit = 21; // Enter A Rotary at a countable exit
|
||||
const constexpr Enum ExitRotary = 22; // Exit a rotary
|
||||
const constexpr Enum EnterRoundaboutIntersectionAtExit =
|
||||
22; // Entering a small Roundabout at a countable exit
|
||||
const constexpr Enum ExitRoundaboutIntersection = 23; // Exiting a small Roundabout
|
||||
const constexpr Enum StayOnRoundabout = 24; // Continue on Either a small or a large Roundabout
|
||||
23; // Entering a small Roundabout at a countable exit
|
||||
const constexpr Enum ExitRoundaboutIntersection = 24; // Exiting a small Roundabout
|
||||
const constexpr Enum StayOnRoundabout = 25; // Continue on Either a small or a large Roundabout
|
||||
const constexpr Enum Sliproad =
|
||||
25; // Something that looks like a ramp, but is actually just a small sliproad
|
||||
26; // Something that looks like a ramp, but is actually just a small sliproad
|
||||
}
|
||||
|
||||
// turn angle in 1.40625 degree -> 128 == 180 degree
|
||||
struct TurnInstruction
|
||||
{
|
||||
using LaneTupel = util::guidance::LaneTupel;
|
||||
TurnInstruction(const TurnType::Enum type = TurnType::Invalid,
|
||||
const DirectionModifier::Enum direction_modifier = DirectionModifier::Straight)
|
||||
const DirectionModifier::Enum direction_modifier = DirectionModifier::UTurn)
|
||||
: type(type), direction_modifier(direction_modifier)
|
||||
{
|
||||
}
|
||||
|
||||
TurnType::Enum type : 5;
|
||||
DirectionModifier::Enum direction_modifier : 3;
|
||||
// the lane tupel that is used for the turn
|
||||
|
||||
static TurnInstruction INVALID()
|
||||
{
|
||||
return TurnInstruction(TurnType::Invalid, DirectionModifier::UTurn);
|
||||
}
|
||||
static TurnInstruction INVALID() { return {TurnType::Invalid, DirectionModifier::UTurn}; }
|
||||
|
||||
static TurnInstruction NO_TURN()
|
||||
{
|
||||
return TurnInstruction(TurnType::NoTurn, DirectionModifier::UTurn);
|
||||
}
|
||||
static TurnInstruction NO_TURN() { return {TurnType::NoTurn, DirectionModifier::UTurn}; }
|
||||
|
||||
static TurnInstruction REMAIN_ROUNDABOUT(const RoundaboutType,
|
||||
const DirectionModifier::Enum modifier)
|
||||
{
|
||||
return TurnInstruction(TurnType::StayOnRoundabout, modifier);
|
||||
return {TurnType::StayOnRoundabout, modifier};
|
||||
}
|
||||
|
||||
static TurnInstruction ENTER_ROUNDABOUT(const RoundaboutType roundabout_type,
|
||||
@@ -146,7 +145,7 @@ struct TurnInstruction
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(TurnInstruction) == 1, "TurnInstruction does not fit one byte");
|
||||
static_assert(sizeof(TurnInstruction) == 1, "TurnInstruction does not fit a byte");
|
||||
|
||||
inline bool operator!=(const TurnInstruction lhs, const TurnInstruction rhs)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_AUGMENTATION_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_AUGMENTATION_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/turn_lane_data.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
namespace lanes
|
||||
{
|
||||
|
||||
LaneDataVector handleNoneValueAtSimpleTurn(LaneDataVector lane_data,
|
||||
const Intersection &intersection);
|
||||
|
||||
} // namespace lanes
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /* OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_AUGMENTATION_HPP_ */
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_DATA_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_DATA_HPP_
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
namespace lanes
|
||||
{
|
||||
|
||||
struct TurnLaneData
|
||||
{
|
||||
TurnLaneType::Mask tag;
|
||||
LaneID from;
|
||||
LaneID to;
|
||||
|
||||
bool operator<(const TurnLaneData &other) const;
|
||||
};
|
||||
typedef std::vector<TurnLaneData> LaneDataVector;
|
||||
|
||||
// convertes a string given in the OSM format into a TurnLaneData vector
|
||||
LaneDataVector laneDataFromDescription(const TurnLaneDescription &turn_lane_description);
|
||||
|
||||
// Locate A Tag in a lane data vector (if multiple tags are set, the first one found is returned)
|
||||
LaneDataVector::const_iterator findTag(const TurnLaneType::Mask tag, const LaneDataVector &data);
|
||||
LaneDataVector::iterator findTag(const TurnLaneType::Mask tag, LaneDataVector &data);
|
||||
|
||||
// Returns true if any of the queried tags is contained
|
||||
bool hasTag(const TurnLaneType::Mask tag, const LaneDataVector &data);
|
||||
|
||||
} // namespace lane_data_generation
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /* OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_DATA_HPP_ */
|
||||
@@ -0,0 +1,85 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_HANDLER_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_HANDLER_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
#include "extractor/guidance/turn_analysis.hpp"
|
||||
#include "extractor/guidance/turn_lane_data.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/name_table.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
// Given an Intersection, the graph to access the data and the turn lanes, the turn lane matcher
|
||||
// assigns appropriate turn tupels to the different turns.
|
||||
namespace lanes
|
||||
{
|
||||
class TurnLaneHandler
|
||||
{
|
||||
public:
|
||||
typedef std::vector<TurnLaneData> LaneDataVector;
|
||||
|
||||
TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const std::vector<std::uint32_t> &turn_lane_offsets,
|
||||
const std::vector<TurnLaneType::Mask> &turn_lane_masks,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const TurnAnalysis &turn_analysis);
|
||||
|
||||
Intersection assignTurnLanes(const NodeID at,
|
||||
const EdgeID via_edge,
|
||||
Intersection intersection,
|
||||
LaneDataIdMap &id_map) const;
|
||||
|
||||
private:
|
||||
// we need to be able to look at previous intersections to, in some cases, find the correct turn
|
||||
// lanes for a turn
|
||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||
const std::vector<std::uint32_t> &turn_lane_offsets;
|
||||
const std::vector<TurnLaneType::Mask> &turn_lane_masks;
|
||||
const std::vector<QueryNode> &node_info_list;
|
||||
const TurnAnalysis &turn_analysis;
|
||||
|
||||
// check whether we can handle an intersection
|
||||
bool isSimpleIntersection(const LaneDataVector &turn_lane_data,
|
||||
const Intersection &intersection) const;
|
||||
|
||||
// in case of a simple intersection, assign the lane entries
|
||||
Intersection simpleMatchTuplesToTurns(Intersection intersection,
|
||||
const LaneDataVector &lane_data,
|
||||
const LaneDescriptionID lane_string_id,
|
||||
LaneDataIdMap &id_map) const;
|
||||
|
||||
// partition lane data into lane data relevant at current turn and at next turn
|
||||
std::pair<TurnLaneHandler::LaneDataVector, TurnLaneHandler::LaneDataVector> partitionLaneData(
|
||||
const NodeID at, LaneDataVector turn_lane_data, const Intersection &intersection) const;
|
||||
|
||||
// if the current intersections turn string is empty, we check whether there is an incoming
|
||||
// intersection whose turns might be related to this current intersection
|
||||
Intersection handleTurnAtPreviousIntersection(const NodeID at,
|
||||
const EdgeID via_edge,
|
||||
Intersection intersection,
|
||||
LaneDataIdMap &id_map) const;
|
||||
};
|
||||
|
||||
} // namespace lanes
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif // OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_HANDLER_HPP_
|
||||
@@ -0,0 +1,51 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_MATCHER_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_MATCHER_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_data.hpp"
|
||||
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
namespace lanes
|
||||
{
|
||||
|
||||
// Translate Turn Lane Tags into a matching modifier
|
||||
DirectionModifier::Enum getMatchingModifier(const TurnLaneType::Mask &tag);
|
||||
|
||||
// check whether a match of a given tag and a turn instruction can be seen as valid
|
||||
bool isValidMatch(const TurnLaneType::Mask &tag, const TurnInstruction instruction);
|
||||
|
||||
// localisation of the best possible match for a tag
|
||||
typename Intersection::const_iterator findBestMatch(const TurnLaneType::Mask &tag,
|
||||
const Intersection &intersection);
|
||||
typename Intersection::const_iterator
|
||||
findBestMatchForReverse(const TurnLaneType::Mask &leftmost_tag, const Intersection &intersection);
|
||||
|
||||
// a match is trivial if all turns can be associated with their best match in a valid way and the
|
||||
// matches occur in order
|
||||
bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &lane_data);
|
||||
|
||||
// perform a trivial match on the turn lanes
|
||||
Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
||||
const LaneDataVector &lane_data,
|
||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const LaneDescriptionID lane_string_id,
|
||||
LaneDataIdMap &lane_data_to_id);
|
||||
|
||||
} // namespace lanes
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /*OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_MATCHER_HPP_*/
|
||||
@@ -0,0 +1,102 @@
|
||||
#ifndef OSRM_GUIDANCE_TURN_LANE_TYPES_HPP_
|
||||
#define OSRM_GUIDANCE_TURN_LANE_TYPES_HPP_
|
||||
|
||||
#include <bitset>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
|
||||
#include "util/simple_logger.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
namespace TurnLaneType
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
const constexpr std::size_t num_supported_lane_types = 11;
|
||||
|
||||
const constexpr char *translations[detail::num_supported_lane_types] = {"none",
|
||||
"straight",
|
||||
"sharp left",
|
||||
"left",
|
||||
"slight left",
|
||||
"slight right",
|
||||
"right",
|
||||
"sharp right",
|
||||
"uturn",
|
||||
"merge to left",
|
||||
"merge to right"};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
typedef std::uint16_t Mask;
|
||||
const constexpr Mask empty = 0u;
|
||||
const constexpr Mask none = 1u << 0u;
|
||||
const constexpr Mask straight = 1u << 1u;
|
||||
const constexpr Mask sharp_left = 1u << 2u;
|
||||
const constexpr Mask left = 1u << 3u;
|
||||
const constexpr Mask slight_left = 1u << 4u;
|
||||
const constexpr Mask slight_right = 1u << 5u;
|
||||
const constexpr Mask right = 1u << 6u;
|
||||
const constexpr Mask sharp_right = 1u << 7u;
|
||||
const constexpr Mask uturn = 1u << 8u;
|
||||
const constexpr Mask merge_to_left = 1u << 9u;
|
||||
const constexpr Mask merge_to_right = 1u << 10u;
|
||||
|
||||
inline std::string toString(const Mask lane_type)
|
||||
{
|
||||
if (lane_type == 0)
|
||||
return "none";
|
||||
|
||||
std::bitset<8 * sizeof(Mask)> mask(lane_type);
|
||||
std::string result = "";
|
||||
for (std::size_t lane_id_nr = 0; lane_id_nr < detail::num_supported_lane_types; ++lane_id_nr)
|
||||
if (mask[lane_id_nr])
|
||||
result += (result.empty() ? detail::translations[lane_id_nr]
|
||||
: (std::string(";") + detail::translations[lane_id_nr]));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline util::json::Array toJsonArray(const Mask lane_type)
|
||||
{
|
||||
util::json::Array result;
|
||||
std::bitset<8 * sizeof(Mask)> mask(lane_type);
|
||||
for (std::size_t lane_id_nr = 0; lane_id_nr < detail::num_supported_lane_types; ++lane_id_nr)
|
||||
if (mask[lane_id_nr])
|
||||
result.values.push_back(detail::translations[lane_id_nr]);
|
||||
return result;
|
||||
}
|
||||
} // TurnLaneType
|
||||
|
||||
typedef std::vector<TurnLaneType::Mask> TurnLaneDescription;
|
||||
|
||||
// hash function for TurnLaneDescription
|
||||
struct TurnLaneDescription_hash
|
||||
{
|
||||
std::size_t operator()(const TurnLaneDescription &lane_description) const
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
for (auto val : lane_description)
|
||||
boost::hash_combine(seed, val);
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
} // guidance
|
||||
} // extractor
|
||||
} // osrm
|
||||
|
||||
#endif /* OSRM_GUIDANCE_TURN_LANE_TYPES_HPP_ */
|
||||
@@ -29,7 +29,6 @@ struct InternalExtractorEdge
|
||||
|
||||
struct WeightData
|
||||
{
|
||||
|
||||
WeightData() : duration(0.0), type(WeightType::INVALID) {}
|
||||
|
||||
union {
|
||||
@@ -51,6 +50,7 @@ struct InternalExtractorEdge
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
false,
|
||||
guidance::TurnLaneType::empty,
|
||||
guidance::RoadClassificationData())
|
||||
{
|
||||
}
|
||||
@@ -66,9 +66,10 @@ struct InternalExtractorEdge
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool is_split,
|
||||
LaneDescriptionID lane_description,
|
||||
guidance::RoadClassificationData road_classification)
|
||||
: result(OSMNodeID(source),
|
||||
OSMNodeID(target),
|
||||
: result(source,
|
||||
target,
|
||||
name_id,
|
||||
0,
|
||||
forward,
|
||||
@@ -78,6 +79,7 @@ struct InternalExtractorEdge
|
||||
startpoint,
|
||||
travel_mode,
|
||||
is_split,
|
||||
lane_description,
|
||||
std::move(road_classification)),
|
||||
weight_data(std::move(weight_data))
|
||||
{
|
||||
@@ -104,6 +106,7 @@ struct InternalExtractorEdge
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
false,
|
||||
INVALID_LANE_DESCRIPTIONID,
|
||||
guidance::RoadClassificationData());
|
||||
}
|
||||
static InternalExtractorEdge max_osm_value()
|
||||
@@ -119,6 +122,7 @@ struct InternalExtractorEdge
|
||||
true,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
false,
|
||||
INVALID_LANE_DESCRIPTIONID,
|
||||
guidance::RoadClassificationData());
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ struct NodeBasedEdge
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool is_split,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassificationData road_classification);
|
||||
|
||||
bool operator<(const NodeBasedEdge &other) const;
|
||||
@@ -41,6 +42,7 @@ struct NodeBasedEdge
|
||||
bool startpoint : 1;
|
||||
bool is_split : 1;
|
||||
TravelMode travel_mode : 4;
|
||||
LaneDescriptionID lane_description_id;
|
||||
guidance::RoadClassificationData road_classification;
|
||||
};
|
||||
|
||||
@@ -57,6 +59,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool is_split,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassificationData road_classification);
|
||||
|
||||
OSMNodeID osm_source_id;
|
||||
@@ -68,7 +71,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
||||
inline NodeBasedEdge::NodeBasedEdge()
|
||||
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), forward(false),
|
||||
backward(false), roundabout(false), access_restricted(false), startpoint(true),
|
||||
is_split(false), travel_mode(false)
|
||||
is_split(false), travel_mode(false), lane_description_id(INVALID_LANE_DESCRIPTIONID)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -83,11 +86,12 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool is_split,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassificationData road_classification)
|
||||
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
|
||||
backward(backward), roundabout(roundabout), access_restricted(access_restricted),
|
||||
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode),
|
||||
road_classification(std::move(road_classification))
|
||||
lane_description_id(lane_description_id), road_classification(std::move(road_classification))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -120,6 +124,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool is_split,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassificationData road_classification)
|
||||
: NodeBasedEdge(SPECIAL_NODEID,
|
||||
SPECIAL_NODEID,
|
||||
@@ -132,6 +137,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(
|
||||
startpoint,
|
||||
travel_mode,
|
||||
is_split,
|
||||
lane_description_id,
|
||||
std::move(road_classification)),
|
||||
osm_source_id(std::move(source)), osm_target_id(std::move(target))
|
||||
{
|
||||
|
||||
@@ -17,18 +17,19 @@ struct OriginalEdgeData
|
||||
{
|
||||
explicit OriginalEdgeData(NodeID via_node,
|
||||
unsigned name_id,
|
||||
LaneDataID lane_data_id,
|
||||
guidance::TurnInstruction turn_instruction,
|
||||
EntryClassID entry_classid,
|
||||
TravelMode travel_mode)
|
||||
: via_node(via_node), name_id(name_id), entry_classid(entry_classid),
|
||||
turn_instruction(turn_instruction), travel_mode(travel_mode)
|
||||
lane_data_id(lane_data_id), turn_instruction(turn_instruction), travel_mode(travel_mode)
|
||||
{
|
||||
}
|
||||
|
||||
OriginalEdgeData()
|
||||
: via_node(std::numeric_limits<unsigned>::max()),
|
||||
name_id(std::numeric_limits<unsigned>::max()), entry_classid(INVALID_ENTRY_CLASSID),
|
||||
turn_instruction(guidance::TurnInstruction::INVALID()),
|
||||
lane_data_id(INVALID_LANE_DATAID), turn_instruction(guidance::TurnInstruction::INVALID()),
|
||||
travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
||||
{
|
||||
}
|
||||
@@ -36,9 +37,13 @@ struct OriginalEdgeData
|
||||
NodeID via_node;
|
||||
unsigned name_id;
|
||||
EntryClassID entry_classid;
|
||||
LaneDataID lane_data_id;
|
||||
guidance::TurnInstruction turn_instruction;
|
||||
TravelMode travel_mode;
|
||||
};
|
||||
|
||||
static_assert(sizeof(OriginalEdgeData) == 16,
|
||||
"Increasing the size of OriginalEdgeData increases memory consumption");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "util/coordinate.hpp"
|
||||
|
||||
#include <limits>
|
||||
#include <cstdint>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -15,16 +16,16 @@ namespace extractor
|
||||
struct QueryNode
|
||||
{
|
||||
using key_type = OSMNodeID; // type of NodeID
|
||||
using value_type = int; // type of lat,lons
|
||||
using value_type = std::int32_t; // type of lat,lons
|
||||
|
||||
explicit QueryNode(const util::FixedLongitude lon_,
|
||||
const util::FixedLatitude lat_,
|
||||
key_type node_id)
|
||||
: lon(lon_), lat(lat_), node_id(std::move(node_id))
|
||||
const key_type node_id_)
|
||||
: lon(lon_), lat(lat_), node_id(node_id_)
|
||||
{
|
||||
}
|
||||
QueryNode()
|
||||
: lon(std::numeric_limits<int>::max()), lat(std::numeric_limits<int>::max()),
|
||||
: lon{std::numeric_limits<value_type>::max()}, lat{std::numeric_limits<value_type>::max()},
|
||||
node_id(SPECIAL_OSM_NODEID)
|
||||
{
|
||||
}
|
||||
@@ -35,15 +36,15 @@ struct QueryNode
|
||||
|
||||
static QueryNode min_value()
|
||||
{
|
||||
return QueryNode(util::FixedLongitude(-180 * COORDINATE_PRECISION),
|
||||
util::FixedLatitude(-90 * COORDINATE_PRECISION),
|
||||
return QueryNode(util::FixedLongitude{static_cast<value_type>(-180 * COORDINATE_PRECISION)},
|
||||
util::FixedLatitude{static_cast<value_type>(-90 * COORDINATE_PRECISION)},
|
||||
MIN_OSM_NODEID);
|
||||
}
|
||||
|
||||
static QueryNode max_value()
|
||||
{
|
||||
return QueryNode(util::FixedLongitude(180 * COORDINATE_PRECISION),
|
||||
util::FixedLatitude(90 * COORDINATE_PRECISION),
|
||||
return QueryNode(util::FixedLongitude{static_cast<value_type>(180 * COORDINATE_PRECISION)},
|
||||
util::FixedLatitude{static_cast<value_type>(90 * COORDINATE_PRECISION)},
|
||||
MAX_OSM_NODEID);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -111,15 +111,15 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
||||
qi::_1,
|
||||
qi::_2)];
|
||||
|
||||
location_rule = (double_ > qi::lit(',') >
|
||||
double_)[qi::_val = ph::bind(
|
||||
[](double lon, double lat) {
|
||||
return util::Coordinate(
|
||||
util::FixedLongitude(lon * COORDINATE_PRECISION),
|
||||
util::FixedLatitude(lat * COORDINATE_PRECISION));
|
||||
},
|
||||
qi::_1,
|
||||
qi::_2)];
|
||||
location_rule =
|
||||
(double_ > qi::lit(',') >
|
||||
double_)[qi::_val = ph::bind(
|
||||
[](double lon, double lat) {
|
||||
return util::Coordinate(util::toFixed(util::FloatLongitude{lon}),
|
||||
util::toFixed(util::FloatLatitude{lat}));
|
||||
},
|
||||
qi::_1,
|
||||
qi::_2)];
|
||||
|
||||
polyline_rule = qi::as_string[qi::lit("polyline(") > +polyline_chars > ')']
|
||||
[qi::_val = ph::bind(
|
||||
|
||||
@@ -14,7 +14,41 @@ namespace storage
|
||||
{
|
||||
|
||||
// Added at the start and end of each block as sanity check
|
||||
const constexpr char CANARY[] = "OSRM";
|
||||
const constexpr char CANARY[4] = {'O', 'S', 'R', 'M'};
|
||||
|
||||
const constexpr char *block_id_to_name[] = {"NAME_OFFSETS",
|
||||
"NAME_BLOCKS",
|
||||
"NAME_CHAR_LIST",
|
||||
"NAME_ID_LIST",
|
||||
"VIA_NODE_LIST",
|
||||
"GRAPH_NODE_LIST",
|
||||
"GRAPH_EDGE_LIST",
|
||||
"COORDINATE_LIST",
|
||||
"OSM_NODE_ID_LIST",
|
||||
"TURN_INSTRUCTION",
|
||||
"TRAVEL_MODE",
|
||||
"ENTRY_CLASSID",
|
||||
"R_SEARCH_TREE",
|
||||
"GEOMETRIES_INDEX",
|
||||
"GEOMETRIES_LIST",
|
||||
"HSGR_CHECKSUM",
|
||||
"TIMESTAMP",
|
||||
"FILE_INDEX_PATH",
|
||||
"CORE_MARKER",
|
||||
"DATASOURCES_LIST",
|
||||
"DATASOURCE_NAME_DATA",
|
||||
"DATASOURCE_NAME_OFFSETS",
|
||||
"DATASOURCE_NAME_LENGTHS",
|
||||
"PROPERTIES",
|
||||
"BEARING_CLASSID",
|
||||
"BEARING_OFFSETS",
|
||||
"BEARING_BLOCKS",
|
||||
"BEARING_VALUES",
|
||||
"ENTRY_CLASS",
|
||||
"LANE_DATA_ID",
|
||||
"TURN_LANE_DATA",
|
||||
"LANE_DESCRIPTION_OFFSETS",
|
||||
"LANE_DESCRIPTION_MASKS"};
|
||||
|
||||
struct SharedDataLayout
|
||||
{
|
||||
@@ -30,8 +64,8 @@ struct SharedDataLayout
|
||||
COORDINATE_LIST,
|
||||
OSM_NODE_ID_LIST,
|
||||
TURN_INSTRUCTION,
|
||||
ENTRY_CLASSID,
|
||||
TRAVEL_MODE,
|
||||
ENTRY_CLASSID,
|
||||
R_SEARCH_TREE,
|
||||
GEOMETRIES_INDEX,
|
||||
GEOMETRIES_LIST,
|
||||
@@ -49,6 +83,10 @@ struct SharedDataLayout
|
||||
BEARING_BLOCKS,
|
||||
BEARING_VALUES,
|
||||
ENTRY_CLASS,
|
||||
LANE_DATA_ID,
|
||||
TURN_LANE_DATA,
|
||||
LANE_DESCRIPTION_OFFSETS,
|
||||
LANE_DESCRIPTION_MASKS,
|
||||
NUM_BLOCKS
|
||||
};
|
||||
|
||||
@@ -63,15 +101,20 @@ struct SharedDataLayout
|
||||
entry_size[bid] = sizeof(T);
|
||||
}
|
||||
|
||||
inline uint64_t AlignBlockSize(uint64_t block_size) const
|
||||
{
|
||||
const uint64_t alignment = 4;
|
||||
return (block_size + (alignment - 1)) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
inline uint64_t GetBlockSize(BlockID bid) const
|
||||
{
|
||||
// special bit encoding
|
||||
if (bid == CORE_MARKER)
|
||||
{
|
||||
return (num_entries[bid] / 32 + 1) * entry_size[bid];
|
||||
return AlignBlockSize((num_entries[bid] / 32 + 1) * entry_size[bid]);
|
||||
}
|
||||
|
||||
return num_entries[bid] * entry_size[bid];
|
||||
return AlignBlockSize(num_entries[bid] * entry_size[bid]);
|
||||
}
|
||||
|
||||
inline uint64_t GetSizeOfLayout() const
|
||||
@@ -108,11 +151,13 @@ struct SharedDataLayout
|
||||
bool end_canary_alive = std::equal(CANARY, CANARY + sizeof(CANARY), end_canary_ptr);
|
||||
if (!start_canary_alive)
|
||||
{
|
||||
throw util::exception("Start canary of block corrupted.");
|
||||
throw util::exception(std::string("Start canary of block corrupted. (") +
|
||||
block_id_to_name[bid] + ")");
|
||||
}
|
||||
if (!end_canary_alive)
|
||||
{
|
||||
throw util::exception("End canary of block corrupted.");
|
||||
throw util::exception(std::string("End canary of block corrupted. (") +
|
||||
block_id_to_name[bid] + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +182,9 @@ struct SharedDataTimestamp
|
||||
SharedDataType data;
|
||||
unsigned timestamp;
|
||||
};
|
||||
|
||||
static_assert(sizeof(block_id_to_name) / sizeof(*block_id_to_name) == SharedDataLayout::NUM_BLOCKS,
|
||||
"Number of blocks needs to match the number of Block names.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,8 @@ struct StorageConfig final
|
||||
boost::filesystem::path names_data_path;
|
||||
boost::filesystem::path properties_path;
|
||||
boost::filesystem::path intersection_class_path;
|
||||
boost::filesystem::path turn_lane_data_path;
|
||||
boost::filesystem::path turn_lane_description_path;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
#ifndef OSRM_ASSERT_HPP
|
||||
#define OSRM_ASSERT_HPP
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
// Assertion type to be thrown for stack unwinding
|
||||
struct assertionError final : std::logic_error
|
||||
{
|
||||
assertionError(const char *msg) : std::logic_error{msg} {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -61,7 +61,7 @@ inline FixedLatitude toFixed(const FloatLatitude floating)
|
||||
{
|
||||
const auto latitude = static_cast<double>(floating);
|
||||
const auto fixed = boost::numeric_cast<std::int32_t>(latitude * COORDINATE_PRECISION);
|
||||
return FixedLatitude(fixed);
|
||||
return FixedLatitude{fixed};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +75,7 @@ inline FixedLongitude toFixed(const FloatLongitude floating)
|
||||
{
|
||||
const auto longitude = static_cast<double>(floating);
|
||||
const auto fixed = boost::numeric_cast<std::int32_t>(longitude * COORDINATE_PRECISION);
|
||||
return FixedLongitude(fixed);
|
||||
return FixedLongitude{fixed};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +89,7 @@ inline FloatLatitude toFloating(const FixedLatitude fixed)
|
||||
{
|
||||
const auto latitude = static_cast<std::int32_t>(fixed);
|
||||
const auto floating = boost::numeric_cast<double>(latitude / COORDINATE_PRECISION);
|
||||
return FloatLatitude(floating);
|
||||
return FloatLatitude{floating};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,7 +103,7 @@ inline FloatLongitude toFloating(const FixedLongitude fixed)
|
||||
{
|
||||
const auto longitude = static_cast<std::int32_t>(fixed);
|
||||
const auto floating = boost::numeric_cast<double>(longitude / COORDINATE_PRECISION);
|
||||
return FloatLongitude(floating);
|
||||
return FloatLongitude{floating};
|
||||
}
|
||||
|
||||
// fwd. decl.
|
||||
@@ -127,7 +127,7 @@ struct Coordinate
|
||||
FixedLongitude lon;
|
||||
FixedLatitude lat;
|
||||
|
||||
Coordinate() : lon(std::numeric_limits<int>::min()), lat(std::numeric_limits<int>::min()) {}
|
||||
Coordinate() : lon{std::numeric_limits<int>::min()}, lat{std::numeric_limits<int>::min()} {}
|
||||
|
||||
Coordinate(const FloatCoordinate &other);
|
||||
|
||||
@@ -173,7 +173,7 @@ struct FloatCoordinate
|
||||
FloatLatitude lat;
|
||||
|
||||
FloatCoordinate()
|
||||
: lon(std::numeric_limits<double>::min()), lat(std::numeric_limits<double>::min())
|
||||
: lon{std::numeric_limits<double>::min()}, lat{std::numeric_limits<double>::min()}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -61,10 +61,10 @@ inline std::pair<double, FloatCoordinate> projectPointOnSegment(const FloatCoord
|
||||
|
||||
return {clamped_ratio,
|
||||
{
|
||||
FloatLongitude(1.0 - clamped_ratio) * source.lon +
|
||||
target.lon * FloatLongitude(clamped_ratio),
|
||||
FloatLatitude(1.0 - clamped_ratio) * source.lat +
|
||||
target.lat * FloatLatitude(clamped_ratio),
|
||||
FloatLongitude{1.0 - clamped_ratio} * source.lon +
|
||||
target.lon * FloatLongitude{clamped_ratio},
|
||||
FloatLatitude{1.0 - clamped_ratio} * source.lat +
|
||||
target.lat * FloatLatitude{clamped_ratio},
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#ifndef OSRM_ENGINE_GUIDANCE_DEBUG_HPP_
|
||||
#define OSRM_ENGINE_GUIDANCE_DEBUG_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/turn_lane_data.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
inline void print(const engine::guidance::RouteStep &step)
|
||||
{
|
||||
std::cout << static_cast<int>(step.maneuver.instruction.type) << " "
|
||||
<< static_cast<int>(step.maneuver.instruction.direction_modifier) << " "
|
||||
<< static_cast<int>(step.maneuver.waypoint_type) << " Duration: " << step.duration
|
||||
<< " Distance: " << step.distance << " Geometry: " << step.geometry_begin << " "
|
||||
<< step.geometry_end << " exit: " << step.maneuver.exit
|
||||
<< " Intersections: " << step.intersections.size() << " [";
|
||||
|
||||
for (const auto &intersection : step.intersections)
|
||||
{
|
||||
std::cout << "(bearings:";
|
||||
for (auto bearing : intersection.bearings)
|
||||
std::cout << " " << bearing;
|
||||
std::cout << ", entry: ";
|
||||
for (auto entry : intersection.entry)
|
||||
std::cout << " " << (entry ? "true" : "false");
|
||||
std::cout << ")";
|
||||
}
|
||||
std::cout << "] name[" << step.name_id << "]: " << step.name;
|
||||
}
|
||||
|
||||
inline void print(const std::vector<engine::guidance::RouteStep> &steps)
|
||||
{
|
||||
std::cout << "Path\n";
|
||||
int segment = 0;
|
||||
for (const auto &step : steps)
|
||||
{
|
||||
std::cout << "\t[" << segment++ << "]: ";
|
||||
print(step);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
inline void print(const extractor::guidance::lanes::LaneDataVector &turn_lane_data)
|
||||
{
|
||||
std::cout << " Tags:\n";
|
||||
for (auto entry : turn_lane_data)
|
||||
std::cout << "\t" << entry.tag << "("
|
||||
<< extractor::guidance::TurnLaneType::toString(entry.tag)
|
||||
<< ") from: " << static_cast<int>(entry.from)
|
||||
<< " to: " << static_cast<int>(entry.to) << "\n";
|
||||
std::cout << std::flush;
|
||||
}
|
||||
|
||||
inline void
|
||||
printTurnAssignmentData(const NodeID at,
|
||||
const extractor::guidance::lanes::LaneDataVector &turn_lane_data,
|
||||
const extractor::guidance::Intersection &intersection,
|
||||
const std::vector<extractor::QueryNode> &node_info_list)
|
||||
{
|
||||
std::cout << "[Turn Assignment Progress]\nLocation:";
|
||||
auto coordinate = node_info_list[at];
|
||||
std::cout << std::setprecision(12) << toFloating(coordinate.lat) << " "
|
||||
<< toFloating(coordinate.lon) << "\n";
|
||||
|
||||
std::cout << " Intersection:\n";
|
||||
for (const auto &road : intersection)
|
||||
std::cout << "\t" << toString(road) << "\n";
|
||||
|
||||
// flushes as well
|
||||
print(turn_lane_data);
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace util
|
||||
} // namespace osrm
|
||||
|
||||
#endif /*OSRM_ENGINE_GUIDANCE_DEBUG_HPP_*/
|
||||
@@ -24,8 +24,8 @@ template <typename EdgeDataT> class DynamicGraph
|
||||
{
|
||||
public:
|
||||
using EdgeData = EdgeDataT;
|
||||
using NodeIterator = unsigned;
|
||||
using EdgeIterator = unsigned;
|
||||
using NodeIterator = std::uint32_t;
|
||||
using EdgeIterator = std::uint32_t;
|
||||
using EdgeRange = range<EdgeIterator>;
|
||||
|
||||
class InputEdge
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef OSRM_GROUP_BY
|
||||
#define OSRM_GROUP_BY
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
|
||||
// Runs fn on consecutive items in sub-ranges determined by pred.
|
||||
//
|
||||
// Example:
|
||||
// vector<int> v{1,2,2,2,3,4,4};
|
||||
// group_by(first, last, even, print);
|
||||
// >>> 2,2,2
|
||||
// >>> 4,4
|
||||
//
|
||||
// Note: this mimics Python's itertools.groupby
|
||||
template <typename Iter, typename Pred, typename Fn>
|
||||
Fn group_by(Iter first, Iter last, Pred pred, Fn fn)
|
||||
{
|
||||
while (first != last)
|
||||
{
|
||||
first = std::find_if(first, last, pred);
|
||||
auto next = std::find_if_not(first, last, pred);
|
||||
|
||||
(void)fn(std::make_pair(first, next));
|
||||
|
||||
first = next;
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
} // ns util
|
||||
} // ns osrm
|
||||
|
||||
#endif
|
||||
@@ -65,6 +65,42 @@ mirrorDirectionModifier(const extractor::guidance::DirectionModifier::Enum modif
|
||||
return results[modifier];
|
||||
}
|
||||
|
||||
inline bool hasLeftModifier(const extractor::guidance::TurnInstruction instruction)
|
||||
{
|
||||
return instruction.direction_modifier == extractor::guidance::DirectionModifier::SharpLeft ||
|
||||
instruction.direction_modifier == extractor::guidance::DirectionModifier::Left ||
|
||||
instruction.direction_modifier == extractor::guidance::DirectionModifier::SlightLeft;
|
||||
}
|
||||
|
||||
inline bool hasRightModifier(const extractor::guidance::TurnInstruction instruction)
|
||||
{
|
||||
return instruction.direction_modifier == extractor::guidance::DirectionModifier::SharpRight ||
|
||||
instruction.direction_modifier == extractor::guidance::DirectionModifier::Right ||
|
||||
instruction.direction_modifier == extractor::guidance::DirectionModifier::SlightRight;
|
||||
}
|
||||
|
||||
inline bool isLeftTurn(const extractor::guidance::TurnInstruction instruction)
|
||||
{
|
||||
switch (instruction.type)
|
||||
{
|
||||
case extractor::guidance::TurnType::Merge:
|
||||
return hasRightModifier(instruction);
|
||||
default:
|
||||
return hasLeftModifier(instruction);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool isRightTurn(const extractor::guidance::TurnInstruction instruction)
|
||||
{
|
||||
switch (instruction.type)
|
||||
{
|
||||
case extractor::guidance::TurnType::Merge:
|
||||
return hasLeftModifier(instruction);
|
||||
default:
|
||||
return hasRightModifier(instruction);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace util
|
||||
} // namespace osrm
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#ifndef OSRM_UTIL_GUIDANCE_TURN_LANES_HPP
|
||||
#define OSRM_UTIL_GUIDANCE_TURN_LANES_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
class LaneTupel;
|
||||
} // namespace guidance
|
||||
} // namespace util
|
||||
} // namespace osrm
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <> struct hash<::osrm::util::guidance::LaneTupel>
|
||||
{
|
||||
inline std::size_t operator()(const ::osrm::util::guidance::LaneTupel &bearing_class) const;
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
// The mapping of turn lanes can be done two values. We describe every turn by the number of
|
||||
// contributing lanes and the first lane from the right..
|
||||
// Given a road like this:
|
||||
// | | |
|
||||
// | | |
|
||||
// ----------- |
|
||||
// -^ |
|
||||
// ----------- -------------
|
||||
// -^ ->
|
||||
// --------------------------------
|
||||
// -v |
|
||||
// ---------- |
|
||||
// | |
|
||||
//
|
||||
// we generate a set of tuples in the form of:
|
||||
// (2,1), (1,1), (1,0) for left, through and right respectively
|
||||
class LaneTupel
|
||||
{
|
||||
public:
|
||||
LaneTupel();
|
||||
LaneTupel(const LaneID lanes_in_turn, const LaneID first_lane_from_the_right);
|
||||
|
||||
bool operator==(const LaneTupel other) const;
|
||||
bool operator!=(const LaneTupel other) const;
|
||||
bool operator<(const LaneTupel other) const;
|
||||
|
||||
LaneID lanes_in_turn;
|
||||
LaneID first_lane_from_the_right;
|
||||
|
||||
friend std::size_t hash_value(const LaneTupel &tup)
|
||||
{
|
||||
std::size_t seed{0};
|
||||
boost::hash_combine(seed, tup.lanes_in_turn);
|
||||
boost::hash_combine(seed, tup.first_lane_from_the_right);
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
using LaneTupelIdPair = std::pair<util::guidance::LaneTupel, LaneDescriptionID>;
|
||||
} // namespace guidance
|
||||
} // namespace util
|
||||
} // namespace osrm
|
||||
|
||||
#endif /* OSRM_UTIL_GUIDANCE_TURN_LANES_HPP */
|
||||
@@ -4,12 +4,14 @@
|
||||
#include "util/simple_logger.hpp"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include <bitset>
|
||||
#include <fstream>
|
||||
#include <stxxl/vector>
|
||||
#include <vector>
|
||||
|
||||
#include "util/fingerprint.hpp"
|
||||
@@ -88,6 +90,84 @@ bool deserializeVector(std::istream &stream, std::vector<simple_type> &data)
|
||||
return static_cast<bool>(stream);
|
||||
}
|
||||
|
||||
// serializes a vector of vectors into an adjacency array (creates a copy of the data internally)
|
||||
template <typename simple_type>
|
||||
bool serializeVectorIntoAdjacencyArray(const std::string &filename,
|
||||
const std::vector<std::vector<simple_type>> &data)
|
||||
{
|
||||
std::ofstream out_stream(filename, std::ios::binary);
|
||||
std::vector<std::uint32_t> offsets;
|
||||
offsets.reserve(data.size() + 1);
|
||||
std::uint64_t current_offset = 0;
|
||||
offsets.push_back(current_offset);
|
||||
for (auto const &vec : data)
|
||||
{
|
||||
current_offset += vec.size();
|
||||
offsets.push_back(boost::numeric_cast<std::uint32_t>(current_offset));
|
||||
}
|
||||
if (!serializeVector(out_stream, offsets))
|
||||
return false;
|
||||
|
||||
std::vector<simple_type> all_data;
|
||||
all_data.reserve(offsets.back());
|
||||
for (auto const &vec : data)
|
||||
all_data.insert(all_data.end(), vec.begin(), vec.end());
|
||||
|
||||
if (!serializeVector(out_stream, all_data))
|
||||
return false;
|
||||
|
||||
return static_cast<bool>(out_stream);
|
||||
}
|
||||
|
||||
template <typename simple_type, std::size_t WRITE_BLOCK_BUFFER_SIZE = 1024>
|
||||
bool serializeVector(std::ofstream &out_stream, const stxxl::vector<simple_type> &data)
|
||||
{
|
||||
const std::uint64_t size = data.size();
|
||||
out_stream.write(reinterpret_cast<const char *>(&size), sizeof(size));
|
||||
|
||||
simple_type write_buffer[WRITE_BLOCK_BUFFER_SIZE];
|
||||
std::size_t buffer_len = 0;
|
||||
|
||||
for (const auto entry : data)
|
||||
{
|
||||
write_buffer[buffer_len++] = entry;
|
||||
|
||||
if (buffer_len >= WRITE_BLOCK_BUFFER_SIZE)
|
||||
{
|
||||
out_stream.write(reinterpret_cast<const char *>(write_buffer),
|
||||
WRITE_BLOCK_BUFFER_SIZE * sizeof(simple_type));
|
||||
buffer_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// write remaining entries
|
||||
if (buffer_len > 0)
|
||||
out_stream.write(reinterpret_cast<const char *>(write_buffer),
|
||||
buffer_len * sizeof(simple_type));
|
||||
|
||||
return static_cast<bool>(out_stream);
|
||||
}
|
||||
|
||||
template <typename simple_type>
|
||||
bool deserializeAdjacencyArray(const std::string &filename,
|
||||
std::vector<std::uint32_t> &offsets,
|
||||
std::vector<simple_type>& data)
|
||||
{
|
||||
std::ifstream in_stream(filename, std::ios::binary);
|
||||
|
||||
if (!deserializeVector(in_stream, offsets))
|
||||
return false;
|
||||
|
||||
if (!deserializeVector(in_stream, data))
|
||||
return false;
|
||||
|
||||
// offsets have to match up with the size of the data
|
||||
if (offsets.empty() || (offsets.back() != boost::numeric_cast<std::uint32_t>(data.size())))
|
||||
return false;
|
||||
|
||||
return static_cast<bool>(in_stream);
|
||||
}
|
||||
|
||||
inline bool serializeFlags(const boost::filesystem::path &path, const std::vector<bool> &flags)
|
||||
{
|
||||
// TODO this should be replaced with a FILE-based write using error checking
|
||||
|
||||
@@ -20,7 +20,8 @@ struct NodeBasedEdgeData
|
||||
NodeBasedEdgeData()
|
||||
: distance(INVALID_EDGE_WEIGHT), edge_id(SPECIAL_NODEID),
|
||||
name_id(std::numeric_limits<unsigned>::max()), access_restricted(false), reversed(false),
|
||||
roundabout(false), travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
||||
roundabout(false), travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
||||
lane_description_id(INVALID_LANE_DESCRIPTIONID)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -31,10 +32,11 @@ struct NodeBasedEdgeData
|
||||
bool reversed,
|
||||
bool roundabout,
|
||||
bool startpoint,
|
||||
extractor::TravelMode travel_mode)
|
||||
extractor::TravelMode travel_mode,
|
||||
const LaneDescriptionID lane_description_id)
|
||||
: distance(distance), edge_id(edge_id), name_id(name_id),
|
||||
access_restricted(access_restricted), reversed(reversed), roundabout(roundabout),
|
||||
startpoint(startpoint), travel_mode(travel_mode)
|
||||
startpoint(startpoint), travel_mode(travel_mode), lane_description_id(lane_description_id)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -46,6 +48,7 @@ struct NodeBasedEdgeData
|
||||
bool roundabout : 1;
|
||||
bool startpoint : 1;
|
||||
extractor::TravelMode travel_mode : 4;
|
||||
LaneDescriptionID lane_description_id;
|
||||
extractor::guidance::RoadClassificationData road_classification;
|
||||
|
||||
bool IsCompatibleTo(const NodeBasedEdgeData &other) const
|
||||
@@ -64,7 +67,7 @@ using NodeBasedDynamicGraph = DynamicGraph<NodeBasedEdgeData>;
|
||||
/// Since DynamicGraph expects directed edges, we need to insert
|
||||
/// two edges for undirected edges.
|
||||
inline std::shared_ptr<NodeBasedDynamicGraph>
|
||||
NodeBasedDynamicGraphFromEdges(std::size_t number_of_nodes,
|
||||
NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
||||
const std::vector<extractor::NodeBasedEdge> &input_edge_list)
|
||||
{
|
||||
auto edges_list = directedEdgesFromCompressed<NodeBasedDynamicGraph::InputEdge>(
|
||||
@@ -80,12 +83,12 @@ NodeBasedDynamicGraphFromEdges(std::size_t number_of_nodes,
|
||||
output_edge.data.travel_mode = input_edge.travel_mode;
|
||||
output_edge.data.startpoint = input_edge.startpoint;
|
||||
output_edge.data.road_classification = input_edge.road_classification;
|
||||
output_edge.data.lane_description_id = input_edge.lane_description_id;
|
||||
});
|
||||
|
||||
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
||||
|
||||
auto graph = std::make_shared<NodeBasedDynamicGraph>(
|
||||
static_cast<NodeBasedDynamicGraph::NodeIterator>(number_of_nodes), edges_list);
|
||||
auto graph = std::make_shared<NodeBasedDynamicGraph>(number_of_nodes, edges_list);
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ namespace osrm
|
||||
namespace util
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Since OSM node IDs are (at the time of writing) not quite yet overflowing 32 bits, and
|
||||
* will predictably be containable within 33 bits for a long time, the following packs
|
||||
@@ -21,16 +20,16 @@ namespace util
|
||||
* NOTE: this type is templated for future use, but will require a slight refactor to
|
||||
* configure BITSIZE and ELEMSIZE
|
||||
*/
|
||||
template <typename T, bool UseSharedMemory=false> class PackedVector
|
||||
template <typename T, bool UseSharedMemory = false> class PackedVector
|
||||
{
|
||||
static const constexpr std::size_t BITSIZE = 33;
|
||||
static const constexpr std::size_t ELEMSIZE = 64;
|
||||
static const constexpr std::size_t PACKSIZE = BITSIZE * ELEMSIZE;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Returns the size of the packed vector datastructure with `elements` packed elements (the size of
|
||||
* Returns the size of the packed vector datastructure with `elements` packed elements (the size
|
||||
* of
|
||||
* its underlying uint64 vector)
|
||||
*/
|
||||
inline static std::size_t elements_to_blocks(std::size_t elements)
|
||||
@@ -96,14 +95,14 @@ template <typename T, bool UseSharedMemory=false> class PackedVector
|
||||
if (left_index == 0)
|
||||
{
|
||||
// ID is at the far left side of this element
|
||||
return static_cast<T>(elem >> (ELEMSIZE - BITSIZE));
|
||||
return T{elem >> (ELEMSIZE - BITSIZE)};
|
||||
}
|
||||
else if (left_index >= BITSIZE)
|
||||
{
|
||||
// ID is entirely contained within this element
|
||||
const std::uint64_t at_right = elem >> (left_index - BITSIZE);
|
||||
const std::uint64_t left_mask = static_cast<std::uint64_t>(pow(2, BITSIZE)) - 1;
|
||||
return static_cast<T>(at_right & left_mask);
|
||||
return T{at_right & left_mask};
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -115,7 +114,7 @@ template <typename T, bool UseSharedMemory=false> class PackedVector
|
||||
const std::uint64_t next_elem = static_cast<std::uint64_t>(vec.at(index + 1));
|
||||
|
||||
const std::uint64_t right_side = next_elem >> (ELEMSIZE - (BITSIZE - left_index));
|
||||
return static_cast<T>(left_side | right_side);
|
||||
return T{left_side | right_side};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-14
@@ -23,10 +23,10 @@ namespace util
|
||||
struct RectangleInt2D
|
||||
{
|
||||
RectangleInt2D()
|
||||
: min_lon(std::numeric_limits<std::int32_t>::max()),
|
||||
max_lon(std::numeric_limits<std::int32_t>::min()),
|
||||
min_lat(std::numeric_limits<std::int32_t>::max()),
|
||||
max_lat(std::numeric_limits<std::int32_t>::min())
|
||||
: min_lon{std::numeric_limits<std::int32_t>::max()},
|
||||
max_lon{std::numeric_limits<std::int32_t>::min()},
|
||||
min_lat{std::numeric_limits<std::int32_t>::max()},
|
||||
max_lat{std::numeric_limits<std::int32_t>::min()}
|
||||
{
|
||||
}
|
||||
|
||||
@@ -56,10 +56,10 @@ struct RectangleInt2D
|
||||
max_lon = std::max(max_lon, other.max_lon);
|
||||
min_lat = std::min(min_lat, other.min_lat);
|
||||
max_lat = std::max(max_lat, other.max_lat);
|
||||
BOOST_ASSERT(min_lon != FixedLongitude(std::numeric_limits<std::int32_t>::min()));
|
||||
BOOST_ASSERT(min_lat != FixedLatitude(std::numeric_limits<std::int32_t>::min()));
|
||||
BOOST_ASSERT(max_lon != FixedLongitude(std::numeric_limits<std::int32_t>::min()));
|
||||
BOOST_ASSERT(max_lat != FixedLatitude(std::numeric_limits<std::int32_t>::min()));
|
||||
BOOST_ASSERT(min_lon != FixedLongitude{std::numeric_limits<std::int32_t>::min()});
|
||||
BOOST_ASSERT(min_lat != FixedLatitude{std::numeric_limits<std::int32_t>::min()});
|
||||
BOOST_ASSERT(max_lon != FixedLongitude{std::numeric_limits<std::int32_t>::min()});
|
||||
BOOST_ASSERT(max_lat != FixedLatitude{std::numeric_limits<std::int32_t>::min()});
|
||||
}
|
||||
|
||||
Coordinate Centroid() const
|
||||
@@ -67,8 +67,8 @@ struct RectangleInt2D
|
||||
Coordinate centroid;
|
||||
// The coordinates of the midpoints are given by:
|
||||
// x = (x1 + x2) /2 and y = (y1 + y2) /2.
|
||||
centroid.lon = (min_lon + max_lon) / FixedLongitude(2);
|
||||
centroid.lat = (min_lat + max_lat) / FixedLatitude(2);
|
||||
centroid.lon = (min_lon + max_lon) / FixedLongitude{2};
|
||||
centroid.lat = (min_lat + max_lat) / FixedLatitude{2};
|
||||
return centroid;
|
||||
}
|
||||
|
||||
@@ -169,10 +169,10 @@ struct RectangleInt2D
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return min_lon != FixedLongitude(std::numeric_limits<std::int32_t>::max()) &&
|
||||
max_lon != FixedLongitude(std::numeric_limits<std::int32_t>::min()) &&
|
||||
min_lat != FixedLatitude(std::numeric_limits<std::int32_t>::max()) &&
|
||||
max_lat != FixedLatitude(std::numeric_limits<std::int32_t>::min());
|
||||
return min_lon != FixedLongitude{std::numeric_limits<std::int32_t>::max()} &&
|
||||
max_lon != FixedLongitude{std::numeric_limits<std::int32_t>::min()} &&
|
||||
min_lat != FixedLatitude{std::numeric_limits<std::int32_t>::max()} &&
|
||||
max_lat != FixedLatitude{std::numeric_limits<std::int32_t>::min()};
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &out, const RectangleInt2D &rect);
|
||||
|
||||
@@ -193,8 +193,8 @@ class StaticRTree
|
||||
Coordinate current_centroid = coordinate_calculation::centroid(
|
||||
m_coordinate_list[current_element.u], m_coordinate_list[current_element.v]);
|
||||
current_centroid.lat =
|
||||
FixedLatitude(COORDINATE_PRECISION *
|
||||
web_mercator::latToY(toFloating(current_centroid.lat)));
|
||||
FixedLatitude{static_cast<std::int32_t>(COORDINATE_PRECISION *
|
||||
web_mercator::latToY(toFloating(current_centroid.lat)))};
|
||||
|
||||
current_wrapper.m_hilbert_value = hilbertCode(current_centroid);
|
||||
}
|
||||
|
||||
@@ -40,32 +40,32 @@ namespace osrm
|
||||
* etc. Also clarifies what this random "int" value is
|
||||
* being used for.
|
||||
*/
|
||||
#define OSRM_STRONG_TYPEDEF(From, To) \
|
||||
class To final \
|
||||
{ \
|
||||
static_assert(std::is_arithmetic<From>(), ""); \
|
||||
From x; \
|
||||
friend std::ostream &operator<<(std::ostream &stream, const To &inst); \
|
||||
\
|
||||
public: \
|
||||
To() = default; \
|
||||
explicit To(const From x_) : x(x_) {} \
|
||||
explicit operator From &() { return x; } \
|
||||
explicit operator From() const { return x; } \
|
||||
To operator+(const To rhs_) const { return To(x + static_cast<const From>(rhs_)); } \
|
||||
To operator-(const To rhs_) const { return To(x - static_cast<const From>(rhs_)); } \
|
||||
To operator*(const To rhs_) const { return To(x * static_cast<const From>(rhs_)); } \
|
||||
To operator/(const To rhs_) const { return To(x / static_cast<const From>(rhs_)); } \
|
||||
bool operator<(const To z_) const { return x < static_cast<const From>(z_); } \
|
||||
bool operator>(const To z_) const { return x > static_cast<const From>(z_); } \
|
||||
bool operator<=(const To z_) const { return x <= static_cast<const From>(z_); } \
|
||||
bool operator>=(const To z_) const { return x >= static_cast<const From>(z_); } \
|
||||
bool operator==(const To z_) const { return x == static_cast<const From>(z_); } \
|
||||
bool operator!=(const To z_) const { return x != static_cast<const From>(z_); } \
|
||||
}; \
|
||||
inline std::ostream &operator<<(std::ostream &stream, const To &inst) \
|
||||
{ \
|
||||
return stream << inst.x; \
|
||||
#define OSRM_STRONG_TYPEDEF(From, To) \
|
||||
struct To final \
|
||||
{ \
|
||||
static_assert(std::is_arithmetic<From>(), ""); \
|
||||
From __value; \
|
||||
friend std::ostream &operator<<(std::ostream &stream, const To &inst); \
|
||||
\
|
||||
explicit operator From &() { return __value; } \
|
||||
explicit operator From() const { return __value; } \
|
||||
To operator+(const To rhs_) const { return To{__value + static_cast<const From>(rhs_)}; } \
|
||||
To operator-(const To rhs_) const { return To{__value - static_cast<const From>(rhs_)}; } \
|
||||
To operator*(const To rhs_) const { return To{__value * static_cast<const From>(rhs_)}; } \
|
||||
To operator/(const To rhs_) const { return To{__value / static_cast<const From>(rhs_)}; } \
|
||||
bool operator<(const To z_) const { return __value < static_cast<const From>(z_); } \
|
||||
bool operator>(const To z_) const { return __value > static_cast<const From>(z_); } \
|
||||
bool operator<=(const To z_) const { return __value <= static_cast<const From>(z_); } \
|
||||
bool operator>=(const To z_) const { return __value >= static_cast<const From>(z_); } \
|
||||
bool operator==(const To z_) const { return __value == static_cast<const From>(z_); } \
|
||||
bool operator!=(const To z_) const { return __value != static_cast<const From>(z_); } \
|
||||
}; \
|
||||
static_assert(std::is_trivial<To>(), #To " is not a trivial type"); \
|
||||
static_assert(std::is_standard_layout<To>(), #To " is not a standart layout"); \
|
||||
static_assert(std::is_pod<To>(), #To " is not a POD layout"); \
|
||||
inline std::ostream &operator<<(std::ostream &stream, const To &inst) \
|
||||
{ \
|
||||
return stream << inst.__value; \
|
||||
}
|
||||
|
||||
#define OSRM_STRONG_TYPEDEF_HASHABLE(From, To) \
|
||||
|
||||
+24
-17
@@ -43,37 +43,44 @@ OSRM_STRONG_TYPEDEF_HASHABLE(std::uint64_t, OSMNodeID)
|
||||
OSRM_STRONG_TYPEDEF(std::uint32_t, OSMWayID)
|
||||
OSRM_STRONG_TYPEDEF_HASHABLE(std::uint32_t, OSMWayID)
|
||||
|
||||
static const OSMNodeID SPECIAL_OSM_NODEID = OSMNodeID(std::numeric_limits<std::uint64_t>::max());
|
||||
static const OSMWayID SPECIAL_OSM_WAYID = OSMWayID(std::numeric_limits<std::uint32_t>::max());
|
||||
static const OSMNodeID SPECIAL_OSM_NODEID = OSMNodeID{std::numeric_limits<std::uint64_t>::max()};
|
||||
static const OSMWayID SPECIAL_OSM_WAYID = OSMWayID{std::numeric_limits<std::uint32_t>::max()};
|
||||
|
||||
static const OSMNodeID MAX_OSM_NODEID = OSMNodeID(std::numeric_limits<std::uint64_t>::max());
|
||||
static const OSMNodeID MIN_OSM_NODEID = OSMNodeID(std::numeric_limits<std::uint64_t>::min());
|
||||
static const OSMWayID MAX_OSM_WAYID = OSMWayID(std::numeric_limits<std::uint32_t>::max());
|
||||
static const OSMWayID MIN_OSM_WAYID = OSMWayID(std::numeric_limits<std::uint32_t>::min());
|
||||
static const OSMNodeID MAX_OSM_NODEID = OSMNodeID{std::numeric_limits<std::uint64_t>::max()};
|
||||
static const OSMNodeID MIN_OSM_NODEID = OSMNodeID{std::numeric_limits<std::uint64_t>::min()};
|
||||
static const OSMWayID MAX_OSM_WAYID = OSMWayID{std::numeric_limits<std::uint32_t>::max()};
|
||||
static const OSMWayID MIN_OSM_WAYID = OSMWayID{std::numeric_limits<std::uint32_t>::min()};
|
||||
|
||||
using OSMNodeID_weak = std::uint64_t;
|
||||
using OSMEdgeID_weak = std::uint64_t;
|
||||
|
||||
using NodeID = unsigned int;
|
||||
using EdgeID = unsigned int;
|
||||
using NodeID = std::uint32_t;
|
||||
using EdgeID = std::uint32_t;
|
||||
using NameID = std::uint32_t;
|
||||
using EdgeWeight = int;
|
||||
using EdgeWeight = std::int32_t;
|
||||
|
||||
using LaneID = std::uint8_t;
|
||||
static const LaneID INVALID_LANEID = std::numeric_limits<LaneID>::max();
|
||||
using LaneDataID = std::uint16_t;
|
||||
static const LaneDataID INVALID_LANE_DATAID = std::numeric_limits<LaneDataID>::max();
|
||||
using LaneDescriptionID = std::uint16_t;
|
||||
static const LaneDescriptionID INVALID_LANE_DESCRIPTIONID = std::numeric_limits<LaneDescriptionID>::max();
|
||||
|
||||
using BearingClassID = std::uint32_t;
|
||||
static const BearingClassID INVALID_BEARING_CLASSID = std::numeric_limits<std::uint32_t>::max();
|
||||
static const BearingClassID INVALID_BEARING_CLASSID = std::numeric_limits<BearingClassID>::max();
|
||||
|
||||
using DiscreteBearing = std::uint16_t;
|
||||
|
||||
using EntryClassID = std::uint16_t;
|
||||
static const EntryClassID INVALID_ENTRY_CLASSID = std::numeric_limits<std::uint16_t>::max();
|
||||
static const EntryClassID INVALID_ENTRY_CLASSID = std::numeric_limits<EntryClassID>::max();
|
||||
|
||||
static const NodeID SPECIAL_NODEID = std::numeric_limits<unsigned>::max();
|
||||
static const NodeID SPECIAL_SEGMENTID = std::numeric_limits<int>::max();
|
||||
static const EdgeID SPECIAL_EDGEID = std::numeric_limits<unsigned>::max();
|
||||
static const unsigned INVALID_NAMEID = std::numeric_limits<unsigned>::max();
|
||||
static const unsigned EMPTY_NAMEID = 0;
|
||||
static const NodeID SPECIAL_NODEID = std::numeric_limits<NodeID>::max();
|
||||
static const NodeID SPECIAL_SEGMENTID = std::numeric_limits<NodeID>::max() >> 1;
|
||||
static const EdgeID SPECIAL_EDGEID = std::numeric_limits<EdgeID>::max();
|
||||
static const NameID INVALID_NAMEID = std::numeric_limits<NameID>::max();
|
||||
static const NameID EMPTY_NAMEID = 0;
|
||||
static const unsigned INVALID_COMPONENTID = 0;
|
||||
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<int>::max();
|
||||
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<EdgeWeight>::max();
|
||||
|
||||
struct SegmentID
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ inline FloatLatitude yToLat(const double y)
|
||||
const double normalized_lat =
|
||||
detail::RAD_TO_DEGREE * 2. * std::atan(std::exp(clamped_y * detail::DEGREE_TO_RAD));
|
||||
|
||||
return FloatLatitude(normalized_lat - 90.);
|
||||
return FloatLatitude{normalized_lat - 90.};
|
||||
}
|
||||
|
||||
inline double latToY(const FloatLatitude latitude)
|
||||
@@ -56,7 +56,7 @@ template <typename T, typename... U> constexpr double horner(double x, T an, U..
|
||||
|
||||
inline double latToYapprox(const FloatLatitude latitude)
|
||||
{
|
||||
if (latitude < FloatLatitude(-70.) || latitude > FloatLatitude(70.))
|
||||
if (latitude < FloatLatitude{-70.} || latitude > FloatLatitude{70.})
|
||||
return latToY(latitude);
|
||||
|
||||
// Approximate the inverse Gudermannian function with the Padé approximant [11/11]: deg → deg
|
||||
@@ -93,14 +93,14 @@ inline double latToYapprox(const FloatLatitude latitude)
|
||||
|
||||
inline FloatLatitude clamp(const FloatLatitude lat)
|
||||
{
|
||||
return std::max(std::min(lat, FloatLatitude(detail::MAX_LATITUDE)),
|
||||
FloatLatitude(-detail::MAX_LATITUDE));
|
||||
return std::max(std::min(lat, FloatLatitude{detail::MAX_LATITUDE}),
|
||||
FloatLatitude{-detail::MAX_LATITUDE});
|
||||
}
|
||||
|
||||
inline FloatLongitude clamp(const FloatLongitude lon)
|
||||
{
|
||||
return std::max(std::min(lon, FloatLongitude(detail::MAX_LONGITUDE)),
|
||||
FloatLongitude(-detail::MAX_LONGITUDE));
|
||||
return std::max(std::min(lon, FloatLongitude{detail::MAX_LONGITUDE}),
|
||||
FloatLongitude{-detail::MAX_LONGITUDE});
|
||||
}
|
||||
|
||||
inline void pixelToDegree(const double shift, double &x, double &y)
|
||||
@@ -159,10 +159,10 @@ inline void xyzToMercator(
|
||||
{
|
||||
xyzToWGS84(x, y, z, minx, miny, maxx, maxy);
|
||||
|
||||
minx = static_cast<double>(clamp(util::FloatLongitude(minx))) * DEGREE_TO_PX;
|
||||
miny = latToY(clamp(util::FloatLatitude(miny))) * DEGREE_TO_PX;
|
||||
maxx = static_cast<double>(clamp(util::FloatLongitude(maxx))) * DEGREE_TO_PX;
|
||||
maxy = latToY(clamp(util::FloatLatitude(maxy))) * DEGREE_TO_PX;
|
||||
minx = static_cast<double>(clamp(util::FloatLongitude{minx})) * DEGREE_TO_PX;
|
||||
miny = latToY(clamp(util::FloatLatitude{miny})) * DEGREE_TO_PX;
|
||||
maxx = static_cast<double>(clamp(util::FloatLongitude{maxx})) * DEGREE_TO_PX;
|
||||
maxy = latToY(clamp(util::FloatLatitude{maxy})) * DEGREE_TO_PX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -9,7 +9,8 @@
|
||||
"node-timeout": "0.0.4",
|
||||
"request": "^2.69.0",
|
||||
"xmlbuilder": "^4.2.1",
|
||||
"chalk": "^1.1.3"
|
||||
"chalk": "^1.1.3",
|
||||
"polyline": "^0.2.0"
|
||||
},
|
||||
"bin": {
|
||||
"cucumber": "./node_modules/cucumber/bin/cucumber.js"
|
||||
|
||||
+6
-12
@@ -207,7 +207,6 @@ function way_function (way, result)
|
||||
local foot = way:get_value_by_key("foot")
|
||||
local foot_forward = way:get_value_by_key("foot:forward")
|
||||
local foot_backward = way:get_value_by_key("foot:backward")
|
||||
local surface = way:get_value_by_key("surface")
|
||||
local bicycle = way:get_value_by_key("bicycle")
|
||||
|
||||
-- name
|
||||
@@ -385,17 +384,12 @@ function way_function (way, result)
|
||||
result.backward_speed = walking_speed
|
||||
end
|
||||
|
||||
-- surfaces
|
||||
if surface then
|
||||
surface_speed = surface_speeds[surface]
|
||||
if surface_speed then
|
||||
if result.forward_speed > 0 then
|
||||
result.forward_speed = surface_speed
|
||||
end
|
||||
if result.backward_speed > 0 then
|
||||
result.backward_speed = surface_speed
|
||||
end
|
||||
end
|
||||
-- reduce speed on bad surfaces
|
||||
local surface = way:get_value_by_key("surface")
|
||||
|
||||
if surface and surface_speeds[surface] then
|
||||
result.forward_speed = math.min(surface_speeds[surface], result.forward_speed)
|
||||
result.backward_speed = math.min(surface_speeds[surface], result.backward_speed)
|
||||
end
|
||||
|
||||
-- maxspeed
|
||||
|
||||
@@ -166,6 +166,56 @@ function get_exceptions(vector)
|
||||
end
|
||||
end
|
||||
|
||||
-- returns forward,backward psv lane count
|
||||
local function getPSVCounts(way)
|
||||
local psv = way:get_value_by_key("lanes:psv")
|
||||
local psv_forward = way:get_value_by_key("lanes:psv:forward");
|
||||
local psv_backward = way:get_value_by_key("lanes:psv:backward");
|
||||
|
||||
local fw = 0;
|
||||
local bw = 0;
|
||||
if( psv and psv ~= "" ) then
|
||||
fw = tonumber(psv)
|
||||
if( fw == nil ) then
|
||||
fw = 0
|
||||
end
|
||||
end
|
||||
if( psv_forward and psv_forward ~= "" ) then
|
||||
fw = tonumber(psv_forward)
|
||||
if( fw == nil ) then
|
||||
fw = 0
|
||||
end
|
||||
end
|
||||
if( psv_backward and psv_backward ~= "" ) then
|
||||
bw = tonumber(psv_backward);
|
||||
if( bw == nil ) then
|
||||
fw = 0
|
||||
end
|
||||
end
|
||||
return fw, bw
|
||||
end
|
||||
|
||||
-- this is broken for left-sided driving. It needs to switch left and right in case of left-sided driving
|
||||
local function getTurnLanes(way)
|
||||
local fw_psv = 0
|
||||
local bw_psv = 0
|
||||
fw_psv, bw_psv = getPSVCounts(way)
|
||||
|
||||
local turn_lanes = way:get_value_by_key("turn:lanes")
|
||||
local turn_lanes_fw = way:get_value_by_key("turn:lanes:forward")
|
||||
local turn_lanes_bw = way:get_value_by_key("turn:lanes:backward")
|
||||
|
||||
if( fw_psv ~= 0 or bw_psv ~= 0 ) then
|
||||
turn_lanes = trimLaneString(turn_lanes, bw_psv, fw_psv )
|
||||
turn_lanes_fw = trimLaneString(turn_lanes_fw, bw_psv, fw_psv )
|
||||
--backwards turn lanes need to treat bw_psv as fw_psv and vice versa
|
||||
turn_lanes_bw = trimLaneString(turn_lanes_bw, fw_psv, bw_psv )
|
||||
end
|
||||
|
||||
return turn_lanes, turn_lanes_fw, turn_lanes_bw
|
||||
end
|
||||
|
||||
|
||||
local function parse_maxspeed(source)
|
||||
if not source then
|
||||
return 0
|
||||
@@ -372,6 +422,25 @@ function way_function (way, result)
|
||||
result.pronunciation = pronunciation
|
||||
end
|
||||
|
||||
local turn_lanes = ""
|
||||
local turn_lanes_forward = ""
|
||||
local turn_lanes_backward = ""
|
||||
|
||||
turn_lanes, turn_lanes_forward, turn_lanes_backward = getTurnLanes(way)
|
||||
if( turn_lanes ~= "" ) then
|
||||
result.turn_lanes_forward = turn_lanes;
|
||||
result.turn_lanes_backward = turn_lanes;
|
||||
else
|
||||
if( turn_lanes_forward ~= "" ) then
|
||||
result.turn_lanes_forward = turn_lanes_forward;
|
||||
end
|
||||
|
||||
if( turn_lanes_backward ~= "" ) then
|
||||
result.turn_lanes_backward = turn_lanes_backward;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if junction and "roundabout" == junction then
|
||||
result.roundabout = true
|
||||
end
|
||||
|
||||
@@ -57,6 +57,7 @@ function way_function (way, result)
|
||||
if name then
|
||||
result.name = name
|
||||
end
|
||||
|
||||
result.forward_mode = mode.driving
|
||||
result.backward_mode = mode.driving
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user