Compare commits
158 Commits
v5.14.3
...
v5.16.0-rc.6
| Author | SHA1 | Date | |
|---|---|---|---|
| a2c7f82ec8 | |||
| be49ed3e91 | |||
| 6763d4c097 | |||
| 6d2860e909 | |||
| d2764bc405 | |||
| 005a146223 | |||
| 02754647f4 | |||
| 82cebfa1f8 | |||
| 986bb6f93d | |||
| 0c0ab78f13 | |||
| 99cda66b58 | |||
| 27fa2fc1d0 | |||
| 7434f18d04 | |||
| 7d1a12a12d | |||
| 6d7420e4e5 | |||
| 8a44660102 | |||
| 0da2029d2d | |||
| e82b51d0cb | |||
| 5531cace7f | |||
| 1aed13500d | |||
| f6db8ff3b0 | |||
| 26e5c4eae2 | |||
| bee3bdb576 | |||
| b96d36f482 | |||
| d13d6566f8 | |||
| aa1048154c | |||
| 6c2d26f9bd | |||
| 84845ffaa6 | |||
| f65958fc14 | |||
| 3d6b667997 | |||
| 97d027a173 | |||
| f48dd665ad | |||
| eb1e83858a | |||
| 371dc57dfc | |||
| 425a46fe78 | |||
| fa553659de | |||
| 03cffd0f56 | |||
| a06d1782c0 | |||
| 05f6b55036 | |||
| fa8d788bb6 | |||
| 92b7d581ce | |||
| 19651c3d91 | |||
| b4cfc8d6e0 | |||
| 71cfb03738 | |||
| e7bb612050 | |||
| 83d7a57b73 | |||
| cac310123b | |||
| bb71d9b28a | |||
| ea4d0fa1dd | |||
| 91561992a7 | |||
| a3ea825a11 | |||
| 7ebbd5cebe | |||
| 9e93f198ae | |||
| 10de243556 | |||
| 988b6e3311 | |||
| 36877e4de5 | |||
| 1794185d43 | |||
| de938df560 | |||
| e02c5c3c6d | |||
| 90ff725125 | |||
| 1cbfbd34cf | |||
| c6d12e064c | |||
| 30ed1fae99 | |||
| 2987292cc0 | |||
| 8114104a43 | |||
| 03f598b93d | |||
| 5a844f4b7d | |||
| 91e6d68604 | |||
| 1119a542d6 | |||
| d706696179 | |||
| c154875272 | |||
| 77f8a4f741 | |||
| 61e06fcaba | |||
| 13bb997525 | |||
| 350bc6f756 | |||
| 02712cd513 | |||
| a9d94d35a2 | |||
| 155772f01f | |||
| 341a5345da | |||
| 72de59ac91 | |||
| a7f1cd36fb | |||
| 26f0b4dc77 | |||
| 181eff29c7 | |||
| cdad265d49 | |||
| 6eb4247484 | |||
| 72a23645a8 | |||
| c3e06356d6 | |||
| 7a8390e68e | |||
| 168e313f73 | |||
| 30f910e861 | |||
| e998c1193d | |||
| a8f3474996 | |||
| 55cc06fd8b | |||
| 8883d8cc56 | |||
| 5b2af6ef09 | |||
| 6d801e7086 | |||
| 17eb7052ba | |||
| 330f25eddb | |||
| 08b88bad63 | |||
| 153f9b02a5 | |||
| 0568dca4a3 | |||
| 60ef179d18 | |||
| c64904f5ea | |||
| 4b9e3a8068 | |||
| db7c76d04d | |||
| cc1a5ea78d | |||
| 9c033ff461 | |||
| 3c3322173c | |||
| e805f85407 | |||
| 4d54456f66 | |||
| 7359d0542f | |||
| da4fb13aa3 | |||
| 3649ab4d31 | |||
| 9e9e3fb1e4 | |||
| e73aa01725 | |||
| a5353c7179 | |||
| a5e0d7011b | |||
| 742c32d936 | |||
| 3dec680058 | |||
| 9237430be2 | |||
| 12d1d84b11 | |||
| 6dd029e6ea | |||
| e45d44cb8e | |||
| 84b6ef4340 | |||
| 5af776d963 | |||
| ddf11cc2cc | |||
| c7b1d0c131 | |||
| 423a4ef326 | |||
| ccfbce5300 | |||
| b99d3a0a69 | |||
| 659b470320 | |||
| 9a8ed30e95 | |||
| 4166b1ebbf | |||
| 89080fb2b0 | |||
| 56459d37d1 | |||
| d5232d5f5c | |||
| 3f7b5da683 | |||
| 24562acd30 | |||
| 8bce061691 | |||
| 701c5f853d | |||
| d1e4ba373a | |||
| 8cf8f0d7d6 | |||
| 978350c388 | |||
| 2e97c78181 | |||
| 979ec7fa78 | |||
| 1d7f179374 | |||
| 994fae0ef6 | |||
| 88ee51ba2e | |||
| 25ee26de3b | |||
| 353829a4cc | |||
| 6fd0b56e32 | |||
| c1efefae27 | |||
| 0c96f093ff | |||
| 6f835d57b4 | |||
| e1e53d274b | |||
| d9a03f8365 | |||
| ce5f284ec6 | |||
| 02a2d25a3f |
@@ -2,12 +2,18 @@
|
||||
|
||||
What issue is this PR targeting? If there is no issue that addresses the problem, please open a corresponding issue and link it here.
|
||||
|
||||
Please read our [documentation](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/releasing.md) on release and version management.
|
||||
If your PR is still work in progress please attach the relevant label.
|
||||
|
||||
## Tasklist
|
||||
- [ ] ADD OWN TASKS HERE
|
||||
|
||||
- [ ] CHANGELOG.md entry ([How to write a changelog entry](http://keepachangelog.com/en/1.0.0/#how))
|
||||
- [ ] update relevant [Wiki pages](https://github.com/Project-OSRM/osrm-backend/wiki)
|
||||
- [ ] add regression / cucumber cases (see docs/testing.md)
|
||||
- [ ] add tests (see [testing documentation](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/testing.md)
|
||||
- [ ] review
|
||||
- [ ] adjust for comments
|
||||
- [ ] cherry pick to release branch
|
||||
|
||||
## Requirements / Relations
|
||||
|
||||
Link any requirements here. Other pull requests this PR is based on?
|
||||
|
||||
+58
-115
@@ -13,6 +13,7 @@ notifications:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- "5.16"
|
||||
# enable building tags
|
||||
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||
|
||||
@@ -64,12 +65,12 @@ matrix:
|
||||
after_success:
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-6-debug-cov"
|
||||
addons: &gcc6
|
||||
compiler: "gcc-7-debug-cov"
|
||||
addons: &gcc7
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev', 'lcov']
|
||||
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Debug' ENABLE_COVERAGE=ON CUCUMBER_TIMEOUT=20000
|
||||
packages: ['g++-7', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libboost-all-dev', 'lcov']
|
||||
env: CCOMPILER='gcc-7' CXXCOMPILER='g++-7' BUILD_TYPE='Debug' ENABLE_COVERAGE=ON CUCUMBER_TIMEOUT=20000
|
||||
before_script:
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- lcov --directory . --zerocounters # clean cached da files
|
||||
@@ -83,20 +84,20 @@ matrix:
|
||||
- bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-6-debug-asan"
|
||||
addons: &gcc6
|
||||
compiler: "gcc-7-debug-asan"
|
||||
addons: &gcc7
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Debug' TARGET_ARCH='x86_64-asan' ENABLE_SANITIZER=ON CUCUMBER_TIMEOUT=20000 LSAN_OPTIONS="suppressions=$TRAVIS_BUILD_DIR/scripts/travis/leaksanitizer.conf"
|
||||
packages: ['g++-7', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-7' CXXCOMPILER='g++-7' BUILD_TYPE='Debug' TARGET_ARCH='x86_64-asan' ENABLE_SANITIZER=ON CUCUMBER_TIMEOUT=20000 LSAN_OPTIONS="suppressions=$TRAVIS_BUILD_DIR/scripts/travis/leaksanitizer.conf"
|
||||
|
||||
- os: linux
|
||||
compiler: "clang-4.0-debug"
|
||||
addons: &clang40
|
||||
compiler: "clang-5.0-debug"
|
||||
addons: &clang50
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-5-dev', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' CUCUMBER_TIMEOUT=60000
|
||||
packages: ['libstdc++-5-dev', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libboost-all-dev']
|
||||
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' CUCUMBER_TIMEOUT=60000
|
||||
|
||||
- os: linux
|
||||
compiler: "mason-linux-debug-asan"
|
||||
@@ -104,7 +105,7 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-4.9-dev']
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_SANITIZER=ON LSAN_OPTIONS="suppressions=$TRAVIS_BUILD_DIR/scripts/travis/leaksanitizer.conf"
|
||||
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_SANITIZER=ON LSAN_OPTIONS="suppressions=$TRAVIS_BUILD_DIR/scripts/travis/leaksanitizer.conf"
|
||||
|
||||
# Release Builds
|
||||
- os: linux
|
||||
@@ -113,80 +114,70 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-4.9-dev']
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON RUN_CLANG_FORMAT=ON ENABLE_LTO=ON
|
||||
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON RUN_CLANG_FORMAT=ON ENABLE_LTO=ON
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-6-release"
|
||||
addons: &gcc6
|
||||
compiler: "gcc-7-release"
|
||||
addons: &gcc7
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release'
|
||||
packages: ['g++-7', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-7' CXXCOMPILER='g++-7' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-6-release-i686"
|
||||
compiler: "gcc-7-release-i686"
|
||||
env: >
|
||||
TARGET_ARCH='i686' CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release'
|
||||
TARGET_ARCH='i686' CCOMPILER='gcc-7' CXXCOMPILER='g++-7' BUILD_TYPE='Release'
|
||||
CFLAGS='-m32 -msse2 -mfpmath=sse' CXXFLAGS='-m32 -msse2 -mfpmath=sse'
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-6-stxxl"
|
||||
addons: &gcc6
|
||||
compiler: "gcc-7-stxxl"
|
||||
addons: &gcc7
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libstxxl-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' ENABLE_STXXL=On
|
||||
packages: ['g++-7', 'libbz2-dev', 'libstxxl-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-7' CXXCOMPILER='g++-7' BUILD_TYPE='Release' ENABLE_STXXL=On
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-4.9-release"
|
||||
compiler: "gcc-5-release"
|
||||
addons: &gcc49
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.9', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='gcc-4.9' CXXCOMPILER='g++-4.9' BUILD_TYPE='Release'
|
||||
packages: ['g++-5', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-6-release"
|
||||
addons: &gcc49
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release'
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode8.2
|
||||
compiler: "mason-osx-release"
|
||||
osx_image: xcode9.2
|
||||
compiler: "mason-osx-release-node-8"
|
||||
# we use the xcode provides clang and don't install our own
|
||||
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="8"
|
||||
after_success:
|
||||
- ./scripts/travis/publish.sh
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode9.2
|
||||
compiler: "mason-osx-release-node-4"
|
||||
# we use the xcode provides clang and don't install our own
|
||||
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="4"
|
||||
after_success:
|
||||
- ./scripts/travis/publish.sh
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode8.2
|
||||
compiler: "mason-osx-release"
|
||||
# we use the xcode provides clang and don't install our own
|
||||
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="6"
|
||||
after_success:
|
||||
- ./scripts/travis/publish.sh
|
||||
|
||||
# Disabled because of CI slowness
|
||||
#- os: linux
|
||||
#- compiler: clang
|
||||
#- addons: &clang40
|
||||
#- apt:
|
||||
#- sources: ['llvm-toolchain-trusty-4.0', 'ubuntu-toolchain-r-test']
|
||||
#- packages: ['clang-4.0', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
#- env: CCOMPILER='clang-4.0' CXXCOMPILER='clang++-4.0' BUILD_TYPE='Release'
|
||||
|
||||
# Shared Library
|
||||
- os: linux
|
||||
compiler: "gcc-6-release-shared"
|
||||
addons: &gcc6
|
||||
compiler: "gcc-7-release-shared"
|
||||
addons: &gcc7
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
|
||||
# Disabled because CI slowness
|
||||
#- os: linux
|
||||
#- compiler: clang
|
||||
#- addons: &clang40
|
||||
#- apt:
|
||||
#- sources: ['llvm-toolchain-trusty-4.0', 'ubuntu-toolchain-r-test']
|
||||
#- packages: ['clang-4.0', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libgdal-dev', 'libboost-all-dev']
|
||||
#- env: CCOMPILER='clang-4.0' CXXCOMPILER='clang++-4.0' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
packages: ['g++-7', 'libbz2-dev', 'libxml2-dev', 'libzip-dev', 'liblua5.2-dev', 'libtbb-dev', 'libboost-all-dev']
|
||||
env: CCOMPILER='gcc-7' CXXCOMPILER='g++-7' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
|
||||
# Node build jobs. These skip running the tests.
|
||||
- os: linux
|
||||
@@ -196,7 +187,7 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-4.9-dev']
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3
|
||||
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="4"
|
||||
install:
|
||||
- pushd ${OSRM_BUILD_DIR}
|
||||
- |
|
||||
@@ -215,60 +206,12 @@ matrix:
|
||||
|
||||
- os: linux
|
||||
sudo: false
|
||||
compiler: "node-4-mason-linux-release"
|
||||
compiler: "node-4-mason-linux-debug"
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-4.9-dev']
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3
|
||||
install:
|
||||
- pushd ${OSRM_BUILD_DIR}
|
||||
- |
|
||||
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
|
||||
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
||||
-DENABLE_CCACHE=ON \
|
||||
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
|
||||
-DENABLE_GLIBC_WORKAROUND=ON
|
||||
- make --jobs=${JOBS}
|
||||
- popd
|
||||
script:
|
||||
- npm run nodejs-tests
|
||||
after_success:
|
||||
- ./scripts/travis/publish.sh
|
||||
|
||||
- os: linux
|
||||
sudo: false
|
||||
compiler: "node-6-mason-linux-release"
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-4.9-dev']
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="6"
|
||||
install:
|
||||
- pushd ${OSRM_BUILD_DIR}
|
||||
- |
|
||||
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
|
||||
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
||||
-DENABLE_CCACHE=ON \
|
||||
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
|
||||
-DENABLE_GLIBC_WORKAROUND=ON
|
||||
- make --jobs=${JOBS}
|
||||
- popd
|
||||
script:
|
||||
- npm run nodejs-tests
|
||||
after_success:
|
||||
- ./scripts/travis/publish.sh
|
||||
|
||||
- os: linux
|
||||
sudo: false
|
||||
compiler: "node-6-mason-linux-release"
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-4.9-dev']
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="6"
|
||||
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="4"
|
||||
install:
|
||||
- pushd ${OSRM_BUILD_DIR}
|
||||
- |
|
||||
@@ -292,7 +235,7 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-4.9-dev']
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="8"
|
||||
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="8"
|
||||
install:
|
||||
- pushd ${OSRM_BUILD_DIR}
|
||||
- |
|
||||
@@ -311,12 +254,12 @@ matrix:
|
||||
|
||||
- os: linux
|
||||
sudo: false
|
||||
compiler: "node-6-mason-linux-release"
|
||||
compiler: "node-8-mason-linux-debug"
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-4.9-dev']
|
||||
env: CLANG_VERSION='4.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="8"
|
||||
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="8"
|
||||
install:
|
||||
- pushd ${OSRM_BUILD_DIR}
|
||||
- |
|
||||
@@ -422,7 +365,7 @@ install:
|
||||
script:
|
||||
- if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi
|
||||
- make -C test/data benchmark
|
||||
- ./example/build/osrm-example test/data/ch/monaco.osrm
|
||||
- ./example/build/osrm-example test/data/mld/monaco.osrm
|
||||
# All tests assume to be run from the build directory
|
||||
- pushd ${OSRM_BUILD_DIR}
|
||||
- ./unit_tests/library-tests
|
||||
@@ -431,7 +374,7 @@ script:
|
||||
- ./unit_tests/engine-tests
|
||||
- ./unit_tests/util-tests
|
||||
- ./unit_tests/server-tests
|
||||
- ./unit_tests/partition-tests
|
||||
- ./unit_tests/partitioner-tests
|
||||
- |
|
||||
if [ -z "${ENABLE_SANITIZER}" ] && [ "$TARGET_ARCH" != "i686" ]; then
|
||||
npm run nodejs-tests
|
||||
|
||||
+66
-1
@@ -1,4 +1,69 @@
|
||||
# UNRELEASED
|
||||
# 5.16.0 RC 6
|
||||
- Changes from 5.15.1:
|
||||
- Guidance
|
||||
- ADDED #4676: Support for maneuver override relation, allowing data-driven overrides for turn-by-turn instructions [#4676](https://github.com/Project-OSRM/osrm-backend/pull/4676)
|
||||
- CHANGED #4830: Announce reference change if names are empty
|
||||
- CHANGED #4835: MAXIMAL_ALLOWED_SEPARATION_WIDTH increased to 12 meters
|
||||
- CHANGED #4842: Lower priority links from a motorway now are used as motorway links [#4842](https://github.com/Project-OSRM/osrm-backend/pull/4842)
|
||||
- CHANGED #4895: Use ramp bifurcations as fork intersections [#4895](https://github.com/Project-OSRM/osrm-backend/issues/4895)
|
||||
- CHANGED #4893: Handle motorway forks with links as normal motorway intersections[#4893](https://github.com/Project-OSRM/osrm-backend/issues/4893)
|
||||
- FIXED #4905: Check required tags of `maneuver` relations [#4905](https://github.com/Project-OSRM/osrm-backend/pull/4905)
|
||||
- Profile:
|
||||
- FIXED: `highway=service` will now be used for restricted access, `access=private` is still disabled for snapping.
|
||||
- ADDED #4775: Exposes more information to the turn function, now being able to set turn weights with highway and access information of the turn as well as other roads at the intersection [#4775](https://github.com/Project-OSRM/osrm-backend/issues/4775)
|
||||
- FIXED #4763: Add support for non-numerical units in car profile for maxheight [#4763](https://github.com/Project-OSRM/osrm-backend/issues/4763)
|
||||
- ADDED #4872: Handling of `barrier=height_restrictor` nodes [#4872](https://github.com/Project-OSRM/osrm-backend/pull/4872)
|
||||
|
||||
# 5.15.1
|
||||
- Changes from 5.15.0:
|
||||
- Bugfixes:
|
||||
- FIXED: Segfault in map matching when RouteLeg collapsing code is run on a match with multiple submatches
|
||||
- Guidance:
|
||||
- Set type of trivial intersections where classes change to Suppressed instead of NoTurn
|
||||
|
||||
# 5.15.0
|
||||
- Changes from 5.14.3:
|
||||
- Bugfixes:
|
||||
- FIXED #4704: Fixed regression in bearings reordering introduced in 5.13 [#4704](https://github.com/Project-OSRM/osrm-backend/issues/4704)
|
||||
- FIXED #4781: Fixed overflow exceptions in percent-encoding parsing
|
||||
- FIXED #4770: Fixed exclude flags for single toll road scenario
|
||||
- FIXED #4283: Fix overflow on zero duration segments
|
||||
- FIXED #4804: Ignore no_*_on_red turn restrictions
|
||||
- Guidance:
|
||||
- CHANGED #4706: Guidance refactoring step to decouple intersection connectivity analysis and turn instructions generation [#4706](https://github.com/Project-OSRM/osrm-backend/pull/4706)
|
||||
- CHANGED #3491: Refactor `isThroughStreet`/Intersection options
|
||||
- Profile:
|
||||
- ADDED: `tunnel` as a new class in car profile so that sections of the route with tunnel tags will be marked as such
|
||||
|
||||
# 5.14.3
|
||||
- Changes from 5.14.2:
|
||||
- Features:
|
||||
- Added a `waypoints` parameter to the match service plugin that accepts indices to input coordinates and treats only those points as waypoints in the response format.
|
||||
- Bugfixes:
|
||||
- FIXED #4754: U-Turn penalties are applied to straight turns.
|
||||
- FIXED #4756: Removed too restrictive road name check in the sliproad handler
|
||||
- FIXED #4731: Use correct weights for edge-based graph duplicated via nodes.
|
||||
- Profile:
|
||||
- CHANGED: added Belarus speed limits
|
||||
- CHANGED: set default urban speed in Ukraine to 50kmh
|
||||
|
||||
# 5.14.2
|
||||
- Changes from 5.14.1:
|
||||
- Bugfixes:
|
||||
- FIXED #4727: Erroring when a old .core file is present.
|
||||
- FIXED #4642: Update checks for EMPTY_NAMEID to check for empty name strings
|
||||
- FIXED #4738: Fix potential segmentation fault
|
||||
- Node.js Bindings:
|
||||
- ADDED: Exposed new `max_radiuses_map_matching` option from `EngingConfig` options
|
||||
- Tools:
|
||||
- ADDED: New osrm-routed `max_radiuses_map_matching` command line flag to optionally set a maximum radius for map matching
|
||||
|
||||
# 5.14.1
|
||||
- Changes from 5.14.0
|
||||
- Bugfixes:
|
||||
- FIXED: don't use removed alternative candidates in `filterPackedPathsByCellSharing`
|
||||
|
||||
# 5.14.0
|
||||
- Changes from 5.13
|
||||
- API:
|
||||
- ADDED: new RouteStep property `driving_side` that has either "left" or "right" for that step
|
||||
|
||||
+26
-31
@@ -43,7 +43,6 @@ if(ENABLE_MASON)
|
||||
set(MASON_LUA_VERSION "5.2.4")
|
||||
set(MASON_BZIP2_VERSION "1.0.6")
|
||||
set(MASON_TBB_VERSION "2017_U7")
|
||||
set(MASON_LIBSHP_VERSION "1.3.0")
|
||||
|
||||
message(STATUS "Enabling mason")
|
||||
|
||||
@@ -61,7 +60,7 @@ if (POLICY CMP0048)
|
||||
endif()
|
||||
project(OSRM C CXX)
|
||||
set(OSRM_VERSION_MAJOR 5)
|
||||
set(OSRM_VERSION_MINOR 14)
|
||||
set(OSRM_VERSION_MINOR 16)
|
||||
set(OSRM_VERSION_PATCH 0)
|
||||
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
|
||||
|
||||
@@ -102,10 +101,10 @@ if(WIN32 AND MSVC_VERSION LESS 1900)
|
||||
message(FATAL_ERROR "Building with Microsoft compiler needs Latest Visual Studio 2015 (Community or better)")
|
||||
endif()
|
||||
|
||||
# Strictly require GCC>=4.9 and Clang>=3.4 - GCC 4.8 is already too old for C++14.
|
||||
# Strictly require GCC>=5.0 and Clang>=3.4 - GCC 4.8 is already too old for C++14.
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
|
||||
message(FATAL_ERROR "GCC>=4.9 required. In case you are on Ubuntu upgrade via ppa:ubuntu-toolchain-r/test")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
|
||||
message(FATAL_ERROR "GCC>=5.0 required. In case you are on Ubuntu upgrade via ppa:ubuntu-toolchain-r/test")
|
||||
endif()
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
|
||||
@@ -126,7 +125,8 @@ configure_file(
|
||||
)
|
||||
file(GLOB UtilGlob src/util/*.cpp src/util/*/*.cpp)
|
||||
file(GLOB ExtractorGlob src/extractor/*.cpp src/extractor/*/*.cpp)
|
||||
file(GLOB PartitionerGlob src/partition/*.cpp)
|
||||
file(GLOB GuidanceGlob src/guidance/*.cpp src/extractor/intersection/*.cpp)
|
||||
file(GLOB PartitionerGlob src/partitioner/*.cpp)
|
||||
file(GLOB CustomizerGlob src/customize/*.cpp)
|
||||
file(GLOB ContractorGlob src/contractor/*.cpp)
|
||||
file(GLOB UpdaterGlob src/updater/*.cpp)
|
||||
@@ -137,6 +137,7 @@ file(GLOB ErrorcodesGlob src/osrm/errorcodes.cpp)
|
||||
|
||||
add_library(UTIL OBJECT ${UtilGlob})
|
||||
add_library(EXTRACTOR OBJECT ${ExtractorGlob})
|
||||
add_library(GUIDANCE OBJECT ${GuidanceGlob})
|
||||
add_library(PARTITIONER OBJECT ${PartitionerGlob})
|
||||
add_library(CUSTOMIZER OBJECT ${CustomizerGlob})
|
||||
add_library(CONTRACTOR OBJECT ${ContractorGlob})
|
||||
@@ -156,8 +157,9 @@ add_executable(osrm-datastore src/tools/store.cpp $<TARGET_OBJECTS:UTIL>)
|
||||
add_library(osrm src/osrm/osrm.cpp $<TARGET_OBJECTS:ENGINE> $<TARGET_OBJECTS:UTIL> $<TARGET_OBJECTS:STORAGE>)
|
||||
add_library(osrm_contract src/osrm/contractor.cpp $<TARGET_OBJECTS:CONTRACTOR> $<TARGET_OBJECTS:UTIL>)
|
||||
add_library(osrm_extract src/osrm/extractor.cpp $<TARGET_OBJECTS:EXTRACTOR> $<TARGET_OBJECTS:UTIL>)
|
||||
add_library(osrm_partition $<TARGET_OBJECTS:PARTITIONER> $<TARGET_OBJECTS:UTIL>)
|
||||
add_library(osrm_customize $<TARGET_OBJECTS:CUSTOMIZER> $<TARGET_OBJECTS:UTIL>)
|
||||
add_library(osrm_guidance $<TARGET_OBJECTS:GUIDANCE> $<TARGET_OBJECTS:UTIL>)
|
||||
add_library(osrm_partition src/osrm/partitioner.cpp $<TARGET_OBJECTS:PARTITIONER> $<TARGET_OBJECTS:UTIL>)
|
||||
add_library(osrm_customize src/osrm/customizer.cpp $<TARGET_OBJECTS:CUSTOMIZER> $<TARGET_OBJECTS:UTIL>)
|
||||
add_library(osrm_update $<TARGET_OBJECTS:UPDATER> $<TARGET_OBJECTS:UTIL>)
|
||||
add_library(osrm_store $<TARGET_OBJECTS:STORAGE> $<TARGET_OBJECTS:UTIL>)
|
||||
|
||||
@@ -256,8 +258,7 @@ if(CMAKE_BUILD_TYPE MATCHES Release OR CMAKE_BUILD_TYPE MATCHES MinRelSize OR CM
|
||||
endif()
|
||||
|
||||
# Since gcc 4.9 the LTO format is non-standart ('slim'), so we need to use the build-in tools
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND
|
||||
NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.9.0" AND NOT MINGW)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND NOT MINGW)
|
||||
find_program(GCC_AR gcc-ar)
|
||||
find_program(GCC_RANLIB gcc-ranlib)
|
||||
if ("${GCC_AR}" STREQUAL "GCC_AR-NOTFOUND" OR "${GCC_RANLIB}" STREQUAL "GCC_RANLIB-NOTFOUND")
|
||||
@@ -285,12 +286,6 @@ if(CMAKE_BUILD_TYPE MATCHES Release OR CMAKE_BUILD_TYPE MATCHES MinRelSize OR CM
|
||||
set(CMAKE_RANLIB ${LLVM_RANLIB})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.9.0")
|
||||
message(STATUS "Disabling LTO on GCC < 4.9.0 since it is broken, see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57038")
|
||||
set(CMAKE_CXX_FLAGS "${OLD_CXX_FLAGS}")
|
||||
set(ENABLE_LTO Off)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -317,8 +312,9 @@ if (ENABLE_SANITIZER)
|
||||
endif()
|
||||
|
||||
# Configuring compilers
|
||||
set(OSRM_WARNING_FLAGS "-Werror=all -Werror=extra -Werror=uninitialized -Werror=unreachable-code -Werror=unused-variable -Werror=unreachable-code -Wno-error=cpp -Wpedantic")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wuninitialized -Wunreachable-code -Wstrict-overflow=2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC -fcolor-diagnostics -ftemplate-depth=1024 -Wno-unused-command-line-argument")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OSRM_WARNING_FLAGS} -Werror=strict-overflow=2 -Wno-error=unused-local-typedef -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC -fcolor-diagnostics -ftemplate-depth=1024 -Wno-unused-command-line-argument")
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
set(COLOR_FLAG "-fdiagnostics-color=auto")
|
||||
check_cxx_compiler_flag("-fdiagnostics-color=auto" HAS_COLOR_FLAG)
|
||||
@@ -326,7 +322,8 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
set(COLOR_FLAG "")
|
||||
endif()
|
||||
# using GCC
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wuninitialized -Wunreachable-code -Wstrict-overflow=1 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 ${COLOR_FLAG} -fPIC -ftemplate-depth=1024")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OSRM_WARNING_FLAGS} -Werror=strict-overflow=1 -Wno-error=maybe-uninitialized -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 ${COLOR_FLAG} -fPIC -ftemplate-depth=1024")
|
||||
|
||||
if(WIN32) # using mingw
|
||||
add_dependency_defines(-DWIN32)
|
||||
set(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
|
||||
@@ -624,6 +621,12 @@ set(EXTRACTOR_LIBRARIES
|
||||
${TBB_LIBRARIES}
|
||||
${ZLIB_LIBRARY}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
set(GUIDANCE_LIBRARIES
|
||||
${BOOST_BASE_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${USED_LUA_LIBRARIES}
|
||||
${TBB_LIBRARIES}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
set(PARTITIONER_LIBRARIES
|
||||
${BOOST_ENGINE_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
@@ -670,13 +673,14 @@ set(UTIL_LIBRARIES
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${MAYBE_STXXL_LIBRARY}
|
||||
${TBB_LIBRARIES}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
${MAYBE_COVERAGE_LIBRARIES}
|
||||
${ZLIB_LIBRARY})
|
||||
|
||||
# Libraries
|
||||
target_link_libraries(osrm ${ENGINE_LIBRARIES})
|
||||
target_link_libraries(osrm_update ${UPDATER_LIBRARIES})
|
||||
target_link_libraries(osrm_contract ${CONTRACTOR_LIBRARIES} osrm_update osrm_store)
|
||||
target_link_libraries(osrm_extract ${EXTRACTOR_LIBRARIES})
|
||||
target_link_libraries(osrm_extract osrm_guidance ${EXTRACTOR_LIBRARIES})
|
||||
target_link_libraries(osrm_partition ${PARTITIONER_LIBRARIES})
|
||||
target_link_libraries(osrm_customize ${CUSTOMIZER_LIBRARIES} osrm_update osrm_store)
|
||||
target_link_libraries(osrm_store ${STORAGE_LIBRARIES})
|
||||
@@ -692,15 +696,6 @@ if(BUILD_TOOLS)
|
||||
target_link_libraries(osrm-io-benchmark ${BOOST_BASE_LIBRARIES})
|
||||
|
||||
install(TARGETS osrm-io-benchmark DESTINATION bin)
|
||||
|
||||
find_package(Shapefile)
|
||||
if(SHAPEFILE_FOUND AND (Boost_VERSION VERSION_GREATER 106000 OR ENABLE_MASON))
|
||||
add_executable(osrm-extract-conditionals src/tools/extract-conditionals.cpp $<TARGET_OBJECTS:UTIL>)
|
||||
target_include_directories(osrm-extract-conditionals PRIVATE ${LIBSHAPEFILE_INCLUDE_DIR})
|
||||
target_link_libraries(osrm-extract-conditionals ${OSMIUM_LIBRARIES} ${BOOST_BASE_LIBRARIES} ${Boost_PROGRAM_OPTIONS_LIBRARY}
|
||||
${UTIL_LIBRARIES} ${BZIP2_LIBRARIES} ${ZLIB_LIBRARY} ${EXPAT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||
install(TARGETS osrm-extract-conditionals DESTINATION bin)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (ENABLE_ASSERTIONS)
|
||||
@@ -723,14 +718,14 @@ file(GLOB ParametersGlob include/engine/api/*_parameters.hpp)
|
||||
set(EngineHeader include/engine/status.hpp include/engine/engine_config.hpp include/engine/hint.hpp include/engine/bearing.hpp include/engine/approach.hpp include/engine/phantom_node.hpp)
|
||||
set(UtilHeader include/util/coordinate.hpp include/util/json_container.hpp include/util/typedefs.hpp include/util/alias.hpp include/util/exception.hpp include/util/bearing.hpp)
|
||||
set(ExtractorHeader include/extractor/extractor.hpp include/storage/io_config.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp)
|
||||
set(PartitionerHeader include/partition/partitioner.hpp include/partition/partition_config.hpp)
|
||||
set(PartitionerHeader include/partitioner/partitioner.hpp include/partitioner/partitioner_config.hpp)
|
||||
set(ContractorHeader include/contractor/contractor.hpp include/contractor/contractor_config.hpp)
|
||||
set(StorageHeader include/storage/storage.hpp include/storage/io_config.hpp include/storage/storage_config.hpp)
|
||||
install(FILES ${EngineHeader} DESTINATION include/osrm/engine)
|
||||
install(FILES ${UtilHeader} DESTINATION include/osrm/util)
|
||||
install(FILES ${StorageHeader} DESTINATION include/osrm/storage)
|
||||
install(FILES ${ExtractorHeader} DESTINATION include/osrm/extractor)
|
||||
install(FILES ${PartitionerHeader} DESTINATION include/osrm/partition)
|
||||
install(FILES ${PartitionerHeader} DESTINATION include/osrm/partitioner)
|
||||
install(FILES ${ContractorHeader} DESTINATION include/osrm/contractor)
|
||||
install(FILES ${LibraryGlob} DESTINATION include/osrm)
|
||||
install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Everyone
|
||||
|
||||
Please take some time to review our [code of conduct](CODE_OF_CONDUCT.md) to help guide your interactions with others on this project.
|
||||
Please take some time to review our [code of conduct](CODE-OF-CONDUCT.md) to help guide your interactions with others on this project.
|
||||
|
||||
# User
|
||||
|
||||
|
||||
@@ -59,9 +59,14 @@ Download OpenStreetMap extracts for example from [Geofabrik](http://download.geo
|
||||
Pre-process the extract with the car profile and start a routing engine HTTP server on port 5000
|
||||
|
||||
docker run -t -v $(pwd):/data osrm/osrm-backend osrm-extract -p /opt/car.lua /data/berlin-latest.osm.pbf
|
||||
|
||||
The flag `-v $(pwd):/data` creates the directory `/data` inside the docker container and makes the current working directory `$(pwd)` available there. The file `/data/berlin-latest.osm.pbf` inside the container is referring to `$(pwd)/berlin-latest.osm.pbf` on the host.
|
||||
|
||||
docker run -t -v $(pwd):/data osrm/osrm-backend osrm-partition /data/berlin-latest.osrm
|
||||
docker run -t -v $(pwd):/data osrm/osrm-backend osrm-customize /data/berlin-latest.osrm
|
||||
|
||||
Note that `berlin-latest.osrm` has a different file extension.
|
||||
|
||||
docker run -t -i -p 5000:5000 -v $(pwd):/data osrm/osrm-backend osrm-routed --algorithm mld /data/berlin-latest.osrm
|
||||
|
||||
Make requests against the HTTP server
|
||||
@@ -114,7 +119,8 @@ sudo cmake --build . --target install
|
||||
|
||||
### Request Against the Demo Server
|
||||
|
||||
Read the [API usage policy](https://github.com/Project-OSRM/osrm-backend/wiki/Api-usage-policy).
|
||||
Read the [API usage policy](https://github.com/Project-OSRM/osrm-backend/wiki/Demo-server).
|
||||
|
||||
Simple query with instructions and alternatives on Berlin:
|
||||
|
||||
```
|
||||
|
||||
@@ -161,29 +161,6 @@ XCOPY /Y corech\*.* ..\test\data\corech\
|
||||
XCOPY /Y mld\*.* ..\test\data\mld\
|
||||
unit_tests\%Configuration%\library-tests.exe
|
||||
|
||||
IF NOT "%APPVEYOR_REPO_BRANCH%"=="master" GOTO DONE
|
||||
ECHO ========= CREATING PACKAGES ==========
|
||||
|
||||
CD %PROJECT_DIR%\build\%Configuration%
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
|
||||
SET P=%PROJECT_DIR%
|
||||
SET ZIP= %P%\osrm_%Configuration%.zip
|
||||
IF EXIST %ZIP% ECHO deleting %ZIP% && DEL /F /Q %ZIP%
|
||||
IF %ERRORLEVEL% NEQ 0 ECHO deleting %ZIP% FAILED && GOTO ERROR
|
||||
|
||||
7z a %ZIP% *.lib *.exe *.pdb %P%/osrm-deps/libs/bin/*.dll -tzip -mx9 | %windir%\system32\FIND "ing archive"
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
|
||||
CD ..\..\profiles
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
|
||||
ECHO disk=c:\temp\stxxl,10000,wincall > .stxxl.txt
|
||||
7z a %ZIP% * -tzip -mx9 | %windir%\system32\FIND "ing archive"
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
|
||||
GOTO DONE
|
||||
|
||||
:ERROR
|
||||
ECHO ~~~~~~~~~~~~~~~~~~~~~~ ERROR %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
ECHO ERRORLEVEL^: %ERRORLEVEL%
|
||||
|
||||
@@ -29,24 +29,7 @@ before_test:
|
||||
- SET OSRM_BUILD_DIR=build\%Configuration%
|
||||
- npm test
|
||||
|
||||
artifacts:
|
||||
- path: osrm_Release.zip
|
||||
name: osrm_Release.zip
|
||||
# - path: osrm_Debug.zip
|
||||
# name: osrm_Debug.zip
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
deploy:
|
||||
provider: FTP
|
||||
server:
|
||||
secure: ef7oiQTTXFGt8NdNiOHm/uRFVrUttzyFbIlnaeHhQvw=
|
||||
username:
|
||||
secure: Bw+Se2GTJxA6+GtRkEc//tQSBHOuFIuJHBjFwR9cD+8=
|
||||
password:
|
||||
secure: eqwESZqxMXC/j5mOCpaXuw==
|
||||
folder: /
|
||||
enable_ssl: true
|
||||
active_mode: false
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
# - Try to find Shapefile C Library
|
||||
# http://shapelib.maptools.org/
|
||||
#
|
||||
# Exports:
|
||||
# Shapefile_FOUND
|
||||
# LIBSHAPEFILE_INCLUDE_DIR
|
||||
# LIBSHAPEFILE_LIBRARY
|
||||
# Hints:
|
||||
# LIBSHAPEFILE_LIBRARY_DIR
|
||||
|
||||
find_path(LIBSHAPEFILE_INCLUDE_DIR
|
||||
shapefil.h)
|
||||
|
||||
find_library(LIBSHAPEFILE_LIBRARY
|
||||
NAMES shp
|
||||
HINTS "${LIBSHAPEFILE_LIBRARY_DIR}")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Shapefile DEFAULT_MSG
|
||||
LIBSHAPEFILE_LIBRARY LIBSHAPEFILE_INCLUDE_DIR)
|
||||
mark_as_advanced(LIBSHAPEFILE_INCLUDE_DIR LIBSHAPEFILE_LIBRARY)
|
||||
+664
-192
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+6
-5
@@ -288,6 +288,7 @@ In addition to the [general options](#general-options) the following options are
|
||||
|radiuses |`{radius};{radius}[;{radius} ...]` |Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy.|
|
||||
|gaps |`split` (default), `ignore` |Allows the input track splitting based on huge timestamp gaps between points. |
|
||||
|tidy |`true`, `false` (default) |Allows the input track modification to obtain better matching quality for noisy tracks. |
|
||||
|waypoints | `{index};{index};{index}...` |Treats input coordinates indicated by given indices as waypoints in returned Match object. Default is to treat all input coordinates as waypoints. |
|
||||
|
||||
|Parameter |Values |
|
||||
|------------|-----------------------------------|
|
||||
@@ -514,10 +515,10 @@ Represents a route between two waypoints.
|
||||
|
||||
- `annotation`: Additional details about each coordinate along the route geometry:
|
||||
|
||||
| annotations | |
|
||||
|--------------|-----------------------------------------------------------------------|
|
||||
| true | An `Annotation` object containing node ids, durations distances and |
|
||||
| false | weights `undefined` |
|
||||
| annotations | |
|
||||
|--------------|-------------------------------------------------------------------------------|
|
||||
| true | An `Annotation` object containing node ids, durations, distances and weights. |
|
||||
| false | `undefined` |
|
||||
|
||||
#### Example
|
||||
|
||||
@@ -586,7 +587,7 @@ step.
|
||||
|
||||
- `name`: The name of the way along which travel proceeds.
|
||||
- `ref`: A reference number or code for the way. Optionally included, if ref data is available for the given way.
|
||||
- `pronunciation`: The pronunciation hint of the way name. Will be `undefined` if there is no pronunciation hit.
|
||||
- `pronunciation`: A string containing an [IPA](https://en.wikipedia.org/wiki/International_Phonetic_Alphabet) phonetic transcription indicating how to pronounce the name in the `name` property. This property is omitted if pronunciation data is unavailable for the step.
|
||||
- `destinations`: The destinations of the way. Will be `undefined` if there are no destinations.
|
||||
- `exits`: The exit numbers or names of the way. Will be `undefined` if there are no exit numbers or names.
|
||||
- `mode`: A string signifying the mode of transportation.
|
||||
|
||||
+134
-48
@@ -6,7 +6,7 @@ OSRM supports "profiles". Profiles representing routing behavior for different t
|
||||
## Available profiles
|
||||
Out-of-the-box OSRM comes with profiles for car, bicycle and foot. You can easily modify these or create new ones if you like.
|
||||
|
||||
Profiles have a 'lua' extension, and are places in 'profiles' directory.
|
||||
Profiles have a 'lua' extension, and are placed in 'profiles' directory.
|
||||
|
||||
When running OSRM preprocessing commands you specify the profile with the --profile (or the shorthand -p) option, for example:
|
||||
|
||||
@@ -17,8 +17,8 @@ It's important to understand that profiles are used when preprocessing the OSM d
|
||||
|
||||
This means that after modifying a profile **you will need to extract, contract and reload the data again** and to see changes in the routing results. See [Processing Flow](https://github.com/Project-OSRM/osrm-backend/wiki/Processing-Flow) for more.
|
||||
|
||||
## Profiles are written in LUA
|
||||
Profiles are not just configuration files. They are scripts written in the [LUA scripting language](http://www.lua.org). The reason for this is that OpenStreetMap data is complex, and it's not possible to simply define tag mappings. LUA scripting offers a powerful way to handle all the possible tag combinations found in OpenStreetMap nodes and ways.
|
||||
## Profiles are written in Lua
|
||||
Profiles are not just configuration files. They are scripts written in the [Lua scripting language](http://www.lua.org). The reason for this is that OpenStreetMap data is complex, and it's not possible to simply define tag mappings. Lua scripting offers a powerful way to handle all the possible tag combinations found in OpenStreetMap nodes and ways.
|
||||
|
||||
## Basic structure of profiles
|
||||
A profile will process every node and way in the OSM input data to determine what ways are routable in which direction, at what speed, etc.
|
||||
@@ -35,40 +35,40 @@ A profile can also define various local functions it needs.
|
||||
|
||||
Looking at [car.lua](../profiles/car.lua) as an example, at the top of the file the api version is defined and then required library files are included.
|
||||
|
||||
Then follows the `setup` functions, which is called once when the profile is loaded. It returns a big hash table of configurations, specifying things like what speed to use for different way types. The configurations are used later in the various processing functions. Many adjustments can be done just be modifying this configuration table.
|
||||
Then follows the `setup` function, which is called once when the profile is loaded. It returns a big hash table of configurations, specifying things like what speed to use for different way types. The configurations are used later in the various processing functions. Many adjustments can be done just by modifying this configuration table.
|
||||
|
||||
The setup function is also where you can do other setup, like loading elevation data source if you want to consider that when processing ways.
|
||||
The setup function is also where you can do other setup, like loading an elevation data source if you want to consider that when processing ways.
|
||||
|
||||
Then comes the `process_node` and `process_way` functions, which are called for each OSM node and way when extracting OpenStreetMap data with `osrm-extract`.
|
||||
Then come the `process_node` and `process_way` functions, which are called for each OSM node and way when extracting OpenStreetMap data with `osrm-extract`.
|
||||
|
||||
The `process_turn` function processes every possible turn in the network, and sets a penalty depending on the angle and turn of the movement.
|
||||
|
||||
Profiles can also define a `process_segment` function to handle differences in speed along an OSM way, for example to handle elevation. As you can see, this is not currently used in the car profile.
|
||||
|
||||
At the end of the file, a table if returned with references to the setup and processing functions the profile has defined.
|
||||
At the end of the file, a table is returned with references to the setup and processing functions the profile has defined.
|
||||
|
||||
## Understanding speed, weight and rate
|
||||
When computing a route from A to B there can be different measure of what is the best route. That's why there's a need for different profiles.
|
||||
When computing a route from A to B there can be different measures of what is the best route. That's why there's a need for different profiles.
|
||||
|
||||
Because speeds very on different types of roads, the shortest and the fastest route are typically different. But there are many other possible preferences. For example a user might prefer a bicycle route that follow parks or other green areas, even though both duration and distance are a bit longer.
|
||||
Because speeds vary on different types of roads, the shortest and the fastest route are typically different. But there are many other possible preferences. For example a user might prefer a bicycle route that follow parks or other green areas, even though both duration and distance are a bit longer.
|
||||
|
||||
To handle this, OSRM doesn't simply choose the ways with the highest speed. Instead it uses the concept of `weight` and `rate`. The rate is an abstract measure that you can assign to ways as you like to make some ways preferable to others. Routing will prefer ways with high rate.
|
||||
To handle this, OSRM doesn't simply choose the ways with the highest speed. Instead it uses the concepts of `weight` and `rate`. The rate is an abstract measure that you can assign to ways as you like to make some ways preferable to others. Routing will prefer ways with high rate.
|
||||
|
||||
The weight of a way normally computed as length / rate. The weight can be thought of as the resistance or cost when passing the way. Routing will prefer ways with low weight.
|
||||
The weight of a way is normally computed as length / rate. The weight can be thought of as the resistance or cost when passing the way. Routing will prefer ways with low weight.
|
||||
|
||||
You can also set the weight of a way to a fixed value, In this case it's not calculated based on the length or rate, and the rate is ignored.
|
||||
You can also set the weight of a way to a fixed value. In this case it's not calculated based on the length or rate, and the rate is ignored.
|
||||
|
||||
You should set the speed to you best estimate of the actual speed that will be used on a particular way. This will result in the best estimated travel times.
|
||||
You should set the speed to your best estimate of the actual speed that will be used on a particular way. This will result in the best estimated travel times.
|
||||
|
||||
If you want to prefer certain ways due to other factors than the speed, adjust the rate accordingly. If you adjust the speed, the time time estimation will be skewed.
|
||||
If you want to prefer certain ways due to other factors than the speed, adjust the rate accordingly. If you adjust the speed, the time estimation will be skewed.
|
||||
|
||||
If you set the same rate on all ways, the result will be shortest path routing.
|
||||
If you set rate = speed on all ways, the result will be fastest path routing.
|
||||
If you want to prioritize certain street, increase the rate on these.
|
||||
If you want to prioritize certain streets, increase the rate on these.
|
||||
|
||||
## Elements
|
||||
### api_version
|
||||
A profile should set api_version at the top of your profile. This is done to ensure that older profiles are still supported when the api changes. If api_version is not defined, 0 will be assumed. The current api version is 2.
|
||||
A profile should set `api_version` at the top of your profile. This is done to ensure that older profiles are still supported when the api changes. If `api_version` is not defined, 0 will be assumed. The current api version is 2.
|
||||
|
||||
### Library files
|
||||
The folder [profiles/lib/](../profiles/lib/) contains LUA library files for handling many common processing tasks.
|
||||
@@ -81,15 +81,15 @@ set.lua | Defines the Set helper for handling sets of values
|
||||
sequence.lua | Defines the Sequence helper for handling sequences of values
|
||||
access.lua | Function for finding relevant access tags
|
||||
destination.lua | Function for finding relevant destination tags
|
||||
destination.lua | Function for determining maximum speed
|
||||
maxspeed.lua | Function for determining maximum speed
|
||||
guidance.lua | Function for processing guidance attributes
|
||||
|
||||
They all return a table of functions when you use `require` to load them. You can either store this table and reference it's functions later, of if you need only a single you can store that directly.
|
||||
They all return a table of functions when you use `require` to load them. You can either store this table and reference its functions later, or if you need only a single function you can store that directly.
|
||||
|
||||
### setup()
|
||||
The `setup` function is called once when the profile is loaded and must return a table of configurations. It's also where you can do other global setup, like loading data sources that are used during processing.
|
||||
|
||||
Note that processing of data is parallelized and several unconnected LUA interpreters will be running at the same time. The `setup` function will be called once for each. Each LUA iinterpreter will have it's own set of globals.
|
||||
Note that processing of data is parallelized and several unconnected LUA interpreters will be running at the same time. The `setup` function will be called once for each. Each LUA iinterpreter will have its own set of globals.
|
||||
|
||||
The following global properties can be set under `properties` in the hash you return in the `setup` function:
|
||||
|
||||
@@ -109,8 +109,7 @@ The following additional global properties can be set in the hash you return in
|
||||
|
||||
Attribute | Type | Notes
|
||||
-------------------------------------|------------------|----------------------------------------------------------------------------
|
||||
excludable | Sequence of Sets | Determines which class-combinations are supported by the `exclude` option at query time.
|
||||
| | E.g. `Sequence{Set{"ferry", "motorway"}, Set{"motorway"}}` will allow you to exclude ferries and motorways, or only motorways.
|
||||
excludable | Sequence of Sets | Determines which class-combinations are supported by the `exclude` option at query time. E.g. `Sequence{Set{"ferry", "motorway"}, Set{"motorway"}}` will allow you to exclude ferries and motorways, or only motorways.
|
||||
classes | Sequence | Determines the allowed classes that can be referenced using `{forward,backward}_classes` on the way in the `process_way` function.
|
||||
restrictions | Sequence | Determines which turn restrictions will be used for this profile.
|
||||
suffix_list | Set | List of name suffixes needed for determining if "Highway 101 NW" the same road as "Highway 101 ES".
|
||||
@@ -147,26 +146,26 @@ Importantly it will set `result.forward_mode` and `result.backward_mode` to indi
|
||||
|
||||
It will also set a number of other attributes on `result`.
|
||||
|
||||
Using the power of the scripting language you wouldn't typically see something as simple as a `result.forward_speed = 20` line within the `process_way` function. Instead `process_way` will examine the tag set on the way, process this information in various ways, calling other local functions and referencing the configuration in `profile`, etc, before arriving at the result.
|
||||
Using the power of the scripting language you wouldn't typically see something as simple as a `result.forward_speed = 20` line within the `process_way` function. Instead `process_way` will examine the tag set on the way, process this information in various ways, calling other local functions and referencing the configuration in `profile`, etc., before arriving at the result.
|
||||
|
||||
The following attributes can be set on the result in `process_way`:
|
||||
|
||||
Attribute | Type | Notes
|
||||
----------------------------------------|----------|--------------------------------------------------------------------------
|
||||
forward_speed | Float | Speed on this way in km/h. Mandatory.
|
||||
backward_speed | Float | " "
|
||||
backward_speed | Float | ""
|
||||
forward_rate | Float | Routing weight, expressed as meters/*weight* (e.g. for a fastest-route weighting, you would want this to be meters/second, so set it to forward_speed/3.6)
|
||||
backward_rate | Float | " "
|
||||
backward_rate | Float | ""
|
||||
forward_mode | Enum | Mode of travel (e.g. `car`, `ferry`). Mandatory. Defined in `include/extractor/travel_mode.hpp`.
|
||||
backward_mode | Enum | " "
|
||||
backward_mode | Enum | ""
|
||||
forward_classes | Table | Mark this way as being of a specific class, e.g. `result.classes["toll"] = true`. This will be exposed in the API as `classes` on each `RouteStep`.
|
||||
backward_classes | Table | " "
|
||||
backward_classes | Table | ""
|
||||
duration | Float | Alternative setter for duration of the whole way in both directions
|
||||
weight | Float | Alternative setter for weight of the whole way in both directions
|
||||
turn_lanes_forward | String | Directions for individual lanes (normalized OSM `turn:lanes` value)
|
||||
turn_lanes_backward | String | " "
|
||||
turn_lanes_backward | String | ""
|
||||
forward_restricted | Boolean | Is this a restricted access road? (e.g. private, or deliveries only; used to enable high turn penalty, so that way is only chosen for start/end of route)
|
||||
backward_restricted | Boolean | " "
|
||||
backward_restricted | Boolean | ""
|
||||
is_startpoint | Boolean | Can a journey start on this way? (e.g. ferry; if `false`, prevents snapping the start point to this way)
|
||||
roundabout | Boolean | Is this part of a roundabout?
|
||||
circular | Boolean | Is this part of a non-roundabout circular junction?
|
||||
@@ -188,18 +187,18 @@ The `process_segment` function is called for every segment of OSM ways. A segmen
|
||||
|
||||
On OpenStreetMap way cannot have different tags on different parts of a way. Instead you would split the way into several smaller ways. However many ways are long. For example, many ways pass hills without any change in tags.
|
||||
|
||||
Processing each segment of an OSM way makes it possible to have different speeds on different parts of a way based on external data like data about elevation, pollution, noise or scenic value and adjust weight and duration of the segment.
|
||||
Processing each segment of an OSM way makes it possible to have different speeds on different parts of a way based on external data like data about elevation, pollution, noise or scenic value and adjust weight and duration of the segment accordingly.
|
||||
|
||||
In the `process_segment` you don't have access to OSM tags. Instead you use the geographical location of the start and end point of the way to lookup other data source, like elevation data. See [rasterbot.lua](../profiles/rasterbot.lua) for an example.
|
||||
In the `process_segment` function you don't have access to OSM tags. Instead you use the geographical location of the start and end point of the way to look up information from another data source, like elevation data. See [rasterbot.lua](../profiles/rasterbot.lua) for an example.
|
||||
|
||||
The following attributes can be read and set on the result in `process_segment`:
|
||||
|
||||
Attribute | Read/write? | Type | Notes
|
||||
-------------------|-------------|---------|----------------------------------------
|
||||
source.lon | Read | Float | Co-ordinates of segment start
|
||||
source.lat | Read | Float | " "
|
||||
source.lat | Read | Float | ""
|
||||
target.lon | Read | Float | Co-ordinates of segment end
|
||||
target.lat | Read | Float | " "
|
||||
target.lat | Read | Float | ""
|
||||
target.distance | Read | Float | Length of segment
|
||||
weight | Read/write | Float | Routing weight for this segment
|
||||
duration | Read/write | Float | Duration for this segment
|
||||
@@ -209,16 +208,103 @@ The `process_turn` function is called for every possible turn in the network. Ba
|
||||
|
||||
The following attributes can be read and set on the result in `process_turn`:
|
||||
|
||||
Attribute | Read/write? | Type | Notes
|
||||
-------------------|-------------|---------|------------------------------------------------------
|
||||
direction_modifier | Read | Enum | Geometry of turn. Defined in `include/extractor/guidance/turn_instruction.hpp`
|
||||
turn_type | Read | Enum | Priority of turn. Defined in `include/extractor/guidance/turn_instruction.hpp`
|
||||
has_traffic_light | Read | Boolean | Is a traffic light present at this turn?
|
||||
source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `process_way`)
|
||||
target_restricted | Read | Boolean | Is it to a restricted access road? (See definition in `process_way`)
|
||||
angle | Read | Float | Angle of turn in degrees (`0-360`: `0`=u-turn, `180`=straight on)
|
||||
duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds)
|
||||
weight | Read/write | Float | Penalty to be applied for this turn (routing weight)
|
||||
Attribute | Read/write? | Type | Notes
|
||||
--------------------- | ------------- | --------- | ------------------------------------------------------
|
||||
angle | Read | Float | Angle of turn in degrees (`[-179, 180]`: `0`=straight, `180`=u turn, `+x`=x degrees to the right, `-x`= x degrees to the left)
|
||||
number_of_roads | Read | Integer | Number of ways at the intersection of the turn
|
||||
is_u_turn | Read | Boolean | Is the turn a u-turn?
|
||||
has_traffic_light | Read | Boolean | Is a traffic light present at this turn?
|
||||
is_left_hand_driving | Read | Boolean | Is left-hand traffic?
|
||||
source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `process_way`)
|
||||
source_mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp`
|
||||
source_is_motorway | Read | Boolean | Is the source road a motorway?
|
||||
source_is_link | Read | Boolean | Is the source road a link?
|
||||
source_number_of_lanes | Read | Integer | How many lanes does the source road have? (default when not tagged: 0)
|
||||
source_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15))
|
||||
source_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15))
|
||||
source_speed | Read | Integer | Speed on this source road in km/h
|
||||
source_priority_class | Read | Enum | The type of road priority class of the source. Defined in `include/extractor/guidance/road_classification.hpp`
|
||||
target_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `process_way`)
|
||||
target_mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp`
|
||||
target_is_motorway | Read | Boolean | Is the target road a motorway?
|
||||
target_is_link | Read | Boolean | Is the target road a link?
|
||||
target_number_of_lanes | Read | Integer | How many lanes does the target road have? (default when not tagged: 0)
|
||||
target_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15))
|
||||
target_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15))
|
||||
target_speed | Read | Integer | Speed on this target road in km/h
|
||||
target_priority_class | Read | Enum | The type of road priority class of the target. Defined in `include/extractor/guidance/road_classification.hpp`
|
||||
roads_on_the_right | Read | Vector<ExtractionTurnLeg> | Vector with information about other roads on the right of the turn that are also connected at the intersection
|
||||
roads_on_the_left | Read | Vector<ExtractionTurnLeg> | Vector with information about other roads on the left of the turn that are also connected at the intersection. If turn is a u turn, this is empty.
|
||||
weight | Read/write | Float | Penalty to be applied for this turn (routing weight)
|
||||
duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds)
|
||||
|
||||
#### `roads_on_the_right` and `roads_on_the_left`
|
||||
|
||||
The information of `roads_on_the_right` and `roads_on_the_left` that can be read are as follows:
|
||||
|
||||
Attribute | Read/write? | Type | Notes
|
||||
--------------------- | ------------- | --------- | ------------------------------------------------------
|
||||
is_restricted | Read | Boolean | Is it a restricted access road? (See definition in `process_way`)
|
||||
mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp`
|
||||
is_motorway | Read | Boolean | Is the road a motorway?
|
||||
is_link | Read | Boolean | Is the road a link?
|
||||
number_of_lanes | Read | Integer | How many lanes does the road have? (default when not tagged: 0)
|
||||
highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)
|
||||
access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)
|
||||
speed | Read | Integer | Speed on this road in km/h
|
||||
priority_class | Read | Enum | The type of road priority class of the leg. Defined in `include/extractor/guidance/road_classification.hpp`
|
||||
is_incoming | Read | Boolean | Is the road an incoming road of the intersection
|
||||
is_outgoing | Read | Boolean | Is the road an outgoing road of the intersection
|
||||
|
||||
The order of the roads in `roads_on_the_right` and `roads_on_the_left` are *counter clockwise*. If the turn is a u turn, all other connected roads will be in `roads_on_the_right`.
|
||||
|
||||
**Example**
|
||||
|
||||
```
|
||||
c e
|
||||
| /
|
||||
| /
|
||||
a ---- x ---- b
|
||||
/|
|
||||
/ |
|
||||
f d
|
||||
|
||||
|
||||
```
|
||||
When turning from `a` to `b` via `x`,
|
||||
* `roads_on_the_right[1]` is the road `xf`
|
||||
* `roads_on_the_right[2]` is the road `xd`
|
||||
* `roads_on_the_left[1]` is the road `xe`
|
||||
* `roads_on_the_left[2]` is the road `xc`
|
||||
|
||||
Note that indices of arrays in lua are 1-based.
|
||||
|
||||
#### `highway_turn_classification` and `access_turn_classification`
|
||||
When setting appropriate turn weights and duration, information about the highway and access tags of roads that are involved in the turn are necessary. The lua turn function `process_turn` does not have access to the original osrm tags anymore. However, `highway_turn_classification` and `access_turn_classification` can be set during setup. The classification set during setup can be later used in `process_turn`.
|
||||
|
||||
**Example**
|
||||
|
||||
In the following example we use `highway_turn_classification` to set the turn weight to `10` if the turn is on a highway and to `5` if the turn is on a primary.
|
||||
|
||||
```
|
||||
function setup()
|
||||
return {
|
||||
highway_turn_classification = {
|
||||
['motorway'] = 2,
|
||||
['primary'] = 1
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function process_turn(profile, turn) {
|
||||
if turn.source_highway_turn_classification == 2 and turn.target_highway_turn_classification == 2 then
|
||||
turn.weight = 10
|
||||
end
|
||||
if turn.source_highway_turn_classification == 1 and turn.target_highway_turn_classification == 1 then
|
||||
turn.weight = 5
|
||||
end
|
||||
}
|
||||
```
|
||||
|
||||
## Guidance
|
||||
The guidance parameters in profiles are currently a work in progress. They can and will change.
|
||||
@@ -231,7 +317,7 @@ The priority-category influences the decision which road is considered the obvio
|
||||
Forks can be emitted between roads of similar priority category only. Obvious choices follow a major priority road, if the priority difference is large.
|
||||
|
||||
### Using raster data
|
||||
OSRM has build-in support for loading an interpolating raster data in ASCII format. This can be used e.g. for factoring in elevation when computing routes.
|
||||
OSRM has built-in support for loading an interpolating raster data in ASCII format. This can be used e.g. for factoring in elevation when computing routes.
|
||||
|
||||
Use `raster:load()` in your `setup` function to load data and store the source in your configuration hash:
|
||||
|
||||
@@ -284,8 +370,8 @@ See [rasterbot.lua](../profiles/rasterbot.lua) and [rasterbotinterp.lua](../prof
|
||||
### Helper functions
|
||||
There are a few helper functions defined in the global scope that profiles can use:
|
||||
|
||||
durationIsValid
|
||||
parseDuration
|
||||
trimLaneString
|
||||
applyAccessTokens
|
||||
canonicalizeStringList
|
||||
- `durationIsValid`
|
||||
- `parseDuration`
|
||||
- `trimLaneString`
|
||||
- `applyAccessTokens`
|
||||
- `canonicalizeStringList`
|
||||
|
||||
@@ -30,9 +30,17 @@ int main(int argc, const char *argv[])
|
||||
|
||||
// Configure based on a .osrm base path, and no datasets in shared mem from osrm-datastore
|
||||
EngineConfig config;
|
||||
|
||||
config.storage_config = {argv[1]};
|
||||
config.use_shared_memory = false;
|
||||
|
||||
// We support two routing speed up techniques:
|
||||
// - Contraction Hierarchies (CH): requires extract+contract pre-processing
|
||||
// - Multi-Level Dijkstra (MLD): requires extract+partition+customize pre-processing
|
||||
//
|
||||
// config.algorithm = EngineConfig::Algorithm::CH;
|
||||
config.algorithm = EngineConfig::Algorithm::MLD;
|
||||
|
||||
// Routing machine with several services (such as Route, Table, Nearest, Trip, Match)
|
||||
const OSRM osrm{config};
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
@routing @car @way
|
||||
Feature: Car - Avoid defined areas
|
||||
|
||||
Background:
|
||||
Given the profile file "car" initialized with
|
||||
"""
|
||||
profile.avoid = Set { 'motorway', 'motorway_link' }
|
||||
profile.speeds = Sequence {
|
||||
highway = {
|
||||
motorway = 90,
|
||||
motorway_link = 45,
|
||||
primary = 50
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: Car - Avoid motorways
|
||||
Then routability should be
|
||||
| highway | bothw |
|
||||
| motorway | |
|
||||
| motorway_link | |
|
||||
| primary | x |
|
||||
|
||||
@@ -45,3 +45,11 @@ Feature: Car - Barriers
|
||||
| bollard | | |
|
||||
| bollard | rising | x |
|
||||
| bollard | removable | |
|
||||
|
||||
Scenario: Car - Height restrictions
|
||||
Then routability should be
|
||||
| node/barrier | node/maxheight | bothw |
|
||||
| height_restrictor | | x |
|
||||
| height_restrictor | 1 | |
|
||||
| height_restrictor | 3 | x |
|
||||
| height_restrictor | default | x |
|
||||
|
||||
@@ -82,7 +82,7 @@ Feature: Car - Mode flag
|
||||
| from | to | route | turns | classes |
|
||||
| a | d | ab,cd | depart,arrive| [(restricted),(motorway,restricted),()],[()] |
|
||||
|
||||
Scenario: Car - We toll restricted with a class
|
||||
Scenario: Car - We tag toll with a class
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
@@ -99,6 +99,45 @@ Feature: Car - Mode flag
|
||||
| from | to | route | turns | classes |
|
||||
| a | d | ab,cd | depart,arrive | [(toll),(motorway,toll),()],[()] |
|
||||
|
||||
Scenario: Car - We tag tunnel with a class
|
||||
Background:
|
||||
Given a grid size of 200 meters
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
c d
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | tunnel |
|
||||
| ab | no |
|
||||
| bc | yes |
|
||||
| cd | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns | classes |
|
||||
| a | d | ab,bc,cd,cd | depart,new name right,new name left,arrive | [()],[(tunnel)],[()],[()] |
|
||||
|
||||
Scenario: Car - We tag classes without intersections
|
||||
Background:
|
||||
Given a grid size of 200 meters
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a b c d
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | name | tunnel |
|
||||
| ab | road | |
|
||||
| bc | road | yes |
|
||||
| cd | road | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns | classes |
|
||||
| a | d | road,road | depart,arrive | [(),(tunnel),()],[()] |
|
||||
|
||||
Scenario: Car - From roundabout on toll road
|
||||
Given the node map
|
||||
"""
|
||||
@@ -124,4 +163,3 @@ Feature: Car - Mode flag
|
||||
When I route I should get
|
||||
| from | to | route | turns | classes |
|
||||
| a | f | ab,df,df,df | depart,roundabout-exit-2,exit roundabout slight right,arrive | [()],[(),(motorway)],[(toll,motorway)],[()] |
|
||||
|
||||
|
||||
@@ -884,7 +884,7 @@ Feature: Car - Turn restrictions
|
||||
| a | c | albic,dobe,dobe,albic,albic | depart,turn left,continue uturn,turn left,arrive |
|
||||
| a | e | albic,dobe,dobe | depart,turn left,arrive |
|
||||
|
||||
@no_turning @conditionals
|
||||
@no_turning @conditionals @restriction-way
|
||||
Scenario: Car - Conditional restriction with multiple time windows
|
||||
Given the extract extra arguments "--parse-conditional-restrictions"
|
||||
# 5pm Wed 02 May, 2017 GMT
|
||||
@@ -1054,4 +1054,3 @@ Feature: Car - Turn restrictions
|
||||
| a | f | ab,be,ef,ef | depart,turn right,turn left,arrive | a,b,e,f |
|
||||
| c | d | bc,be,de,de | depart,turn left,turn right,arrive | c,b,e,d |
|
||||
| c | f | bc,be,ef,ef | depart,turn left,turn left,arrive | c,b,e,f |
|
||||
|
||||
|
||||
@@ -131,3 +131,57 @@ Feature: Car - Destination only, no passing through
|
||||
| e | a | acbe,acbe |
|
||||
| d | a | de,acbe,acbe |
|
||||
| c | d | cd,cd |
|
||||
|
||||
Scenario: Car - Routing through a parking lot tagged access=destination,service
|
||||
Given the node map
|
||||
"""
|
||||
a----c++++b+++g----h---i
|
||||
| + + + |
|
||||
| + + + |
|
||||
| + + + |
|
||||
| d++++e+f /
|
||||
z---------------y
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | access | highway |
|
||||
| ac | | secondary |
|
||||
| ghi | | secondary |
|
||||
| azyhi | | secondary |
|
||||
| cd | destination | service |
|
||||
| def | destination | service |
|
||||
| cbg | destination | service |
|
||||
| be | destination | service |
|
||||
| gf | destination | service |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| a | i | azyhi,azyhi |
|
||||
| b | f | be,def,def |
|
||||
|
||||
Scenario: Car - Disallow snapping to access=private,highway=service
|
||||
Given a grid size of 20 meters
|
||||
Given the node map
|
||||
"""
|
||||
a---c---b
|
||||
:
|
||||
x
|
||||
:
|
||||
d
|
||||
\__e
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | access | highway |
|
||||
| acb | | primary |
|
||||
| cx | private | service |
|
||||
| xd | private | service |
|
||||
| de | | primary |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| a | x | acb,xd,xd |
|
||||
| a | d | acb,xd,xd |
|
||||
| a | e | acb,xd,de |
|
||||
| x | e | de,de |
|
||||
# do not snap to access=private,highway=service roads when routing over them is not necessary
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
@routing @car
|
||||
Feature: Car - Handle physical limitation
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
|
||||
Scenario: Car - Use a narrow way
|
||||
Then routability should be
|
||||
| highway | width | narrow | bothw |
|
||||
| primary | | | x |
|
||||
| primary | narrow | | x |
|
||||
| primary | | yes | x |
|
||||
| primary | 1.8 | | |
|
||||
| primary | 1.9 | | |
|
||||
| primary | 2.0 | | x |
|
||||
| primary | 2.1 | | x |
|
||||
| primary | 1m | | |
|
||||
| primary | 1 m | | |
|
||||
| primary | 3 m | | x |
|
||||
| primary | 6' | | |
|
||||
| primary | 6'0" | | |
|
||||
| primary | 6'2" | | |
|
||||
| primary | 6'3" | | x |
|
||||
| primary | 7' | | x |
|
||||
| primary | 7'0" | | x |
|
||||
|
||||
Scenario: Car - Limited by width
|
||||
Then routability should be
|
||||
| highway | maxwidth:physical | maxwidth | width | est_width | bothw |
|
||||
| primary | 1 | | | | |
|
||||
| primary | 3 | | | | x |
|
||||
| primary | | 1 | | | |
|
||||
| primary | | 3 | | | x |
|
||||
| primary | | | 1 | | |
|
||||
| primary | | | 3 | | x |
|
||||
| primary | | | | 1 | |
|
||||
| primary | | | | 3 | x |
|
||||
|
||||
Scenario: Car - Limited by height
|
||||
Then routability should be
|
||||
| highway | maxheight:physical | maxheight | bothw |
|
||||
| primary | | | x |
|
||||
| primary | 1 | | |
|
||||
| primary | 3 | | x |
|
||||
| primary | | 1 | |
|
||||
| primary | | 3 | x |
|
||||
| primary | | default | x |
|
||||
| primary | | none | x |
|
||||
| primary | | no-sign | x |
|
||||
| primary | | unsigned | x |
|
||||
@@ -141,6 +141,33 @@ Feature: Car - Turn restrictions
|
||||
| c | a | cj,aj,aj |
|
||||
| c | b | cj,bj,bj |
|
||||
|
||||
@no_turning
|
||||
Scenario: Car - Ignore no_*_on_red relations
|
||||
Given the node map
|
||||
"""
|
||||
a
|
||||
d j b
|
||||
c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| cj | yes |
|
||||
| aj | -1 |
|
||||
| dj | -1 |
|
||||
| bj | -1 |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | cj | dj | j | no_turn_on_red |
|
||||
| restriction | cj | bj | j | no_right_turn_on_red |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| c | d | cj,dj,dj |
|
||||
| c | a | cj,aj,aj |
|
||||
| c | b | cj,bj,bj |
|
||||
|
||||
@only_turning
|
||||
Scenario: Car - Only left turn
|
||||
Given the node map
|
||||
@@ -575,7 +602,7 @@ Feature: Car - Turn restrictions
|
||||
| c | d | bc,be,de,de | depart,turn left,turn right,arrive | c,b,e,d |
|
||||
| c | f | bc,be,ef,ef | depart,turn left,turn left,arrive | c,b,e,f |
|
||||
|
||||
@restriction @overlap
|
||||
@restriction-way @overlap
|
||||
Scenario: Car - prohibit turn
|
||||
Given the node map
|
||||
"""
|
||||
@@ -710,7 +737,7 @@ Feature: Car - Turn restrictions
|
||||
| a | j | left,first,right,right |
|
||||
| f | e | right,third,left,left |
|
||||
|
||||
@restriction
|
||||
@restriction-way
|
||||
Scenario: Car - allow only turn
|
||||
Given the node map
|
||||
"""
|
||||
@@ -742,7 +769,7 @@ Feature: Car - Turn restrictions
|
||||
| c | d | bc,be,de,de | depart,turn left,turn right,arrive | c,b,e,d |
|
||||
| c | f | bc,be,ef,ef | depart,turn left,turn left,arrive | c,b,e,f |
|
||||
|
||||
@restriction
|
||||
@restriction-way
|
||||
Scenario: Car - allow only turn
|
||||
Given the node map
|
||||
"""
|
||||
@@ -771,7 +798,7 @@ Feature: Car - Turn restrictions
|
||||
| from | to | route |
|
||||
| a | d | ab,be,de,de |
|
||||
|
||||
@restriction
|
||||
@restriction-way
|
||||
Scenario: Multi Way restriction
|
||||
Given the node map
|
||||
"""
|
||||
@@ -808,7 +835,7 @@ Feature: Car - Turn restrictions
|
||||
| from | to | route |
|
||||
| a | h | horiz,vert,horiz,horiz |
|
||||
|
||||
@restriction
|
||||
@restriction-way
|
||||
Scenario: Multi-Way overlapping single-way
|
||||
Given the node map
|
||||
"""
|
||||
@@ -847,7 +874,7 @@ Feature: Car - Turn restrictions
|
||||
| h | d | hfb,abcd,abcd | depart,end of road right,arrive | h,b,d |
|
||||
|
||||
|
||||
@restriction
|
||||
@restriction-way
|
||||
Scenario: Car - prohibit turn, traffic lights
|
||||
Given the node map
|
||||
"""
|
||||
@@ -890,7 +917,7 @@ Feature: Car - Turn restrictions
|
||||
| c | f | bc,be,ef,ef | depart,turn left,turn left,arrive | c,b,e,f |
|
||||
|
||||
|
||||
@restriction @overlap @geometry
|
||||
@restriction-way @overlap @geometry
|
||||
Scenario: Geometry
|
||||
Given the node map
|
||||
"""
|
||||
@@ -925,7 +952,7 @@ Feature: Car - Turn restrictions
|
||||
| c | d | bc,bge,de,de |
|
||||
| c | f | bc,bge,de,de,ef,ef |
|
||||
|
||||
@restriction @overlap @geometry @traffic-signals
|
||||
@restriction-way @overlap @geometry @traffic-signals
|
||||
Scenario: Geometry
|
||||
Given the node map
|
||||
"""
|
||||
@@ -967,7 +994,7 @@ Feature: Car - Turn restrictions
|
||||
| c | f | bc,bge,de,de,ef,ef |
|
||||
|
||||
# don't crash hard on invalid restrictions
|
||||
@restriction @invalid
|
||||
@restriction-way @invalid
|
||||
Scenario: Geometry
|
||||
Given the node map
|
||||
"""
|
||||
@@ -999,7 +1026,7 @@ Feature: Car - Turn restrictions
|
||||
| a | f | ab,be,ef,ef |
|
||||
|
||||
|
||||
@restriction @overlap @geometry
|
||||
@restriction @restriction-way @overlap @geometry
|
||||
Scenario: Duplicated restriction
|
||||
Given the node map
|
||||
"""
|
||||
@@ -1034,3 +1061,28 @@ Feature: Car - Turn restrictions
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| a | d | ab,bc,bc,bge,de,de |
|
||||
|
||||
|
||||
Scenario: Ambiguous ways
|
||||
Given the node map
|
||||
"""
|
||||
x---a----b-----c---z
|
||||
|
|
||||
d
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| abc |
|
||||
| bd |
|
||||
| xa |
|
||||
| cz |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | bd | abc | b | no_left_turn |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| d | x | bd,abc,xa,xa |
|
||||
| d | z | bd,abc,cz,cz |
|
||||
|
||||
@@ -116,3 +116,28 @@ Feature: Testbot - side bias
|
||||
| from | to | route | driving_side | time |
|
||||
| d | a | bd,ab,ab | right,right,right | 27s +-1 |
|
||||
| d | c | bd,bc,bc | right,right,right | 24s +-1 |
|
||||
|
||||
Scenario: changing sides
|
||||
Given the profile "car"
|
||||
|
||||
# Note - the boundary in null-island.geojson is at lon = 2.0,
|
||||
# and we use the "last node of the way" as the heuristic to detect
|
||||
# whether the way is in our out of the driving_side polygon
|
||||
And the node locations
|
||||
| node | lat | lon |
|
||||
| a | 0 | 0.5 |
|
||||
| b | 0 | 1.5 |
|
||||
| c | 0 | 2.5 |
|
||||
| d | 0 | 3.5 |
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| ab |
|
||||
| bc |
|
||||
| cd |
|
||||
|
||||
And the extract extra arguments "--location-dependent-data test/data/regions/null-island.geojson"
|
||||
When I route I should get
|
||||
| from | to | route | driving_side |
|
||||
| d | a | cd,bc,ab,ab | right,right,left,left |
|
||||
| a | d | ab,bc,cd,cd | left,right,right,right |
|
||||
|
||||
@@ -76,7 +76,7 @@ Feature: Basic Routing
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | summary |
|
||||
| a,c | , | 100, 101 |
|
||||
| a,c | ,, | 100, 101 |
|
||||
|
||||
Scenario: Single Ref
|
||||
Given the node map
|
||||
|
||||
@@ -98,11 +98,11 @@ Feature: Car - Guidance - Bridges and Tunnels
|
||||
| dce | primary | | Nebenstraße |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns |
|
||||
| a | d | Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,arrive |
|
||||
| a | e | Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,arrive |
|
||||
| e | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn left,arrive |
|
||||
| d | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn right,arrive |
|
||||
| from | to | route | turns |
|
||||
| a | d | Hauptstraße,Nebenstraße,Nebenstraße | depart,end of road left,arrive |
|
||||
| a | e | Hauptstraße,Nebenstraße,Nebenstraße | depart,end of road right,arrive |
|
||||
| e | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn left,arrive |
|
||||
| d | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn right,arrive |
|
||||
|
||||
Scenario: Tunnel with Immediate Turn Front and Back
|
||||
Given the node map
|
||||
@@ -129,4 +129,3 @@ Feature: Car - Guidance - Bridges and Tunnels
|
||||
| e | g | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn left,turn left,arrive |
|
||||
| d | f | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn right,turn right,arrive |
|
||||
| d | g | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn right,turn left,arrive |
|
||||
|
||||
|
||||
@@ -992,7 +992,6 @@ Feature: Slipways and Dedicated Turn Lanes
|
||||
| dbef | primary | dbef | |
|
||||
| ae | primary_link | ae | yes |
|
||||
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | locations |
|
||||
| s,f | sabc,dbef,dbef | depart,turn right,arrive | s,a,f |
|
||||
@@ -1019,7 +1018,6 @@ Feature: Slipways and Dedicated Turn Lanes
|
||||
| dbcf | primary | dbcf | |
|
||||
| ac | primary_link | ae | yes |
|
||||
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | locations |
|
||||
| s,f | sab,dbcf,dbcf | depart,turn right,arrive | s,a,f |
|
||||
@@ -1047,7 +1045,55 @@ Feature: Slipways and Dedicated Turn Lanes
|
||||
| ae | primary_link | sab | yes |
|
||||
| cg | primary | cg | |
|
||||
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | locations |
|
||||
| s,f | sab,dbcef,dbcef | depart,turn right,arrive | s,a,f |
|
||||
|
||||
|
||||
@sliproads
|
||||
Scenario: Sliproad converted from a fork
|
||||
Given the node map
|
||||
"""
|
||||
d
|
||||
.
|
||||
b
|
||||
s . a '.
|
||||
`c
|
||||
.
|
||||
f
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | ref | oneway |
|
||||
| sa | tertiary | | D 60A | yes |
|
||||
| ab | tertiary | ab | D 60A | yes |
|
||||
| ac | tertiary | | D 60A | yes |
|
||||
| dbcf | tertiary | dbcf | D 543 | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | locations |
|
||||
| s,f | ,dbcf,dbcf | depart,turn right,arrive | s,a,f |
|
||||
|
||||
|
||||
@sliproads
|
||||
Scenario: Sliproad to a road with a reference only
|
||||
Given the node map
|
||||
"""
|
||||
s . a . b . d
|
||||
` .
|
||||
' .
|
||||
..
|
||||
c
|
||||
.
|
||||
f
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | ref | oneway |
|
||||
| sabd | primary | road | | |
|
||||
| bcf | primary | | K108 | |
|
||||
| ac | primary_link | | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | locations |
|
||||
| s,f | road,, | depart,turn right,arrive | s,a,f |
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
# The route results with #original are what the result should be if the maneuver tag is removed
|
||||
@routing @guidance @maneuver
|
||||
Feature: Maneuver tag support
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 5 meters
|
||||
|
||||
Scenario: simple override #1
|
||||
Given the node map
|
||||
"""
|
||||
a--b---c----d---e
|
||||
|
|
||||
g
|
||||
|
|
||||
h------i--------j
|
||||
"""
|
||||
And the ways
|
||||
| nodes | name | oneway |
|
||||
| abc | A Street | no |
|
||||
| cde | B Street | no |
|
||||
| cgi | C Street | no |
|
||||
| hij | J Street | no |
|
||||
|
||||
And the relations
|
||||
| type | way:from | node:via | way:to | maneuver | direction |
|
||||
| maneuver | abc | c | cgi | turn | sharp_right |
|
||||
| maneuver | hij | i | cde | turn | sharp_left |
|
||||
| maneuver | abc | c | cde | turn | slight_left |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
# Testing directly connected from/to
|
||||
| a,j | A Street,C Street,J Street,J Street | depart,turn sharp right,turn left,arrive |
|
||||
| b,g | A Street,C Street,C Street | depart,turn sharp right,arrive |
|
||||
# Testing re-awakening suppressed turns
|
||||
| a,e | A Street,B Street,B Street | depart,turn slight left,arrive |
|
||||
|
||||
Scenario: single via-way
|
||||
Given the node map
|
||||
""""
|
||||
a--b---c----d---e
|
||||
|
|
||||
g
|
||||
|
|
||||
h------i--------j
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway |
|
||||
| abc | A Street | no |
|
||||
| cde | B Street | no |
|
||||
| cgi | C Street | no |
|
||||
| hi | J Street | no |
|
||||
| ij | J Street | no |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:via | way:to | node:via | maneuver | direction |
|
||||
| maneuver | abc | cgi | ij | c | turn | sharp_right |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,j | A Street,C Street,J Street,J Street | depart,turn sharp right,turn left,arrive |
|
||||
|
||||
|
||||
Scenario: multiple via-way
|
||||
Given the node map
|
||||
""""
|
||||
a--b---c----d---e
|
||||
|
|
||||
g-----k
|
||||
|
|
||||
h------i--------j
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway |
|
||||
| abc | A Street | no |
|
||||
| cde | B Street | no |
|
||||
| cg | C Street | no |
|
||||
| gi | C Street | no |
|
||||
| hi | J Street | no |
|
||||
| ij | J Street | no |
|
||||
| gk | G Street | no |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:via | way:via | way:to | node:via | maneuver | direction |
|
||||
| maneuver | abc | cg | gi | ij | c | turn | sharp_right |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,j | A Street,C Street,J Street,J Street | depart,turn sharp right,end of road left,arrive |
|
||||
|
||||
|
||||
Scenario: Use maneuver tag to announce a particular turn type
|
||||
Given the node map
|
||||
"""
|
||||
f
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
t. .. * h
|
||||
.. ....m** *
|
||||
/ * *
|
||||
/ * * *
|
||||
/
|
||||
/
|
||||
|
|
||||
|
|
||||
\
|
||||
\
|
||||
o
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway | highway |
|
||||
| fm | CA-120 | no | secondary |
|
||||
| mh | CA-120 | no | secondary |
|
||||
| mt | Priest Rd | no | unclassified |
|
||||
| mo | | no | service |
|
||||
|
||||
And the relations
|
||||
| type | way:from | node:via | way:to | maneuver | direction |
|
||||
| maneuver | mh | m | mt | turn | left |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| h,t | CA-120,Priest Rd,Priest Rd | depart,turn left,arrive |
|
||||
#original | h,t | CA-120,Priest Rd,Priest Rd | depart,turn straight,arrive |
|
||||
|
||||
Scenario: Use maneuver tag to announce lane guidance
|
||||
Given a grid size of 10 meters
|
||||
Given the node map
|
||||
"""
|
||||
ad
|
||||
/ \
|
||||
/ \
|
||||
/ \
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
b-----c------e
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
r w
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway | highway |
|
||||
| ab | Marsh Rd | yes | secondary |
|
||||
| br | Marsh Rd | yes | secondary |
|
||||
| cd | Marsh Rd | yes | secondary |
|
||||
| cw | Marsh Rd | yes | secondary |
|
||||
| bc | service | no | service |
|
||||
| ce | service | no | service |
|
||||
|
||||
And the relations
|
||||
| type | way:from | node:via | way:via | way:to | maneuver |
|
||||
| maneuver | ab | c | bc | cd | uturn |
|
||||
| maneuver | ab | b | bc | cd | suppress |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | Marsh Rd,Marsh Rd,Marsh Rd | depart,turn uturn,arrive |
|
||||
#original | a,d | Marsh Rd,service,Marsh Rd,Marsh Rd | depart,turn left,turn left,arrive |
|
||||
|
||||
Scenario: Use maneuver tag to suppress a turn
|
||||
Given the node map
|
||||
"""
|
||||
c
|
||||
|
|
||||
|
|
||||
v---y----------z
|
||||
|
|
||||
n---p----------k
|
||||
|\
|
||||
| \
|
||||
b t
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway | highway |
|
||||
| zy | NY Ave | yes | primary |
|
||||
| yv | NY Ave | yes | primary |
|
||||
| np | NY Ave | yes | primary |
|
||||
| pk | NY Ave | yes | primary |
|
||||
| cp | 4th St | no | tertiary |
|
||||
| yp | | no | motorway_link |
|
||||
| pb | 4th St | no | primary |
|
||||
| pt | 395 | no | primary |
|
||||
|
||||
And the relations
|
||||
| type | way:from | node:via | way:via | way:to | maneuver | # |
|
||||
| maneuver | zy | p | yp | pt | suppress | original: depart,on ramp left,fork slight left,arrive |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:via | way:to | maneuver | # |
|
||||
| maneuver | zy | yp | pb | suppress | invalid relation: missing node:via |
|
||||
|
||||
And the relations
|
||||
| type | node:via | way:via | way:to | maneuver | # |
|
||||
| maneuver | p | yp | pb | suppress | invalid relation: missing way:from |
|
||||
|
||||
And the relations
|
||||
| type | way:from | node:via | way:via | maneuver | # |
|
||||
| maneuver | zy | p | yp | suppress | invalid relation: missing way:to |
|
||||
|
||||
And the relations
|
||||
| type | way:from | node:via | way:via | way:to | maneuver | # |
|
||||
| maneuver | zy | y, p | yp | pb | suppress | invalid relation: multiple node:via |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| z,t | NY Ave,395,395 | depart,on ramp left,arrive |
|
||||
| z,b | NY Ave,,4th St,4th St | depart,on ramp left,fork slight right,arrive |
|
||||
@@ -393,31 +393,44 @@ Feature: Merge Segregated Roads
|
||||
"""
|
||||
a
|
||||
|
|
||||
b
|
||||
b-----z
|
||||
/ \
|
||||
c h
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
d g
|
||||
\ /
|
||||
e
|
||||
|
|
||||
f
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway |
|
||||
| ab | road | no |
|
||||
| ef | road | no |
|
||||
| bcde | road | yes |
|
||||
| eghb | road | yes |
|
||||
| nodes | name | oneway |
|
||||
| ab | road | no |
|
||||
| ef | road | no |
|
||||
| bcde | road | yes |
|
||||
| eghb | road | yes |
|
||||
| bz | cross | no |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | bz | bcde | b | no_left_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| a,f | depart,arrive | road,road |
|
||||
| c,f | depart,arrive | road,road |
|
||||
| f,a | depart,arrive | road,road |
|
||||
| g,a | depart,arrive | road,road |
|
||||
| waypoints | turns | route |
|
||||
| a,f | depart,arrive | road,road |
|
||||
| c,f | depart,arrive | road,road |
|
||||
| f,a | depart,arrive | road,road |
|
||||
| g,a | depart,arrive | road,road |
|
||||
| z,a | depart,turn right,arrive | cross,road,road |
|
||||
|
||||
Scenario: Traffic Island
|
||||
Given the node map
|
||||
@@ -588,10 +601,10 @@ Feature: Merge Segregated Roads
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | germ,ober | depart,arrive |
|
||||
| a,g | germ,germ,germ | depart,continue right,arrive |
|
||||
| a,1 | germ,germ,germ | depart,continue left,arrive |
|
||||
| d,g | ober,germ,germ | depart,turn left,arrive |
|
||||
| a,c | germ,ober | depart,arrive |
|
||||
| a,g | germ,germ,germ | depart,continue right,arrive |
|
||||
| a,1 | germ,germ,germ | depart,continue left,arrive |
|
||||
| d,g | ober,germ,germ | depart,turn left,arrive |
|
||||
|
||||
# https://www.openstreetmap.org/#map=19/51.32888/6.57059
|
||||
Scenario: Places in presence of oneways
|
||||
@@ -623,16 +636,16 @@ Feature: Merge Segregated Roads
|
||||
| cf | albrecht | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,l | schwert,albrecht,marianne,marianne | depart,new name straight,turn left,arrive |
|
||||
| a,j | schwert,luise,luise | depart,turn right,arrive |
|
||||
| a,1 | schwert,albrecht,albrecht,albrecht | depart,new name straight,continue uturn,arrive |
|
||||
| k,l | marianne,marianne | depart,arrive |
|
||||
| k,j | marianne,albrecht,luise,luise | depart,turn left,turn left,arrive |
|
||||
| k,d | marianne,schwert,schwert | depart,turn right,arrive |
|
||||
| i,j | luise,luise | depart,arrive |
|
||||
| i,d | luise,albrecht,schwert,schwert | depart,turn left,turn straight,arrive |
|
||||
| i,l | luise,albrecht,marianne,marianne | depart,turn left,turn left,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,l | schwert,albrecht,marianne,marianne | depart,new name straight,turn left,arrive |
|
||||
| a,j | schwert,luise,luise | depart,turn right,arrive |
|
||||
| a,1 | schwert,albrecht,albrecht,albrecht | depart,new name straight,continue uturn,arrive |
|
||||
| k,l | marianne,marianne | depart,arrive |
|
||||
| k,j | marianne,albrecht,luise,luise | depart,turn left,turn left,arrive |
|
||||
| k,d | marianne,schwert,schwert | depart,turn right,arrive |
|
||||
| i,j | luise,luise | depart,arrive |
|
||||
| i,d | luise,albrecht,schwert,schwert | depart,turn left,turn straight,arrive |
|
||||
| i,l | luise,albrecht,marianne,marianne | depart,turn left,turn left,arrive |
|
||||
|
||||
# https://www.openstreetmap.org/#map=19/52.46339/13.40272
|
||||
Scenario: Do not merge links between segregated roads
|
||||
|
||||
@@ -81,7 +81,7 @@ Feature: Motorway Guidance
|
||||
"""
|
||||
,g,e
|
||||
,f,d
|
||||
a-b-c
|
||||
a-b-c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
@@ -281,3 +281,67 @@ Feature: Motorway Guidance
|
||||
| waypoints | route | turns |
|
||||
| a,d | , | depart,arrive |
|
||||
| b,d | , | depart,arrive |
|
||||
|
||||
|
||||
Scenario: Ramp Exit with Lower Priority
|
||||
Given the node map
|
||||
"""
|
||||
a-b-c-d-e
|
||||
`--f-g
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | oneway |
|
||||
| abcde | trunk | |
|
||||
| bfg | primary_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,e | abcde,abcde | depart,arrive |
|
||||
| a,g | abcde,bfg,bfg | depart,off ramp slight right,arrive |
|
||||
|
||||
|
||||
# https://www.openstreetmap.org/node/67366428#map=18/33.64613/-84.44425
|
||||
Scenario: Ramp Bifurcations should not be suppressed
|
||||
Given the node map
|
||||
"""
|
||||
/-----------c /-----------e
|
||||
a---b------------------d------------f
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | destination |
|
||||
| ab | motorway | | |
|
||||
| bc | motorway_link | | City 17 |
|
||||
| bd | motorway_link | | |
|
||||
| de | motorway_link | | Domestic Terminal;Camp Creek Parkway;Riverdale Road |
|
||||
| df | motorway_link | | Montgomery |
|
||||
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ,, | depart,fork slight left,arrive |
|
||||
| a,e | ,,, | depart,fork slight right,fork slight left,arrive |
|
||||
| a,f | ,,, | depart,fork slight right,fork slight right,arrive |
|
||||
|
||||
|
||||
# https://www.openstreetmap.org/#map=19/53.46186/-2.24509
|
||||
Scenario: Highway Fork with a Link
|
||||
Given the node map
|
||||
"""
|
||||
/-----------d
|
||||
a-b-c------------e
|
||||
\-----------f
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abce | motorway |
|
||||
| cf | motorway |
|
||||
| cd | motorway_link |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | abce,cd,cd | depart,off ramp slight left,arrive |
|
||||
| a,e | abce,abce | depart,arrive |
|
||||
| a,f | abce,cf,cf | depart,turn slight right,arrive |
|
||||
|
||||
@@ -382,6 +382,21 @@ Feature: New-Name Instructions
|
||||
| waypoints | route | turns |
|
||||
| a,c | , | depart,arrive |
|
||||
|
||||
Scenario: No Name, Reference changed
|
||||
Given the node map
|
||||
"""
|
||||
a ----- b ----- c
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | name | ref | highway |
|
||||
| ab | | US 322 | motorway |
|
||||
| bc | | US 422 | motorway |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ,, | depart,new name straight,arrive |
|
||||
|
||||
Scenario: Spaces in refs for containment check, #3086
|
||||
Given the node map
|
||||
"""
|
||||
|
||||
@@ -745,12 +745,15 @@ Feature: Basic Roundabout
|
||||
|
||||
|
||||
Scenario: Drive through roundabout
|
||||
Given a grid size of 5 meters
|
||||
Given the node map
|
||||
"""
|
||||
a
|
||||
b e d f
|
||||
c
|
||||
g h
|
||||
. a .
|
||||
. .
|
||||
b e --- d ---- f
|
||||
. .
|
||||
.c.
|
||||
g h
|
||||
"""
|
||||
|
||||
And the ways
|
||||
@@ -760,12 +763,12 @@ Feature: Basic Roundabout
|
||||
| gch | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | bearings | route | turns |
|
||||
| e,f | 90 90 | edf,edf | depart,arrive |
|
||||
| e,h | 90 135 | edf,gch,gch,gch | depart,roundabout-exit-2,exit roundabout straight,arrive |
|
||||
| g,f | 45 90 | gch,edf,edf,edf | depart,roundabout-exit-2,exit roundabout right,arrive |
|
||||
| g,h | 45 135 | gch,gch,gch | depart,exit roundabout right,arrive |
|
||||
| e,e | 90 270 | edf,edf,edf | depart,continue uturn,arrive |
|
||||
| waypoints | bearings | route | turns |
|
||||
| e,f | 90 90 | edf,edf | depart,arrive |
|
||||
| e,h | 90 130 | edf,gch,gch,gch | depart,roundabout-exit-2,exit roundabout straight,arrive |
|
||||
| g,f | 50 90 | gch,edf,edf,edf | depart,roundabout-exit-2,exit roundabout slight right,arrive |
|
||||
| g,h | 50 130 | gch,gch,gch | depart,exit roundabout right,arrive |
|
||||
| e,e | 90 270 | edf,edf,edf,edf | depart,roundabout-exit-3,exit roundabout sharp left,arrive |
|
||||
|
||||
Scenario: CCW and CW roundabouts with overlaps
|
||||
Given the node map
|
||||
|
||||
@@ -961,12 +961,12 @@ Feature: Simple Turns
|
||||
g
|
||||
.
|
||||
.
|
||||
.
|
||||
.
|
||||
f
|
||||
h .
|
||||
. .
|
||||
. j
|
||||
.
|
||||
.
|
||||
h f
|
||||
.
|
||||
. .
|
||||
. j
|
||||
. .
|
||||
c
|
||||
. . .
|
||||
|
||||
@@ -1372,3 +1372,64 @@ Feature: Simple Turns
|
||||
| waypoints | route | turns |
|
||||
| a,d | ab,bcd,bcd | depart,fork slight right,arrive |
|
||||
| a,g | ab,befg,befg | depart,fork slight left,arrive |
|
||||
|
||||
# https://www.openstreetmap.org/#map=18/52.25130/10.42545
|
||||
Scenario: Turn for roads with no name, ref changes
|
||||
Given the node map
|
||||
"""
|
||||
d
|
||||
.
|
||||
.
|
||||
e c . . f
|
||||
.
|
||||
.
|
||||
b
|
||||
.
|
||||
.
|
||||
a
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | ref | name |
|
||||
| abc | tertiary | K 57 | |
|
||||
| cd | tertiary | K 56 | |
|
||||
| cf | tertiary | K 56 | |
|
||||
| ce | residential | | Heinrichshöhe |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,f | ,, | depart,turn right,arrive |
|
||||
|
||||
# https://www.openstreetmap.org/#map=18/52.24071/10.29066
|
||||
Scenario: Turn for roads with no name, ref changes
|
||||
Given the node map
|
||||
"""
|
||||
x
|
||||
.
|
||||
.
|
||||
d
|
||||
. .
|
||||
. .
|
||||
. .
|
||||
e. . t . c . p. .f
|
||||
. .
|
||||
. .
|
||||
. .
|
||||
b
|
||||
.
|
||||
.
|
||||
a
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | ref | name | oneway |
|
||||
| abp | tertiary | K 23 | | yes |
|
||||
| pdx | tertiary | K 23 | | yes |
|
||||
| xdt | tertiary | K 23 | | yes |
|
||||
| tba | tertiary | K 23 | | yes |
|
||||
| etcpf | primary | B 1 | | no |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| e,x | ,,, | depart,turn sharp left,turn right,arrive |
|
||||
| f,a | ,, | depart,turn left,arrive |
|
||||
|
||||
@@ -129,8 +129,12 @@ Feature: osrm-extract lua ways:get_nodes()
|
||||
"""
|
||||
functions = require('testbot')
|
||||
|
||||
functions.process_node = function(profile, node, result, relations)
|
||||
print ('node ' .. tostring(node:get_location_tag('answer')))
|
||||
end
|
||||
|
||||
functions.process_way = function(profile, way, result, relations)
|
||||
print ('answer ' .. tostring(way:get_location_tag('answer')))
|
||||
print ('way ' .. tostring(way:get_location_tag('answer')))
|
||||
result.forward_mode = mode.driving
|
||||
result.forward_speed = 1
|
||||
end
|
||||
@@ -148,4 +152,5 @@ Feature: osrm-extract lua ways:get_nodes()
|
||||
|
||||
When I run "osrm-extract --profile {profile_file} {osm_file} --location-dependent-data test/data/regions/null-island.geojson"
|
||||
Then it should exit successfully
|
||||
And stdout should contain "answer 42"
|
||||
And stdout should contain "node 42"
|
||||
And stdout should contain "way 42"
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
@routing @testbot @turn_function
|
||||
Feature: Turn Function Information
|
||||
|
||||
|
||||
Background:
|
||||
Given the profile file
|
||||
"""
|
||||
functions = require('car')
|
||||
|
||||
function test_setup()
|
||||
profile = functions.setup()
|
||||
profile.highway_turn_classification = {
|
||||
['motorway'] = 4,
|
||||
['motorway_link'] = 4,
|
||||
['trunk'] = 4,
|
||||
['trunk_link'] = 4,
|
||||
['primary'] = 4,
|
||||
['primary_link'] = 4,
|
||||
['secondary'] = 3,
|
||||
['secondary_link'] = 3,
|
||||
['tertiary'] = 2,
|
||||
['tertiary_link'] = 2,
|
||||
['residential'] = 1,
|
||||
['living_street'] = 1,
|
||||
}
|
||||
|
||||
profile.access_turn_classification = {
|
||||
['discouraged'] = 1;
|
||||
['permissive'] = 1;
|
||||
['private'] = 1;
|
||||
['customers'] = 1;
|
||||
['dismount'] = 1;
|
||||
}
|
||||
return profile
|
||||
end
|
||||
|
||||
function turn_leg_string (leg)
|
||||
return 'speed: ' .. tostring(leg.speed)
|
||||
.. ', is_incoming: ' .. tostring(leg.is_incoming)
|
||||
.. ', is_outgoing: ' .. tostring(leg.is_outgoing)
|
||||
.. ', highway_turn_classification: ' .. tostring(leg.highway_turn_classification)
|
||||
.. ', access_turn_classification: ' .. tostring(leg.access_turn_classification)
|
||||
.. ', priority_class: ' .. tostring(leg.priority_class)
|
||||
end
|
||||
|
||||
function print_turn (profile, turn)
|
||||
print ('source_restricted ' .. string.format("%s", tostring(turn.source_restricted)))
|
||||
print ('source_is_motorway ' .. string.format("%s", tostring(turn.source_is_motorway)))
|
||||
print ('source_is_link ' .. string.format("%s", tostring(turn.source_is_link)))
|
||||
print ('source_number_of_lanes ' .. string.format("%s", tostring(turn.source_number_of_lanes)))
|
||||
print ('source_highway_turn_classification ' .. string.format("%s", tostring(turn.source_highway_turn_classification)))
|
||||
print ('source_access_turn_classification ' .. string.format("%s", tostring(turn.source_access_turn_classification)))
|
||||
print ('source_speed ' .. string.format("%s", tostring(turn.source_speed)))
|
||||
print ('source_priority_class ' .. string.format("%s", tostring(turn.source_priority_class)))
|
||||
print ('source_mode ' .. string.format("%s", tostring(turn.source_mode)))
|
||||
|
||||
print ('target_restricted ' .. string.format("%s", tostring(turn.target_restricted)))
|
||||
print ('target_is_motorway ' .. string.format("%s", tostring(turn.target_is_motorway)))
|
||||
print ('target_is_link ' .. string.format("%s", tostring(turn.target_is_link)))
|
||||
print ('target_number_of_lanes ' .. string.format("%s", tostring(turn.target_number_of_lanes)))
|
||||
print ('target_highway_turn_classification ' .. string.format("%s", tostring(turn.target_highway_turn_classification)))
|
||||
print ('target_access_turn_classification ' .. string.format("%s", tostring(turn.target_access_turn_classification)))
|
||||
print ('target_speed ' .. string.format("%s", tostring(turn.target_speed)))
|
||||
print ('target_priority_class ' .. string.format("%s", tostring(turn.target_priority_class)))
|
||||
print ('target_mode ' .. string.format("%s", tostring(turn.target_mode)))
|
||||
|
||||
print ('number_of_roads ' .. string.format("%s", tostring(turn.number_of_roads)))
|
||||
if not turn.is_u_turn then
|
||||
for roadCount, road in ipairs(turn.roads_on_the_right) do
|
||||
print('roads_on_the_right [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road))
|
||||
end
|
||||
|
||||
for roadCount, road in ipairs(turn.roads_on_the_left) do
|
||||
print('roads_on_the_left [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
setup = test_setup,
|
||||
process_way = functions.process_way,
|
||||
process_node = functions.process_node,
|
||||
process_turn = print_turn
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: Turns should have correct information of source and target
|
||||
Given the node map
|
||||
"""
|
||||
|
||||
a b c
|
||||
|
||||
"""
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | motorway |
|
||||
| bc | motorway |
|
||||
And the data has been saved to disk
|
||||
|
||||
When I run "osrm-extract --profile {profile_file} {osm_file}"
|
||||
Then it should exit successfully
|
||||
And stdout should contain "source_is_motorway true"
|
||||
And stdout should contain "target_is_motorway true"
|
||||
And stdout should contain "source_is_link false"
|
||||
And stdout should contain "source_priority_class 0"
|
||||
And stdout should contain "target_is_motorway true"
|
||||
And stdout should contain "target_is_link false"
|
||||
And stdout should contain "target_priority_class 0"
|
||||
|
||||
|
||||
Scenario: Turns should detect when turn is leaving highway
|
||||
Given the node map
|
||||
"""
|
||||
|
||||
a b c
|
||||
|
||||
"""
|
||||
And the ways
|
||||
| nodes | highway | lanes |
|
||||
| ab | motorway | 3 |
|
||||
| bc | motorway_link | |
|
||||
|
||||
And the data has been saved to disk
|
||||
|
||||
When I run "osrm-extract --profile {profile_file} {osm_file}"
|
||||
Then it should exit successfully
|
||||
And stdout should contain "source_is_motorway true"
|
||||
And stdout should contain "source_is_link false"
|
||||
And stdout should contain "source_number_of_lanes 3"
|
||||
And stdout should contain "target_is_motorway false"
|
||||
And stdout should contain "target_is_link true"
|
||||
And stdout should contain "target_number_of_lanes 0"
|
||||
And stdout should contain "number_of_roads 2"
|
||||
|
||||
Scenario: Turns should have correct information of other roads at intersection I
|
||||
Given the node map
|
||||
"""
|
||||
d
|
||||
^
|
||||
|
|
||||
a->b->c
|
||||
"""
|
||||
And the ways
|
||||
| nodes | highway | oneway |
|
||||
| ab | primary | yes |
|
||||
| bc | motorway | yes |
|
||||
| bd | residential | yes |
|
||||
And the data has been saved to disk
|
||||
|
||||
When I run "osrm-extract --profile {profile_file} {osm_file}"
|
||||
Then it should exit successfully
|
||||
And stdout should contain "number_of_roads 3"
|
||||
And stdout should contain "source_priority_class 4"
|
||||
And stdout should contain "target_priority_class 0"
|
||||
And stdout should contain "target_priority_class 11"
|
||||
# turning abd, give information about bc
|
||||
And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: false, is_outgoing: true, highway_turn_classification: 4, access_turn_classification: 0/
|
||||
# turning abc, give information about bd
|
||||
And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: false, is_outgoing: true, highway_turn_classification: 1, access_turn_classification: 0/
|
||||
|
||||
Scenario: Turns should have correct information of other roads at intersection II
|
||||
Given the node map
|
||||
"""
|
||||
d
|
||||
|
|
||||
v
|
||||
a->b->c
|
||||
"""
|
||||
And the ways
|
||||
| nodes | highway | oneway | access |
|
||||
| ab | secondary | yes | |
|
||||
| bc | motorway | yes | |
|
||||
| db | unclassified | yes | discouraged |
|
||||
And the data has been saved to disk
|
||||
|
||||
When I run "osrm-extract --profile {profile_file} {osm_file}"
|
||||
Then it should exit successfully
|
||||
And stdout should contain "number_of_roads 3"
|
||||
# turning dbc, give information about about ab
|
||||
And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 3, access_turn_classification: 0/
|
||||
# turning abc, give information about about db
|
||||
And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 0, access_turn_classification: 1/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -185,31 +185,34 @@ module.exports = function () {
|
||||
|
||||
let q = d3.queue();
|
||||
|
||||
let addRelation = (row, cb) => {
|
||||
let addRelation = (headers, row, cb) => {
|
||||
let relation = new OSM.Relation(this.makeOSMId(), this.OSM_USER, this.OSM_TIMESTAMP, this.OSM_UID);
|
||||
|
||||
|
||||
var name = null;
|
||||
for (let key in row) {
|
||||
for (let index in row) {
|
||||
|
||||
var key = headers[index];
|
||||
var value = row[index];
|
||||
let isNode = key.match(/^node:?(.*)/),
|
||||
isWay = key.match(/^way:?(.*)/),
|
||||
isRelation = key.match(/^relation:?(.*)/),
|
||||
isColonSeparated = key.match(/^(.*):(.*)/);
|
||||
if (isNode) {
|
||||
row[key].split(',').map(function(v) { return v.trim(); }).forEach((nodeName) => {
|
||||
value.split(',').map(function(v) { return v.trim(); }).forEach((nodeName) => {
|
||||
if (nodeName.length !== 1) throw new Error(util.format('*** invalid relation node member "%s"', nodeName));
|
||||
let node = this.findNodeByName(nodeName);
|
||||
if (!node) throw new Error(util.format('*** unknown relation node member "%s"', nodeName));
|
||||
relation.addMember('node', node.id, isNode[1]);
|
||||
});
|
||||
} else if (isWay) {
|
||||
row[key].split(',').map(function(v) { return v.trim(); }).forEach((wayName) => {
|
||||
value.split(',').map(function(v) { return v.trim(); }).forEach((wayName) => {
|
||||
let way = this.findWayByName(wayName);
|
||||
if (!way) throw new Error(util.format('*** unknown relation way member "%s"', wayName));
|
||||
relation.addMember('way', way.id, isWay[1]);
|
||||
});
|
||||
} else if (isRelation) {
|
||||
row[key].split(',').map(function(v) { return v.trim(); }).forEach((relName) => {
|
||||
value.split(',').map(function(v) { return v.trim(); }).forEach((relName) => {
|
||||
let otherrelation = this.findRelationByName(relName);
|
||||
if (!otherrelation) throw new Error(util.format('*** unknown relation relation member "%s"', relName));
|
||||
relation.addMember('relation', otherrelation.id, isRelation[1]);
|
||||
@@ -217,8 +220,8 @@ module.exports = function () {
|
||||
} else if (isColonSeparated && isColonSeparated[1] !== 'restriction') {
|
||||
throw new Error(util.format('*** unknown relation member type "%s:%s", must be either "node" or "way"', isColonSeparated[1], isColonSeparated[2]));
|
||||
} else {
|
||||
relation.addTag(key, row[key]);
|
||||
if (key.match(/name/)) name = row[key];
|
||||
relation.addTag(key, value);
|
||||
if (key.match(/name/)) name = value;
|
||||
}
|
||||
}
|
||||
relation.uid = this.OSM_UID;
|
||||
@@ -233,7 +236,8 @@ module.exports = function () {
|
||||
cb();
|
||||
};
|
||||
|
||||
table.hashes().forEach((row) => q.defer(addRelation, row));
|
||||
var headers = table.raw()[0];
|
||||
table.rows().forEach((row) => q.defer(addRelation, headers, row));
|
||||
|
||||
q.awaitAll(callback);
|
||||
});
|
||||
|
||||
@@ -150,7 +150,8 @@ module.exports = function () {
|
||||
}
|
||||
var ok = true;
|
||||
var encodedResult = '',
|
||||
extendedTarget = '';
|
||||
extendedTarget = '',
|
||||
resultWaypoints = [];
|
||||
|
||||
var testSubMatching = (sub, si) => {
|
||||
var testSubNode = (ni) => {
|
||||
@@ -186,6 +187,29 @@ module.exports = function () {
|
||||
});
|
||||
}
|
||||
|
||||
if (headers.has('waypoints')) {
|
||||
var got_loc = [];
|
||||
for (let i = 0; i < json.tracepoints.length; i++) {
|
||||
if (!json.tracepoints[i]) continue;
|
||||
if (json.tracepoints[i].waypoint_index != null)
|
||||
got_loc.push(json.tracepoints[i].location);
|
||||
}
|
||||
|
||||
if (row.waypoints.length != got_loc.length)
|
||||
return cb(new Error(`Expected ${row.waypoints.length} waypoints, got ${got_loc.length}`));
|
||||
|
||||
for (i = 0; i < row.waypoints.length; i++)
|
||||
{
|
||||
var want_node = this.findNodeByName(row.waypoints[i]);
|
||||
if (!this.FuzzyMatch.matchLocation(got_loc[i], want_node)) {
|
||||
resultWaypoints.push(util.format('? [%s,%s]', got_loc[i][0], got_loc[i][1]));
|
||||
ok = false;
|
||||
} else {
|
||||
resultWaypoints.push(row.waypoints[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (headers.has('matchings')) {
|
||||
got.matchings = row.matchings;
|
||||
@@ -194,7 +218,12 @@ module.exports = function () {
|
||||
if (headers.has('timestamps')) {
|
||||
got.timestamps = row.timestamps;
|
||||
}
|
||||
|
||||
if (headers.has('waypoints')) {
|
||||
got.waypoints = row.waypoints;
|
||||
}
|
||||
} else {
|
||||
got.waypoints = resultWaypoints.join(';');
|
||||
got.matchings = encodedResult;
|
||||
row.matchings = extendedTarget;
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ module.exports = function() {
|
||||
// shorten uri to be realtive to 'features/'
|
||||
let featurePath = path.relative(path.resolve('./features'), uri);
|
||||
// bicycle/bollards/{HASH}/
|
||||
let featureID = path.join(featurePath, hash);
|
||||
|
||||
let featureID = path.join(featurePath, hash);
|
||||
|
||||
let featureCacheDirectory = this.getFeatureCacheDirectory(featureID);
|
||||
let featureProcessedCacheDirectory = this.getFeatureProcessedCacheDirectory(featureCacheDirectory, this.osrmHash);
|
||||
this.featureIDs[uri] = featureID;
|
||||
@@ -115,6 +115,7 @@ module.exports = function() {
|
||||
this.OSRM_EXTRACT_PATH,
|
||||
this.OSRM_CONTRACT_PATH,
|
||||
this.LIB_OSRM_EXTRACT_PATH,
|
||||
this.LIB_OSRM_GUIDANCE_PATH,
|
||||
this.LIB_OSRM_CONTRACT_PATH
|
||||
];
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@ module.exports = {
|
||||
|
||||
FuzzyMatch: class {
|
||||
match (got, want) {
|
||||
// don't fail if bearings input and extected string is empty and actual result is undefined
|
||||
if (want === '' && (got === '' || got === undefined))
|
||||
return true;
|
||||
|
||||
var matchPercent = want.match(/(.*)\s+~(.+)%$/),
|
||||
matchAbs = want.match(/(.*)\s+\+\-(.+)$/),
|
||||
matchRe = want.match(/^\/(.*)\/$/),
|
||||
|
||||
@@ -44,7 +44,7 @@ module.exports = function () {
|
||||
|
||||
this.OSRM_PORT = process.env.OSRM_PORT && parseInt(process.env.OSRM_PORT) || 5000;
|
||||
this.HOST = 'http://127.0.0.1:' + this.OSRM_PORT;
|
||||
|
||||
|
||||
this.OSRM_PROFILE = process.env.OSRM_PROFILE;
|
||||
|
||||
if (this.PLATFORM_WINDOWS) {
|
||||
@@ -72,6 +72,7 @@ module.exports = function () {
|
||||
this.OSRM_CONTRACT_PATH = path.resolve(util.format('%s/%s%s', this.BIN_PATH, 'osrm-contract', this.EXE));
|
||||
this.OSRM_ROUTED_PATH = path.resolve(util.format('%s/%s%s', this.BIN_PATH, 'osrm-routed', this.EXE));
|
||||
this.LIB_OSRM_EXTRACT_PATH = util.format('%s/' + this.LIB, this.BIN_PATH, 'osrm_extract'),
|
||||
this.LIB_OSRM_GUIDANCE_PATH = util.format('%s/' + this.LIB, this.BIN_PATH, 'osrm_guidance'),
|
||||
this.LIB_OSRM_CONTRACT_PATH = util.format('%s/' + this.LIB, this.BIN_PATH, 'osrm_contract'),
|
||||
this.LIB_OSRM_PATH = util.format('%s/' + this.LIB, this.BIN_PATH, 'osrm');
|
||||
|
||||
|
||||
@@ -50,6 +50,8 @@ module.exports = function () {
|
||||
.defer(mkdirp, logDir)
|
||||
.defer(rimraf, this.scenarioLogFile)
|
||||
.awaitAll(callback);
|
||||
// uncomment to get path to logfile
|
||||
// console.log(" Writing logging output to " + this.scenarioLogFile)
|
||||
});
|
||||
|
||||
this.After((scenario, callback) => {
|
||||
|
||||
@@ -59,3 +59,27 @@ Feature: Annotations
|
||||
| from | to | route | a:datasources | a:speed |
|
||||
| a | i | abcdefghi,abcdefghi | 1:0:1:0:1:0:0:0 | 50:10:50:10:50:10:10:10 |
|
||||
| i | a | abcdefghi,abcdefghi | 0:1:0:0:0:0:0:1 | 10:50:10:10:10:10:10:50 |
|
||||
|
||||
Scenario: Speed annotations should handle zero segments
|
||||
Given the profile "testbot"
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a -- b --- c
|
||||
|
|
||||
d
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| abc |
|
||||
| cd |
|
||||
|
||||
# This test relies on the snapping to the EBN cd to introduce a zero segment after the turn
|
||||
And the query options
|
||||
| annotations | speed,distance,duration,nodes |
|
||||
| bearings | 90,5;180,5 |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | a:speed | a:distance | a:duration | a:nodes |
|
||||
| a | c | abc,abc | 10:10:10 | 249.998641:299.931643:0 | 25:30:0 | 1:2:3 |
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
@routing @testbot @exclude
|
||||
Feature: Testbot - Exclude flags regression tests
|
||||
Background:
|
||||
Given the profile "testbot"
|
||||
|
||||
Scenario: Testbot - Exclude toll regression 1
|
||||
Given the node map
|
||||
"""
|
||||
a g
|
||||
. .
|
||||
b....d-$-$-e....f
|
||||
. .
|
||||
c h
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | toll | # |
|
||||
| ab | primary | | always drivable |
|
||||
| cb | primary | | always drivable |
|
||||
| bd | primary | | always drivable |
|
||||
| de | motorway | yes | not drivable for exclude=toll |
|
||||
| ef | primary | | always drivable |
|
||||
| fg | primary | | always drivable |
|
||||
| fh | primary | | always drivable |
|
||||
|
||||
Given the query options
|
||||
| exclude | toll |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| a | h | |
|
||||
| a | g | |
|
||||
| g | a | |
|
||||
| d | e | |
|
||||
|
||||
Scenario: Testbot - Exclude toll regression 2
|
||||
Given the profile "testbot"
|
||||
|
||||
Given the node map
|
||||
"""
|
||||
a g
|
||||
. .
|
||||
b....d-$-$-e....f
|
||||
. .
|
||||
c h..i
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | toll | # |
|
||||
| ab | primary | | always drivable |
|
||||
| cb | primary | | always drivable |
|
||||
| bd | primary | | always drivable |
|
||||
| de | motorway | yes | not drivable for exclude=toll |
|
||||
| ef | primary | | always drivable |
|
||||
| fg | primary | | always drivable |
|
||||
| fh | primary | | always drivable |
|
||||
| hi | primary | | always drivable |
|
||||
|
||||
Given the query options
|
||||
| exclude | toll |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| a | h | |
|
||||
| a | g | |
|
||||
| g | a | |
|
||||
| d | e | |
|
||||
| d | i | |
|
||||
@@ -480,3 +480,149 @@ Feature: Basic Map Matching
|
||||
| trace | a:nodes |
|
||||
| 12 | 1:2:3:4:5:6 |
|
||||
| 21 | 6:5:4:3:2:1 |
|
||||
|
||||
|
||||
Scenario: Matching with waypoints param for start/end
|
||||
Given the node map
|
||||
"""
|
||||
a-----b---c
|
||||
|
|
||||
|
|
||||
d
|
||||
|
|
||||
|
|
||||
e
|
||||
"""
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| abc | no |
|
||||
| bde | no |
|
||||
|
||||
Given the query options
|
||||
| waypoints | 0;3 |
|
||||
|
||||
When I match I should get
|
||||
| trace | code | matchings | waypoints |
|
||||
| abde | Ok | abde | ae |
|
||||
|
||||
Scenario: Matching with waypoints param that were tidied away
|
||||
Given the node map
|
||||
"""
|
||||
a - b - c - e
|
||||
|
|
||||
f
|
||||
|
|
||||
g
|
||||
"""
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| abce | no |
|
||||
| cfg | no |
|
||||
|
||||
Given the query options
|
||||
| tidy | true |
|
||||
| waypoints | 0;2;5 |
|
||||
|
||||
When I match I should get
|
||||
| trace | code | matchings | waypoints |
|
||||
| abccfg | Ok | abcfg | acg |
|
||||
|
||||
Scenario: Testbot - Map matching refuses to use waypoints with trace splitting
|
||||
Given the node map
|
||||
"""
|
||||
a b c d
|
||||
e
|
||||
"""
|
||||
Given the query options
|
||||
| waypoints | 0;3 |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| abcd | no |
|
||||
|
||||
When I match I should get
|
||||
| trace | timestamps | code |
|
||||
| abcd | 0 1 62 63 | NoMatch |
|
||||
|
||||
Scenario: Testbot - Map matching invalid waypoints
|
||||
Given the node map
|
||||
"""
|
||||
a b c d
|
||||
e
|
||||
"""
|
||||
Given the query options
|
||||
| waypoints | 0;4 |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| abcd | no |
|
||||
|
||||
When I match I should get
|
||||
| trace | code |
|
||||
| abcd | InvalidOptions |
|
||||
|
||||
Scenario: Matching fail with waypoints param missing start/end
|
||||
Given the node map
|
||||
"""
|
||||
a-----b---c
|
||||
|
|
||||
|
|
||||
d
|
||||
|
|
||||
|
|
||||
e
|
||||
"""
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| abc | no |
|
||||
| bde | no |
|
||||
|
||||
Given the query options
|
||||
| waypoints | 1;3 |
|
||||
|
||||
When I match I should get
|
||||
| trace | code |
|
||||
| abde | InvalidValue |
|
||||
|
||||
Scenario: Testbot - Map matching with outlier that has no candidate and waypoint parameter
|
||||
Given a grid size of 100 meters
|
||||
Given the node map
|
||||
"""
|
||||
a b c d
|
||||
|
||||
1
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| abcd | no |
|
||||
|
||||
Given the query options
|
||||
| waypoints | 0;2;3 |
|
||||
|
||||
When I match I should get
|
||||
| trace | timestamps | code |
|
||||
| ab1d | 0 1 2 3 | NoMatch |
|
||||
|
||||
Scenario: Regression test - avoid collapsing legs of a tidied split trace
|
||||
Given a grid size of 20 meters
|
||||
Given the node map
|
||||
"""
|
||||
a--b--f
|
||||
|
|
||||
|
|
||||
e--c---d--g
|
||||
"""
|
||||
Given the query options
|
||||
| tidy | true |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| abf | no |
|
||||
| be | no |
|
||||
| ecdg | no |
|
||||
|
||||
When I match I should get
|
||||
| trace | timestamps | matchings | code |
|
||||
| abbecd | 10 11 27 1516914902 1516914913 1516914952 | ab,ecd | Ok |
|
||||
|
||||
|
||||
@@ -309,7 +309,7 @@ Feature: Via points
|
||||
| waypoints | route |
|
||||
| a,b,e | |
|
||||
|
||||
@todo @3359
|
||||
@3359
|
||||
Scenario: U-Turn In Bearings
|
||||
Given the node map
|
||||
"""
|
||||
|
||||
@@ -69,6 +69,11 @@ inline auto contractExcludableGraph(ContractorGraph contractor_graph_,
|
||||
});
|
||||
non_core_edges.resize(new_end - non_core_edges.begin());
|
||||
edge_container.Insert(std::move(non_core_edges));
|
||||
|
||||
for (const auto filter_index : util::irange<std::size_t>(0, filters.size()))
|
||||
{
|
||||
edge_container.Filter(filters[filter_index], filter_index);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract core graph for further contraction
|
||||
|
||||
@@ -60,6 +60,25 @@ struct ContractedEdgeContainer
|
||||
flags.resize(edges.size(), ALL_FLAGS);
|
||||
}
|
||||
|
||||
void Filter(const std::vector<bool> &filter, std::size_t index)
|
||||
{
|
||||
BOOST_ASSERT(index < sizeof(MergedFlags) * CHAR_BIT);
|
||||
const MergedFlags flag = 1 << index;
|
||||
|
||||
for (auto edge_index : util::irange<std::size_t>(0, edges.size()))
|
||||
{
|
||||
auto allowed = filter[edges[edge_index].source] && filter[edges[edge_index].target];
|
||||
if (allowed)
|
||||
{
|
||||
flags[edge_index] |= flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags[edge_index] &= ~flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Merge(std::vector<QueryEdge> new_edges)
|
||||
{
|
||||
BOOST_ASSERT(index < sizeof(MergedFlags) * CHAR_BIT);
|
||||
@@ -108,7 +127,7 @@ struct ContractedEdgeContainer
|
||||
edges.insert(edges.end(), new_edges.begin(), new_end);
|
||||
auto edges_size = edges.size();
|
||||
auto new_edges_size = std::distance(new_edges.begin(), new_end);
|
||||
BOOST_ASSERT(edges_size >= new_edges_size);
|
||||
BOOST_ASSERT(static_cast<int>(edges_size) >= new_edges_size);
|
||||
flags.resize(edges_size);
|
||||
std::fill(flags.begin() + edges_size - new_edges_size, flags.end(), flag);
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@ template <typename QueryGraphT, typename EdgeFilterT>
|
||||
inline void readGraph(const boost::filesystem::path &path,
|
||||
unsigned &checksum,
|
||||
QueryGraphT &graph,
|
||||
std::vector<EdgeFilterT> &edge_filter)
|
||||
std::vector<EdgeFilterT> &edge_filter,
|
||||
std::uint32_t &connectivity_checksum)
|
||||
{
|
||||
static_assert(std::is_same<QueryGraphView, QueryGraphT>::value ||
|
||||
std::is_same<QueryGraph, QueryGraphT>::value,
|
||||
@@ -39,6 +40,7 @@ inline void readGraph(const boost::filesystem::path &path,
|
||||
{
|
||||
storage::serialization::read(reader, edge_filter[index]);
|
||||
}
|
||||
reader.ReadInto(connectivity_checksum);
|
||||
}
|
||||
|
||||
// writes .osrm.hsgr file
|
||||
@@ -46,7 +48,8 @@ template <typename QueryGraphT, typename EdgeFilterT>
|
||||
inline void writeGraph(const boost::filesystem::path &path,
|
||||
unsigned checksum,
|
||||
const QueryGraphT &graph,
|
||||
const std::vector<EdgeFilterT> &edge_filter)
|
||||
const std::vector<EdgeFilterT> &edge_filter,
|
||||
const std::uint32_t connectivity_checksum)
|
||||
{
|
||||
static_assert(std::is_same<QueryGraphView, QueryGraphT>::value ||
|
||||
std::is_same<QueryGraph, QueryGraphT>::value,
|
||||
@@ -64,6 +67,7 @@ inline void writeGraph(const boost::filesystem::path &path,
|
||||
{
|
||||
storage::serialization::write(writer, filter);
|
||||
}
|
||||
writer.WriteOne(connectivity_checksum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#ifndef OSRM_CELLS_CUSTOMIZER_HPP
|
||||
#define OSRM_CELLS_CUSTOMIZER_HPP
|
||||
|
||||
#include "partition/cell_storage.hpp"
|
||||
#include "partition/multi_level_partition.hpp"
|
||||
#include "partitioner/cell_storage.hpp"
|
||||
#include "partitioner/multi_level_partition.hpp"
|
||||
#include "util/query_heap.hpp"
|
||||
|
||||
#include <tbb/enumerable_thread_specific.h>
|
||||
#include <tbb/parallel_for.h>
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
@@ -28,12 +29,12 @@ class CellCustomizer
|
||||
util::QueryHeap<NodeID, NodeID, EdgeWeight, HeapData, util::ArrayStorage<NodeID, int>>;
|
||||
using HeapPtr = tbb::enumerable_thread_specific<Heap>;
|
||||
|
||||
CellCustomizer(const partition::MultiLevelPartition &partition) : partition(partition) {}
|
||||
CellCustomizer(const partitioner::MultiLevelPartition &partition) : partition(partition) {}
|
||||
|
||||
template <typename GraphT>
|
||||
void Customize(const GraphT &graph,
|
||||
Heap &heap,
|
||||
const partition::CellStorage &cells,
|
||||
const partitioner::CellStorage &cells,
|
||||
const std::vector<bool> &allowed_nodes,
|
||||
CellMetric &metric,
|
||||
LevelID level,
|
||||
@@ -96,7 +97,7 @@ class CellCustomizer
|
||||
|
||||
template <typename GraphT>
|
||||
void Customize(const GraphT &graph,
|
||||
const partition::CellStorage &cells,
|
||||
const partitioner::CellStorage &cells,
|
||||
const std::vector<bool> &allowed_nodes,
|
||||
CellMetric &metric) const
|
||||
{
|
||||
@@ -120,7 +121,7 @@ class CellCustomizer
|
||||
private:
|
||||
template <typename GraphT>
|
||||
void RelaxNode(const GraphT &graph,
|
||||
const partition::CellStorage &cells,
|
||||
const partitioner::CellStorage &cells,
|
||||
const std::vector<bool> &allowed_nodes,
|
||||
const CellMetric &metric,
|
||||
Heap &heap,
|
||||
@@ -208,7 +209,7 @@ class CellCustomizer
|
||||
}
|
||||
}
|
||||
|
||||
const partition::MultiLevelPartition &partition;
|
||||
const partitioner::MultiLevelPartition &partition;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#define OSRM_CUSTOMIZE_EDGE_BASED_GRAPH_HPP
|
||||
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "partition/edge_based_graph.hpp"
|
||||
#include "partition/multi_level_graph.hpp"
|
||||
#include "partitioner/edge_based_graph.hpp"
|
||||
#include "partitioner/multi_level_graph.hpp"
|
||||
#include "util/static_graph.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
@@ -16,19 +16,20 @@ namespace osrm
|
||||
namespace customizer
|
||||
{
|
||||
|
||||
using EdgeBasedGraphEdgeData = partition::EdgeBasedGraphEdgeData;
|
||||
using EdgeBasedGraphEdgeData = partitioner::EdgeBasedGraphEdgeData;
|
||||
|
||||
struct MultiLevelEdgeBasedGraph
|
||||
: public partition::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>
|
||||
: public partitioner::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>
|
||||
{
|
||||
using Base = partition::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>;
|
||||
using Base =
|
||||
partitioner::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>;
|
||||
using Base::Base;
|
||||
};
|
||||
|
||||
struct MultiLevelEdgeBasedGraphView
|
||||
: public partition::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::View>
|
||||
: public partitioner::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::View>
|
||||
{
|
||||
using Base = partition::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::View>;
|
||||
using Base = partitioner::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::View>;
|
||||
using Base::Base;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef OSRM_CUSTOMIZER_SERIALIZATION_HPP
|
||||
#define OSRM_CUSTOMIZER_SERIALIZATION_HPP
|
||||
|
||||
#include "partition/cell_storage.hpp"
|
||||
#include "partitioner/cell_storage.hpp"
|
||||
|
||||
#include "storage/io.hpp"
|
||||
#include "storage/serialization.hpp"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef ENGINE_RESPONSE_OBJECTS_HPP_
|
||||
#define ENGINE_RESPONSE_OBJECTS_HPP_
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/route.hpp"
|
||||
#include "engine/guidance/route_leg.hpp"
|
||||
|
||||
@@ -86,6 +86,10 @@ class MatchAPI final : public RouteAPI
|
||||
for (auto point_index : util::irange(
|
||||
0u, static_cast<unsigned>(sub_matchings[sub_matching_index].indices.size())))
|
||||
{
|
||||
// tidied_to_original: index of the input coordinate that a tidied coordinate
|
||||
// corresponds to.
|
||||
// sub_matching indices: index of the coordinate passed to map matching plugin that
|
||||
// a matched node corresponds to.
|
||||
trace_idx_to_matching_idx[tidy_result
|
||||
.tidied_to_original[sub_matchings[sub_matching_index]
|
||||
.indices[point_index]]] =
|
||||
@@ -93,6 +97,9 @@ class MatchAPI final : public RouteAPI
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_ASSERT(parameters.waypoints.empty() || sub_matchings.size() == 1);
|
||||
|
||||
std::size_t was_waypoint_idx = 0;
|
||||
for (auto trace_index : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
|
||||
{
|
||||
if (tidy_result.can_be_removed[trace_index])
|
||||
@@ -114,6 +121,20 @@ class MatchAPI final : public RouteAPI
|
||||
waypoint.values["alternatives_count"] =
|
||||
sub_matchings[matching_index.sub_matching_index]
|
||||
.alternatives_count[matching_index.point_index];
|
||||
// waypoint indices need to be adjusted if route legs were collapsed
|
||||
// waypoint parameter assumes there is only one match object
|
||||
if (!parameters.waypoints.empty())
|
||||
{
|
||||
if (tidy_result.was_waypoint[trace_index])
|
||||
{
|
||||
waypoint.values["waypoint_index"] = was_waypoint_idx;
|
||||
was_waypoint_idx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
waypoint.values["waypoint_index"] = util::json::Null();
|
||||
}
|
||||
}
|
||||
waypoints.values.push_back(std::move(waypoint));
|
||||
}
|
||||
|
||||
|
||||
@@ -63,25 +63,40 @@ struct MatchParameters : public RouteParameters
|
||||
RouteParameters::GeometriesType::Polyline,
|
||||
RouteParameters::OverviewType::Simplified,
|
||||
{}),
|
||||
gaps(GapsType::Split), tidy(false)
|
||||
gaps(GapsType::Split), tidy(false), waypoints()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
MatchParameters(std::vector<unsigned> timestamps_, GapsType gaps_, bool tidy_, Args... args_)
|
||||
: MatchParameters(std::move(timestamps_), gaps_, tidy_, {}, std::forward<Args>(args_)...)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
MatchParameters(std::vector<unsigned> timestamps_,
|
||||
GapsType gaps_,
|
||||
bool tidy_,
|
||||
std::vector<std::size_t> waypoints_,
|
||||
Args... args_)
|
||||
: RouteParameters{std::forward<Args>(args_)...}, timestamps{std::move(timestamps_)},
|
||||
gaps(gaps_), tidy(tidy_)
|
||||
gaps(gaps_), tidy(tidy_), waypoints{std::move(waypoints_)}
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<unsigned> timestamps;
|
||||
GapsType gaps;
|
||||
bool tidy;
|
||||
std::vector<std::size_t> waypoints;
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
const auto valid_waypoints =
|
||||
std::all_of(waypoints.begin(), waypoints.end(), [this](const auto &w) {
|
||||
return w < coordinates.size();
|
||||
});
|
||||
return RouteParameters::IsValid() &&
|
||||
(timestamps.empty() || timestamps.size() == coordinates.size());
|
||||
(timestamps.empty() || timestamps.size() == coordinates.size()) && valid_waypoints;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -37,6 +37,9 @@ struct Result
|
||||
Mask can_be_removed;
|
||||
// Maps the MatchParameter's original items to items which should not be removed.
|
||||
Mapping tidied_to_original;
|
||||
// Masking the MatchParameter coordinates for items whose indices were present in the
|
||||
// `waypoints` parameter.
|
||||
Mask was_waypoint;
|
||||
};
|
||||
|
||||
inline Result keep_all(const MatchParameters ¶ms)
|
||||
@@ -44,6 +47,17 @@ inline Result keep_all(const MatchParameters ¶ms)
|
||||
Result result;
|
||||
|
||||
result.can_be_removed.resize(params.coordinates.size(), false);
|
||||
result.was_waypoint.resize(params.coordinates.size(), true);
|
||||
// by default all input coordinates are treated as waypoints
|
||||
if (!params.waypoints.empty())
|
||||
{
|
||||
for (const auto p : params.waypoints)
|
||||
{
|
||||
result.was_waypoint.set(p, false);
|
||||
}
|
||||
// logic is a little funny, uses inversion to set the bitfield
|
||||
result.was_waypoint.flip();
|
||||
}
|
||||
result.tidied_to_original.reserve(params.coordinates.size());
|
||||
for (std::size_t current = 0; current < params.coordinates.size(); ++current)
|
||||
{
|
||||
@@ -61,6 +75,8 @@ inline Result keep_all(const MatchParameters ¶ms)
|
||||
{
|
||||
result.parameters.coordinates.push_back(params.coordinates[i]);
|
||||
|
||||
if (result.was_waypoint[i])
|
||||
result.parameters.waypoints.push_back(result.parameters.coordinates.size() - 1);
|
||||
if (!params.hints.empty())
|
||||
result.parameters.hints.push_back(params.hints[i]);
|
||||
|
||||
@@ -74,6 +90,8 @@ inline Result keep_all(const MatchParameters ¶ms)
|
||||
result.parameters.timestamps.push_back(params.timestamps[i]);
|
||||
}
|
||||
}
|
||||
if (params.waypoints.empty())
|
||||
result.parameters.waypoints.clear();
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -85,6 +103,15 @@ inline Result tidy(const MatchParameters ¶ms, Thresholds cfg = {15., 5})
|
||||
Result result;
|
||||
|
||||
result.can_be_removed.resize(params.coordinates.size(), false);
|
||||
result.was_waypoint.resize(params.coordinates.size(), true);
|
||||
if (!params.waypoints.empty())
|
||||
{
|
||||
for (const auto p : params.waypoints)
|
||||
{
|
||||
result.was_waypoint.set(p, false);
|
||||
}
|
||||
result.was_waypoint.flip();
|
||||
}
|
||||
|
||||
result.tidied_to_original.push_back(0);
|
||||
|
||||
@@ -138,13 +165,14 @@ inline Result tidy(const MatchParameters ¶ms, Thresholds cfg = {15., 5})
|
||||
|
||||
// We have to filter parallel arrays that may be empty or the exact same size.
|
||||
// result.parameters contains an empty MatchParameters at this point: conditionally fill.
|
||||
|
||||
for (std::size_t i = 0; i < result.can_be_removed.size(); ++i)
|
||||
{
|
||||
if (!result.can_be_removed[i])
|
||||
{
|
||||
result.parameters.coordinates.push_back(params.coordinates[i]);
|
||||
|
||||
if (result.was_waypoint[i])
|
||||
result.parameters.waypoints.push_back(result.parameters.coordinates.size() - 1);
|
||||
if (!params.hints.empty())
|
||||
result.parameters.hints.push_back(params.hints[i]);
|
||||
|
||||
@@ -157,8 +185,17 @@ inline Result tidy(const MatchParameters ¶ms, Thresholds cfg = {15., 5})
|
||||
if (!params.timestamps.empty())
|
||||
result.parameters.timestamps.push_back(params.timestamps[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// one of the coordinates meant to be used as a waypoint was marked for removal
|
||||
// update the original waypoint index to the new representative coordinate
|
||||
const auto last_idx = result.parameters.coordinates.size() - 1;
|
||||
if (result.was_waypoint[i] && (result.parameters.waypoints.back() != last_idx))
|
||||
{
|
||||
result.parameters.waypoints.push_back(last_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_ASSERT(result.tidied_to_original.size() == result.parameters.coordinates.size());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef ENGINE_API_ROUTE_HPP
|
||||
#define ENGINE_API_ROUTE_HPP
|
||||
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "engine/api/base_api.hpp"
|
||||
#include "engine/api/json_factory.hpp"
|
||||
#include "engine/api/route_parameters.hpp"
|
||||
@@ -19,6 +20,8 @@
|
||||
|
||||
#include "engine/internal_route_result.hpp"
|
||||
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/json_util.hpp"
|
||||
@@ -88,11 +91,12 @@ class RouteAPI : public BaseAPI
|
||||
{
|
||||
util::json::Array annotations_store;
|
||||
annotations_store.values.reserve(leg.annotations.size());
|
||||
std::for_each(leg.annotations.begin(),
|
||||
leg.annotations.end(),
|
||||
[Get, &annotations_store](const auto &step) {
|
||||
annotations_store.values.push_back(Get(step));
|
||||
});
|
||||
|
||||
for (const auto &step : leg.annotations)
|
||||
{
|
||||
annotations_store.values.push_back(Get(step));
|
||||
}
|
||||
|
||||
return annotations_store;
|
||||
}
|
||||
|
||||
@@ -129,6 +133,7 @@ class RouteAPI : public BaseAPI
|
||||
reversed_target,
|
||||
parameters.steps);
|
||||
|
||||
util::Log(logDEBUG) << "Assembling steps " << std::endl;
|
||||
if (parameters.steps)
|
||||
{
|
||||
auto steps = guidance::assembleSteps(BaseAPI::facade,
|
||||
@@ -139,6 +144,10 @@ class RouteAPI : public BaseAPI
|
||||
reversed_source,
|
||||
reversed_target);
|
||||
|
||||
// Apply maneuver overrides before any other post
|
||||
// processing is performed
|
||||
guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry);
|
||||
|
||||
/* Perform step-based post-processing.
|
||||
*
|
||||
* Using post-processing on basis of route-steps for a single leg at a time
|
||||
@@ -255,10 +264,19 @@ class RouteAPI : public BaseAPI
|
||||
// AnnotationsType uses bit flags, & operator checks if a property is set
|
||||
if (parameters.annotations_type & RouteParameters::AnnotationsType::Speed)
|
||||
{
|
||||
double prev_speed = 0;
|
||||
annotation.values["speed"] = GetAnnotations(
|
||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
auto val = std::round(anno.distance / anno.duration * 10.) / 10.;
|
||||
return util::json::clamp_float(val);
|
||||
leg_geometry, [&prev_speed](const guidance::LegGeometry::Annotation &anno) {
|
||||
if (anno.duration < std::numeric_limits<double>::min())
|
||||
{
|
||||
return prev_speed;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto speed = std::round(anno.distance / anno.duration * 10.) / 10.;
|
||||
prev_speed = speed;
|
||||
return util::json::clamp_float(speed);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -293,11 +311,10 @@ class RouteAPI : public BaseAPI
|
||||
{
|
||||
util::json::Array nodes;
|
||||
nodes.values.reserve(leg_geometry.osm_node_ids.size());
|
||||
std::for_each(leg_geometry.osm_node_ids.begin(),
|
||||
leg_geometry.osm_node_ids.end(),
|
||||
[this, &nodes](const OSMNodeID &node_id) {
|
||||
nodes.values.push_back(static_cast<std::uint64_t>(node_id));
|
||||
});
|
||||
for (const auto node_id : leg_geometry.osm_node_ids)
|
||||
{
|
||||
nodes.values.push_back(static_cast<std::uint64_t>(node_id));
|
||||
}
|
||||
annotation.values["nodes"] = std::move(nodes);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "engine/algorithm.hpp"
|
||||
|
||||
#include "partition/cell_storage.hpp"
|
||||
#include "partition/multi_level_partition.hpp"
|
||||
#include "partitioner/cell_storage.hpp"
|
||||
#include "partitioner/multi_level_partition.hpp"
|
||||
|
||||
#include "util/filtered_graph.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
@@ -75,9 +75,9 @@ template <> class AlgorithmDataFacade<MLD>
|
||||
|
||||
virtual EdgeRange GetAdjacentEdgeRange(const NodeID node) const = 0;
|
||||
|
||||
virtual const partition::MultiLevelPartitionView &GetMultiLevelPartition() const = 0;
|
||||
virtual const partitioner::MultiLevelPartitionView &GetMultiLevelPartition() const = 0;
|
||||
|
||||
virtual const partition::CellStorageView &GetCellStorage() const = 0;
|
||||
virtual const partitioner::CellStorageView &GetCellStorage() const = 0;
|
||||
|
||||
virtual const customizer::CellMetricView &GetCellMetric() const = 0;
|
||||
|
||||
|
||||
@@ -13,19 +13,22 @@
|
||||
|
||||
#include "extractor/datasources.hpp"
|
||||
#include "extractor/edge_based_node.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/intersection_bearings_container.hpp"
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "extractor/packed_osm_ids.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "extractor/segment_data_container.hpp"
|
||||
#include "extractor/turn_data_container.hpp"
|
||||
#include "extractor/turn_lane_types.hpp"
|
||||
|
||||
#include "guidance/turn_bearing.hpp"
|
||||
#include "guidance/turn_data_container.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
|
||||
#include "contractor/query_graph.hpp"
|
||||
|
||||
#include "partition/cell_storage.hpp"
|
||||
#include "partition/multi_level_partition.hpp"
|
||||
#include "partitioner/cell_storage.hpp"
|
||||
#include "partitioner/multi_level_partition.hpp"
|
||||
|
||||
#include "storage/shared_datatype.hpp"
|
||||
#include "storage/shared_memory_ownership.hpp"
|
||||
@@ -35,7 +38,6 @@
|
||||
#include "util/filtered_graph.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/turn_bearing.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/log.hpp"
|
||||
#include "util/name_table.hpp"
|
||||
@@ -192,18 +194,21 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
util::vector_view<util::Coordinate> m_coordinate_list;
|
||||
extractor::PackedOSMIDsView m_osmnodeid_list;
|
||||
util::vector_view<std::uint32_t> m_lane_description_offsets;
|
||||
util::vector_view<extractor::guidance::TurnLaneType::Mask> m_lane_description_masks;
|
||||
util::vector_view<extractor::TurnLaneType::Mask> m_lane_description_masks;
|
||||
util::vector_view<TurnPenalty> m_turn_weight_penalties;
|
||||
util::vector_view<TurnPenalty> m_turn_duration_penalties;
|
||||
extractor::SegmentDataView segment_data;
|
||||
extractor::TurnDataView turn_data;
|
||||
extractor::EdgeBasedNodeDataView edge_based_node_data;
|
||||
guidance::TurnDataView turn_data;
|
||||
|
||||
util::vector_view<char> m_datasource_name_data;
|
||||
util::vector_view<std::size_t> m_datasource_name_offsets;
|
||||
util::vector_view<std::size_t> m_datasource_name_lengths;
|
||||
util::vector_view<util::guidance::LaneTupleIdPair> m_lane_tupel_id_pairs;
|
||||
|
||||
util::vector_view<extractor::StorageManeuverOverride> m_maneuver_overrides;
|
||||
util::vector_view<NodeID> m_maneuver_override_node_sequences;
|
||||
|
||||
std::unique_ptr<SharedRTree> m_static_rtree;
|
||||
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
|
||||
boost::filesystem::path file_index_path;
|
||||
@@ -318,10 +323,9 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
util::vector_view<LaneDataID> lane_data_ids(
|
||||
lane_data_id_ptr, layout.num_entries[storage::DataLayout::LANE_DATA_ID]);
|
||||
|
||||
const auto turn_instruction_list_ptr =
|
||||
layout.GetBlockPtr<extractor::guidance::TurnInstruction>(
|
||||
memory_ptr, storage::DataLayout::TURN_INSTRUCTION);
|
||||
util::vector_view<extractor::guidance::TurnInstruction> turn_instructions(
|
||||
const auto turn_instruction_list_ptr = layout.GetBlockPtr<guidance::TurnInstruction>(
|
||||
memory_ptr, storage::DataLayout::TURN_INSTRUCTION);
|
||||
util::vector_view<guidance::TurnInstruction> turn_instructions(
|
||||
turn_instruction_list_ptr, layout.num_entries[storage::DataLayout::TURN_INSTRUCTION]);
|
||||
|
||||
const auto entry_class_id_list_ptr =
|
||||
@@ -329,21 +333,21 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
util::vector_view<EntryClassID> entry_class_ids(
|
||||
entry_class_id_list_ptr, layout.num_entries[storage::DataLayout::ENTRY_CLASSID]);
|
||||
|
||||
const auto pre_turn_bearing_ptr = layout.GetBlockPtr<util::guidance::TurnBearing>(
|
||||
const auto pre_turn_bearing_ptr = layout.GetBlockPtr<guidance::TurnBearing>(
|
||||
memory_ptr, storage::DataLayout::PRE_TURN_BEARING);
|
||||
util::vector_view<util::guidance::TurnBearing> pre_turn_bearings(
|
||||
util::vector_view<guidance::TurnBearing> pre_turn_bearings(
|
||||
pre_turn_bearing_ptr, layout.num_entries[storage::DataLayout::PRE_TURN_BEARING]);
|
||||
|
||||
const auto post_turn_bearing_ptr = layout.GetBlockPtr<util::guidance::TurnBearing>(
|
||||
const auto post_turn_bearing_ptr = layout.GetBlockPtr<guidance::TurnBearing>(
|
||||
memory_ptr, storage::DataLayout::POST_TURN_BEARING);
|
||||
util::vector_view<util::guidance::TurnBearing> post_turn_bearings(
|
||||
util::vector_view<guidance::TurnBearing> post_turn_bearings(
|
||||
post_turn_bearing_ptr, layout.num_entries[storage::DataLayout::POST_TURN_BEARING]);
|
||||
|
||||
turn_data = extractor::TurnDataView(std::move(turn_instructions),
|
||||
std::move(lane_data_ids),
|
||||
std::move(entry_class_ids),
|
||||
std::move(pre_turn_bearings),
|
||||
std::move(post_turn_bearings));
|
||||
turn_data = guidance::TurnDataView(std::move(turn_instructions),
|
||||
std::move(lane_data_ids),
|
||||
std::move(entry_class_ids),
|
||||
std::move(pre_turn_bearings),
|
||||
std::move(post_turn_bearings));
|
||||
}
|
||||
|
||||
void InitializeNamePointers(storage::DataLayout &data_layout, char *memory_block)
|
||||
@@ -363,10 +367,10 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
offsets_ptr, data_layout.num_entries[storage::DataLayout::LANE_DESCRIPTION_OFFSETS]);
|
||||
m_lane_description_offsets = std::move(offsets);
|
||||
|
||||
auto masks_ptr = data_layout.GetBlockPtr<extractor::guidance::TurnLaneType::Mask>(
|
||||
auto masks_ptr = data_layout.GetBlockPtr<extractor::TurnLaneType::Mask>(
|
||||
memory_block, storage::DataLayout::LANE_DESCRIPTION_MASKS);
|
||||
|
||||
util::vector_view<extractor::guidance::TurnLaneType::Mask> masks(
|
||||
util::vector_view<extractor::TurnLaneType::Mask> masks(
|
||||
masks_ptr, data_layout.num_entries[storage::DataLayout::LANE_DESCRIPTION_MASKS]);
|
||||
m_lane_description_masks = std::move(masks);
|
||||
|
||||
@@ -499,6 +503,21 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
m_entry_class_table = std::move(entry_class_table);
|
||||
}
|
||||
|
||||
void InitializeManeuverOverridePointers(storage::DataLayout &data_layout, char *memory_block)
|
||||
{
|
||||
auto maneuver_overrides_ptr = data_layout.GetBlockPtr<extractor::StorageManeuverOverride>(
|
||||
memory_block, storage::DataLayout::MANEUVER_OVERRIDES);
|
||||
m_maneuver_overrides = util::vector_view<extractor::StorageManeuverOverride>(
|
||||
maneuver_overrides_ptr,
|
||||
data_layout.num_entries[storage::DataLayout::MANEUVER_OVERRIDES]);
|
||||
|
||||
auto maneuver_override_node_sequences_ptr = data_layout.GetBlockPtr<NodeID>(
|
||||
memory_block, storage::DataLayout::MANEUVER_OVERRIDE_NODE_SEQUENCES);
|
||||
m_maneuver_override_node_sequences = util::vector_view<NodeID>(
|
||||
maneuver_override_node_sequences_ptr,
|
||||
data_layout.num_entries[storage::DataLayout::MANEUVER_OVERRIDE_NODE_SEQUENCES]);
|
||||
}
|
||||
|
||||
void InitializeInternalPointers(storage::DataLayout &data_layout,
|
||||
char *memory_block,
|
||||
const std::size_t exclude_index)
|
||||
@@ -515,6 +534,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
InitializeProfilePropertiesPointer(data_layout, memory_block, exclude_index);
|
||||
InitializeRTreePointers(data_layout, memory_block);
|
||||
InitializeIntersectionClassPointers(data_layout, memory_block);
|
||||
InitializeManeuverOverridePointers(data_layout, memory_block);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -609,7 +629,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
return m_turn_duration_penalties[id];
|
||||
}
|
||||
|
||||
extractor::guidance::TurnInstruction
|
||||
osrm::guidance::TurnInstruction
|
||||
GetTurnInstructionForEdgeID(const EdgeID id) const override final
|
||||
{
|
||||
return turn_data.GetTurnInstruction(id);
|
||||
@@ -845,11 +865,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
return intersection_bearings_view.GetBearingClass(node);
|
||||
}
|
||||
|
||||
util::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const override final
|
||||
guidance::TurnBearing PreTurnBearing(const EdgeID eid) const override final
|
||||
{
|
||||
return turn_data.GetPreTurnBearing(eid);
|
||||
}
|
||||
util::guidance::TurnBearing PostTurnBearing(const EdgeID eid) const override final
|
||||
guidance::TurnBearing PostTurnBearing(const EdgeID eid) const override final
|
||||
{
|
||||
return turn_data.GetPostTurnBearing(eid);
|
||||
}
|
||||
@@ -868,13 +888,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
return m_lane_tupel_id_pairs.at(turn_data.GetLaneDataID(id));
|
||||
}
|
||||
|
||||
extractor::guidance::TurnLaneDescription
|
||||
extractor::TurnLaneDescription
|
||||
GetTurnDescription(const LaneDescriptionID lane_description_id) const override final
|
||||
{
|
||||
if (lane_description_id == INVALID_LANE_DESCRIPTIONID)
|
||||
return {};
|
||||
else
|
||||
return extractor::guidance::TurnLaneDescription(
|
||||
return extractor::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]);
|
||||
@@ -890,6 +910,39 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
{
|
||||
return edge_based_node_data.IsSegregated(id);
|
||||
}
|
||||
|
||||
std::vector<extractor::ManeuverOverride>
|
||||
GetOverridesThatStartAt(const NodeID edge_based_node_id) const override final
|
||||
{
|
||||
std::vector<extractor::ManeuverOverride> results;
|
||||
|
||||
// heterogeneous comparison:
|
||||
struct Comp
|
||||
{
|
||||
bool operator()(const extractor::StorageManeuverOverride &s, NodeID i) const
|
||||
{
|
||||
return s.start_node < i;
|
||||
}
|
||||
bool operator()(NodeID i, const extractor::StorageManeuverOverride &s) const
|
||||
{
|
||||
return i < s.start_node;
|
||||
}
|
||||
};
|
||||
|
||||
auto found_range = std::equal_range(
|
||||
m_maneuver_overrides.begin(), m_maneuver_overrides.end(), edge_based_node_id, Comp{});
|
||||
|
||||
std::for_each(found_range.first, found_range.second, [&](const auto & override) {
|
||||
std::vector<NodeID> sequence(
|
||||
m_maneuver_override_node_sequences.begin() + override.node_sequence_offset_begin,
|
||||
m_maneuver_override_node_sequences.begin() + override.node_sequence_offset_end);
|
||||
results.push_back(extractor::ManeuverOverride{std::move(sequence),
|
||||
override.instruction_node,
|
||||
override.override_type,
|
||||
override.direction});
|
||||
});
|
||||
return results;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AlgorithmT> class ContiguousInternalMemoryDataFacade;
|
||||
@@ -912,8 +965,8 @@ class ContiguousInternalMemoryDataFacade<CH>
|
||||
template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public AlgorithmDataFacade<MLD>
|
||||
{
|
||||
// MLD data
|
||||
partition::MultiLevelPartitionView mld_partition;
|
||||
partition::CellStorageView mld_cell_storage;
|
||||
partitioner::MultiLevelPartitionView mld_partition;
|
||||
partitioner::CellStorageView mld_cell_storage;
|
||||
customizer::CellMetricView mld_cell_metric;
|
||||
using QueryGraph = customizer::MultiLevelEdgeBasedGraphView;
|
||||
using GraphNode = QueryGraph::NodeArrayEntry;
|
||||
@@ -939,7 +992,7 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
|
||||
BOOST_ASSERT(data_layout.GetBlockSize(storage::DataLayout::MLD_CELL_TO_CHILDREN) > 0);
|
||||
|
||||
auto level_data =
|
||||
data_layout.GetBlockPtr<partition::MultiLevelPartitionView::LevelData>(
|
||||
data_layout.GetBlockPtr<partitioner::MultiLevelPartitionView::LevelData>(
|
||||
memory_block, storage::DataLayout::MLD_LEVEL_DATA);
|
||||
|
||||
auto mld_partition_ptr = data_layout.GetBlockPtr<PartitionID>(
|
||||
@@ -955,7 +1008,7 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
|
||||
util::vector_view<CellID> cell_to_children(mld_chilren_ptr, children_entries_count);
|
||||
|
||||
mld_partition =
|
||||
partition::MultiLevelPartitionView{level_data, partition, cell_to_children};
|
||||
partitioner::MultiLevelPartitionView{level_data, partition, cell_to_children};
|
||||
}
|
||||
|
||||
const auto weights_block_id = static_cast<storage::DataLayout::BlockID>(
|
||||
@@ -988,7 +1041,7 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
|
||||
memory_block, storage::DataLayout::MLD_CELL_SOURCE_BOUNDARY);
|
||||
auto mld_destination_boundary_ptr = data_layout.GetBlockPtr<NodeID>(
|
||||
memory_block, storage::DataLayout::MLD_CELL_DESTINATION_BOUNDARY);
|
||||
auto mld_cells_ptr = data_layout.GetBlockPtr<partition::CellStorageView::CellData>(
|
||||
auto mld_cells_ptr = data_layout.GetBlockPtr<partitioner::CellStorageView::CellData>(
|
||||
memory_block, storage::DataLayout::MLD_CELLS);
|
||||
auto mld_cell_level_offsets_ptr = data_layout.GetBlockPtr<std::uint64_t>(
|
||||
memory_block, storage::DataLayout::MLD_CELL_LEVEL_OFFSETS);
|
||||
@@ -1005,15 +1058,15 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
|
||||
source_boundary_entries_count);
|
||||
util::vector_view<NodeID> destination_boundary(mld_destination_boundary_ptr,
|
||||
destination_boundary_entries_count);
|
||||
util::vector_view<partition::CellStorageView::CellData> cells(mld_cells_ptr,
|
||||
cells_entries_counts);
|
||||
util::vector_view<partitioner::CellStorageView::CellData> cells(mld_cells_ptr,
|
||||
cells_entries_counts);
|
||||
util::vector_view<std::uint64_t> level_offsets(mld_cell_level_offsets_ptr,
|
||||
cell_level_offsets_entries_count);
|
||||
|
||||
mld_cell_storage = partition::CellStorageView{std::move(source_boundary),
|
||||
std::move(destination_boundary),
|
||||
std::move(cells),
|
||||
std::move(level_offsets)};
|
||||
mld_cell_storage = partitioner::CellStorageView{std::move(source_boundary),
|
||||
std::move(destination_boundary),
|
||||
std::move(cells),
|
||||
std::move(level_offsets)};
|
||||
}
|
||||
}
|
||||
void InitializeGraphPointer(storage::DataLayout &data_layout, char *memory_block)
|
||||
@@ -1050,12 +1103,12 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
|
||||
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory(), exclude_index);
|
||||
}
|
||||
|
||||
const partition::MultiLevelPartitionView &GetMultiLevelPartition() const override
|
||||
const partitioner::MultiLevelPartitionView &GetMultiLevelPartition() const override
|
||||
{
|
||||
return mld_partition;
|
||||
}
|
||||
|
||||
const partition::CellStorageView &GetCellStorage() const override { return mld_cell_storage; }
|
||||
const partitioner::CellStorageView &GetCellStorage() const override { return mld_cell_storage; }
|
||||
|
||||
const customizer::CellMetricView &GetCellMetric() const override { return mld_cell_metric; }
|
||||
|
||||
|
||||
@@ -10,16 +10,19 @@
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/edge_based_node_segment.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/original_edge_data.hpp"
|
||||
//#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
//#include "extractor/original_edge_data.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "extractor/turn_lane_types.hpp"
|
||||
|
||||
#include "guidance/turn_bearing.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
|
||||
#include "util/exception.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/turn_bearing.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/string_util.hpp"
|
||||
@@ -87,8 +90,7 @@ class BaseDataFacade
|
||||
// Gets the name of a datasource
|
||||
virtual StringView GetDatasourceName(const DatasourceID id) const = 0;
|
||||
|
||||
virtual extractor::guidance::TurnInstruction
|
||||
GetTurnInstructionForEdgeID(const EdgeID id) const = 0;
|
||||
virtual osrm::guidance::TurnInstruction GetTurnInstructionForEdgeID(const EdgeID id) const = 0;
|
||||
|
||||
virtual extractor::TravelMode GetTravelMode(const NodeID id) const = 0;
|
||||
|
||||
@@ -156,7 +158,7 @@ class BaseDataFacade
|
||||
|
||||
virtual bool HasLaneData(const EdgeID id) const = 0;
|
||||
virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0;
|
||||
virtual extractor::guidance::TurnLaneDescription
|
||||
virtual extractor::TurnLaneDescription
|
||||
GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0;
|
||||
|
||||
virtual NameID GetNameIndex(const NodeID id) const = 0;
|
||||
@@ -183,8 +185,8 @@ class BaseDataFacade
|
||||
|
||||
virtual double GetWeightMultiplier() const = 0;
|
||||
|
||||
virtual util::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const = 0;
|
||||
virtual util::guidance::TurnBearing PostTurnBearing(const EdgeID eid) const = 0;
|
||||
virtual osrm::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const = 0;
|
||||
virtual osrm::guidance::TurnBearing PostTurnBearing(const EdgeID eid) const = 0;
|
||||
|
||||
virtual util::guidance::BearingClass GetBearingClass(const NodeID node) const = 0;
|
||||
|
||||
@@ -193,6 +195,9 @@ class BaseDataFacade
|
||||
virtual bool IsLeftHandDriving(const NodeID id) const = 0;
|
||||
|
||||
virtual bool IsSegregated(const NodeID) const = 0;
|
||||
|
||||
virtual std::vector<extractor::ManeuverOverride>
|
||||
GetOverridesThatStartAt(const NodeID edge_based_node_id) const = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@ namespace datafacade
|
||||
{
|
||||
|
||||
/**
|
||||
* This allocator uses an IPC shared memory block as the data location.
|
||||
* Many SharedMemoryDataFacade objects can be created that point to the same shared
|
||||
* memory block.
|
||||
*/
|
||||
* This allocator uses an IPC shared memory block as the data location.
|
||||
* Many SharedMemoryDataFacade objects can be created that point to the same shared
|
||||
* memory block.
|
||||
*/
|
||||
class SharedMemoryAllocator : public ContiguousBlockAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -53,12 +53,12 @@ template <typename Algorithm> class Engine final : public EngineInterface
|
||||
{
|
||||
public:
|
||||
explicit Engine(const EngineConfig &config)
|
||||
: route_plugin(config.max_locations_viaroute, config.max_alternatives), //
|
||||
table_plugin(config.max_locations_distance_table), //
|
||||
nearest_plugin(config.max_results_nearest), //
|
||||
trip_plugin(config.max_locations_trip), //
|
||||
match_plugin(config.max_locations_map_matching), //
|
||||
tile_plugin() //
|
||||
: route_plugin(config.max_locations_viaroute, config.max_alternatives), //
|
||||
table_plugin(config.max_locations_distance_table), //
|
||||
nearest_plugin(config.max_results_nearest), //
|
||||
trip_plugin(config.max_locations_trip), //
|
||||
match_plugin(config.max_locations_map_matching, config.max_radius_map_matching), //
|
||||
tile_plugin() //
|
||||
|
||||
{
|
||||
if (config.use_shared_memory)
|
||||
|
||||
@@ -84,6 +84,7 @@ struct EngineConfig final
|
||||
int max_locations_viaroute = -1;
|
||||
int max_locations_distance_table = -1;
|
||||
int max_locations_map_matching = -1;
|
||||
double max_radius_map_matching = -1.0;
|
||||
int max_results_nearest = -1;
|
||||
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
|
||||
bool use_shared_memory = true;
|
||||
|
||||
@@ -79,7 +79,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
{
|
||||
auto results = rtree.Nearest(
|
||||
input_coordinate,
|
||||
[this, approach, &input_coordinate, bearing, bearing_range, max_distance](
|
||||
[this, approach, &input_coordinate, bearing, bearing_range](
|
||||
const CandidateSegment &segment) {
|
||||
auto use_direction =
|
||||
boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef ENGINE_GUIDANCE_ASSEMBLE_GEOMETRY_HPP
|
||||
#define ENGINE_GUIDANCE_ASSEMBLE_GEOMETRY_HPP
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
@@ -70,7 +70,7 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
|
||||
cumulative_distance += current_distance;
|
||||
|
||||
// all changes to this check have to be matched with assemble_steps
|
||||
if (path_point.turn_instruction.type != extractor::guidance::TurnType::NoTurn)
|
||||
if (path_point.turn_instruction.type != osrm::guidance::TurnType::NoTurn)
|
||||
{
|
||||
geometry.segment_distances.push_back(cumulative_distance);
|
||||
geometry.segment_offsets.push_back(geometry.locations.size());
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifndef ENGINE_GUIDANCE_ASSEMBLE_STEPS_HPP_
|
||||
#define ENGINE_GUIDANCE_ASSEMBLE_STEPS_HPP_
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "extractor/turn_lane_types.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
@@ -83,7 +83,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
StepManeuver maneuver{source_node.location,
|
||||
bearings.first,
|
||||
bearings.second,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
osrm::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Depart,
|
||||
0};
|
||||
|
||||
@@ -115,7 +115,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
segment_weight += path_point.weight_until_turn;
|
||||
|
||||
// all changes to this check have to be matched with assemble_geometry
|
||||
if (path_point.turn_instruction.type != extractor::guidance::TurnType::NoTurn)
|
||||
if (path_point.turn_instruction.type != osrm::guidance::TurnType::NoTurn)
|
||||
{
|
||||
BOOST_ASSERT(segment_weight >= 0);
|
||||
const auto name = facade.GetNameForID(step_name_id);
|
||||
@@ -127,7 +127,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
// intersections contain the classes of exiting road
|
||||
intersection.classes = facade.GetClasses(path_point.classes);
|
||||
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
steps.push_back(RouteStep{path_point.from_edge_based_node,
|
||||
step_name_id,
|
||||
is_segregated,
|
||||
name.to_string(),
|
||||
ref.to_string(),
|
||||
@@ -171,7 +172,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
intersection.lane_description =
|
||||
path_point.lane_data.second != INVALID_LANE_DESCRIPTIONID
|
||||
? facade.GetTurnDescription(path_point.lane_data.second)
|
||||
: extractor::guidance::TurnLaneDescription();
|
||||
: extractor::TurnLaneDescription();
|
||||
|
||||
// Lanes in turn are bound by total number of lanes at the location
|
||||
BOOST_ASSERT(intersection.lanes.lanes_in_turn <=
|
||||
@@ -209,7 +210,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
// intersections contain the classes of exiting road
|
||||
intersection.classes = facade.GetClasses(facade.GetClassData(target_node_id));
|
||||
BOOST_ASSERT(duration >= 0);
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
steps.push_back(RouteStep{leg_data[leg_data.size() - 1].from_edge_based_node,
|
||||
step_name_id,
|
||||
is_segregated,
|
||||
facade.GetNameForID(step_name_id).to_string(),
|
||||
facade.GetRefForID(step_name_id).to_string(),
|
||||
@@ -253,7 +255,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
BOOST_ASSERT(target_duration >= source_duration || weight == 0);
|
||||
const EdgeWeight duration = std::max(0, target_duration - source_duration);
|
||||
|
||||
steps.push_back(RouteStep{source_name_id,
|
||||
steps.push_back(RouteStep{source_node_id,
|
||||
source_name_id,
|
||||
is_segregated,
|
||||
facade.GetNameForID(source_name_id).to_string(),
|
||||
facade.GetRefForID(source_name_id).to_string(),
|
||||
@@ -290,12 +293,13 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
maneuver = {intersection.location,
|
||||
bearings.first,
|
||||
bearings.second,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
osrm::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Arrive,
|
||||
0};
|
||||
|
||||
BOOST_ASSERT(!leg_geometry.locations.empty());
|
||||
steps.push_back(RouteStep{target_name_id,
|
||||
steps.push_back(RouteStep{target_node_id,
|
||||
target_name_id,
|
||||
facade.IsSegregated(target_node_id),
|
||||
facade.GetNameForID(target_name_id).to_string(),
|
||||
facade.GetRefForID(target_name_id).to_string(),
|
||||
@@ -312,7 +316,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
leg_geometry.locations.size() - 1,
|
||||
leg_geometry.locations.size(),
|
||||
{intersection},
|
||||
facade.IsLeftHandDriving(source_node_id)});
|
||||
facade.IsLeftHandDriving(target_node_id)});
|
||||
|
||||
BOOST_ASSERT(steps.front().intersections.size() == 1);
|
||||
BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1);
|
||||
|
||||
@@ -77,10 +77,10 @@ struct AdjustToCombinedTurnStrategy : CombineStrategy
|
||||
// Set a fixed instruction type
|
||||
struct SetFixedInstructionStrategy : CombineStrategy
|
||||
{
|
||||
SetFixedInstructionStrategy(const extractor::guidance::TurnInstruction instruction);
|
||||
SetFixedInstructionStrategy(const osrm::guidance::TurnInstruction instruction);
|
||||
void operator()(RouteStep &step_at_turn_location, const RouteStep &transfer_from_step) const;
|
||||
|
||||
const extractor::guidance::TurnInstruction instruction;
|
||||
const osrm::guidance::TurnInstruction instruction;
|
||||
};
|
||||
|
||||
// Handling of staggered intersections
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef OSRM_ENGINE_GUIDANCE_COLLAPSING_UTILITY_HPP_
|
||||
#define OSRM_ENGINE_GUIDANCE_COLLAPSING_UTILITY_HPP_
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "util/attributes.hpp"
|
||||
#include "util/bearing.hpp"
|
||||
@@ -10,9 +10,6 @@
|
||||
#include <boost/range/algorithm_ext/erase.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
using osrm::extractor::guidance::TurnInstruction;
|
||||
using namespace osrm::extractor::guidance;
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
@@ -30,7 +27,7 @@ const constexpr double NAME_SEGMENT_CUTOFF_LENGTH = 105.0;
|
||||
// check if a step is completely without turn type
|
||||
inline bool hasTurnType(const RouteStep &step)
|
||||
{
|
||||
return step.maneuver.instruction.type != TurnType::NoTurn;
|
||||
return step.maneuver.instruction.type != osrm::guidance::TurnType::NoTurn;
|
||||
}
|
||||
inline bool hasWaypointType(const RouteStep &step)
|
||||
{
|
||||
@@ -67,12 +64,13 @@ inline RouteStepIterator findNextTurn(RouteStepIterator current_step)
|
||||
}
|
||||
|
||||
// alias for comparisons
|
||||
inline bool hasTurnType(const RouteStep &step, const TurnType::Enum type)
|
||||
inline bool hasTurnType(const RouteStep &step, const osrm::guidance::TurnType::Enum type)
|
||||
{
|
||||
return type == step.maneuver.instruction.type;
|
||||
}
|
||||
// alias for comparisons
|
||||
inline bool hasModifier(const RouteStep &step, const DirectionModifier::Enum modifier)
|
||||
inline bool hasModifier(const RouteStep &step,
|
||||
const osrm::guidance::DirectionModifier::Enum modifier)
|
||||
{
|
||||
return modifier == step.maneuver.instruction.direction_modifier;
|
||||
}
|
||||
@@ -96,12 +94,12 @@ inline std::size_t numberOfAllowedTurns(const RouteStep &step)
|
||||
// fulfill:
|
||||
inline bool isTrafficLightStep(const RouteStep &step)
|
||||
{
|
||||
return hasTurnType(step, TurnType::Suppressed) && numberOfAvailableTurns(step) == 2 &&
|
||||
numberOfAllowedTurns(step) == 1;
|
||||
return hasTurnType(step, osrm::guidance::TurnType::Suppressed) &&
|
||||
numberOfAvailableTurns(step) == 2 && numberOfAllowedTurns(step) == 1;
|
||||
}
|
||||
|
||||
// alias for readability
|
||||
inline void setInstructionType(RouteStep &step, const TurnType::Enum type)
|
||||
inline void setInstructionType(RouteStep &step, const osrm::guidance::TurnType::Enum type)
|
||||
{
|
||||
step.maneuver.instruction.type = type;
|
||||
}
|
||||
@@ -151,12 +149,12 @@ inline bool haveSameName(const RouteStep &lhs, const RouteStep &rhs)
|
||||
inline bool areSameSide(const RouteStep &lhs, const RouteStep &rhs)
|
||||
{
|
||||
const auto is_left = [](const RouteStep &step) {
|
||||
return hasModifier(step, DirectionModifier::Straight) ||
|
||||
return hasModifier(step, osrm::guidance::DirectionModifier::Straight) ||
|
||||
hasLeftModifier(step.maneuver.instruction);
|
||||
};
|
||||
|
||||
const auto is_right = [](const RouteStep &step) {
|
||||
return hasModifier(step, DirectionModifier::Straight) ||
|
||||
return hasModifier(step, osrm::guidance::DirectionModifier::Straight) ||
|
||||
hasRightModifier(step.maneuver.instruction);
|
||||
};
|
||||
|
||||
@@ -174,7 +172,7 @@ inline std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> st
|
||||
|
||||
// keep valid instructions
|
||||
const auto not_is_valid = [](const RouteStep &step) {
|
||||
return step.maneuver.instruction == TurnInstruction::NO_TURN() &&
|
||||
return step.maneuver.instruction == osrm::guidance::TurnInstruction::NO_TURN() &&
|
||||
step.maneuver.waypoint_type == WaypointType::None;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef ENGINE_GUIDANCE_POST_PROCESSING_HPP
|
||||
#define ENGINE_GUIDANCE_POST_PROCESSING_HPP
|
||||
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
@@ -45,6 +46,18 @@ std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps);
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
LegGeometry resyncGeometry(LegGeometry leg_geometry, const std::vector<RouteStep> &steps);
|
||||
|
||||
/**
|
||||
* Apply maneuver override relations to the selected route.
|
||||
* Should be called before any other post-processing is performed
|
||||
* to ensure that all sequences of edge-based-nodes are still in the
|
||||
* steps list.
|
||||
*
|
||||
* @param steps the steps of the route
|
||||
*/
|
||||
void applyOverrides(const datafacade::BaseDataFacade &facade,
|
||||
std::vector<RouteStep> &steps,
|
||||
const LegGeometry &geometry);
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef OSRM_ENGINE_GUIDANCE_POSTPROCESSING_TOOLKIT_HPP_
|
||||
#define OSRM_ENGINE_GUIDANCE_POSTPROCESSING_TOOLKIT_HPP_
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/turn_lane_types.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
@@ -41,7 +41,7 @@ struct IntermediateIntersection
|
||||
|
||||
// turn lane information
|
||||
util::guidance::LaneTuple lanes;
|
||||
extractor::guidance::TurnLaneDescription lane_description;
|
||||
extractor::TurnLaneDescription lane_description;
|
||||
std::vector<std::string> classes;
|
||||
};
|
||||
|
||||
@@ -59,6 +59,7 @@ inline IntermediateIntersection getInvalidIntersection()
|
||||
|
||||
struct RouteStep
|
||||
{
|
||||
NodeID from_id;
|
||||
unsigned name_id;
|
||||
bool is_segregated;
|
||||
std::string name;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef ENGINE_GUIDANCE_STEP_MANEUVER_HPP
|
||||
#define ENGINE_GUIDANCE_STEP_MANEUVER_HPP
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
@@ -28,7 +28,7 @@ struct StepManeuver
|
||||
util::Coordinate location;
|
||||
short bearing_before;
|
||||
short bearing_after;
|
||||
extractor::guidance::TurnInstruction instruction;
|
||||
osrm::guidance::TurnInstruction instruction;
|
||||
|
||||
WaypointType waypoint_type;
|
||||
unsigned exit;
|
||||
@@ -39,7 +39,7 @@ inline StepManeuver getInvalidStepManeuver()
|
||||
return {util::Coordinate{util::FloatLongitude{0.0}, util::FloatLatitude{0.0}},
|
||||
0,
|
||||
0,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
osrm::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::None,
|
||||
0};
|
||||
}
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
#define RAW_ROUTE_DATA_H
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
|
||||
#include "guidance/turn_bearing.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
|
||||
#include "engine/phantom_node.hpp"
|
||||
|
||||
#include "osrm/coordinate.hpp"
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/turn_bearing.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <vector>
|
||||
@@ -23,7 +24,9 @@ namespace engine
|
||||
|
||||
struct PathData
|
||||
{
|
||||
// id of via node of the turn
|
||||
// from edge-based-node id
|
||||
NodeID from_edge_based_node;
|
||||
// the internal OSRM id of the OSM node id that is the via node of the turn
|
||||
NodeID turn_via_node;
|
||||
// name of the street that leads to the turn
|
||||
unsigned name_id;
|
||||
@@ -42,7 +45,7 @@ struct PathData
|
||||
// will contain the duration of the turn. Otherwise it will be 0.
|
||||
EdgeWeight duration_of_turn;
|
||||
// instruction to execute at the turn
|
||||
extractor::guidance::TurnInstruction turn_instruction;
|
||||
osrm::guidance::TurnInstruction turn_instruction;
|
||||
// turn lane data
|
||||
util::guidance::LaneTupleIdPair lane_data;
|
||||
// travel mode of the street that leads to the turn
|
||||
@@ -56,9 +59,9 @@ struct PathData
|
||||
DatasourceID datasource_id;
|
||||
|
||||
// bearing (as seen from the intersection) pre-turn
|
||||
util::guidance::TurnBearing pre_turn_bearing;
|
||||
osrm::guidance::TurnBearing pre_turn_bearing;
|
||||
// bearing (as seen from the intersection) post-turn
|
||||
util::guidance::TurnBearing post_turn_bearing;
|
||||
osrm::guidance::TurnBearing post_turn_bearing;
|
||||
|
||||
// Driving side of the turn
|
||||
bool is_left_hand_driving;
|
||||
@@ -102,6 +105,58 @@ struct InternalManyRoutesResult
|
||||
|
||||
std::vector<InternalRouteResult> routes;
|
||||
};
|
||||
|
||||
inline InternalRouteResult CollapseInternalRouteResult(const InternalRouteResult &leggy_result,
|
||||
const std::vector<bool> &is_waypoint)
|
||||
{
|
||||
BOOST_ASSERT(leggy_result.is_valid());
|
||||
BOOST_ASSERT(is_waypoint[0]); // first and last coords
|
||||
BOOST_ASSERT(is_waypoint.back()); // should always be waypoints
|
||||
// Nothing to collapse! return result as is
|
||||
if (leggy_result.unpacked_path_segments.size() == 1)
|
||||
return leggy_result;
|
||||
|
||||
BOOST_ASSERT(leggy_result.segment_end_coordinates.size() > 1);
|
||||
|
||||
InternalRouteResult collapsed;
|
||||
collapsed.shortest_path_weight = leggy_result.shortest_path_weight;
|
||||
for (auto i : util::irange<std::size_t>(0, leggy_result.unpacked_path_segments.size()))
|
||||
{
|
||||
if (is_waypoint[i])
|
||||
{
|
||||
// start another leg vector
|
||||
collapsed.unpacked_path_segments.push_back(leggy_result.unpacked_path_segments[i]);
|
||||
// save new phantom node pair
|
||||
collapsed.segment_end_coordinates.push_back(leggy_result.segment_end_coordinates[i]);
|
||||
// save data about phantom nodes
|
||||
collapsed.source_traversed_in_reverse.push_back(
|
||||
leggy_result.source_traversed_in_reverse[i]);
|
||||
collapsed.target_traversed_in_reverse.push_back(
|
||||
leggy_result.target_traversed_in_reverse[i]);
|
||||
}
|
||||
else
|
||||
// no new leg, collapse the next segment into the last leg
|
||||
{
|
||||
BOOST_ASSERT(!collapsed.unpacked_path_segments.empty());
|
||||
auto &last_segment = collapsed.unpacked_path_segments.back();
|
||||
// deduplicate last segment (needs to be checked for empty for the same node query edge
|
||||
// case)
|
||||
if (!last_segment.empty())
|
||||
last_segment.pop_back();
|
||||
// update target phantom node of leg
|
||||
BOOST_ASSERT(!collapsed.segment_end_coordinates.empty());
|
||||
collapsed.segment_end_coordinates.back().target_phantom =
|
||||
leggy_result.segment_end_coordinates[i].target_phantom;
|
||||
collapsed.target_traversed_in_reverse.back() =
|
||||
leggy_result.target_traversed_in_reverse[i];
|
||||
// copy path segments into current leg
|
||||
last_segment.insert(last_segment.end(),
|
||||
leggy_result.unpacked_path_segments[i].begin(),
|
||||
leggy_result.unpacked_path_segments[i].end());
|
||||
}
|
||||
}
|
||||
return collapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,21 +25,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef PHANTOM_NODES_H
|
||||
#define PHANTOM_NODES_H
|
||||
#ifndef OSRM_ENGINE_PHANTOM_NODES_H
|
||||
#define OSRM_ENGINE_PHANTOM_NODES_H
|
||||
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "util/bearing.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
@@ -199,31 +195,6 @@ struct PhantomNodes
|
||||
PhantomNode source_phantom;
|
||||
PhantomNode target_phantom;
|
||||
};
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &out, const PhantomNodes &pn)
|
||||
{
|
||||
out << "source_coord: " << pn.source_phantom.location << "\n";
|
||||
out << "target_coord: " << pn.target_phantom.location << std::endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
|
||||
{
|
||||
out << "node1: " << pn.forward_segment_id.id << ", "
|
||||
<< "node2: " << pn.reverse_segment_id.id << ", "
|
||||
<< "fwd-w: " << pn.forward_weight << ", "
|
||||
<< "rev-w: " << pn.reverse_weight << ", "
|
||||
<< "fwd-o: " << pn.forward_weight_offset << ", "
|
||||
<< "rev-o: " << pn.reverse_weight_offset << ", "
|
||||
<< "fwd-d: " << pn.forward_duration << ", "
|
||||
<< "rev-d: " << pn.reverse_duration << ", "
|
||||
<< "fwd-do: " << pn.forward_duration_offset << ", "
|
||||
<< "rev-do: " << pn.reverse_duration_offset << ", "
|
||||
<< "comp: " << pn.component.is_tiny << " / " << pn.component.id << ", "
|
||||
<< "pos: " << pn.fwd_segment_position << ", "
|
||||
<< "loc: " << pn.location;
|
||||
return out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,9 @@ class MatchPlugin : public BasePlugin
|
||||
using CandidateLists = routing_algorithms::CandidateLists;
|
||||
static const constexpr double RADIUS_MULTIPLIER = 3;
|
||||
|
||||
MatchPlugin(const int max_locations_map_matching)
|
||||
: max_locations_map_matching(max_locations_map_matching)
|
||||
MatchPlugin(const int max_locations_map_matching, const double max_radius_map_matching)
|
||||
: max_locations_map_matching(max_locations_map_matching),
|
||||
max_radius_map_matching(max_radius_map_matching)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -35,6 +36,7 @@ class MatchPlugin : public BasePlugin
|
||||
|
||||
private:
|
||||
const int max_locations_map_matching;
|
||||
const double max_radius_map_matching;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#ifndef OSRM_ENGINE_ROUTING_BASE_HPP
|
||||
#define OSRM_ENGINE_ROUTING_BASE_HPP
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "guidance/turn_bearing.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/datafacade.hpp"
|
||||
@@ -10,7 +11,6 @@
|
||||
#include "engine/search_engine_data.hpp"
|
||||
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/guidance/turn_bearing.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
@@ -192,21 +192,22 @@ void annotatePath(const FacadeT &facade,
|
||||
BOOST_ASSERT(start_index < end_index);
|
||||
for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx)
|
||||
{
|
||||
unpacked_path.push_back(PathData{id_vector[segment_idx + 1],
|
||||
unpacked_path.push_back(PathData{*node_from,
|
||||
id_vector[segment_idx + 1],
|
||||
name_index,
|
||||
is_segregated,
|
||||
weight_vector[segment_idx],
|
||||
0,
|
||||
duration_vector[segment_idx],
|
||||
0,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
guidance::TurnInstruction::NO_TURN(),
|
||||
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
|
||||
travel_mode,
|
||||
classes,
|
||||
EMPTY_ENTRY_CLASS,
|
||||
datasource_vector[segment_idx],
|
||||
util::guidance::TurnBearing(0),
|
||||
util::guidance::TurnBearing(0),
|
||||
osrm::guidance::TurnBearing(0),
|
||||
osrm::guidance::TurnBearing(0),
|
||||
is_left_hand_driving});
|
||||
}
|
||||
BOOST_ASSERT(unpacked_path.size() > 0);
|
||||
@@ -266,21 +267,22 @@ void annotatePath(const FacadeT &facade,
|
||||
BOOST_ASSERT(segment_idx < id_vector.size() - 1);
|
||||
BOOST_ASSERT(facade.GetTravelMode(target_node_id) > 0);
|
||||
unpacked_path.push_back(
|
||||
PathData{id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
|
||||
PathData{target_node_id,
|
||||
id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
|
||||
facade.GetNameIndex(target_node_id),
|
||||
facade.IsSegregated(target_node_id),
|
||||
weight_vector[segment_idx],
|
||||
0,
|
||||
duration_vector[segment_idx],
|
||||
0,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
guidance::TurnInstruction::NO_TURN(),
|
||||
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
|
||||
facade.GetTravelMode(target_node_id),
|
||||
facade.GetClassData(target_node_id),
|
||||
EMPTY_ENTRY_CLASS,
|
||||
datasource_vector[segment_idx],
|
||||
util::guidance::TurnBearing(0),
|
||||
util::guidance::TurnBearing(0),
|
||||
guidance::TurnBearing(0),
|
||||
guidance::TurnBearing(0),
|
||||
is_target_left_hand_driving});
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ struct TurnData final
|
||||
const int turn_angle;
|
||||
const EdgeWeight weight;
|
||||
const EdgeWeight duration;
|
||||
const extractor::guidance::TurnInstruction turn_instruction;
|
||||
const guidance::TurnInstruction turn_instruction;
|
||||
};
|
||||
|
||||
using RTreeLeaf = datafacade::BaseDataFacade::RTreeLeaf;
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
@@ -41,8 +39,8 @@ class CompressedEdgeContainer
|
||||
const EdgeDuration duration2,
|
||||
// node-penalties can be added before/or after the traversal of an edge which
|
||||
// depends on whether we traverse the link forwards or backwards.
|
||||
const boost::optional<EdgeWeight> node_weight_penalty = boost::none,
|
||||
const boost::optional<EdgeDuration> node_duration_penalty = boost::none);
|
||||
const EdgeWeight node_weight_penalty = INVALID_EDGE_WEIGHT,
|
||||
const EdgeDuration node_duration_penalty = MAXIMAL_EDGE_DURATION);
|
||||
|
||||
void AddUncompressedEdge(const EdgeID edge_id,
|
||||
const NodeID target_node,
|
||||
|
||||
@@ -8,15 +8,15 @@
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "extractor/edge_based_node_segment.hpp"
|
||||
#include "extractor/extraction_turn.hpp"
|
||||
#include "extractor/guidance/turn_analysis.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "extractor/nbg_to_ebg.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "extractor/original_edge_data.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/restriction_index.hpp"
|
||||
#include "extractor/turn_lane_types.hpp"
|
||||
#include "extractor/way_restriction_map.hpp"
|
||||
#include "guidance/turn_analysis.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
|
||||
#include "util/concurrent_id_map.hpp"
|
||||
#include "util/deallocating_vector.hpp"
|
||||
@@ -76,31 +76,26 @@ class EdgeBasedGraphFactory
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const util::NameTable &name_table,
|
||||
const std::unordered_set<EdgeID> &segregated_edges,
|
||||
guidance::LaneDescriptionMap &lane_description_map);
|
||||
const LaneDescriptionMap &lane_description_map);
|
||||
|
||||
void Run(ScriptingEnvironment &scripting_environment,
|
||||
const std::string &turn_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &cnbg_ebg_mapping_path,
|
||||
const std::string &conditional_penalties_filename,
|
||||
const std::string &maneuver_overrides_filename,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const ConditionalRestrictionMap &conditional_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map);
|
||||
const WayRestrictionMap &way_restriction_map,
|
||||
const std::vector<UnresolvedManeuverOverride> &maneuver_overrides);
|
||||
|
||||
// The following get access functions destroy the content in the factory
|
||||
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
|
||||
void GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSegment> &nodes);
|
||||
void GetStartPointMarkers(std::vector<bool> &node_is_startpoint);
|
||||
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
|
||||
|
||||
// These access functions don't destroy the content
|
||||
const std::vector<BearingClassID> &GetBearingClassIds() const;
|
||||
std::vector<BearingClassID> &GetBearingClassIds();
|
||||
std::vector<util::guidance::BearingClass> GetBearingClasses() const;
|
||||
std::vector<util::guidance::EntryClass> GetEntryClasses() const;
|
||||
std::uint32_t GetConnectivityChecksum() const;
|
||||
|
||||
std::uint64_t GetNumberOfEdgeBasedNodes() const;
|
||||
|
||||
@@ -142,6 +137,7 @@ class EdgeBasedGraphFactory
|
||||
std::vector<EdgeBasedNodeSegment> m_edge_based_node_segments;
|
||||
EdgeBasedNodeDataContainer &m_edge_based_node_container;
|
||||
util::DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
|
||||
std::uint32_t m_connectivity_checksum;
|
||||
|
||||
// The number of edge-based nodes is mostly made up out of the edges in the node-based graph.
|
||||
// Any edge in the node-based graph represents a node in the edge-based graph. In addition, we
|
||||
@@ -159,7 +155,7 @@ class EdgeBasedGraphFactory
|
||||
|
||||
const util::NameTable &name_table;
|
||||
const std::unordered_set<EdgeID> &segregated_edges;
|
||||
guidance::LaneDescriptionMap &lane_description_map;
|
||||
const LaneDescriptionMap &lane_description_map;
|
||||
|
||||
// In the edge based graph, any traversable (non reversed) edge of the node-based graph forms a
|
||||
// node of the edge-based graph. To be able to name these nodes, we loop over the node-based
|
||||
@@ -175,28 +171,22 @@ class EdgeBasedGraphFactory
|
||||
|
||||
// Edge-expanded edges are generate for all valid turns. The validity can be checked via the
|
||||
// restriction maps
|
||||
void GenerateEdgeExpandedEdges(ScriptingEnvironment &scripting_environment,
|
||||
const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &conditional_turn_penalties_filename,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const ConditionalRestrictionMap &conditional_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map);
|
||||
void
|
||||
GenerateEdgeExpandedEdges(ScriptingEnvironment &scripting_environment,
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &conditional_turn_penalties_filename,
|
||||
const std::string &maneuver_overrides_filename,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const ConditionalRestrictionMap &conditional_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map,
|
||||
const std::vector<UnresolvedManeuverOverride> &maneuver_overrides);
|
||||
|
||||
NBGToEBG InsertEdgeBasedNode(const NodeID u, const NodeID v);
|
||||
|
||||
std::size_t restricted_turns_counter;
|
||||
std::size_t skipped_uturns_counter;
|
||||
std::size_t skipped_barrier_turns_counter;
|
||||
|
||||
// mapping of node-based edges to edge-based nodes
|
||||
std::vector<NodeID> nbe_to_ebn_mapping;
|
||||
util::ConcurrentIDMap<util::guidance::BearingClass, BearingClassID> bearing_class_hash;
|
||||
std::vector<BearingClassID> bearing_class_by_node_based_node;
|
||||
util::ConcurrentIDMap<util::guidance::EntryClass, EntryClassID> entry_class_hash;
|
||||
};
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace extractor
|
||||
class ExtractionContainers
|
||||
{
|
||||
void PrepareNodes();
|
||||
void PrepareManeuverOverrides();
|
||||
void PrepareRestrictions();
|
||||
void PrepareEdges(ScriptingEnvironment &scripting_environment);
|
||||
|
||||
@@ -63,6 +64,9 @@ class ExtractionContainers
|
||||
std::vector<ConditionalTurnRestriction> conditional_turn_restrictions;
|
||||
std::vector<TurnRestriction> unconditional_turn_restrictions;
|
||||
|
||||
std::vector<InputManeuverOverride> external_maneuver_overrides_list;
|
||||
std::vector<UnresolvedManeuverOverride> internal_maneuver_overrides;
|
||||
|
||||
ExtractionContainers();
|
||||
|
||||
void PrepareData(ScriptingEnvironment &scripting_environment,
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "extractor/guidance/parsing_toolkit.hpp"
|
||||
#include "guidance/parsing_toolkit.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -35,10 +35,10 @@ template <typename Iterator> struct iso_8601_grammar : qi::grammar<Iterator, uns
|
||||
using qi::_c;
|
||||
using qi::_pass;
|
||||
using qi::_val;
|
||||
using qi::char_;
|
||||
using qi::eoi;
|
||||
using qi::eps;
|
||||
using qi::uint_;
|
||||
using qi::char_;
|
||||
|
||||
hh = uint2_p[_pass = bind([](unsigned x) { return x < 24; }, _1), _val = _1];
|
||||
mm = uint2_p[_pass = bind([](unsigned x) { return x < 60; }, _1), _val = _1];
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#ifndef OSRM_EXTRACTION_TURN_HPP
|
||||
#define OSRM_EXTRACTION_TURN_HPP
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include "extractor/road_classification.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
|
||||
#include <extractor/guidance/intersection.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
@@ -12,35 +13,122 @@ namespace osrm
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
struct ExtractionTurnLeg
|
||||
{
|
||||
ExtractionTurnLeg(bool is_restricted,
|
||||
bool is_motorway,
|
||||
bool is_link,
|
||||
int number_of_lanes,
|
||||
int highway_turn_classification,
|
||||
int access_turn_classification,
|
||||
int speed,
|
||||
RoadPriorityClass::Enum priority_class,
|
||||
bool is_incoming,
|
||||
bool is_outgoing)
|
||||
: is_restricted(is_restricted), is_motorway(is_motorway), is_link(is_link),
|
||||
number_of_lanes(number_of_lanes),
|
||||
highway_turn_classification(highway_turn_classification),
|
||||
access_turn_classification(access_turn_classification), speed(speed),
|
||||
priority_class(priority_class), is_incoming(is_incoming), is_outgoing(is_outgoing)
|
||||
{
|
||||
}
|
||||
|
||||
const bool is_restricted;
|
||||
const bool is_motorway;
|
||||
const bool is_link;
|
||||
const int number_of_lanes;
|
||||
const int highway_turn_classification;
|
||||
const int access_turn_classification;
|
||||
const int speed;
|
||||
const RoadPriorityClass::Enum priority_class;
|
||||
const bool is_incoming;
|
||||
const bool is_outgoing;
|
||||
};
|
||||
|
||||
struct ExtractionTurn
|
||||
{
|
||||
ExtractionTurn(double angle,
|
||||
int number_of_roads,
|
||||
bool is_u_turn,
|
||||
bool has_traffic_light,
|
||||
bool source_restricted,
|
||||
bool target_restricted,
|
||||
bool is_left_hand_driving,
|
||||
bool source_restricted,
|
||||
TravelMode source_mode,
|
||||
TravelMode target_mode)
|
||||
bool source_is_motorway,
|
||||
bool source_is_link,
|
||||
int source_number_of_lanes,
|
||||
int source_highway_turn_classification,
|
||||
int source_access_turn_classification,
|
||||
int source_speed,
|
||||
RoadPriorityClass::Enum source_priority_class,
|
||||
|
||||
bool target_restricted,
|
||||
TravelMode target_mode,
|
||||
bool target_is_motorway,
|
||||
bool target_is_link,
|
||||
int target_number_of_lanes,
|
||||
int target_highway_turn_classification,
|
||||
int target_access_turn_classification,
|
||||
int target_speed,
|
||||
RoadPriorityClass::Enum target_priority_class,
|
||||
|
||||
const std::vector<ExtractionTurnLeg> &roads_on_the_right,
|
||||
const std::vector<ExtractionTurnLeg> &roads_on_the_left)
|
||||
: angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn),
|
||||
has_traffic_light(has_traffic_light), source_restricted(source_restricted),
|
||||
target_restricted(target_restricted), is_left_hand_driving(is_left_hand_driving),
|
||||
weight(0.), duration(0.), source_mode(source_mode), target_mode(target_mode)
|
||||
has_traffic_light(has_traffic_light), is_left_hand_driving(is_left_hand_driving),
|
||||
|
||||
source_restricted(source_restricted), source_mode(source_mode),
|
||||
source_is_motorway(source_is_motorway), source_is_link(source_is_link),
|
||||
source_number_of_lanes(source_number_of_lanes),
|
||||
source_highway_turn_classification(source_highway_turn_classification),
|
||||
source_access_turn_classification(source_access_turn_classification),
|
||||
source_speed(source_speed), source_priority_class(source_priority_class),
|
||||
|
||||
target_restricted(target_restricted), target_mode(target_mode),
|
||||
target_is_motorway(target_is_motorway), target_is_link(target_is_link),
|
||||
target_number_of_lanes(target_number_of_lanes),
|
||||
target_highway_turn_classification(target_highway_turn_classification),
|
||||
target_access_turn_classification(target_access_turn_classification),
|
||||
target_speed(target_speed), target_priority_class(target_priority_class),
|
||||
|
||||
roads_on_the_right(roads_on_the_right), roads_on_the_left(roads_on_the_left), weight(0.),
|
||||
duration(0.)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
const double angle;
|
||||
const int number_of_roads;
|
||||
const bool is_u_turn;
|
||||
const bool has_traffic_light;
|
||||
const bool source_restricted;
|
||||
const bool target_restricted;
|
||||
const bool is_left_hand_driving;
|
||||
|
||||
// source info
|
||||
const bool source_restricted;
|
||||
const TravelMode source_mode;
|
||||
const bool source_is_motorway;
|
||||
const bool source_is_link;
|
||||
const int source_number_of_lanes;
|
||||
const int source_highway_turn_classification;
|
||||
const int source_access_turn_classification;
|
||||
const int source_speed;
|
||||
const RoadPriorityClass::Enum source_priority_class;
|
||||
|
||||
// target info
|
||||
const bool target_restricted;
|
||||
const TravelMode target_mode;
|
||||
const bool target_is_motorway;
|
||||
const bool target_is_link;
|
||||
const int target_number_of_lanes;
|
||||
const int target_highway_turn_classification;
|
||||
const int target_access_turn_classification;
|
||||
const int target_speed;
|
||||
const RoadPriorityClass::Enum target_priority_class;
|
||||
|
||||
const std::vector<ExtractionTurnLeg> roads_on_the_right;
|
||||
const std::vector<ExtractionTurnLeg> roads_on_the_left;
|
||||
|
||||
double weight;
|
||||
double duration;
|
||||
TravelMode source_mode;
|
||||
TravelMode target_mode;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef EXTRACTION_WAY_HPP
|
||||
#define EXTRACTION_WAY_HPP
|
||||
|
||||
#include "extractor/guidance/road_classification.hpp"
|
||||
#include "extractor/road_classification.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
@@ -54,15 +54,17 @@ struct ExtractionWay
|
||||
exits.clear();
|
||||
turn_lanes_forward.clear();
|
||||
turn_lanes_backward.clear();
|
||||
road_classification = guidance::RoadClassification();
|
||||
forward_travel_mode = extractor::TRAVEL_MODE_INACCESSIBLE;
|
||||
backward_travel_mode = extractor::TRAVEL_MODE_INACCESSIBLE;
|
||||
road_classification = RoadClassification();
|
||||
forward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
|
||||
backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
|
||||
roundabout = false;
|
||||
circular = false;
|
||||
is_startpoint = true;
|
||||
forward_restricted = false;
|
||||
backward_restricted = false;
|
||||
is_left_hand_driving = false;
|
||||
highway_turn_classification = 0;
|
||||
access_turn_classification = 0;
|
||||
}
|
||||
|
||||
// wrappers to allow assigning nil (nullptr) to string values
|
||||
@@ -111,9 +113,9 @@ struct ExtractionWay
|
||||
std::string exits;
|
||||
std::string turn_lanes_forward;
|
||||
std::string turn_lanes_backward;
|
||||
guidance::RoadClassification road_classification;
|
||||
extractor::TravelMode forward_travel_mode : 4;
|
||||
extractor::TravelMode backward_travel_mode : 4;
|
||||
RoadClassification road_classification;
|
||||
TravelMode forward_travel_mode : 4;
|
||||
TravelMode backward_travel_mode : 4;
|
||||
|
||||
// Boolean flags
|
||||
bool roundabout : 1;
|
||||
@@ -123,6 +125,10 @@ struct ExtractionWay
|
||||
bool backward_restricted : 1;
|
||||
bool is_left_hand_driving : 1;
|
||||
bool : 2;
|
||||
|
||||
// user classifications for turn penalties
|
||||
std::uint8_t highway_turn_classification : 4;
|
||||
std::uint8_t access_turn_classification : 4;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "extractor/edge_based_graph_factory.hpp"
|
||||
#include "extractor/extractor_config.hpp"
|
||||
#include "extractor/graph_compressor.hpp"
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "extractor/packed_osm_ids.hpp"
|
||||
|
||||
#include "guidance/guidance_processing.hpp"
|
||||
#include "guidance/turn_data_container.hpp"
|
||||
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
@@ -47,7 +51,6 @@ namespace extractor
|
||||
|
||||
class ScriptingEnvironment;
|
||||
struct ProfileProperties;
|
||||
class NodeBasedGraphFactory;
|
||||
|
||||
class Extractor
|
||||
{
|
||||
@@ -58,9 +61,10 @@ class Extractor
|
||||
private:
|
||||
ExtractorConfig config;
|
||||
|
||||
std::tuple<guidance::LaneDescriptionMap,
|
||||
std::tuple<LaneDescriptionMap,
|
||||
std::vector<TurnRestriction>,
|
||||
std::vector<ConditionalTurnRestriction>>
|
||||
std::vector<ConditionalTurnRestriction>,
|
||||
std::vector<UnresolvedManeuverOverride>>
|
||||
ParseOSMData(ScriptingEnvironment &scripting_environment, const unsigned number_of_threads);
|
||||
|
||||
EdgeID BuildEdgeExpandedGraph(
|
||||
@@ -73,8 +77,9 @@ class Extractor
|
||||
const std::vector<TurnRestriction> &turn_restrictions,
|
||||
const std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
|
||||
const std::unordered_set<EdgeID> &segregated_edges,
|
||||
// might have to be updated to add new lane combinations
|
||||
guidance::LaneDescriptionMap &turn_lane_map,
|
||||
const util::NameTable &name_table,
|
||||
const std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
const LaneDescriptionMap &turn_lane_map,
|
||||
// for calculating turn penalties
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
// output data
|
||||
@@ -83,7 +88,7 @@ class Extractor
|
||||
std::vector<bool> &node_is_startpoint,
|
||||
std::vector<EdgeWeight> &edge_based_node_weights,
|
||||
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
||||
const std::string &intersection_class_output_file);
|
||||
std::uint32_t &connectivity_checksum);
|
||||
|
||||
void FindComponents(unsigned max_edge_id,
|
||||
const util::DeallocatingVector<EdgeBasedEdge> &input_edge_list,
|
||||
@@ -103,12 +108,17 @@ class Extractor
|
||||
const std::string &path,
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions);
|
||||
|
||||
// Find all "segregated" edges, e.g. edges that can be skipped in turn instructions.
|
||||
// The main cases are:
|
||||
// - middle edges between two osm ways in one logic road (U-turn)
|
||||
// - staggered intersections (X-cross)
|
||||
// - square/circle intersections
|
||||
std::unordered_set<EdgeID> FindSegregatedNodes(NodeBasedGraphFactory &factory);
|
||||
void ProcessGuidanceTurns(
|
||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const EdgeBasedNodeDataContainer &edge_based_node_container,
|
||||
const std::vector<util::Coordinate> &node_coordinates,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::vector<TurnRestriction> &turn_restrictions,
|
||||
const std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
|
||||
const util::NameTable &name_table,
|
||||
LaneDescriptionMap lane_description_map,
|
||||
ScriptingEnvironment &scripting_environment);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define EXTRACTOR_CALLBACKS_HPP
|
||||
|
||||
#include "extractor/class_data.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/turn_lane_types.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
@@ -48,6 +48,7 @@ struct ExtractionWay;
|
||||
struct ExtractionRelation;
|
||||
struct ProfileProperties;
|
||||
struct InputConditionalTurnRestriction;
|
||||
struct InputManeuverOverride;
|
||||
|
||||
/**
|
||||
* This class is used by the extractor with the results of the
|
||||
@@ -67,7 +68,7 @@ class ExtractorCallbacks
|
||||
StringMap string_map;
|
||||
ExtractionContainers &external_memory;
|
||||
std::unordered_map<std::string, ClassData> &classes_map;
|
||||
guidance::LaneDescriptionMap &lane_description_map;
|
||||
LaneDescriptionMap &lane_description_map;
|
||||
bool fallback_to_duration;
|
||||
bool force_split_edges;
|
||||
|
||||
@@ -76,7 +77,7 @@ class ExtractorCallbacks
|
||||
|
||||
explicit ExtractorCallbacks(ExtractionContainers &extraction_containers,
|
||||
std::unordered_map<std::string, ClassData> &classes_map,
|
||||
guidance::LaneDescriptionMap &lane_description_map,
|
||||
LaneDescriptionMap &lane_description_map,
|
||||
const ProfileProperties &properties);
|
||||
|
||||
ExtractorCallbacks(const ExtractorCallbacks &) = delete;
|
||||
@@ -90,6 +91,9 @@ class ExtractorCallbacks
|
||||
|
||||
// warning: caller needs to take care of synchronization!
|
||||
void ProcessWay(const osmium::Way ¤t_way, const ExtractionWay &result_way);
|
||||
|
||||
// warning: caller needs to take care of synchronization!
|
||||
void ProcessManeuverOverride(const InputManeuverOverride & override);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,8 @@ struct ExtractorConfig final : storage::IOConfig
|
||||
".osrm.properties",
|
||||
".osrm.icd",
|
||||
".osrm.cnbg",
|
||||
".osrm.cnbg_to_ebg"}),
|
||||
".osrm.cnbg_to_ebg",
|
||||
".osrm.maneuver_overrides"}),
|
||||
requested_num_threads(0),
|
||||
parse_conditionals(false),
|
||||
use_locations_cache(true)
|
||||
|
||||
+11
-38
@@ -2,11 +2,10 @@
|
||||
#define OSRM_EXTRACTOR_FILES_HPP
|
||||
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/node_data_container.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "extractor/serialization.hpp"
|
||||
#include "extractor/turn_data_container.hpp"
|
||||
#include "extractor/turn_lane_types.hpp"
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
@@ -79,7 +78,8 @@ inline void writeProfileProperties(const boost::filesystem::path &path,
|
||||
template <typename EdgeBasedEdgeVector>
|
||||
void writeEdgeBasedGraph(const boost::filesystem::path &path,
|
||||
EdgeID const number_of_edge_based_nodes,
|
||||
const EdgeBasedEdgeVector &edge_based_edge_list)
|
||||
const EdgeBasedEdgeVector &edge_based_edge_list,
|
||||
const std::uint32_t connectivity_checksum)
|
||||
{
|
||||
static_assert(std::is_same<typename EdgeBasedEdgeVector::value_type, EdgeBasedEdge>::value, "");
|
||||
|
||||
@@ -87,12 +87,14 @@ void writeEdgeBasedGraph(const boost::filesystem::path &path,
|
||||
|
||||
writer.WriteElementCount64(number_of_edge_based_nodes);
|
||||
storage::serialization::write(writer, edge_based_edge_list);
|
||||
writer.WriteOne(connectivity_checksum);
|
||||
}
|
||||
|
||||
template <typename EdgeBasedEdgeVector>
|
||||
void readEdgeBasedGraph(const boost::filesystem::path &path,
|
||||
EdgeID &number_of_edge_based_nodes,
|
||||
EdgeBasedEdgeVector &edge_based_edge_list)
|
||||
EdgeBasedEdgeVector &edge_based_edge_list,
|
||||
std::uint32_t &connectivity_checksum)
|
||||
{
|
||||
static_assert(std::is_same<typename EdgeBasedEdgeVector::value_type, EdgeBasedEdge>::value, "");
|
||||
|
||||
@@ -100,6 +102,7 @@ void readEdgeBasedGraph(const boost::filesystem::path &path,
|
||||
|
||||
number_of_edge_based_nodes = reader.ReadElementCount64();
|
||||
storage::serialization::read(reader, edge_based_edge_list);
|
||||
reader.ReadInto(connectivity_checksum);
|
||||
}
|
||||
|
||||
// reads .osrm.nodes
|
||||
@@ -197,34 +200,6 @@ inline void writeSegmentData(const boost::filesystem::path &path, const SegmentD
|
||||
serialization::write(writer, segment_data);
|
||||
}
|
||||
|
||||
// reads .osrm.edges
|
||||
template <typename TurnDataT>
|
||||
inline void readTurnData(const boost::filesystem::path &path, TurnDataT &turn_data)
|
||||
{
|
||||
static_assert(std::is_same<TurnDataContainer, TurnDataT>::value ||
|
||||
std::is_same<TurnDataView, TurnDataT>::value ||
|
||||
std::is_same<TurnDataExternalContainer, TurnDataT>::value,
|
||||
"");
|
||||
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
|
||||
storage::io::FileReader reader{path, fingerprint};
|
||||
|
||||
serialization::read(reader, turn_data);
|
||||
}
|
||||
|
||||
// writes .osrm.edges
|
||||
template <typename TurnDataT>
|
||||
inline void writeTurnData(const boost::filesystem::path &path, const TurnDataT &turn_data)
|
||||
{
|
||||
static_assert(std::is_same<TurnDataContainer, TurnDataT>::value ||
|
||||
std::is_same<TurnDataView, TurnDataT>::value ||
|
||||
std::is_same<TurnDataExternalContainer, TurnDataT>::value,
|
||||
"");
|
||||
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
|
||||
storage::io::FileWriter writer{path, fingerprint};
|
||||
|
||||
serialization::write(writer, turn_data);
|
||||
}
|
||||
|
||||
// reads .osrm.ebg_nodes
|
||||
template <typename NodeDataT>
|
||||
inline void readNodeData(const boost::filesystem::path &path, NodeDataT &node_data)
|
||||
@@ -259,9 +234,8 @@ inline void readTurnLaneDescriptions(const boost::filesystem::path &path,
|
||||
OffsetsT &turn_offsets,
|
||||
MaskT &turn_masks)
|
||||
{
|
||||
static_assert(
|
||||
std::is_same<typename MaskT::value_type, extractor::guidance::TurnLaneType::Mask>::value,
|
||||
"");
|
||||
static_assert(std::is_same<typename MaskT::value_type, extractor::TurnLaneType::Mask>::value,
|
||||
"");
|
||||
static_assert(std::is_same<typename OffsetsT::value_type, std::uint32_t>::value, "");
|
||||
|
||||
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
|
||||
@@ -277,9 +251,8 @@ inline void writeTurnLaneDescriptions(const boost::filesystem::path &path,
|
||||
const OffsetsT &turn_offsets,
|
||||
const MaskT &turn_masks)
|
||||
{
|
||||
static_assert(
|
||||
std::is_same<typename MaskT::value_type, extractor::guidance::TurnLaneType::Mask>::value,
|
||||
"");
|
||||
static_assert(std::is_same<typename MaskT::value_type, extractor::TurnLaneType::Mask>::value,
|
||||
"");
|
||||
static_assert(std::is_same<typename OffsetsT::value_type, std::uint32_t>::value, "");
|
||||
|
||||
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#include "util/node_based_graph.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "extractor/guidance/coordinate_extractor.hpp"
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "guidance/coordinate_extractor.hpp"
|
||||
#include "guidance/intersection.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/geojson_debug_policy_toolkit.hpp"
|
||||
|
||||
@@ -60,7 +60,7 @@ operator()(const NodeID intersection_node,
|
||||
const boost::optional<util::json::Object> &way_style) const
|
||||
{
|
||||
// request the number of lanes. This process needs to be in sync with what happens over at
|
||||
// intersection_generator
|
||||
// intersection analysis
|
||||
const auto intersection_lanes =
|
||||
intersection.FindMaximum(guidance::makeExtractLanesForRoad(node_based_graph));
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "extractor/scripting_environment.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "extractor/maneuver_override.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
|
||||
#include <memory>
|
||||
@@ -28,6 +29,7 @@ class GraphCompressor
|
||||
ScriptingEnvironment &scripting_environment,
|
||||
std::vector<TurnRestriction> &turn_restrictions,
|
||||
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
|
||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||
util::NodeBasedDynamicGraph &graph,
|
||||
const std::vector<NodeBasedEdgeAnnotation> &node_data_container,
|
||||
CompressedEdgeContainer &geometry_compressor);
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_GENERATOR_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_GENERATOR_HPP_
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/guidance/coordinate_extractor.hpp"
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/intersection_normalization_operation.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/restriction_index.hpp"
|
||||
#include "util/attributes.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
struct IntersectionGenerationParameters
|
||||
{
|
||||
NodeID nid;
|
||||
EdgeID via_eid;
|
||||
};
|
||||
|
||||
// The Intersection Generator is given a turn location and generates an intersection representation
|
||||
// from it. For this all turn possibilities are analysed.
|
||||
// We consider turn restrictions to indicate possible turns. U-turns are generated based on profile
|
||||
// decisions.
|
||||
class IntersectionGenerator
|
||||
{
|
||||
public:
|
||||
IntersectionGenerator(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const EdgeBasedNodeDataContainer &node_data_container,
|
||||
const RestrictionMap &restriction_map,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const CompressedEdgeContainer &compressed_edge_container);
|
||||
|
||||
// For a source node `a` and a via edge `ab` creates an intersection at target `b`.
|
||||
//
|
||||
// a . . . b . .
|
||||
// .
|
||||
// .
|
||||
//
|
||||
IntersectionView operator()(const NodeID nid, const EdgeID via_eid) const;
|
||||
|
||||
/*
|
||||
* Compute the shape of an intersection, returning a set of connected roads, without any further
|
||||
* concern for which of the entries are actually allowed.
|
||||
* The shape also only comes with turn bearings, not with turn angles. All turn angles will be
|
||||
* set to zero
|
||||
*/
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
IntersectionShape
|
||||
ComputeIntersectionShape(const NodeID center_node,
|
||||
const boost::optional<NodeID> sorting_base = boost::none,
|
||||
bool use_low_precision_angles = false) const;
|
||||
|
||||
// Graph Compression cannot compress every setting. For example any barrier/traffic light cannot
|
||||
// be compressed. As a result, a simple road of the form `a ----- b` might end up as having an
|
||||
// intermediate intersection, if there is a traffic light in between. If we want to look farther
|
||||
// down a road, finding the next actual decision requires the look at multiple intersections.
|
||||
// Here we follow the road until we either reach a dead end or find the next intersection with
|
||||
// more than a single next road. This function skips over degree two nodes to find coorect input
|
||||
// for GetConnectedRoads.
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
IntersectionGenerationParameters SkipDegreeTwoNodes(const NodeID starting_node,
|
||||
const EdgeID via_edge) const;
|
||||
|
||||
// Allow access to the coordinate extractor for all owners
|
||||
const CoordinateExtractor &GetCoordinateExtractor() const;
|
||||
|
||||
// Check for restrictions/barriers and generate a list of valid and invalid turns present at
|
||||
// the node reached from `from_node` via `via_eid`. The resulting candidates have to be analysed
|
||||
// for their actual instructions later on.
|
||||
// The switch for `use_low_precision_angles` enables a faster mode that will procude less
|
||||
// accurate coordinates. It should be good enough to check order of turns, find straightmost
|
||||
// turns. Even good enough to do some simple angle verifications. It is mostly available to
|
||||
// allow for faster graph traversal in the extraction phase.
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
IntersectionView GetConnectedRoads(const NodeID from_node,
|
||||
const EdgeID via_eid,
|
||||
const bool use_low_precision_angles = false) const;
|
||||
|
||||
/*
|
||||
* To be used in the road network, we need to check for valid/restricted turns. These two
|
||||
* functions transform a basic intersection / a normalised intersection into the
|
||||
* correct view when entering via a given edge.
|
||||
*/
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
IntersectionView
|
||||
TransformIntersectionShapeIntoView(const NodeID previous_node,
|
||||
const EdgeID entering_via_edge,
|
||||
const IntersectionShape &intersection) const;
|
||||
// version for normalised intersection
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
IntersectionView TransformIntersectionShapeIntoView(
|
||||
const NodeID previous_node,
|
||||
const EdgeID entering_via_edge,
|
||||
const IntersectionShape &normalised_intersection,
|
||||
const IntersectionShape &intersection,
|
||||
const std::vector<IntersectionNormalizationOperation> &merging_map) const;
|
||||
|
||||
private:
|
||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||
const EdgeBasedNodeDataContainer &node_data_container;
|
||||
const RestrictionMap &restriction_map;
|
||||
const std::unordered_set<NodeID> &barrier_nodes;
|
||||
const std::vector<util::Coordinate> &coordinates;
|
||||
|
||||
// own state, used to find the correct coordinates along a road
|
||||
const CoordinateExtractor coordinate_extractor;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /* OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_GENERATOR_HPP_ */
|
||||
@@ -1,25 +0,0 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_NORMALIZATION_OPERATION_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_NORMALIZATION_OPERATION_HPP_
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
struct IntersectionNormalizationOperation
|
||||
{
|
||||
// the source of the merge, not part of the intersection after the merge is performed.
|
||||
EdgeID merged_eid;
|
||||
// the edge that is covering the `merged_eid`
|
||||
EdgeID into_eid;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /*OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_NORMALIZATION_OPERATION_HPP_*/
|
||||
@@ -1,125 +0,0 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_NORMALIZER_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_NORMALIZER_HPP_
|
||||
|
||||
#include "util/attributes.hpp"
|
||||
#include "util/name_table.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "extractor/guidance/coordinate_extractor.hpp"
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/intersection_generator.hpp"
|
||||
#include "extractor/guidance/intersection_normalization_operation.hpp"
|
||||
#include "extractor/guidance/mergable_road_detector.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/suffix_table.hpp"
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
/*
|
||||
* An intersection is a central part in computing guidance decisions. However the model in OSM and
|
||||
* the view we want to use in guidance are not necessarily the same thing. We have to account for
|
||||
* some models that are chosen explicitly in OSM and that don't actually describe how a human would
|
||||
* experience an intersection.
|
||||
*
|
||||
* For example, if a small pedestrian island is located at a traffic light right in the middle of a
|
||||
* road, OSM tends to model the road as two separate ways. A human would consider these two ways a
|
||||
* single road, though. In this normalizer, we try to account for these subtle differences between
|
||||
* OSM data and human perception to improve our decision base for guidance later on.
|
||||
*/
|
||||
class IntersectionNormalizer
|
||||
{
|
||||
public:
|
||||
struct NormalizationResult
|
||||
{
|
||||
IntersectionShape normalized_shape;
|
||||
std::vector<IntersectionNormalizationOperation> performed_merges;
|
||||
};
|
||||
IntersectionNormalizer(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const EdgeBasedNodeDataContainer &node_data_container,
|
||||
const std::vector<util::Coordinate> &node_coordinates,
|
||||
const util::NameTable &name_table,
|
||||
const SuffixTable &street_name_suffix_table,
|
||||
const IntersectionGenerator &intersection_generator);
|
||||
|
||||
// The function takes an intersection an converts it to a `perceived` intersection which closer
|
||||
// represents how a human might experience the intersection
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
NormalizationResult operator()(const NodeID node_at_intersection,
|
||||
IntersectionShape intersection) const;
|
||||
|
||||
private:
|
||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||
const IntersectionGenerator &intersection_generator;
|
||||
const MergableRoadDetector mergable_road_detector;
|
||||
|
||||
/* check if two indices in an intersection can be seen as a single road in the perceived
|
||||
* intersection representation. See below for an example. Utility function for
|
||||
* MergeSegregatedRoads. It also checks for neighboring merges.
|
||||
* This is due possible segments where multiple roads could end up being merged into one.
|
||||
* We only support merging two roads, not three or more, though.
|
||||
* c c
|
||||
* / /
|
||||
* a - b -> a - b - (c,d) but not a - b d -> a,b,(cde)
|
||||
* \ \
|
||||
* d e
|
||||
*/
|
||||
bool CanMerge(const NodeID intersection_node,
|
||||
const IntersectionShape &intersection,
|
||||
std::size_t first_index,
|
||||
std::size_t second_index) const;
|
||||
|
||||
// Perform an Actual Merge
|
||||
IntersectionNormalizationOperation
|
||||
DetermineMergeDirection(const IntersectionShapeData &lhs,
|
||||
const IntersectionShapeData &rhs) const;
|
||||
IntersectionShapeData MergeRoads(const IntersectionShapeData &destination,
|
||||
const IntersectionShapeData &source) const;
|
||||
IntersectionShapeData MergeRoads(const IntersectionNormalizationOperation direction,
|
||||
const IntersectionShapeData &lhs,
|
||||
const IntersectionShapeData &rhs,
|
||||
const double opposite_bearing) const;
|
||||
|
||||
// Merge segregated roads to omit invalid turns in favor of treating segregated roads as
|
||||
// one.
|
||||
// This function combines roads the following way:
|
||||
//
|
||||
// * *
|
||||
// * is converted to *
|
||||
// v ^ +
|
||||
// v ^ +
|
||||
//
|
||||
// The treatment results in a straight turn angle of 180º rather than a turn angle of approx
|
||||
// 160
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
NormalizationResult MergeSegregatedRoads(const NodeID intersection_node,
|
||||
IntersectionShape intersection) const;
|
||||
|
||||
// The counterpiece to mergeSegregatedRoads. While we can adjust roads that split up at the
|
||||
// intersection itself, it can also happen that intersections are connected to joining roads.
|
||||
//
|
||||
// * *
|
||||
// * is converted to *
|
||||
// v a --- a ---
|
||||
// v ^ +
|
||||
// v ^ +
|
||||
// b
|
||||
//
|
||||
// for the local view of b at a.
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
IntersectionShape AdjustBearingsForMergeAtDestination(const NodeID node_at_intersection,
|
||||
IntersectionShape intersection) const;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /* OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_NORMALIZER_HPP_ */
|
||||
@@ -1,104 +0,0 @@
|
||||
#ifndef OSRM_EXTRACTOR_TURN_ANALYSIS
|
||||
#define OSRM_EXTRACTOR_TURN_ANALYSIS
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/guidance/driveway_handler.hpp"
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/intersection_generator.hpp"
|
||||
#include "extractor/guidance/intersection_normalization_operation.hpp"
|
||||
#include "extractor/guidance/intersection_normalizer.hpp"
|
||||
#include "extractor/guidance/motorway_handler.hpp"
|
||||
#include "extractor/guidance/roundabout_handler.hpp"
|
||||
#include "extractor/guidance/sliproad_handler.hpp"
|
||||
#include "extractor/guidance/statistics_handler.hpp"
|
||||
#include "extractor/guidance/suppress_mode_handler.hpp"
|
||||
#include "extractor/guidance/turn_classification.hpp"
|
||||
#include "extractor/guidance/turn_handler.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/restriction_index.hpp"
|
||||
#include "extractor/suffix_table.hpp"
|
||||
|
||||
#include "util/attributes.hpp"
|
||||
#include "util/name_table.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
class TurnAnalysis
|
||||
{
|
||||
public:
|
||||
TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const EdgeBasedNodeDataContainer &node_data_container,
|
||||
const std::vector<util::Coordinate> &coordinates,
|
||||
const RestrictionMap &restriction_map,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const util::NameTable &name_table,
|
||||
const SuffixTable &street_name_suffix_table);
|
||||
|
||||
/* Full Analysis Process for a single node/edge combination. Use with caution, as the process is
|
||||
* relatively expensive */
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
Intersection operator()(const NodeID node_prior_to_intersection,
|
||||
const EdgeID entering_via_edge) const;
|
||||
|
||||
/*
|
||||
* Returns a normalized intersection without any assigned turn types.
|
||||
* This intersection can be used as input for intersection classification, turn lane assignment
|
||||
* and similar.
|
||||
*/
|
||||
struct ShapeResult
|
||||
{
|
||||
// the basic shape, containing all turns
|
||||
IntersectionShape intersection_shape;
|
||||
// normalized shape, merged some roads into others, adjusted bearings
|
||||
// see intersection_normalizer for further explanations
|
||||
IntersectionNormalizer::NormalizationResult annotated_normalized_shape;
|
||||
};
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
ShapeResult ComputeIntersectionShapes(const NodeID node_at_center_of_intersection) const;
|
||||
|
||||
// Select turn types based on the intersection shape
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
Intersection AssignTurnTypes(const NodeID from_node,
|
||||
const EdgeID via_eid,
|
||||
const IntersectionView &intersection) const;
|
||||
|
||||
const IntersectionGenerator &GetIntersectionGenerator() const;
|
||||
|
||||
private:
|
||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||
const IntersectionGenerator intersection_generator;
|
||||
const IntersectionNormalizer intersection_normalizer;
|
||||
const RoundaboutHandler roundabout_handler;
|
||||
const MotorwayHandler motorway_handler;
|
||||
const TurnHandler turn_handler;
|
||||
const SliproadHandler sliproad_handler;
|
||||
const SuppressModeHandler suppress_mode_handler;
|
||||
const DrivewayHandler driveway_handler;
|
||||
const StatisticsHandler statistics_handler;
|
||||
|
||||
// Utility function, setting basic turn types. Prepares for normal turn handling.
|
||||
Intersection
|
||||
setTurnTypes(const NodeID from, const EdgeID via_edge, Intersection intersection) const;
|
||||
}; // class TurnAnalysis
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif // OSRM_EXTRACTOR_TURN_ANALYSIS
|
||||
@@ -1,36 +0,0 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_TURN_DISCOVERY_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_TURN_DISCOVERY_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/intersection_generator.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
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 IntersectionGenerator &intersection_generator,
|
||||
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,
|
||||
IntersectionView &result_intersection);
|
||||
|
||||
} // namespace lanes
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /*OSRM_EXTRACTOR_GUIDANCE_TURN_DISCOVERY_HPP_*/
|
||||
@@ -1,26 +0,0 @@
|
||||
#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"
|
||||
#include "util/attributes.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
namespace lanes
|
||||
{
|
||||
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
LaneDataVector handleNoneValueAtSimpleTurn(LaneDataVector lane_data,
|
||||
const Intersection &intersection);
|
||||
|
||||
} // namespace lanes
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /* OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_AUGMENTATION_HPP_ */
|
||||
@@ -1,8 +1,6 @@
|
||||
#ifndef INTERNAL_EXTRACTOR_EDGE_HPP
|
||||
#define INTERNAL_EXTRACTOR_EDGE_HPP
|
||||
|
||||
#include "extractor/guidance/road_classification.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/node_based_edge.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "osrm/coordinate.hpp"
|
||||
|
||||
+5
-18
@@ -1,15 +1,13 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_CONSTANTS_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_CONSTANTS_HPP_
|
||||
#ifndef OSRM_EXTRACTOR_INTERSECTION_CONSTANTS_HPP_
|
||||
#define OSRM_EXTRACTOR_INTERSECTION_CONSTANTS_HPP_
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
namespace intersection
|
||||
{
|
||||
|
||||
const bool constexpr INVERT = true;
|
||||
|
||||
// what angle is interpreted as going straight
|
||||
const double constexpr STRAIGHT_ANGLE = 180.;
|
||||
const double constexpr ORTHOGONAL_ANGLE = 90.;
|
||||
@@ -20,17 +18,6 @@ const double constexpr NARROW_TURN_ANGLE = 40.;
|
||||
const double constexpr GROUP_ANGLE = 60;
|
||||
// angle difference that can be classified as straight, if its the only narrow turn
|
||||
const double constexpr FUZZY_ANGLE_DIFFERENCE = 25.;
|
||||
const double constexpr DISTINCTION_RATIO = 2;
|
||||
|
||||
// Named roundabouts with radii larger then than this are seen as rotary
|
||||
const double constexpr MAX_ROUNDABOUT_RADIUS = 15;
|
||||
// Unnamed small roundabouts that look like intersections are announced as turns,
|
||||
// guard against data issues or such roundabout intersections getting too large.
|
||||
const double constexpr MAX_ROUNDABOUT_INTERSECTION_RADIUS = 15;
|
||||
|
||||
const double constexpr INCREASES_BY_FOURTY_PERCENT = 1.4;
|
||||
|
||||
const int constexpr MAX_SLIPROAD_THRESHOLD = 250;
|
||||
|
||||
// Road priorities give an idea of how obvious a turn is. If two priorities differ greatly (e.g.
|
||||
// service road over a primary road, the better priority can be seen as obvious due to its road
|
||||
@@ -43,8 +30,8 @@ const auto constexpr ASSUMED_LANE_WIDTH = 3.25;
|
||||
// how far apart can roads be at the most, when thinking about merging them?
|
||||
const auto constexpr MERGABLE_ANGLE_DIFFERENCE = 95.0;
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace intersection
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif // OSRM_EXTRACTOR_GUIDANCE_CONSTANTS_HPP_
|
||||
#endif // OSRM_EXTRACTOR_INTERSECTION_CONSTANTS_HPP_
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
#ifndef OSRM_EXTRACTOR_COORDINATE_EXTRACTOR_HPP_
|
||||
#define OSRM_EXTRACTOR_COORDINATE_EXTRACTOR_HPP_
|
||||
#ifndef OSRM_EXTRACTOR_INTERSECTION_COORDINATE_EXTRACTOR_HPP_
|
||||
#define OSRM_EXTRACTOR_INTERSECTION_COORDINATE_EXTRACTOR_HPP_
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -15,7 +15,7 @@ namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
namespace intersection
|
||||
{
|
||||
|
||||
class CoordinateExtractor
|
||||
@@ -251,8 +251,8 @@ class CoordinateExtractor
|
||||
const std::uint8_t considered_lanes) const;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace intersection
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif // OSRM_EXTRACTOR_COORDINATE_EXTRACTOR_HPP_
|
||||
#endif // OSRM_EXTRACTOR_INTERSECTION_COORDINATE_EXTRACTOR_HPP_
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef OSRM_EXTRACTOR_INTERSECTION_HAVE_IDENTICAL_NAMES_HPP_
|
||||
#define OSRM_EXTRACTOR_INTERSECTION_HAVE_IDENTICAL_NAMES_HPP_
|
||||
|
||||
#include "extractor/suffix_table.hpp"
|
||||
#include "guidance/constants.hpp"
|
||||
#include "util/name_table.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace intersection
|
||||
{
|
||||
|
||||
// check if two name ids can be seen as identical (in presence of refs/others)
|
||||
// in our case this translates into no name announcement in either direction (lhs->rhs and
|
||||
// rhs->lhs)
|
||||
bool HaveIdenticalNames(const NameID lhs,
|
||||
const NameID rhs,
|
||||
const util::NameTable &name_table,
|
||||
const SuffixTable &street_name_suffix_table);
|
||||
|
||||
} // namespace intersection
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /*OSRM_EXTRACTOR_INTERSECTION_HAVE_IDENTICAL_NAMES_HPP_*/
|
||||
@@ -0,0 +1,86 @@
|
||||
#ifndef OSRM_EXTRACTOR_INTERSECTION_INTERSECTION_ANALYSIS_HPP
|
||||
#define OSRM_EXTRACTOR_INTERSECTION_INTERSECTION_ANALYSIS_HPP
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/intersection/intersection_edge.hpp"
|
||||
#include "extractor/intersection/intersection_view.hpp"
|
||||
#include "extractor/intersection/mergable_road_detector.hpp"
|
||||
#include "extractor/restriction_index.hpp"
|
||||
#include "extractor/turn_lane_types.hpp"
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace intersection
|
||||
{
|
||||
|
||||
IntersectionEdges getIncomingEdges(const util::NodeBasedDynamicGraph &graph,
|
||||
const NodeID intersection);
|
||||
|
||||
IntersectionEdges getOutgoingEdges(const util::NodeBasedDynamicGraph &graph,
|
||||
const NodeID intersection);
|
||||
|
||||
bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph,
|
||||
const EdgeBasedNodeDataContainer &node_data_container,
|
||||
const RestrictionMap &restriction_map,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const IntersectionEdgeGeometries &geometries,
|
||||
const TurnLanesIndexedArray &turn_lanes_data,
|
||||
const IntersectionEdge &from,
|
||||
const IntersectionEdge &to);
|
||||
|
||||
double findEdgeBearing(const IntersectionEdgeGeometries &geometries, const EdgeID &edge);
|
||||
|
||||
double findEdgeLength(const IntersectionEdgeGeometries &geometries, const EdgeID &edge);
|
||||
|
||||
std::pair<IntersectionEdgeGeometries, std::unordered_set<EdgeID>>
|
||||
getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph,
|
||||
const extractor::CompressedEdgeContainer &compressed_geometries,
|
||||
const std::vector<util::Coordinate> &node_coordinates,
|
||||
const MergableRoadDetector &detector,
|
||||
const NodeID intersection);
|
||||
|
||||
IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &graph,
|
||||
const EdgeBasedNodeDataContainer &node_data_container,
|
||||
const RestrictionMap &restriction_map,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const IntersectionEdgeGeometries &edge_geometries,
|
||||
const TurnLanesIndexedArray &turn_lanes_data,
|
||||
const IntersectionEdge &incoming_edge,
|
||||
const IntersectionEdges &outgoing_edges,
|
||||
const std::unordered_set<EdgeID> &merged_edges);
|
||||
|
||||
// Check for restrictions/barriers and generate a list of valid and invalid turns present at
|
||||
// the node reached from `incoming_edge`. The resulting candidates have to be analyzed
|
||||
// for their actual instructions later on.
|
||||
template <bool USE_CLOSE_COORDINATE>
|
||||
IntersectionView getConnectedRoads(const util::NodeBasedDynamicGraph &graph,
|
||||
const EdgeBasedNodeDataContainer &node_data_container,
|
||||
const std::vector<util::Coordinate> &node_coordinates,
|
||||
const extractor::CompressedEdgeContainer &compressed_geometries,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const TurnLanesIndexedArray &turn_lanes_data,
|
||||
const IntersectionEdge &incoming_edge);
|
||||
|
||||
// Graph Compression cannot compress every setting. For example any barrier/traffic light cannot
|
||||
// be compressed. As a result, a simple road of the form `a ----- b` might end up as having an
|
||||
// intermediate intersection, if there is a traffic light in between. If we want to look farther
|
||||
// down a road, finding the next actual decision requires the look at multiple intersections.
|
||||
// Here we follow the road until we either reach a dead end or find the next intersection with
|
||||
// more than a single next road. This function skips over degree two nodes to find correct input
|
||||
// for getConnectedRoads.
|
||||
IntersectionEdge skipDegreeTwoNodes(const util::NodeBasedDynamicGraph &graph,
|
||||
IntersectionEdge road);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef OSRM_EXTRACTOR_INTERSECTION_INTERSECTION_EDGE_HPP
|
||||
#define OSRM_EXTRACTOR_INTERSECTION_INTERSECTION_EDGE_HPP
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace intersection
|
||||
{
|
||||
|
||||
// IntersectionEdge is an alias for incoming and outgoing node-based graph edges of an intersection
|
||||
struct IntersectionEdge
|
||||
{
|
||||
NodeID node;
|
||||
EdgeID edge;
|
||||
|
||||
bool operator<(const IntersectionEdge &other) const
|
||||
{
|
||||
return std::tie(node, edge) < std::tie(other.node, other.edge);
|
||||
}
|
||||
};
|
||||
|
||||
using IntersectionEdges = std::vector<IntersectionEdge>;
|
||||
|
||||
struct IntersectionEdgeGeometry
|
||||
{
|
||||
EdgeID edge;
|
||||
double initial_bearing;
|
||||
double perceived_bearing;
|
||||
double length;
|
||||
|
||||
bool operator<(const IntersectionEdgeGeometry &other) const { return edge < other.edge; }
|
||||
};
|
||||
|
||||
using IntersectionEdgeGeometries = std::vector<IntersectionEdgeGeometry>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+6
-92
@@ -1,5 +1,5 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_HPP_
|
||||
#ifndef OSRM_EXTRACTOR_INTERSECTION_INTERSECTION_VIEW_HPP_
|
||||
#define OSRM_EXTRACTOR_INTERSECTION_INTERSECTION_VIEW_HPP_
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "util/node_based_graph.hpp"
|
||||
#include "util/typedefs.hpp" // EdgeID
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
|
||||
#include <boost/range/algorithm/count_if.hpp>
|
||||
#include <boost/range/algorithm/find_if.hpp>
|
||||
@@ -23,7 +23,7 @@ namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
namespace intersection
|
||||
{
|
||||
|
||||
// the shape of an intersection only knows about edge IDs and bearings
|
||||
@@ -44,14 +44,6 @@ inline auto makeCompareShapeDataByBearing(const double base_bearing)
|
||||
};
|
||||
}
|
||||
|
||||
inline auto makeCompareShapeDataAngleToBearing(const double base_bearing)
|
||||
{
|
||||
return [base_bearing](const auto &lhs, const auto &rhs) {
|
||||
return util::bearing::angleBetween(lhs.bearing, base_bearing) <
|
||||
util::bearing::angleBetween(rhs.bearing, base_bearing);
|
||||
};
|
||||
}
|
||||
|
||||
inline auto makeCompareAngularDeviation(const double angle)
|
||||
{
|
||||
return [angle](const auto &lhs, const auto &rhs) {
|
||||
@@ -83,53 +75,6 @@ struct IntersectionViewData : IntersectionShapeData
|
||||
bool CompareByAngle(const IntersectionViewData &other) const;
|
||||
};
|
||||
|
||||
// A Connected Road is the internal representation of a potential turn. Internally, we require
|
||||
// full list of all connected roads to determine the outcome.
|
||||
// The reasoning behind is that even invalid turns can influence the perceived angles, or even
|
||||
// instructions themselves. An possible example can be described like this:
|
||||
//
|
||||
// aaa(2)aa
|
||||
// a - bbbbb
|
||||
// aaa(1)aa
|
||||
//
|
||||
// will not be perceived as a turn from (1) -> b, and as a U-turn from (1) -> (2).
|
||||
// In addition, they can influence whether a turn is obvious or not. b->(2) would also be no
|
||||
// turn-operation, but rather a name change.
|
||||
//
|
||||
// If this were a normal intersection with
|
||||
//
|
||||
// cccccccc
|
||||
// o bbbbb
|
||||
// aaaaaaaa
|
||||
//
|
||||
// We would perceive a->c as a sharp turn, a->b as a slight turn, and b->c as a slight turn.
|
||||
struct ConnectedRoad final : IntersectionViewData
|
||||
{
|
||||
ConnectedRoad(const IntersectionViewData &view,
|
||||
const TurnInstruction instruction,
|
||||
const LaneDataID lane_data_id)
|
||||
: IntersectionViewData(view), instruction(instruction), lane_data_id(lane_data_id)
|
||||
{
|
||||
}
|
||||
|
||||
TurnInstruction instruction;
|
||||
LaneDataID lane_data_id;
|
||||
|
||||
// used to sort the set of connected roads (we require sorting throughout turn handling)
|
||||
bool compareByAngle(const ConnectedRoad &other) const;
|
||||
|
||||
// make a left turn into an equivalent right turn and vice versa
|
||||
void mirror();
|
||||
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
ConnectedRoad getMirroredCopy() const;
|
||||
};
|
||||
|
||||
// small helper function to print the content of a connected road
|
||||
std::string toString(const IntersectionShapeData &shape);
|
||||
std::string toString(const IntersectionViewData &view);
|
||||
std::string toString(const ConnectedRoad &road);
|
||||
|
||||
// Intersections are sorted roads: [0] being the UTurn road, then from sharp right to sharp left.
|
||||
// common operations shared amongst all intersection types
|
||||
template <typename Self> struct EnableShapeOps
|
||||
@@ -300,39 +245,8 @@ struct IntersectionView final : std::vector<IntersectionViewData>, //
|
||||
using Base = std::vector<IntersectionViewData>;
|
||||
};
|
||||
|
||||
// `Intersection` is a relative view of an intersection by an incoming edge.
|
||||
// `Intersection` are streets at an intersection ordered from from sharp right counter-clockwise to
|
||||
// sharp left where `intersection[0]` is _always_ a u-turn
|
||||
|
||||
// An intersection is an ordered list of connected roads ordered from from sharp right
|
||||
// counter-clockwise to sharp left where `intersection[0]` is always a u-turn
|
||||
//
|
||||
// |
|
||||
// |
|
||||
// (intersec[3])
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// nid ---(via_eid/intersec[0])--- nbg.GetTarget(via) ---(intersec[2])---
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// (intersec[1])
|
||||
// |
|
||||
// |
|
||||
//
|
||||
// intersec := intersection
|
||||
// nbh := node_based_graph
|
||||
//
|
||||
struct Intersection final : std::vector<ConnectedRoad>, //
|
||||
EnableShapeOps<Intersection>, //
|
||||
EnableIntersectionOps<Intersection> //
|
||||
{
|
||||
using Base = std::vector<ConnectedRoad>;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace intersection
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /*OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_HPP_*/
|
||||
#endif /* OSRM_EXTRACTOR_INTERSECTION_INTERSECTION_VIEW_HPP_*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user