Compare commits
229 Commits
v5.1.0
...
v5.3.0-rc.3
| Author | SHA1 | Date | |
|---|---|---|---|
| 2cc293ad16 | |||
| 6ac65a922f | |||
| 3d80f989d0 | |||
| 4fcb5d28a4 | |||
| 3ebdacf369 | |||
| 2ddc00c21e | |||
| e76e39a398 | |||
| 04667f1ed8 | |||
| 2091c3443b | |||
| 2b466b2fb2 | |||
| e17b306265 | |||
| b00b15ab98 | |||
| f4db79fe9b | |||
| 0e4061f858 | |||
| 043a1446e1 | |||
| 49221995e8 | |||
| 247a7488b8 | |||
| 1806198971 | |||
| 375331b80c | |||
| 8fdbe965cc | |||
| dc77d02e8a | |||
| 6265b8fa77 | |||
| 311b348d09 | |||
| ec02cdc4cc | |||
| 5905708111 | |||
| 5d91b759d1 | |||
| ec0a1a4ab1 | |||
| efa29edf09 | |||
| 2a05b70dfc | |||
| 8693e68271 | |||
| d21a9a514d | |||
| e03d132823 | |||
| 61ba985bc9 | |||
| 4629a20fe4 | |||
| a28125ee9a | |||
| df877aca1b | |||
| 05dc415aba | |||
| 6dedd9cb72 | |||
| 256d39b572 | |||
| d186ae1863 | |||
| fddc19e98d | |||
| 2592cd2e58 | |||
| 93b6438cea | |||
| f6746d88b7 | |||
| 34ace4dd4b | |||
| 41d0f42ddf | |||
| 2868f702a5 | |||
| ec4dcee8bd | |||
| 8c378191df | |||
| b98431e8e6 | |||
| 3c8781855e | |||
| 27a94f3ca6 | |||
| 04e334e3e2 | |||
| 12d4832037 | |||
| 6e4f6fec91 | |||
| 57c9525e5c | |||
| 543e4fb57d | |||
| 3881ead8e5 | |||
| 911d1e81b6 | |||
| ae06300c17 | |||
| 26879ca91a | |||
| 306744e5cb | |||
| 3ca32898a1 | |||
| 532fda267f | |||
| 494845b160 | |||
| 0fc823041e | |||
| 71eae4137d | |||
| 47b19f209b | |||
| 2b5355edca | |||
| e9a0beb4e8 | |||
| 6bdfe68897 | |||
| cf2d2b6763 | |||
| 95cd44f34f | |||
| d330e60d40 | |||
| 99004bbec8 | |||
| bbcc728a07 | |||
| 033dc0a72d | |||
| 1c140a112a | |||
| 312e86eb58 | |||
| 1dfdb38d4a | |||
| dfafe7dc5f | |||
| 6ecc123d15 | |||
| 6f322d2140 | |||
| dfa762bccc | |||
| 87f00d2c4c | |||
| 6f94e0dfb8 | |||
| ad70759f91 | |||
| 27c4e8ddd0 | |||
| 805d74b6ae | |||
| 4ad78309e2 | |||
| b78207ddd8 | |||
| b6834da9a4 | |||
| 801cc72691 | |||
| e198709643 | |||
| ed8d5e0b0a | |||
| e8fb312703 | |||
| 058b8c3b31 | |||
| ae3ccb009e | |||
| 0c60a2aef8 | |||
| 44fdf86702 | |||
| 1659bbf7b1 | |||
| 46b58fba83 | |||
| 84da86ba4a | |||
| 6777127497 | |||
| a4ac07866a | |||
| 448f8377fb | |||
| c490752ca7 | |||
| 6edc565c01 | |||
| bb0c2754d3 | |||
| 58d6e8f4d0 | |||
| bdc66049a5 | |||
| 0a53775fb3 | |||
| 9cdc9008aa | |||
| bd707b0cfc | |||
| a85f39c140 | |||
| ef7b36da32 | |||
| 14fdf861ca | |||
| 7641b12b08 | |||
| e7159adf59 | |||
| 51f08f2994 | |||
| a03eac8e48 | |||
| 503137221d | |||
| fb9205bf81 | |||
| bfbb313088 | |||
| 25d3c4b843 | |||
| 371c06d66d | |||
| 3e5c978719 | |||
| 843f1a6356 | |||
| a5c5faa21d | |||
| 6a1e17c6fa | |||
| cd30f370b8 | |||
| 4ae8abe6a3 | |||
| 82bfd4ee40 | |||
| e08c4cff13 | |||
| 6e16eab6ec | |||
| 21c47514da | |||
| d6de2ca71c | |||
| 451a0d9090 | |||
| 262354f733 | |||
| 498370330d | |||
| 6865853776 | |||
| 1418c0dbbc | |||
| bbc79dd49f | |||
| 8036320d94 | |||
| c30f69d6e9 | |||
| 2e2f34f241 | |||
| cbbeef5c46 | |||
| 823ee54f22 | |||
| 3d03797e53 | |||
| 089e60fa1e | |||
| baf8e4784b | |||
| d53350b263 | |||
| 824afdceca | |||
| a8230e976f | |||
| 6af7e6866c | |||
| aaa27333ba | |||
| 797f2a196b | |||
| 51066ff18f | |||
| 4de64a92cb | |||
| a21fd2ea18 | |||
| 0df0b4305d | |||
| a5ed53e7aa | |||
| 0587c5f5c4 | |||
| 57dbb18c4c | |||
| 4d92f08424 | |||
| 254ee07942 | |||
| 0bf8bd2230 | |||
| b5225f07cb | |||
| abed7690d0 | |||
| f96174ddbe | |||
| e5b713841a | |||
| 3b1b12069f | |||
| 1635f7351d | |||
| ce5ae411c1 | |||
| d1bc32fb31 | |||
| f9f87f25d4 | |||
| 89aa6b7881 | |||
| edf9e0c1ed | |||
| c2e520ad9d | |||
| 7649187095 | |||
| fe39d0fd10 | |||
| 98b83b7208 | |||
| 57321979ae | |||
| e3ce0c5887 | |||
| 95af72c70c | |||
| 3b37769624 | |||
| d150df1c5c | |||
| a322e27e05 | |||
| 98fe0badbe | |||
| 44b841a25d | |||
| 9c8bf820de | |||
| 4d9aa65e78 | |||
| 0f3942558f | |||
| ba074b0116 | |||
| 6aa97048df | |||
| d9a5c79ea6 | |||
| 9d7714c714 | |||
| 8291be375a | |||
| 0a73737f69 | |||
| 2fd1b6c913 | |||
| ea38a1d880 | |||
| f576e13c51 | |||
| ee7bb8731a | |||
| da0c3ff394 | |||
| 6ae559b42b | |||
| 95ca6ebdaa | |||
| 0d6964d9c8 | |||
| ba386d4b2c | |||
| b5ffb51e18 | |||
| a9f674497a | |||
| 1e8a92ccb4 | |||
| b9178bb8c7 | |||
| 520b29d0d5 | |||
| fe397e6953 | |||
| dcb741d827 | |||
| 508c205d35 | |||
| d5294bb5d0 | |||
| 6ed9be31ca | |||
| 3bbd3a8a65 | |||
| 73a608895a | |||
| 96c73baeb3 | |||
| 73113f5eb8 | |||
| 7b74b86891 | |||
| 0903b8227f | |||
| fa525ad610 | |||
| 0f2bb5dde5 | |||
| 84dc1b6845 | |||
| 4ce1a37772 | |||
| 8dd4cc5c40 |
+59
-23
@@ -2,53 +2,89 @@
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: true
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: true
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
IndentBraces: true
|
||||
BreakBeforeBinaryOperators: false
|
||||
BreakBeforeBraces: Allman
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BinPackParameters: false
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
DerivePointerBinding: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
- Regex: '^<'
|
||||
Priority: 3
|
||||
- Regex: '^"(osrm|util|engine|extract|contract)/'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
IndentCaseLabels: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyExcessCharacter: 1000
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerBindsToType: false
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
Cpp11BracedListStyle: true
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
IndentWidth: 4
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
BreakBeforeBraces: Allman
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInAngles: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
ContinuationIndentWidth: 4
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
SpaceBeforeParens: ControlStatements
|
||||
...
|
||||
|
||||
|
||||
+34
-15
@@ -17,6 +17,8 @@ branches:
|
||||
cache:
|
||||
ccache: true
|
||||
apt: true
|
||||
directories:
|
||||
- test/cache
|
||||
|
||||
env:
|
||||
global:
|
||||
@@ -37,7 +39,7 @@ matrix:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-5', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Debug'
|
||||
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Debug' COVERAGE=ON
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-4.8-debug"
|
||||
@@ -51,9 +53,9 @@ matrix:
|
||||
compiler: "clang-3.8-debug"
|
||||
addons: &clang38
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Debug' RUN_CLANG_FORMAT=ON
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-5-dev', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CLANG_VERSION='3.8.0' BUILD_TYPE='Debug' RUN_CLANG_FORMAT=ON
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
@@ -69,6 +71,15 @@ matrix:
|
||||
packages: ['g++-5', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release'
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-5-release-i686"
|
||||
env: TARGET_ARCH='i686' CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release'
|
||||
|
||||
# FIXME disabled until sourceforge fixes its packages for stxxl
|
||||
#- os: linux
|
||||
#- compiler: "gcc-4.8-release-armhf"
|
||||
#- env: TARGET_ARCH='armhf' CCOMPILER='arm-linux-gnueabihf-gcc-4.8' CXXCOMPILER='arm-linux-gnueabihf-g++-4.8' BUILD_TYPE='Release'
|
||||
|
||||
# Disabled because of CI slowness
|
||||
#- os: linux
|
||||
#- compiler: gcc
|
||||
@@ -112,22 +123,28 @@ matrix:
|
||||
#- env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
|
||||
before_install:
|
||||
- if [[ ! -z $TARGET_ARCH ]] ; then source ./scripts/travis/before_install.$TARGET_ARCH.sh ; fi
|
||||
- if [[ $(uname -s) == 'Darwin' ]]; then sudo mdutil -i off /; fi;
|
||||
- source ./scripts/install_node.sh 4
|
||||
- npm install
|
||||
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
|
||||
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
|
||||
- export PATH=${DEPS_DIR}/bin:${PATH} && mkdir -p ${DEPS_DIR}
|
||||
- CMAKE_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/cmake/3.5.2.tar.gz"
|
||||
- travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
|
||||
- |
|
||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||
CMAKE_URL="http://www.cmake.org/files/v3.5/cmake-3.5.1-Linux-x86_64.tar.gz"
|
||||
mkdir cmake && travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
|
||||
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
|
||||
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
||||
if [[ ${CLANG_VERSION:-false} != false ]]; then
|
||||
export CCOMPILER='clang'
|
||||
export CXXCOMPILER='clang++'
|
||||
CLANG_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/clang/${CLANG_VERSION}.tar.gz"
|
||||
travis_retry wget --quiet -O - ${CLANG_URL} | tar --strip-components=1 -xz -C ${DEPS_DIR} || exit 1
|
||||
fi
|
||||
- |
|
||||
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
||||
# implicit deps, but seem to be installed by default with recent images: libxml2 GDAL boost
|
||||
brew install cmake libzip libstxxl lua51 luabind tbb md5sha1sum ccache
|
||||
brew install libzip libstxxl lua51 luabind tbb md5sha1sum ccache
|
||||
fi
|
||||
|
||||
install:
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- |
|
||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||
./scripts/check_taginfo.py taginfo.json profiles/car.lua
|
||||
@@ -136,6 +153,7 @@ install:
|
||||
- export CC=${CCOMPILER} CXX=${CXXCOMPILER}
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-OFF} -DCOVERAGE=${COVERAGE:-OFF} -DBUILD_TOOLS=1 -DENABLE_CCACHE=ON
|
||||
- echo "travis_fold:start:MAKE"
|
||||
- make osrm-extract --jobs=3
|
||||
- make --jobs=${JOBS}
|
||||
- make tests --jobs=${JOBS}
|
||||
- make benchmarks --jobs=${JOBS}
|
||||
@@ -148,11 +166,12 @@ install:
|
||||
fi
|
||||
- popd
|
||||
- mkdir example/build && pushd example/build
|
||||
- cmake ..
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
|
||||
- make
|
||||
- popd
|
||||
|
||||
script:
|
||||
- if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi
|
||||
- echo "travis_fold:start:BENCHMARK"
|
||||
- make -C test/data benchmark
|
||||
- echo "travis_fold:end:BENCHMARK"
|
||||
@@ -170,9 +189,9 @@ script:
|
||||
after_success:
|
||||
- |
|
||||
if [ -n "${RUN_CLANG_FORMAT}" ]; then
|
||||
./scripts/format.sh || true # we don't want to fail just yet
|
||||
./scripts/format.sh # we don't want to fail just yet
|
||||
fi
|
||||
- |
|
||||
if [ -n "${COVERAGE}" ]; then
|
||||
coveralls --build-root build --exclude unit_tests --exclude third_party --exclude node_modules --gcov-options '\-lp'
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
fi
|
||||
|
||||
+138
@@ -1,3 +1,141 @@
|
||||
# 5.3.0 RC3
|
||||
Changes from 5.3.0-rc.2
|
||||
- Guidance
|
||||
- Improved detection of obvious turns
|
||||
- Improved turn lane detection
|
||||
- Bugfixes
|
||||
- Fix bug that didn't chose minimal weights on overlapping edges
|
||||
|
||||
# 5.3.0 RC2
|
||||
Changes from 5.3.0-rc.1
|
||||
- Bugfixes
|
||||
- Fixes invalid checks in the lane-extraction part of the car profile
|
||||
|
||||
# 5.3.0 RC1
|
||||
- API
|
||||
- Introduces new `TurnType` in the form of `use lane`. The type indicates that you have to stick to a lane without turning
|
||||
- Introduces lanes to the route response. The lane data contains both the markings at the intersection and a flag indicating their involvement in the turn
|
||||
|
||||
- Infrastructure
|
||||
- BREAKING: The new turn type changes the turn-type order. This breaks the **data format**.
|
||||
- BREAKING: Turn lane data introduces two new files (osrm.tld,osrm.tls). This breaks the fileformat for older versions.
|
||||
|
||||
# 5.2.5
|
||||
- Bugfixes
|
||||
- Fixes a segfault caused by incorrect trimming logic for very short steps.
|
||||
|
||||
# 5.2.4
|
||||
- Bugfixes:
|
||||
- Fixed in issue that arised on roundabouts in combination with intermediate intersections and sliproads
|
||||
|
||||
# 5.2.3
|
||||
- Bugfixes:
|
||||
- Fixed an issue with name changes in roundabouts that could result in crashes
|
||||
|
||||
# 5.2.2
|
||||
Changes from 5.2.1
|
||||
- Bugfixes:
|
||||
- Buffer overrun in tile plugin response handling
|
||||
|
||||
# 5.2.1
|
||||
Changes from 5.2.0
|
||||
- Bugfixes:
|
||||
- Removed debug statement that was spamming the console
|
||||
|
||||
# 5.2.0
|
||||
Changes from 5.2.0 RC2
|
||||
- Bugfixes:
|
||||
- Fixed crash when loading shared memory caused by invalid OSM IDs segment size.
|
||||
- Various small instructions handling fixes
|
||||
|
||||
Changes from 5.1.0
|
||||
- API:
|
||||
- new parameter `annotations` for `route`, `trip` and `match` requests. Returns additional data about each
|
||||
coordinate along the selected/matched route line per `RouteLeg`:
|
||||
- duration of each segment
|
||||
- distance of each segment
|
||||
- OSM node ids of all segment endpoints
|
||||
- Introducing Intersections for Route Steps. This changes the API format in multiple ways.
|
||||
- `bearing_before`/`bearing_after` of `StepManeuver` are now deprecated and will be removed in the next major release
|
||||
- `location` of `StepManeuvers` is now deprecated and will be removed in the next major release
|
||||
- every `RouteStep` now has property `intersections` containing a list of `Intersection` objects.
|
||||
- Support for destination signs. New member `destinations` in `RouteStep`, based on `destination` and `destination:ref`
|
||||
- Support for name pronunciations. New member `pronunciation` in `RouteStep`, based on `name:pronunciation`
|
||||
|
||||
- Profile changes:
|
||||
- duration parser now accepts P[n]DT[n]H[n]M[n]S, P[n]W, PTHHMMSS and PTHH:MM:SS ISO8601 formats.
|
||||
- `result.destinations` allows you to set a way's destinations
|
||||
- `result.pronunciation` allows you to set way name pronunciations
|
||||
- `highway=motorway_link` no longer implies `oneway` as per the OSM Wiki
|
||||
|
||||
- Infrastructure:
|
||||
- BREAKING: Changed the on-disk encoding of the StaticRTree to reduce ramIndex file size. This breaks the **data format**
|
||||
- BREAKING: Intersection Classification adds a new file to the mix (osrm.icd). This breaks the fileformat for older versions.
|
||||
- Better support for osrm-routed binary upgrade on the fly [UNIX specific]:
|
||||
- Open sockets with SO_REUSEPORT to allow multiple osrm-routed processes serving requests from the same port.
|
||||
- Add SIGNAL_PARENT_WHEN_READY environment variable to enable osrm-routed signal its parent with USR1 when it's running and waiting for requests.
|
||||
- Disable http access logging via DISABLE_ACCESS_LOGGING environment variable.
|
||||
|
||||
- Guidance:
|
||||
- BREAKING: modifies the file format with new internal identifiers
|
||||
- improved detection of turning streets, not reporting new-name in wrong situations
|
||||
- improved handling of sliproads (emit turns instead of 'take the ramp')
|
||||
- improved collapsing of instructions. Some 'new name' instructions will be suppressed if they are without alternative and the segment is short
|
||||
|
||||
- Bugfixes
|
||||
- fixed broken summaries for very short routes
|
||||
|
||||
# 5.2.0 RC2
|
||||
Changes from 5.2.0 RC1
|
||||
|
||||
- Guidance:
|
||||
- improved handling of sliproads (emit turns instead of 'take the ramp')
|
||||
- improved collapsing of instructions. Some 'new name' instructions will be suppressed if they are without alternative and the segment is short
|
||||
- BREAKING: modifies the file format with new internal identifiers
|
||||
|
||||
- API:
|
||||
- paramater `annotate` was renamed to `annotations`.
|
||||
- `annotation` as accidentally placed in `Route` instead of `RouteLeg`
|
||||
- Support for destination signs. New member `destinations` in `RouteStep`, based on `destination` and `destination:ref`
|
||||
- Support for name pronunciations. New member `pronunciation` in `RouteStep`, based on `name:pronunciation`
|
||||
- Add `nodes` property to `annotation` in `RouteLeg` containing the ids of nodes covered by the route
|
||||
|
||||
- Profile changes:
|
||||
- `result.destinations` allows you to set a way's destinations
|
||||
- `result.pronunciation` allows you to set way name pronunciations
|
||||
- `highway=motorway_link` no longer implies `oneway` as per the OSM Wiki
|
||||
|
||||
- Infrastructure
|
||||
- BREAKING: Changed the on-disk encoding of the StaticRTree to reduce ramIndex file size. This breaks the **data format**
|
||||
|
||||
- Bugfixes
|
||||
- fixed broken summaries for very short routes
|
||||
|
||||
# 5.2.0 RC1
|
||||
Changes from 5.1.0
|
||||
|
||||
- API:
|
||||
- new parameter `annotate` for `route` and `match` requests. Returns additional data about each
|
||||
coordinate along the selected/matched route line.
|
||||
- Introducing Intersections for Route Steps. This changes the API format in multiple ways.
|
||||
- `bearing_before`/`bearing_after` of `StepManeuver` are now deprecated and will be removed in the next major release
|
||||
- `location` of `StepManeuvers` is now deprecated and will be removed in the next major release
|
||||
- every `RouteStep` now has property `intersections` containing a list of `Intersection` objects.
|
||||
|
||||
- Profile changes:
|
||||
- duration parser now accepts P[n]DT[n]H[n]M[n]S, P[n]W, PTHHMMSS and PTHH:MM:SS ISO8601 formats.
|
||||
|
||||
- Infrastructure:
|
||||
- Better support for osrm-routed binary upgrade on the fly [UNIX specific]:
|
||||
- Open sockets with SO_REUSEPORT to allow multiple osrm-routed processes serving requests from the same port.
|
||||
- Add SIGNAL_PARENT_WHEN_READY environment variable to enable osrm-routed signal its parent with USR1 when it's running and waiting for requests.
|
||||
- BREAKING: Intersection Classification adds a new file to the mix (osrm.icd). This breaks the fileformat for older versions.
|
||||
- Disable http access logging via DISABLE_ACCESS_LOGGING environment
|
||||
variable.
|
||||
|
||||
- Guidance:
|
||||
- improved detection of turning streets, not reporting new-name in wrong situations
|
||||
|
||||
# 5.1.0
|
||||
Changes with regard to 5.0.0
|
||||
|
||||
|
||||
+79
-36
@@ -1,4 +1,5 @@
|
||||
cmake_minimum_required(VERSION 2.8.8)
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
# we depend on 2.8.11 introducing target_include_directories
|
||||
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR AND NOT MSVC_IDE)
|
||||
message(FATAL_ERROR "In-source builds are not allowed.
|
||||
@@ -8,9 +9,25 @@ endif()
|
||||
|
||||
project(OSRM C CXX)
|
||||
set(OSRM_VERSION_MAJOR 5)
|
||||
set(OSRM_VERSION_MINOR 1)
|
||||
set(OSRM_VERSION_MINOR 3)
|
||||
set(OSRM_VERSION_PATCH 0)
|
||||
|
||||
# these two functions build up custom variables:
|
||||
# OSRM_INCLUDE_PATHS and OSRM_DEFINES
|
||||
# These variables we want to pass to
|
||||
# include_directories and add_definitions for both
|
||||
# this build and for sharing externally via pkg-config
|
||||
|
||||
function(add_dependency_includes includes)
|
||||
list(APPEND OSRM_INCLUDE_PATHS "${includes}")
|
||||
set(OSRM_INCLUDE_PATHS "${OSRM_INCLUDE_PATHS}" PARENT_SCOPE)
|
||||
endfunction(add_dependency_includes)
|
||||
|
||||
function(add_dependency_defines defines)
|
||||
list(APPEND OSRM_DEFINES "${defines}")
|
||||
set(OSRM_DEFINES "${OSRM_DEFINES}" PARENT_SCOPE)
|
||||
endfunction(add_dependency_defines)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
@@ -22,7 +39,7 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(bitness 64)
|
||||
message(STATUS "Building on a 64 bit system")
|
||||
else()
|
||||
message(WARNING "Building on a 32 bit system is unsupported")
|
||||
message(STATUS "Building on a 32 bit system")
|
||||
endif()
|
||||
|
||||
if(WIN32 AND MSVC_VERSION LESS 1900)
|
||||
@@ -32,10 +49,11 @@ endif()
|
||||
option(ENABLE_CCACHE "Speed up incremental rebuilds via ccache" ON)
|
||||
option(ENABLE_JSON_LOGGING "Adds additional JSON debug logging to the response" OFF)
|
||||
option(BUILD_TOOLS "Build OSRM tools" OFF)
|
||||
option(BUILD_COMPONENTS "Build osrm-components" ON)
|
||||
option(BUILD_COMPONENTS "Build osrm-components" OFF)
|
||||
option(ENABLE_ASSERTIONS OFF)
|
||||
option(COVERAGE OFF)
|
||||
option(SANITIZER OFF)
|
||||
option(ENABLE_LTO "Use LTO if available" ON)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/)
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
||||
@@ -54,7 +72,7 @@ configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/util/version.hpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/util/version.hpp
|
||||
)
|
||||
file(GLOB UtilGlob src/util/*.cpp)
|
||||
file(GLOB UtilGlob src/util/*.cpp src/util/*/*.cpp)
|
||||
file(GLOB ExtractorGlob src/extractor/*.cpp src/extractor/*/*.cpp)
|
||||
file(GLOB ContractorGlob src/contractor/*.cpp)
|
||||
file(GLOB StorageGlob src/storage/*.cpp)
|
||||
@@ -101,7 +119,7 @@ if(CMAKE_BUILD_TYPE MATCHES Release)
|
||||
message(STATUS "Configuring OSRM in release mode")
|
||||
# Check if LTO is available
|
||||
check_cxx_compiler_flag("-flto" LTO_AVAILABLE)
|
||||
if(LTO_AVAILABLE)
|
||||
if(ENABLE_LTO AND LTO_AVAILABLE)
|
||||
set(OLD_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
# GCC in addition allows parallelizing LTO
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
@@ -163,7 +181,7 @@ elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
|
||||
# using GCC
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wuninitialized -Wunreachable-code -Wstrict-overflow=1 -D_FORTIFY_SOURCE=2 ${COLOR_FLAG} -fPIC")
|
||||
if(WIN32) # using mingw
|
||||
add_definitions(-DWIN32)
|
||||
add_dependency_defines(-DWIN32)
|
||||
set(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
|
||||
endif()
|
||||
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
|
||||
@@ -172,12 +190,12 @@ elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
|
||||
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
|
||||
# using Visual Studio C++
|
||||
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} date_time chrono zlib)
|
||||
add_definitions(-DBOOST_LIB_DIAGNOSTIC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
add_definitions(-DNOMINMAX) # avoid min and max macros that can break compilation
|
||||
add_definitions(-D_USE_MATH_DEFINES) #needed for M_PI with cmath.h
|
||||
add_definitions(-D_WIN32_WINNT=0x0501)
|
||||
add_definitions(-DXML_STATIC)
|
||||
add_dependency_defines(-DBOOST_LIB_DIAGNOSTIC)
|
||||
add_dependency_defines(-D_CRT_SECURE_NO_WARNINGS)
|
||||
add_dependency_defines(-DNOMINMAX) # avoid min and max macros that can break compilation
|
||||
add_dependency_defines(-D_USE_MATH_DEFINES) #needed for M_PI with cmath.h
|
||||
add_dependency_defines(-D_WIN32_WINNT=0x0501)
|
||||
add_dependency_defines(-DXML_STATIC)
|
||||
find_library(ws2_32_LIBRARY_PATH ws2_32)
|
||||
target_link_libraries(osrm-extract wsock32 ws2_32)
|
||||
endif()
|
||||
@@ -204,7 +222,7 @@ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}")
|
||||
|
||||
# Activate C++11
|
||||
if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
endif()
|
||||
|
||||
# Configuring other platform dependencies
|
||||
@@ -229,41 +247,54 @@ endif()
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/cmake")
|
||||
set(OSMIUM_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include")
|
||||
find_package(Osmium REQUIRED COMPONENTS io)
|
||||
include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
|
||||
add_dependency_includes(${OSMIUM_INCLUDE_DIR})
|
||||
|
||||
|
||||
find_package(Boost 1.49.0 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||
if(NOT WIN32)
|
||||
add_definitions(-DBOOST_TEST_DYN_LINK)
|
||||
|
||||
# collect a subset of the boost libraries needed
|
||||
# by libosrm
|
||||
foreach(lib ${Boost_LIBRARIES})
|
||||
if(NOT WIN32)
|
||||
if(lib MATCHES filesystem OR lib MATCHES thread OR lib MATCHES iostreams OR lib MATCHES system)
|
||||
list(APPEND BOOST_ENGINE_LIBRARIES "${lib}")
|
||||
endif()
|
||||
else()
|
||||
list(APPEND BOOST_ENGINE_LIBRARIES "${lib}")
|
||||
endif()
|
||||
endforeach(lib)
|
||||
|
||||
if(NOT WIN32 AND NOT Boost_USE_STATIC_LIBS)
|
||||
add_dependency_defines(-DBOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
add_definitions(-DBOOST_SPIRIT_USE_PHOENIX_V3)
|
||||
add_definitions(-DBOOST_RESULT_OF_USE_DECLTYPE)
|
||||
add_definitions(-DBOOST_FILESYSTEM_NO_DEPRECATED)
|
||||
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
|
||||
add_dependency_defines(-DBOOST_SPIRIT_USE_PHOENIX_V3)
|
||||
add_dependency_defines(-DBOOST_RESULT_OF_USE_DECLTYPE)
|
||||
add_dependency_defines(-DBOOST_FILESYSTEM_NO_DEPRECATED)
|
||||
add_dependency_includes(${Boost_INCLUDE_DIRS})
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
find_package(TBB REQUIRED)
|
||||
include_directories(SYSTEM ${TBB_INCLUDE_DIR})
|
||||
add_dependency_includes(${TBB_INCLUDE_DIR})
|
||||
if(WIN32 AND CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(TBB_LIBRARIES ${TBB_DEBUG_LIBRARIES})
|
||||
endif()
|
||||
|
||||
find_package(Luabind REQUIRED)
|
||||
include(check_luabind)
|
||||
include_directories(SYSTEM ${LUABIND_INCLUDE_DIR})
|
||||
add_dependency_includes(${LUABIND_INCLUDE_DIR})
|
||||
|
||||
set(USED_LUA_LIBRARIES ${LUA_LIBRARY})
|
||||
if(LUAJIT_FOUND)
|
||||
set(USED_LUA_LIBRARIES, LUAJIT_LIBRARIES)
|
||||
endif()
|
||||
include_directories(SYSTEM ${LUA_INCLUDE_DIR})
|
||||
add_dependency_includes(${LUA_INCLUDE_DIR})
|
||||
|
||||
find_package(EXPAT REQUIRED)
|
||||
include_directories(SYSTEM ${EXPAT_INCLUDE_DIRS})
|
||||
add_dependency_includes(${EXPAT_INCLUDE_DIRS})
|
||||
|
||||
find_package(STXXL REQUIRED)
|
||||
include_directories(SYSTEM ${STXXL_INCLUDE_DIR})
|
||||
add_dependency_includes(${STXXL_INCLUDE_DIR})
|
||||
|
||||
set(OpenMP_FIND_QUIETLY ON)
|
||||
find_package(OpenMP)
|
||||
@@ -273,20 +304,23 @@ if(OPENMP_FOUND)
|
||||
endif()
|
||||
|
||||
find_package(BZip2 REQUIRED)
|
||||
include_directories(SYSTEM ${BZIP_INCLUDE_DIRS})
|
||||
add_dependency_includes(${BZIP2_INCLUDE_DIR})
|
||||
|
||||
find_package(ZLIB REQUIRED)
|
||||
include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS})
|
||||
add_dependency_includes(${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
if (ENABLE_JSON_LOGGING)
|
||||
message(STATUS "Enabling json logging")
|
||||
add_definitions(-DENABLE_JSON_LOGGING)
|
||||
add_dependency_defines(-DENABLE_JSON_LOGGING)
|
||||
endif()
|
||||
|
||||
add_definitions(${OSRM_DEFINES})
|
||||
include_directories(SYSTEM ${OSRM_INCLUDE_PATHS})
|
||||
|
||||
# Binaries
|
||||
target_link_libraries(osrm-datastore osrm_store ${Boost_LIBRARIES})
|
||||
target_link_libraries(osrm-extract osrm_extract ${Boost_LIBRARIES})
|
||||
target_link_libraries(osrm-contract osrm_contract ${Boost_LIBRARIES})
|
||||
target_link_libraries(osrm-contract ${Boost_LIBRARIES} ${TBB_LIBRARIES} osrm_contract)
|
||||
target_link_libraries(osrm-routed osrm ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} ${ZLIB_LIBRARY})
|
||||
|
||||
set(EXTRACTOR_LIBRARIES
|
||||
@@ -311,12 +345,12 @@ set(CONTRACTOR_LIBRARIES
|
||||
${MAYBE_RT_LIBRARY}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
set(ENGINE_LIBRARIES
|
||||
${Boost_LIBRARIES}
|
||||
${BOOST_ENGINE_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${STXXL_LIBRARY}
|
||||
${TBB_LIBRARIES}
|
||||
${MAYBE_RT_LIBRARY}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
${MAYBE_COVERAGE_LIBRARIES}
|
||||
${ZLIB_LIBRARY})
|
||||
set(STORAGE_LIBRARIES
|
||||
${Boost_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
@@ -412,14 +446,23 @@ foreach(lib ${ENGINE_LIBRARIES})
|
||||
set(ENGINE_LIBRARY_LISTING "${ENGINE_LIBRARY_LISTING} -L${ENGINE_LIBRARY_PATH} -l${ENGINE_LIBRARY_NAME}")
|
||||
endforeach()
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
|
||||
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig)
|
||||
|
||||
if(BUILD_DEBIAN_PACKAGE)
|
||||
include(CPackDebianConfig)
|
||||
include(CPack)
|
||||
endif()
|
||||
|
||||
function(JOIN VALUES GLUE OUTPUT)
|
||||
string (REPLACE ";" "${GLUE}" _TMP_STR "${VALUES}")
|
||||
set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Set up variables, then write to pkgconfig file
|
||||
JOIN("${OSRM_DEFINES}" " " OSRM_DEFINES_STRING)
|
||||
JOIN("-I${OSRM_INCLUDE_PATHS}" " -I" OSRM_INCLUDE_PATHS_STRING)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
|
||||
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig)
|
||||
|
||||
# add a target to generate API documentation with Doxygen
|
||||
find_package(Doxygen)
|
||||
if(DOXYGEN_FOUND)
|
||||
|
||||
@@ -8,7 +8,7 @@ The Open Source Routing Machine is a high performance routing engine written in
|
||||
|:-------------|:-------|
|
||||
| Linux | [](https://travis-ci.org/Project-OSRM/osrm-backend) |
|
||||
| Windows | [](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
|
||||
| Coverage | [](https://coveralls.io/github/Project-OSRM/osrm-backend?branch=master) |
|
||||
| Coverage | [](https://codecov.io/gh/Project-OSRM/osrm-backend) |
|
||||
|
||||
## Building
|
||||
|
||||
|
||||
@@ -280,4 +280,5 @@ if (TBB_FOUND)
|
||||
FILE(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _TBB_VERSION_CONTENTS)
|
||||
STRING(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}")
|
||||
set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}")
|
||||
message(STATUS "TBB interface version: ${TBB_INTERFACE_VERSION}")
|
||||
endif (TBB_FOUND)
|
||||
|
||||
+1
-1
@@ -8,4 +8,4 @@ Version: v@OSRM_VERSION_MAJOR@.@OSRM_VERSION_MINOR@.@OSRM_VERSION_PATCH@
|
||||
Requires:
|
||||
Libs: -L${libdir} -losrm
|
||||
Libs.private: @ENGINE_LIBRARY_LISTING@
|
||||
Cflags: -I${includedir} -I${includedir}/osrm
|
||||
Cflags: -I${includedir} -I${includedir}/osrm @OSRM_INCLUDE_PATHS_STRING@ @OSRM_DEFINES_STRING@ @CMAKE_CXX_FLAGS@
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
coverage:
|
||||
|
||||
ignore:
|
||||
- unit_tests/.*
|
||||
- third_party/.*
|
||||
|
||||
comment: off
|
||||
+9
-1
@@ -5,15 +5,23 @@ RUN apt-get install -y build-essential git-core python-pip python-software-prope
|
||||
|
||||
RUN apt-get -y install gcc-4.8 g++-4.8 libboost1.55-all-dev llvm-3.4
|
||||
RUN apt-get -y install libbz2-dev libstxxl-dev libstxxl1 libxml2-dev
|
||||
RUN apt-get -y install libzip-dev lua5.1 liblua5.1-0-dev libtbb-dev libgdal-dev ruby1.9
|
||||
RUN apt-get -y install libzip-dev lua5.1 liblua5.1-0-dev libtbb-dev libgdal-dev
|
||||
RUN apt-get -y install curl cmake cmake-curses-gui
|
||||
|
||||
RUN pip install awscli
|
||||
|
||||
|
||||
# luabind
|
||||
RUN curl https://gist.githubusercontent.com/DennisOSRM/f2eb7b948e6fe1ae319e/raw/install-luabind.sh | sudo bash
|
||||
|
||||
WORKDIR /opt
|
||||
RUN git clone --depth 1 --branch v0.31.0 https://github.com/creationix/nvm.git
|
||||
RUN /bin/bash -c "source /opt/nvm/nvm.sh && nvm install v4"
|
||||
|
||||
RUN useradd -ms /bin/bash mapbox
|
||||
USER mapbox
|
||||
ENV HOME /home/mapbox
|
||||
WORKDIR /home/mapbox
|
||||
|
||||
RUN echo "source /opt/nvm/nvm.sh" > .bashrc
|
||||
RUN echo "source /home/mapbox/.bashrc" > .profile
|
||||
|
||||
+1
-1
@@ -8,4 +8,4 @@ docker run \
|
||||
-e "CXX=clang++" \
|
||||
-v `pwd`:/home/mapbox/osrm-backend \
|
||||
-t mapbox/osrm:linux \
|
||||
osrm-backend/docker/test.sh
|
||||
/bin/bash -lc "osrm-backend/docker/test.sh"
|
||||
|
||||
+1
-1
@@ -8,4 +8,4 @@ docker run \
|
||||
-e "CXX=g++" \
|
||||
-v `pwd`:/home/mapbox/osrm-backend \
|
||||
-t mapbox/osrm:linux \
|
||||
osrm-backend/docker/test.sh
|
||||
/bin/bash -lc "osrm-backend/docker/test.sh"
|
||||
|
||||
+5
-6
@@ -4,11 +4,8 @@ set -e
|
||||
set -o pipefail
|
||||
|
||||
export CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release"
|
||||
export PATH=$PATH:/home/mapbox/.gem/ruby/1.9.1/bin:/home/mapbox/osrm-backend/vendor/bundle/ruby/1.9.1/bin
|
||||
|
||||
cd /home/mapbox/osrm-backend
|
||||
gem install --user-install bundler
|
||||
bundle install --path vendor/bundle
|
||||
[ -d build ] && rm -rf build
|
||||
mkdir -p build
|
||||
cd build
|
||||
@@ -16,7 +13,9 @@ cmake .. $CMAKEOPTIONS -DBUILD_TOOLS=1
|
||||
|
||||
make -j`nproc`
|
||||
make tests -j`nproc`
|
||||
./datastructure-tests
|
||||
./algorithm-tests
|
||||
#./unit_tests/server-tests
|
||||
#./unit_tests/library-tests
|
||||
#./unit_tests/extractor-tests
|
||||
#./unit_tests/util-tests
|
||||
cd ..
|
||||
bundle exec cucumber -p verify
|
||||
npm test
|
||||
|
||||
+160
-39
@@ -1,3 +1,18 @@
|
||||
## Environent Variables
|
||||
|
||||
### SIGNAL_PARENT_WHEN_READY
|
||||
|
||||
If the SIGNAL_PARENT_WHEN_READY environment variable is set osrm-routed will
|
||||
send the USR1 signal to its parent when it will be running and waiting for
|
||||
requests. This could be used to upgrade osrm-routed to a new binary on the fly
|
||||
without any service downtime - no incoming requests will be lost.
|
||||
|
||||
### DISABLE_ACCESS_LOGGING
|
||||
|
||||
If the DISABLE_ACCESS_LOGGING environment variable is set osrm-routed will
|
||||
**not** log any http requests to standard output. This can be useful in high
|
||||
traffic setup.
|
||||
|
||||
## HTTP API
|
||||
|
||||
`osrm-routed` supports only `GET` requests of the form. If you your response size
|
||||
@@ -136,7 +151,7 @@ http://router.project-osrm.org/nearest/v1/driving/13.388860,52.517037?number=3&b
|
||||
### Request
|
||||
|
||||
```
|
||||
http://{server}/route/v1/{profile}/{coordinates}?alternatives={true|false}&steps={true|false}&geometries={polyline|geojson}&overview={full|simplified|false}
|
||||
http://{server}/route/v1/{profile}/{coordinates}?alternatives={true|false}&steps={true|false}&geometries={polyline|geojson}&overview={full|simplified|false}&annotations={true|false}
|
||||
```
|
||||
|
||||
In addition to the [general options](#general-options) the following options are supported for this service:
|
||||
@@ -145,6 +160,7 @@ In addition to the [general options](#general-options) the following options are
|
||||
|------------|------------------------------------------|-------------------------------------------------------------------------------|
|
||||
|alternatives|`true`, `false` (default) |Search for alternative routes and return as well.\* |
|
||||
|steps |`true`, `false` (default) |Return route steps for each route leg |
|
||||
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|
||||
|geometries |`polyline` (default), `geojson` |Returned route geometry format (influences overview and per step) |
|
||||
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
||||
|continue_straight |`default` (default), `true`, `false`|Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile. |
|
||||
@@ -237,7 +253,7 @@ The algorithm might not be able to match all points. Outliers are removed if the
|
||||
### Request
|
||||
|
||||
```
|
||||
http://{server}/match/v1/{profile}/{coordinates}?steps={true|false}&geometries={polyline|geojson}&overview={simplified|full|false}
|
||||
http://{server}/match/v1/{profile}/{coordinates}?steps={true|false}&geometries={polyline|geojson}&overview={simplified|full|false}&annotations={true|false}
|
||||
```
|
||||
|
||||
In addition to the [general options](#general-options) the following options are supported for this service:
|
||||
@@ -247,6 +263,7 @@ In addition to the [general options](#general-options) the following options are
|
||||
|------------|------------------------------------------------|------------------------------------------------------------------------------------------|
|
||||
|steps |`true`, `false` (default) |Return route steps for each route |
|
||||
|geometries |`polyline` (default), `geojson` |Returned route geometry format (influences overview and per step) |
|
||||
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|
||||
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
||||
|timestamps |`{timestamp};{timestamp}[;{timestamp} ...]` |Timestamp of the input location. |
|
||||
|radiuses |`{radius};{radius}[;{radius} ...]` |Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy.|
|
||||
@@ -284,7 +301,7 @@ multiple trips for each connected component are returned.
|
||||
### Request
|
||||
|
||||
```
|
||||
http://{server}/trip/v1/{profile}/{coordinates}?steps={true|false}&geometries={polyline|geojson}&overview={simplified|full|false}
|
||||
http://{server}/trip/v1/{profile}/{coordinates}?steps={true|false}&geometries={polyline|geojson}&overview={simplified|full|false}&annotations={true|false}
|
||||
```
|
||||
|
||||
In addition to the [general options](#general-options) the following options are supported for this service:
|
||||
@@ -292,6 +309,7 @@ In addition to the [general options](#general-options) the following options are
|
||||
|Option |Values |Description |
|
||||
|------------|------------------------------------------------|---------------------------------------------------------------------------|
|
||||
|steps |`true`, `false` (default) |Return route instructions for each trip |
|
||||
|annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. |
|
||||
|geometries |`polyline` (default), `geojson` |Returned route geometry format (influences overview and per step) |
|
||||
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|
||||
|
||||
@@ -339,7 +357,7 @@ Three input coordinates, `geometry=geojson`, `steps=false`:
|
||||
{
|
||||
"distance": 90.0,
|
||||
"duration": 300.0,
|
||||
"geometry": {"type": "LineString", "coordinates": [[120., 10.], [120.1, 10.], [120.2, 10.], [120.3, 10.]]},
|
||||
"geometry": {"type": "LineString", "coordinates": [[120.0, 10.0], [120.1, 10.0], [120.2, 10.0], [120.3, 10.0]]},
|
||||
"legs": [
|
||||
{
|
||||
"distance": 30.0,
|
||||
@@ -377,15 +395,27 @@ Represents a route between two waypoints.
|
||||
| true | array of `RouteStep` objects describing the turn-by-turn instructions |
|
||||
| false | empty array |
|
||||
|
||||
- `annotation`: Additional details about each coordinate along the route geometry:
|
||||
|
||||
| annotations | |
|
||||
|--------------|-----------------------------------------------------------------------|
|
||||
| true | returns distance and durations of each coordinate along the route |
|
||||
| false | will not exist |
|
||||
|
||||
#### Example
|
||||
|
||||
With `steps=false`:
|
||||
With `steps=false` and `annotations=true`:
|
||||
|
||||
```json
|
||||
{
|
||||
"distance": 30.0,
|
||||
"duration": 100.0,
|
||||
"steps": []
|
||||
"steps": [],
|
||||
"annotation": {
|
||||
"distance": [5,5,10,5,5],
|
||||
"duration": [15,15,40,15,15],
|
||||
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -407,11 +437,43 @@ step.
|
||||
| geojson | [GeoJSON `LineString`](http://geojson.org/geojson-spec.html#linestring) or [GeoJSON `Point`](http://geojson.org/geojson-spec.html#point) if it is only one coordinate (not wrapped by a GeoJSON feature)|
|
||||
|
||||
- `name`: The name of the way along which travel proceeds.
|
||||
- `pronunciation`: The pronunciation hint of the way name. Will be `undefined` if there is no pronunciation hit.
|
||||
- `destinations`: The destinations of the way. Will be `undefined` if there are no destinations.
|
||||
- `mode`: A string signifying the mode of transportation.
|
||||
- `maneuver`: A `StepManeuver` object representing the maneuver.
|
||||
- `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver
|
||||
|
||||
#### Example
|
||||
|
||||
```
|
||||
{
|
||||
"distance":152.3,
|
||||
"duration":15.6,
|
||||
"name":"Lortzingstraße",
|
||||
"maneuver":{
|
||||
"type":"turn",
|
||||
"modifier":"right",
|
||||
"lanes":[
|
||||
{"indications":["left","straight"], "valid":"false"},
|
||||
{"indications":["right"], "valid":"true"}
|
||||
]},
|
||||
"geometry":"{lu_IypwpAVrAvAdI",
|
||||
"mode":"driving",
|
||||
"intersections":[
|
||||
{"location":[13.39677,52.54366],
|
||||
"in":3,
|
||||
"out":1,
|
||||
"bearings":[10,92,184,270],
|
||||
"entry":[false,"true","true"]},
|
||||
{"location":[13.394718,52.543096],
|
||||
"in":0,
|
||||
"out":2,
|
||||
"bearings":[60,150,240,330],
|
||||
"entry":["false","true","true","true"]
|
||||
}
|
||||
]}
|
||||
```
|
||||
|
||||
### StepManeuver
|
||||
|
||||
#### Properties
|
||||
@@ -424,61 +486,120 @@ step.
|
||||
- `type` A string indicating the type of maneuver. **new identifiers might be introduced without API change**
|
||||
Types unknown to the client should be handled like the `turn` type, the existance of correct `modifier` values is guranteed.
|
||||
|
||||
| `type` | Description |
|
||||
|-------------------|--------------------------------------------------------------|
|
||||
| turn | a basic turn into direction of the `modifier` |
|
||||
| new name | no turn is taken, but the road name changes. The Road can take a turn itself, following `modifier` |
|
||||
| depart | indicates the departure of the leg |
|
||||
| arrive | indicates the destination of the leg |
|
||||
| merge | merge onto a street (e.g. getting on the highway from a ramp, the `modifier specifies the direction of the merge`) |
|
||||
| ramp | **Deprecated**. Replaced by `on_ramp` and `off_ramp`. |
|
||||
| on ramp | take a ramp to enter a highway (direction given my `modifier`) |
|
||||
| off ramp | take a ramp to exit a highway (direction given my `modifier`) |
|
||||
| fork | take the left/right side at a fork depending on `modifier` |
|
||||
| end of road | road ends in a T intersection turn in direction of `modifier`|
|
||||
| continue | Turn in direction of `modifier` to stay on the same road |
|
||||
| roundabout | traverse roundabout, has additional field `exit` with NR if the roundabout is left. `the modifier specifies the direction of entering the roundabout` |
|
||||
| rotary | a larger version of a roundabout, can offer `rotary_name` in addition to the `exit` parameter. |
|
||||
| roundabout turn | Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. |
|
||||
| notification | not an actual turn but a change in the driving conditions. For example the travel mode. If the road takes a turn itself, the `modifier` describes the direction |
|
||||
| `type` | Description |
|
||||
|------------------|--------------------------------------------------------------|
|
||||
| `turn` | a basic turn into direction of the `modifier` |
|
||||
| `new name` | no turn is taken/possible, but the road name changes. The road can take a turn itself, following `modifier`. |
|
||||
| `depart` | indicates the departure of the leg |
|
||||
| `arrive` | indicates the destination of the leg |
|
||||
| `merge` | merge onto a street (e.g. getting on the highway from a ramp, the `modifier specifies the direction of the merge`) |
|
||||
| `ramp` | **Deprecated**. Replaced by `on_ramp` and `off_ramp`. |
|
||||
| `on ramp` | take a ramp to enter a highway (direction given my `modifier`) |
|
||||
| `off ramp` | take a ramp to exit a highway (direction given my `modifier`) |
|
||||
| `fork` | take the left/right side at a fork depending on `modifier` |
|
||||
| `end of road` | road ends in a T intersection turn in direction of `modifier`|
|
||||
| `use lane` | going straight on a specific lane |
|
||||
| `continue` | Turn in direction of `modifier` to stay on the same road |
|
||||
| `roundabout` | traverse roundabout, has additional field `exit` with NR if the roundabout is left. `the modifier specifies the direction of entering the roundabout` |
|
||||
| `rotary` | a larger version of a roundabout, can offer `rotary_name` in addition to the `exit` parameter. |
|
||||
| `roundabout turn`| Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. |
|
||||
| `notification` | not an actual turn but a change in the driving conditions. For example the travel mode. If the road takes a turn itself, the `modifier` describes the direction |
|
||||
|
||||
Please note that even though there are `new name` and `notification` instructions, the `mode` and `name` can change
|
||||
between all instructions. They only offer a fallback in case nothing else is to report.
|
||||
|
||||
|
||||
- `modifier` An optional `string` indicating the direction change of the maneuver.
|
||||
|
||||
|
||||
| `modifier` | Description |
|
||||
|-------------------|-------------------------------------------|
|
||||
| uturn | indicates reversal of direction |
|
||||
| sharp right | a sharp right turn |
|
||||
| right | a normal turn to the right |
|
||||
| slight right | a slight turn to the right |
|
||||
| straight | no relevant change in direction |
|
||||
| slight left | a slight turn to the left |
|
||||
| left | a normal turn to the left |
|
||||
| sharp left | a sharp turn to the left |
|
||||
|
||||
The list of turns without a modifier is limited to: `depart/arrive`. If the source/target location is close enough to the `depart/arrive` location, no modifier will be given.
|
||||
| `uturn` | indicates reversal of direction |
|
||||
| `sharp right` | a sharp right turn |
|
||||
| `right` | a normal turn to the right |
|
||||
| `slight right` | a slight turn to the right |
|
||||
| `straight` | no relevant change in direction |
|
||||
| `slight left` | a slight turn to the left |
|
||||
| `left` | a normal turn to the left |
|
||||
| `sharp left` | a sharp turn to the left |
|
||||
|
||||
The list of turns without a modifier is limited to: `depart/arrive`. If the source/target location is close enough to the `depart/arrive` location, no modifier will be given.
|
||||
|
||||
The meaning depends on the `type` field.
|
||||
|
||||
|
||||
| `type` | Description |
|
||||
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
|
||||
| `turn` | `modifier` indicates the change in direction accomplished through the turn |
|
||||
| `depart`/`arrive` | `modifier` indicates the position of departure point and arrival point in relation to the current direction of travel |
|
||||
|
||||
|
||||
|
||||
- `exit` An optional `integer` indicating number of the exit to take. The field exists for the following `type` field:
|
||||
|
||||
| `type` | Description |
|
||||
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
|
||||
| `roundabout` | Number of the roundabout exit to take. If exit is `undefined` the destination is on the roundabout. |
|
||||
| `turn` or `end of road`| Indicates the number of intersections passed until the turn. Example instruction: `at the fourth intersection, turn left` |
|
||||
| else | Indicates the number of intersections passed until the turn. Example instruction: `at the fourth intersection, turn left` |
|
||||
|
||||
- `lanes`: Array of `Lane` objects that denote the available turn lanes at the turn location
|
||||
|
||||
New properties (potentially depending on `type`) may be introduced in the future without an API version change.
|
||||
|
||||
### Lane
|
||||
|
||||
A `Lane` represents a turn lane at the corresponding turn location.
|
||||
|
||||
#### Properties
|
||||
|
||||
- `indications`: a indication (e.g. marking on the road) specifying the turn lane. A road can have multiple indications (e.g. an arrow pointing straight and left). The indications are given in an array, each containing one of the following types. Further indications might be added on without an API version change.
|
||||
|
||||
| `value` | Description |
|
||||
|------------------------|---------------------------------------------------------------------------------------------------------------------------|
|
||||
| `none` | No dedicated indication is shown. |
|
||||
| `uturn` | An indication signaling the possibility to reverse (i.e. fully bend arrow). |
|
||||
| `sharp right` | An indication indicating a sharp right turn (i.e. strongly bend arrow). |
|
||||
| `right` | An indication indicating a right turn (i.e. bend arrow). |
|
||||
| `slight right` | An indication indicating a slight right turn (i.e. slightly bend arrow). |
|
||||
| `straight` | No dedicated indication is shown (i.e. straight arrow). |
|
||||
| `slight left` | An indication indicating a slight left turn (i.e. slightly bend arrow). |
|
||||
| `left` | An indication indicating a left turn (i.e. bend arrow). |
|
||||
| `sharp left` | An indication indicating a sharp left turn (i.e. strongly bend arrow). |
|
||||
|
||||
- `valid`: a boolean flag indicating whether the lane is a valid choice in the current maneuver
|
||||
|
||||
#### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"indications": ["left", "straight"],
|
||||
"valid": "false"
|
||||
}
|
||||
```
|
||||
|
||||
### Intersection
|
||||
|
||||
An intersection gives a full representation of any cross-way the path passes bay. For every step, the very first intersection (`intersections[0]`) corresponds to the
|
||||
location of the StepManeuver. Further intersections are listed for every cross-way until the next turn instruction.
|
||||
|
||||
#### Properties
|
||||
|
||||
- `location`: A `[longitude, latitude]` pair describing the location of the turn.
|
||||
- `bearings`: A list of bearing values (e.g. [0,90,180,270]) that are available at the intersection. The bearings describe all available roads at the intersection.
|
||||
- `entry`: A list of entry flags, corresponding in a 1:1 relationship to the bearings. A value of `true` indicates that the respective road could be entered on a valid route.
|
||||
`false` indicates that the turn onto the respective road would violate a restriction.
|
||||
- `in`: index into bearings/entry array. Used to calculate the bearing just before the turn. Namely, the clockwise angle from true north to the
|
||||
direction of travel immediately before the maneuver/passing the intersection. Bearings are given relative to the intersection. To get the bearing
|
||||
in the direction of driving, the bearing has to be rotated by a value of 180. The value is not supplied for `depart` maneuvers.
|
||||
- `out`: index into the bearings/entry array. Used to extract the bearing just after the turn. Namely, The clockwise angle from true north to the
|
||||
direction of travel immediately after the maneuver/passing the intersection. The value is not supplied for `arrive` maneuvers.
|
||||
|
||||
#### Example
|
||||
```
|
||||
{
|
||||
"location":[13.394718,52.543096],
|
||||
"in":0,
|
||||
"out":2,
|
||||
"bearings":[60,150,240,330],
|
||||
"entry":["false","true","true","true"]
|
||||
}
|
||||
```
|
||||
|
||||
### Waypoint
|
||||
|
||||
Object used to describe waypoint on a route.
|
||||
|
||||
+239
@@ -0,0 +1,239 @@
|
||||
# Testsuite
|
||||
|
||||
OSRM comes with a testsuite containing both unit-tests using the Boost library and cucucmber.js for scenario driven testing.
|
||||
|
||||
## Unit Tests
|
||||
|
||||
For a general introduction on Boost.Test have a look at [its docs](http://www.boost.org/doc/libs/1_60_0/libs/test/doc/html/index.html).
|
||||
|
||||
### Separate Test Binaries
|
||||
|
||||
Unit tests should be registered according to the sub-project they're in.
|
||||
If you want to write tests for utility functions, add them to the utility test binary.
|
||||
See `CMakeLists.txt` in the unit test directory for how to register new unit tests.
|
||||
|
||||
### Using Boost.Test Primitives
|
||||
|
||||
There is a difference between only reporting a failed condition and aborting the test right at a failed condition.
|
||||
Have a look at [`BOOST_CHECK` vs `BOOST_REQUIRE`](http://www.boost.org/doc/libs/1_60_0/libs/test/doc/html/boost_test/utf_reference/testing_tool_ref/assertion_boost_level.html).
|
||||
Instead of manually checking e.g. for equality, less than, if a function throws etc. use their [corresponding Boost.Test primitives](http://www.boost.org/doc/libs/1_60_0/libs/test/doc/html/boost_test/utf_reference/testing_tool_ref.html).
|
||||
|
||||
If you use `BOOST_CHECK_EQUAL` you have to implement `operator<<` for your type so that Boost.Test can print mismatches.
|
||||
If you do not want to do this, define `BOOST_TEST_DONT_PRINT_LOG_VALUE` (and undef it after the check call) or sidestep it with `BOOST_CHECK(fst == snd);`.
|
||||
|
||||
### Test Fixture
|
||||
|
||||
If you need to test features on a real dataset (think about this twice: prefer cucumber and dataset-independent tests for their reproducibility and minimality), there is a fixed dataset in `test/data`.
|
||||
This dataset is a small extract and may not even contain all tags or edge cases.
|
||||
Furthermore this dataset is not in sync with what you see in up-to-date OSM maps or on the demo server.
|
||||
See the library tests for how to add new dataset dependent tests.
|
||||
|
||||
|
||||
## Cucumber
|
||||
|
||||
For a general introduction on cucumber in our testsuite, have a look at [the wiki](https://github.com/Project-OSRM/osrm-backend/wiki/Cucumber-Test-Suite).
|
||||
|
||||
This documentation aims to supply a guideline on how to write cucumber tests that test new features introduced into osrm.
|
||||
|
||||
### Test the feature
|
||||
|
||||
It is often tempting to reduce the test to a path and accompanying instructions. Instructions can and will change over the course of improving guidance.
|
||||
|
||||
Instructions should only be used when writing a feature located in `features/guidance`. All other features should avoid using instructions at all.
|
||||
|
||||
### Write Tests to Scale
|
||||
|
||||
OSRM is a navigation engine. Tests should always consider this background.
|
||||
|
||||
An important implication is the grid size. If tests use a very small grid size, you run into the chance of instructions being omitted.
|
||||
For example:
|
||||
|
||||
```
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 10 meters
|
||||
|
||||
Scenario: Testbot - Straight Road
|
||||
Given the node map
|
||||
| a | b | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| bc | primary |
|
||||
| cd | primary |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| a | d | ab,bc,cd,cd |
|
||||
|
||||
```
|
||||
|
||||
In a navigation engine, the instructions
|
||||
|
||||
- depart east on ab
|
||||
- in 10 meters the road name changes to bc
|
||||
- in 10 meters the road name changes to cd
|
||||
- you arrived at cd
|
||||
|
||||
would be impossible to announce and not helpful at all.
|
||||
Since no actual choices exist, the route you get could result in `ab,cd` and simply say `depart` and `arrive`.
|
||||
|
||||
To prevent such surprises, always consider the availability of other roads and use grid sizes/road lengths that correspond to actually reasonable scenarios in a road network.
|
||||
|
||||
### Use names
|
||||
|
||||
If you specify many nodes in close succession to present a specific road geometry, consider using `name` to indicate to OSRM that the segment is a single road.
|
||||
|
||||
```
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 10 meters
|
||||
|
||||
Scenario: Testbot - Straight Road
|
||||
Given the node map
|
||||
| a | b | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| ab | primary | road |
|
||||
| bc | primary | road |
|
||||
| cd | primary | road |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns |
|
||||
| a | d | road,road | depart,arrive |
|
||||
|
||||
```
|
||||
|
||||
Guidance guarantees only essential maneuvers. You will always see `depart` and `arrive` as well as all turns that are not obvious.
|
||||
|
||||
So the following scenario does not change the instructions
|
||||
|
||||
```
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 10 meters
|
||||
|
||||
Scenario: Testbot - Straight Road
|
||||
Given the node map
|
||||
| a | b |
|
||||
| d | c |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| ab | primary | road |
|
||||
| bc | primary | road |
|
||||
| cd | primary | road |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns |
|
||||
| a | d | road,road | depart,arrive |
|
||||
```
|
||||
|
||||
but if we modify it to
|
||||
|
||||
```
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 10 meters
|
||||
|
||||
Scenario: Testbot - Straight Road
|
||||
Given the node map
|
||||
| a | b | e |
|
||||
| d | c | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| ab | primary | road |
|
||||
| bc | primary | road |
|
||||
| cd | primary | road |
|
||||
| be | primary | turn |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns |
|
||||
| a | d | road,road,road | depart,continue right,arrive |
|
||||
```
|
||||
|
||||
### Test all directions
|
||||
|
||||
Modelling a road as roundabout has an implied oneway tag associated with it. In the following case, we can route from `a` to `d` but not from `d` to `a`.
|
||||
To discover those errors, make sure to check for all allowed directions.
|
||||
|
||||
```
|
||||
Scenario: Enter and Exit mini roundabout with sharp angle # features/guidance/mini-roundabout.feature:37
|
||||
Given the profile "car" # features/step_definitions/data.js:8
|
||||
Given a grid size of 10 meters # features/step_definitions/data.js:20
|
||||
Given the node map # features/step_definitions/data.js:45
|
||||
| a | b | |
|
||||
| | c | d |
|
||||
And the ways # features/step_definitions/data.js:128
|
||||
| nodes | highway | name |
|
||||
| ab | tertiary | MySt |
|
||||
| bc | roundabout | |
|
||||
| cd | tertiary | MySt |
|
||||
When I route I should get # features/step_definitions/routing.js:4
|
||||
| from | to | route | turns | # |
|
||||
| a | d | MySt,MySt | depart,arrive | # suppress multiple enter/exit mini roundabouts |
|
||||
| d | a | MySt,MySt | depart,arrive | # suppress multiple enter/exit mini roundabouts |
|
||||
Tables were not identical:
|
||||
| from | to | route | turns | #
|
||||
| a | d | MySt,MySt | depart,arrive | # suppress multiple enter/exit mini roundabouts |
|
||||
| (-) d | (-) a | (-) MySt,MySt | (-) depart,arrive | (-) # suppress multiple enter/exit mini roundabouts |
|
||||
| (+) d | (+) a | (+) | (+) | (+) # suppress multiple enter/exit mini roundabouts |
|
||||
```
|
||||
|
||||
### Prevent Randomness
|
||||
|
||||
Some features in OSRM can result in strange experiences during testcases. To prevent some of these issues, follow the guidelines below.
|
||||
|
||||
#### Use Waypoints
|
||||
|
||||
Using grid nodes as waypoints offers the chance of unwanted side effects.
|
||||
OSRM converts the grid into a so called edge-based graph.
|
||||
|
||||
```
|
||||
Scenario: Testbot - Intersection
|
||||
Given the node map
|
||||
| | e | |
|
||||
| b | a | d |
|
||||
| | c | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | oneway |
|
||||
| ab | primary | yes |
|
||||
| ac | primary | yes |
|
||||
| ad | primary | yes |
|
||||
| ae | primary | yes |
|
||||
```
|
||||
Selecting `a` as a `waypoint` results in four possible starting locations. Which one of the routes `a,b`, `a,c`, `a,d`, or `a,e` is found is pure chance and depends on the order in the static `r-tree`.
|
||||
|
||||
To guarantee discovery, use:
|
||||
|
||||
```
|
||||
Scenario: Testbot - Intersection
|
||||
Given the node map
|
||||
| | | e | | |
|
||||
| | | 4 | | |
|
||||
| b | 1 | a | 3 | d |
|
||||
| | | 2 | | |
|
||||
| | | c | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | oneway |
|
||||
| ab | primary | yes |
|
||||
| ac | primary | yes |
|
||||
| ad | primary | yes |
|
||||
| ae | primary | yes |
|
||||
```
|
||||
And use `1`,`2`,`3`, and `4` as starting waypoints. The routes `1,b`, `2,c`, `3,d`, and `4,e` can all be discovered.
|
||||
|
||||
#### Allow For Small Offsets
|
||||
|
||||
Whenever you are independent of the start location (see use waypoints), the waypoint chosen as start/end location can still influence distances/durations.
|
||||
|
||||
If you are testing for a duration metric, allow for a tiny offset to ensure a passing test in the presence of rounding/snapping issues.
|
||||
|
||||
#### Don't Rely on Alternatives
|
||||
|
||||
Alternative route discovery is a random feature in itself. The discovery of routes depends on the contraction order of roads and cannot be assumed successful, ever.
|
||||
@@ -6,10 +6,13 @@ Please create a directory and run cmake from there, passing the path to this sou
|
||||
This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. Please delete them.")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
project(osrm-example C CXX)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ")
|
||||
|
||||
set(bitness 32)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
@@ -23,11 +26,11 @@ if(WIN32 AND MSVC_VERSION LESS 1900)
|
||||
message(FATAL_ERROR "Building with Microsoft compiler needs Latest Visual Studio 2015 (Community or better)")
|
||||
endif()
|
||||
|
||||
link_directories(${LibOSRM_LIBRARY_DIRS})
|
||||
add_executable(osrm-example example.cpp)
|
||||
|
||||
find_package(LibOSRM REQUIRED)
|
||||
find_package(Boost 1.49.0 COMPONENTS filesystem system thread REQUIRED)
|
||||
|
||||
target_link_libraries(osrm-example ${LibOSRM_LIBRARIES} ${Boost_LIBRARIES})
|
||||
include_directories(SYSTEM ${LibOSRM_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
|
||||
|
||||
target_link_libraries(osrm-example ${LibOSRM_LIBRARIES} ${LibOSRM_DEPENDENT_LIBRARIES})
|
||||
include_directories(SYSTEM ${LibOSRM_INCLUDE_DIRS})
|
||||
set(CMAKE_CXX_FLAGS ${LibOSRM_CXXFLAGS})
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
# - Try to find LibOSRM
|
||||
# Once done this will define
|
||||
# LibOSRM_FOUND - System has LibOSRM
|
||||
# LibOSRM_INCLUDE_DIRS - The LibOSRM include directories
|
||||
# LibOSRM_LIBRARIES - The libraries needed to use LibOSRM
|
||||
# LibOSRM_DEFINITIONS - Compiler switches required for using LibOSRM
|
||||
# LibOSRM_LIBRARIES - The libraries and ldflags needed to use LibOSRM
|
||||
# LibOSRM_DEPENDENT_LIBRARIES - The libraries and ldflags need to link LibOSRM dependencies
|
||||
# LibOSRM_LIBRARY_DIRS - The libraries paths needed to find LibOSRM
|
||||
# LibOSRM_CXXFLAGS - Compiler switches required for using LibOSRM
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PC_LibOSRM QUIET libosrm)
|
||||
set(LibOSRM_DEFINITIONS ${PC_LibOSRM_CFLAGS_OTHER})
|
||||
pkg_search_module(PC_LibOSRM QUIET libosrm)
|
||||
|
||||
function(JOIN VALUES GLUE OUTPUT)
|
||||
string (REPLACE ";" "${GLUE}" _TMP_STR "${VALUES}")
|
||||
set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
list(REMOVE_ITEM PC_LibOSRM_CFLAGS " ")
|
||||
JOIN("${PC_LibOSRM_CFLAGS}" " " output)
|
||||
|
||||
set(LibOSRM_CXXFLAGS ${output})
|
||||
set(LibOSRM_LIBRARY_DIRS ${PC_LibOSRM_LIBRARY_DIRS})
|
||||
|
||||
find_path(LibOSRM_INCLUDE_DIR osrm/osrm.hpp
|
||||
PATH_SUFFIXES osrm include/osrm include
|
||||
@@ -19,8 +30,6 @@ find_path(LibOSRM_INCLUDE_DIR osrm/osrm.hpp
|
||||
/opt/local
|
||||
/opt)
|
||||
|
||||
set(LibOSRM_INCLUDE_DIRS ${LibOSRM_INCLUDE_DIR} ${LibOSRM_INCLUDE_DIR}/osrm)
|
||||
|
||||
find_library(TEST_LibOSRM_STATIC_LIBRARY Names osrm.lib libosrm.a
|
||||
PATH_SUFFIXES osrm lib/osrm lib
|
||||
HINTS ${PC_LibOSRM_LIBDIR} ${PC_LibOSRM_LIBRARY_DIRS}
|
||||
@@ -30,7 +39,7 @@ find_library(TEST_LibOSRM_STATIC_LIBRARY Names osrm.lib libosrm.a
|
||||
/usr
|
||||
/opt/local
|
||||
/opt)
|
||||
find_library(TEST_LibOSRM_DYNAMIC_LIBRARY Names osrm.dynlib libosrm.so
|
||||
find_library(TEST_LibOSRM_DYNAMIC_LIBRARY Names libosrm.dylib libosrm.so
|
||||
PATH_SUFFIXES osrm lib/osrm lib
|
||||
HINTS ${PC_LibOSRM_LIBDIR} ${PC_LibOSRM_LIBRARY_DIRS}
|
||||
~/Library/Frameworks
|
||||
@@ -40,26 +49,15 @@ find_library(TEST_LibOSRM_DYNAMIC_LIBRARY Names osrm.dynlib libosrm.so
|
||||
/opt/local
|
||||
/opt)
|
||||
|
||||
if (NOT ("${TEST_LibOSRM_STATIC_LIBRARY}" STREQUAL "TEST_LibOSRM_STATIC_LIBRARY-NOTFOUND"))
|
||||
if ("${PC_LibOSRM_STATIC_LIBRARIES}" STREQUAL "")
|
||||
set(LibOSRM_STATIC_LIBRARIES ${TEST_LibOSRM_STATIC_LIBRARY})
|
||||
else()
|
||||
set(LibOSRM_STATIC_LIBRARIES ${PC_LibOSRM_STATIC_LIBRARIES})
|
||||
endif()
|
||||
set(LibOSRM_LIBRARIES ${LibOSRM_STATIC_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (NOT ("${TEST_LibOSRM_DYNAMIC_LIBRARY}" STREQUAL "TEST_LibOSRM_DYNAMIC_LIBRARY-NOTFOUND"))
|
||||
if ("${PC_LibOSRM_LIBRARIES}" STREQUAL "")
|
||||
set(LibOSRM_DYNAMIC_LIBRARIES ${TEST_LibOSRM_DYNAMIC_LIBRARY})
|
||||
else()
|
||||
set(LibOSRM_DYNAMIC_LIBRARIES ${PC_LibOSRM_LIBRARIES})
|
||||
endif()
|
||||
set(LibOSRM_LIBRARIES ${LibOSRM_DYNAMIC_LIBRARIES})
|
||||
endif()
|
||||
set(LibOSRM_DEPENDENT_LIBRARIES ${PC_LibOSRM_STATIC_LDFLAGS})
|
||||
set(LibOSRM_LIBRARIES ${PC_LibOSRM_LDFLAGS})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LIBOSRM_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(LibOSRM DEFAULT_MSG
|
||||
LibOSRM_LIBRARIES LibOSRM_INCLUDE_DIR)
|
||||
LibOSRM_LIBRARY_DIRS
|
||||
LibOSRM_CXXFLAGS
|
||||
LibOSRM_LIBRARIES
|
||||
LibOSRM_DEPENDENT_LIBRARIES
|
||||
LibOSRM_INCLUDE_DIR)
|
||||
|
||||
+7
-7
@@ -1,20 +1,20 @@
|
||||
#include "osrm/match_parameters.hpp"
|
||||
#include "osrm/nearest_parameters.hpp"
|
||||
#include "osrm/route_parameters.hpp"
|
||||
#include "osrm/table_parameters.hpp"
|
||||
#include "osrm/nearest_parameters.hpp"
|
||||
#include "osrm/trip_parameters.hpp"
|
||||
#include "osrm/match_parameters.hpp"
|
||||
|
||||
#include "osrm/coordinate.hpp"
|
||||
#include "osrm/engine_config.hpp"
|
||||
#include "osrm/json_container.hpp"
|
||||
|
||||
#include "osrm/status.hpp"
|
||||
#include "osrm/osrm.hpp"
|
||||
#include "osrm/status.hpp"
|
||||
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
@@ -40,8 +40,8 @@ int main(int argc, const char *argv[]) try
|
||||
RouteParameters params;
|
||||
|
||||
// Route in monaco
|
||||
params.coordinates.push_back({util::FloatLongitude(7.419758), util::FloatLatitude(43.731142)});
|
||||
params.coordinates.push_back({util::FloatLongitude(7.419505), util::FloatLatitude(43.736825)});
|
||||
params.coordinates.push_back({util::FloatLongitude{7.419758}, util::FloatLatitude{43.731142}});
|
||||
params.coordinates.push_back({util::FloatLongitude{7.419505}, util::FloatLatitude{43.736825}});
|
||||
|
||||
// Response is in JSON format
|
||||
json::Object result;
|
||||
|
||||
@@ -46,14 +46,17 @@ Feature: Bike - Mode flag
|
||||
|
||||
Scenario: Bike - Mode when pushing bike against oneways
|
||||
Given the node map
|
||||
| a | b | |
|
||||
| | c | d |
|
||||
| a | b | e |
|
||||
| f | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | oneway |
|
||||
| ab | primary | |
|
||||
| bc | primary | yes |
|
||||
| cd | primary | |
|
||||
| be | primary | |
|
||||
| cf | primary | |
|
||||
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | modes |
|
||||
|
||||
@@ -18,8 +18,8 @@ Feature: Bike - Oneway streets
|
||||
|
||||
Scenario: Bike - Around the Block
|
||||
Given the node map
|
||||
| a | b |
|
||||
| d | c |
|
||||
| | a | b | |
|
||||
| f | d | c | e |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway | foot |
|
||||
@@ -27,6 +27,8 @@ Feature: Bike - Oneway streets
|
||||
| bc | | no |
|
||||
| cd | | no |
|
||||
| da | | no |
|
||||
| df | | no |
|
||||
| ce | | no |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
@@ -48,22 +50,22 @@ Feature: Bike - Oneway streets
|
||||
|
||||
Scenario: Bike - Implied oneways
|
||||
Then routability should be
|
||||
| highway | foot | bicycle | junction | forw | backw |
|
||||
| | no | | | x | x |
|
||||
| | no | | roundabout | x | |
|
||||
| motorway | no | yes | | x | |
|
||||
| motorway_link | no | yes | | x | |
|
||||
| motorway | no | yes | roundabout | x | |
|
||||
| motorway_link | no | yes | roundabout | x | |
|
||||
| highway | foot | bicycle | junction | forw | backw | # |
|
||||
| | no | | | x | x | |
|
||||
| | no | | roundabout | x | | |
|
||||
| motorway | no | yes | | x | | |
|
||||
| motorway_link | no | yes | | x | x | does not imply oneway |
|
||||
| motorway | no | yes | roundabout | x | | |
|
||||
| motorway_link | no | yes | roundabout | x | | |
|
||||
|
||||
Scenario: Bike - Overriding implied oneways
|
||||
Then routability should be
|
||||
| highway | foot | junction | oneway | forw | backw |
|
||||
| primary | no | roundabout | no | x | x |
|
||||
| primary | no | roundabout | yes | x | |
|
||||
| motorway_link | no | | -1 | | |
|
||||
| trunk_link | no | | -1 | | |
|
||||
| primary | no | roundabout | -1 | | x |
|
||||
| highway | foot | junction | oneway | forw | backw |
|
||||
| primary | no | roundabout | no | x | x |
|
||||
| primary | no | roundabout | yes | x | |
|
||||
| motorway_link | no | | -1 | | |
|
||||
| trunk_link | no | | -1 | | |
|
||||
| primary | no | roundabout | -1 | | x |
|
||||
|
||||
Scenario: Bike - Oneway:bicycle should override normal oneways tags
|
||||
Then routability should be
|
||||
@@ -115,7 +117,7 @@ Feature: Bike - Oneway streets
|
||||
|
||||
Scenario: Bike - Two consecutive oneways
|
||||
Given the node map
|
||||
| a | b | c |
|
||||
| a | b | | c |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
|
||||
@@ -87,14 +87,16 @@ Feature: Bike - Accessability of different way types
|
||||
|
||||
Scenario: Bike - Instructions when pushing bike on oneways
|
||||
Given the node map
|
||||
| a | b | |
|
||||
| | c | d |
|
||||
| a | b | e |
|
||||
| f | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | oneway |
|
||||
| ab | primary | |
|
||||
| bc | primary | yes |
|
||||
| cd | primary | |
|
||||
| be | primary | |
|
||||
| cf | primary | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | modes |
|
||||
|
||||
@@ -38,3 +38,20 @@ Feature: Bike - Surfaces
|
||||
| cycleway | | 48s |
|
||||
| nosense | | |
|
||||
| nosense | asphalt | |
|
||||
|
||||
Scenario: Bicycle - Surfaces should not increase speed when pushing bikes
|
||||
Given the node map
|
||||
| a | b |
|
||||
| c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | oneway | surface |
|
||||
| ab | primary | yes | asphalt |
|
||||
| cd | footway | | asphalt |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | modes | speed |
|
||||
| a | b | ab,ab | cycling,cycling | 15 km/h |
|
||||
| b | a | ab,ab | pushing bike,pushing bike | 6 km/h |
|
||||
| c | d | cd,cd | pushing bike,pushing bike | 6 km/h |
|
||||
| d | c | cd,cd | pushing bike,pushing bike | 6 km/h |
|
||||
|
||||
@@ -18,6 +18,23 @@ Feature: Car - Street names in instructions
|
||||
| from | to | route |
|
||||
| a | c | My Way,Your Way (A1),Your Way (A1) |
|
||||
|
||||
Scenario: Car - A named street with pronunciation
|
||||
Given the node map
|
||||
| a | b | d |
|
||||
| | 1 | |
|
||||
| | c | |
|
||||
|
||||
And the ways
|
||||
| nodes | name |name:pronunciation | ref |
|
||||
| ab | My Way | | |
|
||||
| bd | My Way | meyeway | A1 |
|
||||
| cd | Your Way | yourewaye | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | pronunciations |
|
||||
| a | d | My Way,My Way (A1) | ,meyeway |
|
||||
| 1 | c | Your Way,Your Way | yourewaye,yourewaye |
|
||||
|
||||
@todo
|
||||
Scenario: Car - Use way type to describe unnamed ways
|
||||
Given the node map
|
||||
|
||||
+17
-13
@@ -17,24 +17,26 @@ Feature: Car - Oneway streets
|
||||
|
||||
Scenario: Car - Implied oneways
|
||||
Then routability should be
|
||||
| highway | junction | forw | backw |
|
||||
| motorway | | x | |
|
||||
| motorway_link | | x | |
|
||||
| primary | | x | x |
|
||||
| motorway | roundabout | x | |
|
||||
| motorway_link | roundabout | x | |
|
||||
| primary | roundabout | x | |
|
||||
| highway | junction | forw | backw | # |
|
||||
| motorway | | x | | |
|
||||
| motorway_link | | x | x | does not imply oneway |
|
||||
| primary | | x | x | |
|
||||
| motorway | roundabout | x | | |
|
||||
| motorway_link | roundabout | x | | |
|
||||
| primary | roundabout | x | | |
|
||||
|
||||
Scenario: Car - Overrule implied oneway
|
||||
Then routability should be
|
||||
| highway | oneway | forw | backw |
|
||||
| motorway | no | x | x |
|
||||
| motorway_link | no | x | x |
|
||||
| highway | oneway | forw | backw | # |
|
||||
| motorway | no | x | x | |
|
||||
| motorway_link | no | x | x | |
|
||||
| motorway_link | yes | x | | |
|
||||
| motorway_link | | x | x | does not imply onway |
|
||||
|
||||
Scenario: Car - Around the Block
|
||||
Given the node map
|
||||
| a | b |
|
||||
| d | c |
|
||||
| | a | b | |
|
||||
| f | d | c | e |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
@@ -42,6 +44,8 @@ Feature: Car - Oneway streets
|
||||
| bc | |
|
||||
| cd | |
|
||||
| da | |
|
||||
| ce | |
|
||||
| df | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
@@ -66,7 +70,7 @@ Feature: Car - Oneway streets
|
||||
|
||||
Scenario: Car - Two consecutive oneways
|
||||
Given the node map
|
||||
| a | b | c |
|
||||
| a | b | | c |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
|
||||
@@ -5,6 +5,7 @@ Feature: Car - Turn restrictions
|
||||
|
||||
Background: Use car routing
|
||||
Given the profile "car"
|
||||
Given a grid size of 200 meters
|
||||
|
||||
@no_turning
|
||||
Scenario: Car - No left turn
|
||||
|
||||
@@ -12,19 +12,17 @@ Feature: Traffic - turn penalties
|
||||
| nodes | highway |
|
||||
| ad | primary |
|
||||
| cd | primary |
|
||||
| de | primary |
|
||||
| def | primary |
|
||||
| dhk | primary |
|
||||
|
||||
| bf | primary |
|
||||
| ef | primary |
|
||||
| fg | primary |
|
||||
| fim | primary |
|
||||
|
||||
| jk | primary |
|
||||
| kl | primary |
|
||||
| klm | primary |
|
||||
| ko | primary |
|
||||
|
||||
| lm | primary |
|
||||
| mn | primary |
|
||||
| mp | primary |
|
||||
And the profile "car"
|
||||
@@ -32,22 +30,22 @@ Feature: Traffic - turn penalties
|
||||
|
||||
Scenario: Weighting not based on turn penalty file
|
||||
When I route I should get
|
||||
| from | to | route | speed | time |
|
||||
| a | h | ad,dhk,dhk | 63 km/h | 11.5s +-1 |
|
||||
| from | to | route | speed | time |
|
||||
| a | h | ad,dhk,dhk | 63 km/h | 11.5s +-1 |
|
||||
# straight
|
||||
| i | g | fim,fg,fg | 59 km/h | 12s +-1 |
|
||||
| i | g | fim,fg,fg | 59 km/h | 12s +-1 |
|
||||
# right
|
||||
| a | e | ad,de,de | 57 km/h | 12.5s +-1 |
|
||||
| a | e | ad,def,def | 57 km/h | 12.5s +-1 |
|
||||
# left
|
||||
| c | g | cd,de,ef,fg,fg | 63 km/h | 23s +-1 |
|
||||
| c | g | cd,def,fg,fg | 63 km/h | 23s +-1 |
|
||||
# double straight
|
||||
| p | g | mp,fim,fg,fg | 61 km/h | 23.5s +-1 |
|
||||
| p | g | mp,fim,fg,fg | 61 km/h | 23.5s +-1 |
|
||||
# straight-right
|
||||
| a | l | ad,dhk,kl,kl | 60 km/h | 24s +-1 |
|
||||
| a | l | ad,dhk,klm,klm | 60 km/h | 24s +-1 |
|
||||
# straight-left
|
||||
| l | e | kl,dhk,de,de | 59 km/h | 24.5s +-1 |
|
||||
| l | e | klm,dhk,def,def | 59 km/h | 24.5s +-1 |
|
||||
# double right
|
||||
| g | n | fg,fim,mn,mn | 57 km/h | 25s +-1 |
|
||||
| g | n | fg,fim,mn,mn | 57 km/h | 25s +-1 |
|
||||
# double left
|
||||
|
||||
Scenario: Weighting based on turn penalty file
|
||||
@@ -62,24 +60,24 @@ Feature: Traffic - turn penalties
|
||||
"""
|
||||
And the contract extra arguments "--turn-penalty-file penalties.csv"
|
||||
When I route I should get
|
||||
| from | to | route | speed | time |
|
||||
| a | h | ad,dhk,dhk | 63 km/h | 11.5s +-1 |
|
||||
| from | to | route | speed | time |
|
||||
| a | h | ad,dhk,dhk | 63 km/h | 11.5s +-1 |
|
||||
# straight
|
||||
| i | g | fim,fg,fg | 55 km/h | 13s +-1 |
|
||||
| i | g | fim,fg,fg | 55 km/h | 13s +-1 |
|
||||
# right - ifg penalty
|
||||
| a | e | ad,de,de | 64 km/h | 11s +-1 |
|
||||
| a | e | ad,def,def | 64 km/h | 11s +-1 |
|
||||
# left - faster because of negative ade penalty
|
||||
| c | g | cd,de,ef,fg,fg | 63 km/h | 23s +-1 |
|
||||
| c | g | cd,def,fg,fg | 63 km/h | 23s +-1 |
|
||||
# double straight
|
||||
| p | g | mp,fim,fg,fg | 59 km/h | 24.5s +-1 |
|
||||
| p | g | mp,fim,fg,fg | 59 km/h | 24.5s +-1 |
|
||||
# straight-right - ifg penalty
|
||||
| a | l | ad,de,ef,fim,lm,lm | 61 km/h | 35.5s +-1 |
|
||||
| a | l | ad,def,fim,klm,klm | 61 km/h | 35.5s +-1 |
|
||||
# was straight-left - forced around by hkl penalty
|
||||
| l | e | lm,fim,ef,ef | 57 km/h | 25s +-1 |
|
||||
| l | e | klm,fim,def,def | 57 km/h | 25s +-1 |
|
||||
# double right - forced left by lkh penalty
|
||||
| g | n | fg,fim,mn,mn | 30 km/h | 47.5s +-1 |
|
||||
| g | n | fg,fim,mn,mn | 30 km/h | 47.5s +-1 |
|
||||
# double left - imn penalty
|
||||
| j | c | jk,kl,lm,fim,ef,de,cd,cd | 60 km/h | 48s +-1 |
|
||||
| j | c | jk,klm,fim,def,cd,cd | 60 km/h | 48s +-1 |
|
||||
# double left - hdc penalty ever so slightly higher than imn; forces all the way around
|
||||
|
||||
Scenario: Too-negative penalty clamps, but does not fail
|
||||
@@ -90,8 +88,8 @@ Feature: Traffic - turn penalties
|
||||
1,4,5,-10
|
||||
"""
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
| a | d | ad,ad | 10s +-1 |
|
||||
| a | e | ad,de,de | 10s +-1 |
|
||||
| b | f | bf,bf | 10s +-1 |
|
||||
| b | g | bf,fg,fg | 20s +-1 |
|
||||
| from | to | route | time |
|
||||
| a | d | ad,ad | 10s +-1 |
|
||||
| a | e | ad,def,def | 10s +-1 |
|
||||
| b | f | bf,bf | 10s +-1 |
|
||||
| b | g | bf,fg,fg | 20s +-1 |
|
||||
|
||||
@@ -0,0 +1,444 @@
|
||||
@routing @guidance @turn-lanes
|
||||
Feature: Turn Lane Guidance
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 20 meters
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate Lane Change for subsequent multi-lane intersections
|
||||
Given the node map
|
||||
| a | | b | | x | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | | z |
|
||||
| | | | | | | |
|
||||
| | | y | | e | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward |
|
||||
| ab | through\|right\|right\|right |
|
||||
| bx | |
|
||||
| bc | left\|left\|through |
|
||||
| cd | through\|right |
|
||||
| cy | |
|
||||
| dz | |
|
||||
| de | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes | # |
|
||||
| a,d | ab,bc,cd,cd | depart,turn right,turn left,arrive | ,straight:false right:true right:true right:false,left:true left:true straight:false, | 2 hops |
|
||||
| a,e | ab,bc,cd,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true, | 3 hops |
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate Lane Change for quick same direction turns, staying on the same street
|
||||
Given the node map
|
||||
| a | | b | x |
|
||||
| | | | |
|
||||
| | | c | |
|
||||
| | | | |
|
||||
| e | | d | y |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | turn:lanes:backward | name |
|
||||
| ab | through\|right\|right | | MySt |
|
||||
| bx | | | XSt |
|
||||
| bc | | left\|right | MySt |
|
||||
| cd | left\|right | through\|through | MySt |
|
||||
| de | | left\|left\|through | MySt |
|
||||
| dy | | | YSt |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | MySt,MySt,MySt,MySt | depart,continue right,turn right,arrive | ,straight:false right:false right:true,left:false right:true, |
|
||||
| e,a | MySt,MySt,MySt,MySt | depart,continue left,turn left,arrive | ,left:true left:false straight:false,left:true right:false, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate Lane Change for quick same direction turns, changing between streets
|
||||
Given the node map
|
||||
| a | | b | x |
|
||||
| | | | |
|
||||
| | | c | |
|
||||
| | | | |
|
||||
| e | | d | y |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | turn:lanes:backward | name |
|
||||
| ab | through\|right\|right | | AXSt |
|
||||
| bx | | | AXSt |
|
||||
| bc | | left\|right | BDSt |
|
||||
| cd | left\|right | through\|through | BDSt |
|
||||
| de | | left\|left\|through | EYSt |
|
||||
| dy | | | EYSt |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | AXSt,BDSt,EYSt,EYSt | depart,turn right,turn right,arrive | ,straight:false right:false right:true,left:false right:true, |
|
||||
| e,a | EYSt,BDSt,AXSt,AXSt | depart,turn left,turn left,arrive | ,left:true left:false straight:false,left:true right:false, |
|
||||
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate Lane Change for quick turns during a merge
|
||||
Given the node map
|
||||
| a | | | | |
|
||||
| x | b | | c | y |
|
||||
| | | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | name | highway | oneway |
|
||||
| ab | slight_left\|slight_left | On | motorway_link | yes |
|
||||
| xb | | Hwy | motorway | |
|
||||
| bc | through\|slight_right | Hwy | motorway | |
|
||||
| cd | | Off | motorway_link | yes |
|
||||
| cy | | Hwy | motorway | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive | ,slight left:false slight left:true,straight:false slight right:true, |
|
||||
|
||||
|
||||
@anticipate
|
||||
Scenario: Schoenefelder Kreuz
|
||||
# https://www.openstreetmap.org/way/264306388#map=16/52.3202/13.5568
|
||||
Given the node map
|
||||
| a | b | x | | | i |
|
||||
| | | c | d | | |
|
||||
| | | | | | j |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | lanes | highway | oneway | name |
|
||||
| ab | none\|none\|none\|slight_right\|slight_right | 5 | motorway | | abx |
|
||||
| bx | | 3 | motorway | | abx |
|
||||
| bc | | 2 | motorway_link | yes | bcd |
|
||||
| cd | slight_left\|slight_left;slight_right\|slight_right | 3 | motorway_link | yes | bcd |
|
||||
| di | slight_left\|slight_right | 2 | motorway_link | yes | di |
|
||||
| dj | | 2 | motorway_link | yes | dj |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,i | abx,bcd,di,di | depart,off ramp right,fork slight left,arrive | ,none:false none:false none:false slight right:true slight right:true,slight left:true slight left;slight right:true slight right:false, |
|
||||
| a,j | abx,bcd,dj,dj | depart,off ramp right,fork slight right,arrive | ,none:false none:false none:false slight right:true slight right:true,slight left:false slight left;slight right:true slight right:true, |
|
||||
|
||||
|
||||
@anticipate
|
||||
Scenario: Kreuz Oranienburg
|
||||
# https://www.openstreetmap.org/way/4484007#map=18/52.70439/13.20269
|
||||
Given the node map
|
||||
| i | | | | | a |
|
||||
| j | | c | b | | x |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | lanes | highway | oneway | name |
|
||||
| ab | | 1 | motorway_link | yes | ab |
|
||||
| xb | | 1 | motorway_link | yes | xbcj |
|
||||
| bc | none\|slight_right | 2 | motorway_link | yes | xbcj |
|
||||
| ci | | 1 | motorway_link | yes | ci |
|
||||
| cj | | 1 | motorway_link | yes | xbcj |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,i | ab,xbcj,ci,ci | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
|
||||
| a,j | ab,xbcj,xbcj,xbcj | depart,merge slight left,use lane straight,arrive | ,,none:true slight right:false, |
|
||||
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for fan-in
|
||||
Given the node map
|
||||
| a | | b | | x | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | | z |
|
||||
| | | | | | | |
|
||||
| | | y | | e | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | name |
|
||||
| ab | through\|right\|right\|right | abx |
|
||||
| bx | | abx |
|
||||
| bc | left\|left\|through | bcy |
|
||||
| cy | | bcy |
|
||||
| cd | through\|right | cdz |
|
||||
| dz | | cdz |
|
||||
| de | | de |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for fan-out
|
||||
Given the node map
|
||||
| a | | b | | x | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | | z |
|
||||
| | | | | | | |
|
||||
| | | y | | e | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | name |
|
||||
| ab | through\|right | abx |
|
||||
| bx | | abx |
|
||||
| bc | left\|left\|through | bcy |
|
||||
| cy | | bcy |
|
||||
| cd | through\|right\|right\|right | cdz |
|
||||
| dz | | cdz |
|
||||
| de | | de |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:true,left:true left:true straight:false,straight:false right:true right:true right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for fan-in followed by fan-out
|
||||
Given the node map
|
||||
| a | | b | | x | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | | z |
|
||||
| | | | | | | |
|
||||
| | | y | | e | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | name |
|
||||
| ab | through\|right\|right\|right | abx |
|
||||
| bx | | abx |
|
||||
| bc | left\|left\|through | bcy |
|
||||
| cy | | bcy |
|
||||
| cd | through\|right\|right\|right | cdz |
|
||||
| dz | | cdz |
|
||||
| de | | de |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:true right:true right:false,left:true left:true straight:false,straight:false right:true right:true right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for fan-out followed by fan-in
|
||||
Given the node map
|
||||
| a | | b | | x | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | | z |
|
||||
| | | | | | | |
|
||||
| | | y | | e | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | name |
|
||||
| ab | through\|right | abx |
|
||||
| bx | | abx |
|
||||
| bc | left\|left\|through | bcy |
|
||||
| cy | | bcy |
|
||||
| cd | through\|right | cdz |
|
||||
| dz | | cdz |
|
||||
| de | | de |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | abx,bcy,cdz,de,de | depart,turn right,turn left,turn right,arrive | ,straight:false right:true,left:false left:true straight:false,straight:false right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Lane anticipation for multiple hops with same number of lanes
|
||||
Given the node map
|
||||
| a | | b | | x | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | | z |
|
||||
| | | | | | | |
|
||||
| | | y | | e | | f |
|
||||
| | | | | | | |
|
||||
| | | | | w | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | name |
|
||||
| ab | through\|right\|right\|right | abx |
|
||||
| bx | | abx |
|
||||
| bc | left\|left\|through | bcy |
|
||||
| cy | | bcy |
|
||||
| cd | through\|right\|right | cdz |
|
||||
| dz | | cdz |
|
||||
| de | left\|through | dew |
|
||||
| ew | | dew |
|
||||
| ef | | ef |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | abx,bcy,cdz,dew,ef,ef | depart,turn right,turn left,turn right,turn left,arrive | ,straight:false right:false right:true right:false,left:false left:true straight:false,straight:false right:true right:false,left:true straight:false, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate with lanes in roundabout: roundabouts as the unit of anticipation
|
||||
Given the node map
|
||||
| | | e | | |
|
||||
| a | b | | d | f |
|
||||
| | | c | | |
|
||||
| | | | | |
|
||||
| | | g | | |
|
||||
| k | h | | j | l |
|
||||
| | | i | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | highway | junction | # |
|
||||
| ab | slight_right\|slight_right\|slight_right | primary | | |
|
||||
| bc | slight_left\|slight_right\|slight_right | primary | roundabout | top |
|
||||
| cd | | primary | roundabout | top |
|
||||
| de | | primary | roundabout | top |
|
||||
| eb | | primary | roundabout | top |
|
||||
| df | | primary | | |
|
||||
| cg | slight_right\|slight_right | primary | | |
|
||||
| gh | slight_left\|slight_right | primary | roundabout | bot |
|
||||
| hi | | primary | roundabout | bot |
|
||||
| ij | slight_left\|slight_right | primary | roundabout | bot |
|
||||
| jg | | primary | roundabout | bot |
|
||||
| hk | | primary | | |
|
||||
| jl | | primary | | |
|
||||
|
||||
When I route I should get
|
||||
| # | waypoints | route | turns | lanes |
|
||||
| right-right | a,k | ab,cg,hk,hk | depart,roundabout-exit-1,roundabout-exit-1,arrive | ,slight right:false slight right:false slight right:true,slight right:false slight right:true, |
|
||||
| right-left | a,l | ab,cg,jl,jl | depart,roundabout-exit-1,roundabout-exit-2,arrive | ,slight right:false slight right:false slight right:true,slight right:false slight right:true, |
|
||||
| todo exits | a,f | ab,df,df | depart,roundabout-exit-2,arrive | ,slight right:false slight right:false slight right:true, |
|
||||
| todo exits | a,e | ab,bc,eb | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true slight right:true, |
|
||||
|
||||
@anticipate @todo
|
||||
Scenario: Roundabout with lanes only tagged on exit
|
||||
Given the node map
|
||||
| | | e | | |
|
||||
| a | b | | d | f |
|
||||
| | | c | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | highway | junction |
|
||||
| ab | | primary | |
|
||||
| bc | | primary | roundabout |
|
||||
| cd | slight_left\|slight_left\|slight_right | primary | roundabout |
|
||||
| de | | primary | roundabout |
|
||||
| eb | | primary | roundabout |
|
||||
| df | | primary | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | ab,df,df | depart,roundabout-exit-1,use lane slight right,arrive | ,,slight left:false slight left:false slight right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate with lanes in roundabout where we stay on the roundabout for multiple exits
|
||||
Given the node map
|
||||
| | | a | | |
|
||||
| | | b | | |
|
||||
| | c | | g | h |
|
||||
| | | | | |
|
||||
| | d | | f | |
|
||||
| | | e | | |
|
||||
| x | | | | y |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | highway | junction |
|
||||
| ab | slight_right\|slight_right | primary | |
|
||||
| bc | | primary | roundabout |
|
||||
| cd | | primary | roundabout |
|
||||
| de | | primary | roundabout |
|
||||
| ef | | primary | roundabout |
|
||||
| fg | slight_right | primary | roundabout |
|
||||
| gb | | primary | roundabout |
|
||||
| gh | | primary | |
|
||||
| cx | | primary | |
|
||||
| dx | | primary | |
|
||||
| ey | | primary | |
|
||||
| fy | | primary | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,h | ab,gh,gh | depart,roundabout-exit-5,arrive | ,slight right:false slight right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Departing or arriving inside a roundabout does not yet anticipate lanes
|
||||
Given the node map
|
||||
| | | a | | |
|
||||
| x | b | | d | y |
|
||||
| | | c | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | highway | junction | name |
|
||||
| xb | slight_right\|slight_right | primary | | xb |
|
||||
| dy | | primary | | dy |
|
||||
| ab | | primary | roundabout | roundabout |
|
||||
| bc | | primary | roundabout | roundabout |
|
||||
| cd | left\|slight_right | primary | roundabout | roundabout |
|
||||
| da | | primary | roundabout | roundabout |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| x,y | xb,dy,dy | depart,roundabout-exit-1,arrive | ,slight right:false slight right:true, |
|
||||
| x,c | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
|
||||
| x,a | xb,roundabout,roundabout | depart,roundabout-exit-undefined,arrive | ,slight right:true slight right:true, |
|
||||
|
||||
@anticipate
|
||||
Scenario: Anticipate Lanes for turns before and / or after roundabout
|
||||
Given the node map
|
||||
| a | b | | | x |
|
||||
| | c | | | |
|
||||
| d | | f | g | z |
|
||||
| | e | | h | |
|
||||
| | | | | |
|
||||
| | y | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | highway | junction | name |
|
||||
| ab | through\|right\|right\|right\|right | primary | | abx |
|
||||
| bx | | primary | | abx |
|
||||
| bc | right\|right\|right\|right | primary | | bc |
|
||||
| cd | | primary | roundabout | cdefc |
|
||||
| de | slight_left\|slight_left&slight_left\|slight_right | primary | roundabout | cdefc |
|
||||
| ef | left\|slight_right\|slight_right | primary | roundabout | cdefc |
|
||||
| fc | | primary | roundabout | cdefc |
|
||||
| ey | | primary | | ey |
|
||||
| fg | through\|right | primary | | fg |
|
||||
| gz | | primary | | gz |
|
||||
| gh | | primary | | gh |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,h | abx,bc,fg,gh,gh | depart,turn right,cdefc-exit-2,turn right,arrive | ,straight:false right:false right:false right:false right:true,right:false right:false right:false right:true,straight:false right:true, |
|
||||
|
||||
@anticipate @bug @todo
|
||||
Scenario: Tripple Right keeping Left
|
||||
Given the node map
|
||||
| a | | | | b | | i |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| f | | e | | | | g |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | j | d | | c | | |
|
||||
| | | | | h | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | highway | name |
|
||||
| abi | \|\|right\|right | primary | start |
|
||||
| bch | \|\|right\|right | primary | first |
|
||||
| cdj | \|\|right\|right | primary | second |
|
||||
| de | left\|right\|right | secondary | third |
|
||||
| feg | | tertiary | fourth |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,end of road left,arrive | ,none:false none:true right:false right:false,none:false none:true right:false right:false,none:false none:true right:false right:false,left:true right:false right:false, |
|
||||
| a,g | start,first,second,third,fourth,fourth | depart,turn right,turn right,turn right,end of road right,arrive | ,none:false none:false right:true right:true,none:false none:false right:true right:true,none:false none:false right:true right:true,left:false right:true right:true, |
|
||||
|
||||
@anticipate @bug @todo
|
||||
Scenario: Tripple Left keeping Right
|
||||
Given the node map
|
||||
| i | | b | | | | a |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| g | | | | e | | f |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | c | | d | j | |
|
||||
| | | h | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes:forward | highway | name |
|
||||
| abi | left\|left\|\| | primary | start |
|
||||
| bch | left\|left\|\| | primary | first |
|
||||
| cdj | left\|left\|\| | primary | second |
|
||||
| de | left\|left\|right | secondary | third |
|
||||
| feg | | tertiary | fourth |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,end of road right,arrive | ,left:false left:false none:true none:false,left:false left:false none:true none:false,left:false left:false none:true none:false,left:false left:false right:true, |
|
||||
| a,g | start,first,second,third,fourth,fourth | depart,turn left,turn left,turn left,end of road left,arrive | ,left:true left:true none:false none:false,left:true left:true none:false none:false,left:true left:true none:false none:false,left:true left:true right:false, |
|
||||
@@ -344,4 +344,289 @@ Feature: Collapse
|
||||
| waypoints | route | turns |
|
||||
| a,d | first,first,first,first | depart,continue left,continue right,arrive |
|
||||
| a,e | first,second,second | depart,turn left,arrive |
|
||||
| a,f | first,third,third | depart,new name straight,arrive |
|
||||
| a,f | first,third,third | depart,turn straight,arrive |
|
||||
|
||||
Scenario: Bridge on unnamed road
|
||||
Given the node map
|
||||
| a | b | | | | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| ab | primary | |
|
||||
| bc | primary | Bridge |
|
||||
| cd | primary | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | , | depart,arrive |
|
||||
|
||||
Scenario: Crossing Bridge into Segregated Turn
|
||||
Given the node map
|
||||
| | | | | | f |
|
||||
| i | h | | | g | e |
|
||||
| a | b | | | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | oneway | name |
|
||||
| ab | primary | yes | to_bridge |
|
||||
| bc | primary | yes | bridge |
|
||||
| cd | primary | yes | off_bridge |
|
||||
| de | primary | yes | |
|
||||
| ef | primary | no | target_road |
|
||||
| eg | primary | yes | off_bridge |
|
||||
| gh | primary | yes | bridge |
|
||||
| hi | primary | yes | to_bridge |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,f | to_bridge,target_road,target_road | depart,turn left,arrive |
|
||||
|
||||
Scenario: Pankenbruecke
|
||||
Given the node map
|
||||
| h | | | | | | i | | | | | | |
|
||||
| | | b | c | d | e | f | | | | | | g |
|
||||
| a | | | | | | | | | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
| abh | primary | inroad | yes |
|
||||
| bc | primary | inroad | no |
|
||||
| cd | primary | bridge | no |
|
||||
| defg | primary | outroad | no |
|
||||
| fi | primary | cross | no |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,g | inroad,outroad,outroad | depart,new name straight,arrive |
|
||||
| a,i | inroad,cross,cross | depart,turn left,arrive |
|
||||
|
||||
Scenario: Close Turns - Don't Collapse
|
||||
Given the node map
|
||||
| | g | d | |
|
||||
| | | | |
|
||||
| e | b | c | f |
|
||||
| | | | |
|
||||
| | a | h | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| ab | primary | in |
|
||||
| ebcf | primary | cross |
|
||||
| cd | primary | out |
|
||||
| bg | primary | straight |
|
||||
| ch | primary | reverse |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | in,cross,out,out | depart,turn right,turn left,arrive |
|
||||
| a,h | in,cross,reverse,reverse | depart,turn right,turn right,arrive |
|
||||
| g,d | straight,cross,out,out | depart,turn left,turn left,arrive |
|
||||
|
||||
Scenario: No Name During Turns
|
||||
Given the node map
|
||||
| a | b | |
|
||||
| | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| ab | tertiary | road |
|
||||
| bc | tertiary | |
|
||||
| cd | tertiary | road |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | road,road | depart,arrive |
|
||||
|
||||
Scenario: No Name During Turns, Random Oneway
|
||||
Given the node map
|
||||
| a | b | |
|
||||
| | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
| ab | tertiary | road | no |
|
||||
| bc | tertiary | | yes |
|
||||
| cd | tertiary | road | no |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | road,road | depart,arrive |
|
||||
|
||||
Scenario: Pulled Back Turn
|
||||
Given the node map
|
||||
| | | d |
|
||||
| a | b | c |
|
||||
| | e | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abc | tertiary | road |
|
||||
| cd | tertiary | left |
|
||||
| be | tertiary | right |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | road,left,left | depart,turn left,arrive |
|
||||
| a,e | road,right,right | depart,turn right,arrive |
|
||||
|
||||
Scenario: No Name During Turns, keep important turns
|
||||
Given the node map
|
||||
| a | b | e |
|
||||
| | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| ab | tertiary | road |
|
||||
| bc | tertiary | |
|
||||
| cd | tertiary | road |
|
||||
| be | tertiary | other |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | road,road,road | depart,continue right,arrive |
|
||||
|
||||
Scenario: Segregated Intersection into Slight Turn
|
||||
Given the node map
|
||||
| h | | | | | | |
|
||||
| a | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | g | | | | |
|
||||
| | | b | f | | | |
|
||||
| | | | c | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | e |
|
||||
| | | | | | | d |
|
||||
| | | j | i | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
| abcd | primary | road | yes |
|
||||
| efgh | primary | road | yes |
|
||||
| icf | secondary | in | yes |
|
||||
| gbj | secondary | out | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| i,h | in,road,road | depart,turn slight left,arrive |
|
||||
| a,d | road,road | depart,arrive |
|
||||
| a,j | road,out,out | depart,turn slight right,arrive |
|
||||
|
||||
Scenario: Don't collapse everything to u-turn / too wide
|
||||
Given the node map
|
||||
| a | | b | | e |
|
||||
| | | | | |
|
||||
| d | | c | | f |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abcd | primary | road |
|
||||
| be | secondary | top |
|
||||
| cf | secondary | bottom |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| a,d | depart,continue right,turn right,arrive | road,road,road,road |
|
||||
| d,a | depart,continue left,turn left,arrive | road,road,road,road |
|
||||
|
||||
Scenario: Forking before a turn
|
||||
Given the node map
|
||||
| | | | g | |
|
||||
| | | | | |
|
||||
| | | | c | |
|
||||
| a | | b | d | e |
|
||||
| | | | | |
|
||||
| | | | f | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway | highway |
|
||||
| ab | road | yes | primary |
|
||||
| bd | road | yes | primary |
|
||||
| bc | road | yes | primary |
|
||||
| de | road | yes | primary |
|
||||
| fdcg | cross | no | secondary |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | bd | fdcg | d | no_left_turn |
|
||||
| restriction | bc | fdcg | c | no_right_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,g | road,cross,cross | depart,turn left,arrive |
|
||||
| a,e | road,road | depart,arrive |
|
||||
|
||||
Scenario: Forking before a turn (narrow)
|
||||
Given the node map
|
||||
| | | | g | |
|
||||
| | | | | |
|
||||
| | | | c | |
|
||||
| a | b | | d | e |
|
||||
| | | | | |
|
||||
| | | | f | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway | highway |
|
||||
| ab | road | yes | primary |
|
||||
| bd | road | yes | primary |
|
||||
| bc | road | yes | primary |
|
||||
| de | road | yes | primary |
|
||||
| fdcg | cross | no | secondary |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | bd | fdcg | d | no_left_turn |
|
||||
| restriction | bc | fdcg | c | no_right_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,g | road,cross,cross | depart,turn left,arrive |
|
||||
| a,e | road,road | depart,arrive |
|
||||
|
||||
Scenario: Forking before a turn (forky)
|
||||
Given the node map
|
||||
| | | | g | | |
|
||||
| | | | | | |
|
||||
| | | | c | | |
|
||||
| a | b | | | | |
|
||||
| | | | | d | |
|
||||
| | | | | f | e |
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway | highway |
|
||||
| ab | road | yes | primary |
|
||||
| bd | road | yes | primary |
|
||||
| bc | road | yes | primary |
|
||||
| de | road | yes | primary |
|
||||
| fdcg | cross | no | secondary |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | bd | fdcg | d | no_left_turn |
|
||||
| restriction | bc | fdcg | c | no_right_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,g | road,cross,cross | depart,turn left,arrive |
|
||||
| a,e | road,road,road | depart,continue slight right,arrive |
|
||||
# We should discuss whether the next item should be collapsed to depart,turn right,arrive.
|
||||
| a,f | road,road,cross,cross | depart,continue slight right,turn right,arrive |
|
||||
|
||||
Scenario: On-Off on Highway
|
||||
Given the node map
|
||||
| f | | | |
|
||||
| a | b | c | d |
|
||||
| | | | e |
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway | oneway |
|
||||
| abcd | Hwy | motorway | yes |
|
||||
| fb | on | motorway_link | yes |
|
||||
| ce | off | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | Hwy,Hwy | depart,arrive |
|
||||
| f,d | on,Hwy,Hwy | depart,merge slight right,arrive |
|
||||
| f,e | on,Hwy,off,off | depart,merge slight right,off ramp right,arrive |
|
||||
| a,e | Hwy,off,off | depart,off ramp right,arrive |
|
||||
|
||||
@@ -16,9 +16,42 @@ Feature: Continue Instructions
|
||||
| bd | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | abc,abc,abc | depart,continue left,arrive |
|
||||
| a,d | abc,bd,bd | depart,new name straight,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | abc,abc,abc | depart,continue left,arrive |
|
||||
| a,d | abc,bd,bd | depart,turn straight,arrive |
|
||||
|
||||
Scenario: Road turning left and straight
|
||||
Given the node map
|
||||
| | | c | |
|
||||
| a | | b | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abc | primary | road |
|
||||
| bd | primary | road |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | road,road,road | depart,continue left,arrive |
|
||||
| a,d | road,road | depart,arrive |
|
||||
|
||||
Scenario: Road turning left and straight
|
||||
Given the node map
|
||||
| | | c | |
|
||||
| a | | b | d |
|
||||
| | | e | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abc | primary | road |
|
||||
| bd | primary | road |
|
||||
| be | primary | road |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | road,road,road | depart,continue left,arrive |
|
||||
| a,d | road,road | depart,arrive |
|
||||
| a,e | road,road,road | depart,continue right,arrive |
|
||||
|
||||
Scenario: Road turning right
|
||||
Given the node map
|
||||
@@ -31,9 +64,9 @@ Feature: Continue Instructions
|
||||
| bd | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | abc,abc,abc | depart,continue right,arrive |
|
||||
| a,d | abc,bd,bd | depart,new name straight,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | abc,abc,abc | depart,continue right,arrive |
|
||||
| a,d | abc,bd,bd | depart,turn straight,arrive |
|
||||
|
||||
Scenario: Road turning slight left
|
||||
Given the node map
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
@routing @guidance
|
||||
Feature: Slipways and Dedicated Turn Lanes
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 5 meters
|
||||
|
||||
Scenario: Turn Instead of Ramp
|
||||
Given the node map
|
||||
| | | | | e | |
|
||||
| a | b | | | c | d |
|
||||
| | | | h | | |
|
||||
| | | | | | |
|
||||
| | | | 1 | | |
|
||||
| | | | | | |
|
||||
| | | | | f | |
|
||||
| | | | | | |
|
||||
| | | | | g | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abcd | trunk | first |
|
||||
| bhf | trunk_link | |
|
||||
| ecfg | primary | second |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | abcd | ecfg | c | no_right_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,g | first,second,second | depart,turn right,arrive |
|
||||
| a,1 | first,, | depart,turn slight right,arrive |
|
||||
|
||||
Scenario: Turn Instead of Ramp
|
||||
Given the node map
|
||||
| | | | | e | |
|
||||
| a | b | | | c | d |
|
||||
| | | | h | | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | f | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | g | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abcd | motorway | first |
|
||||
| bhf | motorway_link | |
|
||||
| efg | primary | second |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,g | first,,second,second | depart,off ramp slight right,merge slight left,arrive |
|
||||
|
||||
Scenario: Inner city expressway with on road
|
||||
Given the node map
|
||||
| a | b | | | | c | g |
|
||||
| | | | | f | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | d | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | e | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abc | primary | road |
|
||||
| cg | primary | road |
|
||||
| bfd | trunk_link | |
|
||||
| cde | trunk | trunk |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | abc | cde | c | no_right_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,e | road,trunk,trunk | depart,turn right,arrive |
|
||||
|
||||
|
||||
Scenario: Slipway Round U-Turn
|
||||
Given the node map
|
||||
| a | | f |
|
||||
| | | |
|
||||
| b | | e |
|
||||
| | | |
|
||||
| | | |
|
||||
| | g | |
|
||||
| | | |
|
||||
| c | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
| abc | primary | road | yes |
|
||||
| bge | primary_link | | yes |
|
||||
| def | primary | road | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,f | road,road,road | depart,continue uturn,arrive |
|
||||
|
||||
Scenario: Slipway Steep U-Turn
|
||||
Given the node map
|
||||
| a | | f |
|
||||
| | | |
|
||||
| b | | e |
|
||||
| | g | |
|
||||
| | | |
|
||||
| | | |
|
||||
| c | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
| abc | primary | road | yes |
|
||||
| bge | primary_link | | yes |
|
||||
| def | primary | road | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,f | road,road,road | depart,continue uturn,arrive |
|
||||
|
||||
Scenario: Schwarzwaldstrasse Autobahn
|
||||
Given the node map
|
||||
| | | | | i | | | | | | h | | | | | g |
|
||||
| | | j | | | | | | | | | | | | | |
|
||||
| a | | | | | | | k | | | | | | | | |
|
||||
| | | | b | | r | c | | d | | e | | | | | f |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | l | | | | | | | | | | |
|
||||
| | | | | | m | | | | | | | | | | |
|
||||
| | | | | | | n | | q | | | | | | | |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | | | | |
|
||||
| | | | | | | o | | p | | | | | | | |
|
||||
|
||||
And the nodes
|
||||
# the traffic light at `l` is not actually in the data, but necessary for the test to check everything
|
||||
# http://www.openstreetmap.org/#map=19/48.99211/8.40336
|
||||
| node | highway |
|
||||
| r | traffic_signals |
|
||||
| l | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | ref | oneway |
|
||||
| abrcd | secondary | Schwarzwaldstrasse | L561 | yes |
|
||||
| hija | secondary | Schwarzwaldstrasse | L561 | yes |
|
||||
| def | secondary | Ettlinger Strasse | | yes |
|
||||
| gh | secondary | Ettlinger Strasse | | yes |
|
||||
| blmn | secondary_link | | L561 | yes |
|
||||
| hkc | secondary_link | Ettlinger Strasse | | yes |
|
||||
| qdki | secondary_link | Ettlinger Allee | | yes |
|
||||
| cn | secondary_link | Ettlinger Allee | | yes |
|
||||
| no | primary | Ettlinger Allee | | yes |
|
||||
| pq | primary | Ettlinger Allee | | yes |
|
||||
| qe | secondary_link | Ettlinger Allee | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,o | Schwarzwaldstrasse (L561),Ettlinger Allee,Ettlinger Allee | depart,turn right,arrive |
|
||||
@@ -29,13 +29,13 @@ Feature: Destination Signs
|
||||
| qr | QR | | | A1;A2 | yes | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | # |
|
||||
| a | b | AB (E1),AB (E1) | |
|
||||
| c | d | CD (Berlin),CD (Berlin) | |
|
||||
| e | f | EF (A1: Berlin),EF (A1: Berlin) | |
|
||||
| g | h | , | |
|
||||
| i | j | , | |
|
||||
| k | l | KL (E1),KL (E1) | |
|
||||
| m | n | MN (A1, A2: Berlin, Hamburg),MN (A1, A2: Berlin, Hamburg) | |
|
||||
| o | p | OP,OP | guard against mis-tagging |
|
||||
| q | r | QR (A1, A2),QR (A1, A2) | |
|
||||
| from | to | route | destinations | # |
|
||||
| a | b | AB (E1),AB (E1) | , | |
|
||||
| c | d | CD (Berlin),CD (Berlin) | Berlin,Berlin | |
|
||||
| e | f | EF (A1: Berlin),EF (A1: Berlin) | A1: Berlin,A1: Berlin | |
|
||||
| g | h | , | A1: Berlin,A1: Berlin | |
|
||||
| i | j | , | Berlin,Berlin | |
|
||||
| k | l | KL (E1),KL (E1) | A1: Berlin,A1: Berlin | |
|
||||
| m | n | MN (A1, A2: Berlin, Hamburg),MN (A1, A2: Berlin, Hamburg) | A1, A2: Berlin, Hamburg,A1, A2: Berlin, Hamburg | |
|
||||
| o | p | OP,OP | , | guard against mis-tagging |
|
||||
| q | r | QR (A1, A2),QR (A1, A2) | A1, A2,A1, A2 | |
|
||||
|
||||
@@ -8,116 +8,123 @@ Feature: End Of Road Instructions
|
||||
Scenario: End of Road with through street
|
||||
Given the node map
|
||||
| | | c |
|
||||
| a | | b |
|
||||
| | | d |
|
||||
| a | e | b |
|
||||
| | f | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| cbd | primary |
|
||||
| ef | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
|
||||
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,cbd,cbd | depart,end of road left,arrive |
|
||||
| a,d | aeb,cbd,cbd | depart,end of road right,arrive |
|
||||
|
||||
Scenario: End of Road with three streets
|
||||
Given the node map
|
||||
| | | c |
|
||||
| a | | b |
|
||||
| | | d |
|
||||
| a | e | b |
|
||||
| | f | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| cb | primary |
|
||||
| bd | primary |
|
||||
| ef | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,cb,cb | depart,end of road left,arrive |
|
||||
| a,d | ab,bd,bd | depart,end of road right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,cb,cb | depart,end of road left,arrive |
|
||||
| a,d | aeb,bd,bd | depart,end of road right,arrive |
|
||||
|
||||
Scenario: End of Road with three streets, slightly angled
|
||||
Given the node map
|
||||
| a | | | | | c |
|
||||
| | | | | | b |
|
||||
| a | e | | | | c |
|
||||
| | f | | | | b |
|
||||
| | | | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| cb | primary |
|
||||
| bd | primary |
|
||||
| ef | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,cb,cb | depart,end of road left,arrive |
|
||||
| a,d | ab,bd,bd | depart,end of road right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,cb,cb | depart,end of road left,arrive |
|
||||
| a,d | aeb,bd,bd | depart,end of road right,arrive |
|
||||
|
||||
Scenario: End of Road with three streets, slightly angled
|
||||
Given the node map
|
||||
| | | | | | c |
|
||||
| | | | | | b |
|
||||
| a | | | | | d |
|
||||
| | f | | | | b |
|
||||
| a | e | | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| ef | primary |
|
||||
| cb | primary |
|
||||
| bd | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,cb,cb | depart,end of road left,arrive |
|
||||
| a,d | ab,bd,bd | depart,end of road right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,cb,cb | depart,end of road left,arrive |
|
||||
| a,d | aeb,bd,bd | depart,end of road right,arrive |
|
||||
|
||||
Scenario: End of Road with through street, slightly angled
|
||||
Given the node map
|
||||
| a | | | | | c |
|
||||
| | | | | | b |
|
||||
| a | e | | | | c |
|
||||
| | f | | | | b |
|
||||
| | | | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| ef | primary |
|
||||
| cbd | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
|
||||
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,cbd,cbd | depart,end of road left,arrive |
|
||||
| a,d | aeb,cbd,cbd | depart,end of road right,arrive |
|
||||
|
||||
Scenario: End of Road with through street, slightly angled
|
||||
Given the node map
|
||||
| | | | | | c |
|
||||
| | | | | | b |
|
||||
| a | | | | | d |
|
||||
| | f | | | | b |
|
||||
| a | e | | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| ef | primary |
|
||||
| cbd | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
|
||||
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,cbd,cbd | depart,end of road left,arrive |
|
||||
| a,d | aeb,cbd,cbd | depart,end of road right,arrive |
|
||||
|
||||
Scenario: End of Road with two ramps - prefer ramp over end of road
|
||||
Given the node map
|
||||
| | | c |
|
||||
| a | | b |
|
||||
| | | d |
|
||||
| a | e | b |
|
||||
| | f | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| aeb | primary |
|
||||
| ef | primary |
|
||||
| bc | motorway_link |
|
||||
| bd | motorway_link |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | ab,bc,bc | depart,on ramp left,arrive |
|
||||
| a,d | ab,bd,bd | depart,on ramp right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,c | aeb,bc,bc | depart,on ramp left,arrive |
|
||||
| a,d | aeb,bd,bd | depart,on ramp right,arrive |
|
||||
|
||||
|
||||
@@ -281,3 +281,36 @@ Feature: Fork Instructions
|
||||
| a,c | abd,bc,bc | depart,turn slight left,arrive |
|
||||
| a,d | abd,abd | depart,arrive |
|
||||
| a,e | abd,be,be | depart,turn slight right,arrive |
|
||||
|
||||
Scenario: Don't Fork when leaving Road
|
||||
Given the node map
|
||||
| a | | b | | c |
|
||||
| | | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | secondary |
|
||||
| bd | secondary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,c | abc,abc | depart,arrive |
|
||||
| a,d | abc,bd,bd | depart,turn slight right,arrive |
|
||||
|
||||
Scenario: Fork on motorway links - don't fork on through
|
||||
Given the node map
|
||||
| i | | | | | a |
|
||||
| j | | c | b | | x |
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway |
|
||||
| xb | xbcj | motorway_link |
|
||||
| bc | xbcj | motorway_link |
|
||||
| cj | xbcj | motorway_link |
|
||||
| ci | off | motorway_link |
|
||||
| ab | on | motorway_link |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,j | on,xbcj,xbcj | depart,merge slight left,arrive |
|
||||
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive |
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
@routing @guidance @intersections
|
||||
Feature: Intersections Data
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 10 meters
|
||||
|
||||
Scenario: Passing Three Way South
|
||||
Given the node map
|
||||
| a | | b | | c |
|
||||
| | | d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name |
|
||||
| ab | through |
|
||||
| bc | through |
|
||||
| bd | corner |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | intersections |
|
||||
| a,c | through,through | true:90,true:90 true:180 false:270;true:270 |
|
||||
|
||||
Scenario: Passing Three Way North
|
||||
Given the node map
|
||||
| | | d | | |
|
||||
| a | | b | | c |
|
||||
|
||||
And the ways
|
||||
| nodes | name |
|
||||
| ab | through |
|
||||
| bc | through |
|
||||
| bd | corner |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | intersections |
|
||||
| a,c | through,through | true:90,true:0 true:90 false:270;true:270 |
|
||||
|
||||
Scenario: Passing Oneway Street In
|
||||
Given the node map
|
||||
| | | d | | |
|
||||
| a | | b | | c |
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway |
|
||||
| ab | through | no |
|
||||
| bc | through | no |
|
||||
| db | corner | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | intersections |
|
||||
| a,c | through,through | true:90,false:0 true:90 false:270;true:270 |
|
||||
|
||||
Scenario: Passing Oneway Street Out
|
||||
Given the node map
|
||||
| | | d | | |
|
||||
| a | | b | | c |
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway |
|
||||
| ab | through | no |
|
||||
| bc | through | no |
|
||||
| bd | corner | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | intersections |
|
||||
| a,c | through,through | true:90,true:0 true:90 false:270;true:270 |
|
||||
|
||||
Scenario: Passing Two Intersections
|
||||
Given the node map
|
||||
| | | e | | | | |
|
||||
| a | | b | | c | | d |
|
||||
| | | | | f | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name |
|
||||
| ab | through |
|
||||
| bc | through |
|
||||
| cd | through |
|
||||
| be | corner |
|
||||
| cf | corner |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | intersections |
|
||||
| a,d | through,through | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
|
||||
|
||||
Scenario: Passing Two Intersections, Collapsing
|
||||
Given the node map
|
||||
| | | e | | | | |
|
||||
| a | | b | | c | | d |
|
||||
| | | | | f | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name |
|
||||
| ab | through |
|
||||
| bc | throughbridge |
|
||||
| cd | through |
|
||||
| be | corner |
|
||||
| cf | corner |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | intersections |
|
||||
| a,d | through,through | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
|
||||
| f,a | corner,through,through | true:0;true:90 false:180 true:270,true:0 false:90 true:270;true:90 |
|
||||
|
||||
Scenario: Roundabouts
|
||||
Given the node map
|
||||
| | | | | e | | | | |
|
||||
| | | | | | | | | |
|
||||
| | | | | a | | | | |
|
||||
| | | | 1 | | 4 | | | |
|
||||
| | | | | | | | | |
|
||||
| f | | b | | | | d | | h |
|
||||
| | | | | | | | | |
|
||||
| | | | 2 | | 3 | | | |
|
||||
| | | | | c | | | | |
|
||||
| | | | | | | | | |
|
||||
| | | | | g | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | junction |
|
||||
| abcda | roundabout |
|
||||
| ea | |
|
||||
| fb | |
|
||||
| gc | |
|
||||
| hd | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | intersections |
|
||||
| e,f | ea,fb,fb | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 |
|
||||
| e,g | ea,gc,gc | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0 |
|
||||
| e,h | ea,hd,hd | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330,true:90 false:210 true:330;true:270 |
|
||||
| e,2 | ea,abcda,abcda | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1 |
|
||||
| 1,g | abcda,gc,gc | true:214;false:30 true:150 true:270,true:30 true:180 false:330;true:0 |
|
||||
| 1,3 | abcda,abcda | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214 |
|
||||
@@ -50,3 +50,27 @@ Feature: Merging
|
||||
| waypoints | route | turns |
|
||||
| d,c | db,abc,abc | depart,merge slight left,arrive |
|
||||
|
||||
Scenario: Merge onto a turning road
|
||||
Given the node map
|
||||
| | | | | | | e |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | d | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | c | | |
|
||||
| | | | b | | | |
|
||||
| a | | | | | | f |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abcde | primary | road |
|
||||
| fd | residential | in |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| f,e | depart,merge slight left,arrive | in,road,road |
|
||||
| f,a | depart,turn sharp left,arrive | in,road,road |
|
||||
|
||||
@@ -11,9 +11,9 @@ Feature: Motorway Guidance
|
||||
| | | | f | g |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abcde | motorway |
|
||||
| bfg | motorway_link |
|
||||
| nodes | highway | oneway |
|
||||
| abcde | motorway | |
|
||||
| bfg | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
@@ -27,9 +27,9 @@ Feature: Motorway Guidance
|
||||
| | | | g | e |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abcde | motorway |
|
||||
| bfg | motorway_link |
|
||||
| nodes | highway | oneway |
|
||||
| abcde | motorway | |
|
||||
| bfg | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
@@ -44,9 +44,9 @@ Feature: Motorway Guidance
|
||||
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abcde | motorway |
|
||||
| cfg | motorway_link |
|
||||
| nodes | highway | oneway |
|
||||
| abcde | motorway | |
|
||||
| cfg | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
@@ -60,9 +60,9 @@ Feature: Motorway Guidance
|
||||
| a | b | c | d | e |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abcde | motorway |
|
||||
| bfg | motorway_link |
|
||||
| nodes | highway | oneway |
|
||||
| abcde | motorway | |
|
||||
| bfg | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
@@ -76,9 +76,9 @@ Feature: Motorway Guidance
|
||||
| a | b | c | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abcde | motorway |
|
||||
| bfg | motorway_link |
|
||||
| nodes | highway | oneway |
|
||||
| abcde | motorway | |
|
||||
| bfg | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
@@ -92,9 +92,9 @@ Feature: Motorway Guidance
|
||||
| | | | | e |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abcde | motorway |
|
||||
| cfg | motorway_link |
|
||||
| nodes | highway | oneway |
|
||||
| abcde | motorway | |
|
||||
| cfg | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
@@ -107,9 +107,9 @@ Feature: Motorway Guidance
|
||||
| f | g | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abcde | motorway |
|
||||
| fgd | motorway_link |
|
||||
| nodes | highway | oneway |
|
||||
| abcde | motorway | |
|
||||
| fgd | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
@@ -122,9 +122,9 @@ Feature: Motorway Guidance
|
||||
| a | b | c | d | e |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abcde | motorway |
|
||||
| fgd | motorway_link |
|
||||
| nodes | highway | oneway |
|
||||
| abcde | motorway | |
|
||||
| fgd | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
@@ -154,10 +154,10 @@ Feature: Motorway Guidance
|
||||
| | | | | f | g |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abc | motorway_link |
|
||||
| cde | motorway |
|
||||
| cfg | motorway |
|
||||
| nodes | highway | oneway |
|
||||
| abc | motorway_link | yes |
|
||||
| cde | motorway | |
|
||||
| cfg | motorway | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
@@ -170,17 +170,17 @@ Feature: Motorway Guidance
|
||||
| f | g | | | | h | i |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abcde | motorway |
|
||||
| fgc | motorway_link |
|
||||
| chi | motorway_link |
|
||||
| nodes | highway | oneway |
|
||||
| abcde | motorway | |
|
||||
| fgc | motorway_link | yes |
|
||||
| chi | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,e | abcde,abcde | depart,arrive |
|
||||
| f,e | fgc,abcde,abcde | depart,merge slight left,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,e | abcde,abcde | depart,arrive |
|
||||
| f,e | fgc,abcde,abcde | depart,merge slight left,arrive |
|
||||
| a,i | abcde,chi,chi | depart,off ramp slight right,arrive |
|
||||
| f,i | fgc,chi,chi | depart,off ramp right,arrive |
|
||||
| f,i | fgc,chi,chi | depart,off ramp right,arrive |
|
||||
|
||||
Scenario: On And Off Ramp Left
|
||||
Given the node map
|
||||
@@ -188,17 +188,17 @@ Feature: Motorway Guidance
|
||||
| a | b | | c | | d | e |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| abcde | motorway |
|
||||
| fgc | motorway_link |
|
||||
| chi | motorway_link |
|
||||
| nodes | highway | oneway |
|
||||
| abcde | motorway | |
|
||||
| fgc | motorway_link | yes |
|
||||
| chi | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,e | abcde,abcde | depart,arrive |
|
||||
| f,e | fgc,abcde,abcde | depart,merge slight right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,e | abcde,abcde | depart,arrive |
|
||||
| f,e | fgc,abcde,abcde | depart,merge slight right,arrive |
|
||||
| a,i | abcde,chi,chi | depart,off ramp slight left,arrive |
|
||||
| f,i | fgc,chi,chi | depart,off ramp left,arrive |
|
||||
| f,i | fgc,chi,chi | depart,off ramp left,arrive |
|
||||
|
||||
Scenario: Merging Motorways
|
||||
Given the node map
|
||||
@@ -216,3 +216,21 @@ Feature: Motorway Guidance
|
||||
| waypoints | route | turns |
|
||||
| d,c | db,abc,abc | depart,merge slight left,arrive |
|
||||
| e,c | eb,abc,abc | depart,merge slight right,arrive |
|
||||
|
||||
Scenario: Handle 90 degree off ramps correctly
|
||||
Given the node map
|
||||
| a | | | | |
|
||||
| x | b | | c | y |
|
||||
| | | | d | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway | oneway |
|
||||
| ab | On | motorway_link | yes |
|
||||
| xb | Hwy | motorway | |
|
||||
| bc | Hwy | motorway | |
|
||||
| cd | Off | motorway_link | yes |
|
||||
| cy | Hwy | motorway | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive |
|
||||
|
||||
@@ -3,7 +3,7 @@ Feature: New-Name Instructions
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 10 meters
|
||||
Given a grid size of 100 meters
|
||||
|
||||
Scenario: Undisturbed name Change
|
||||
Given the node map
|
||||
@@ -136,7 +136,7 @@ Feature: New-Name Instructions
|
||||
|
||||
Scenario: Empty road names - Announce Change From, suppress Change To
|
||||
Given the node map
|
||||
| a | | b | | c | | d |
|
||||
| a | | b | 1 | c | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | name |
|
||||
@@ -147,7 +147,7 @@ Feature: New-Name Instructions
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | ab,cd,cd | depart,new name straight,arrive |
|
||||
| a,c | ab, | depart,arrive |
|
||||
| a,1 | ab, | depart,arrive |
|
||||
|
||||
Scenario: Empty road names - Loose name shortly
|
||||
Given the node map
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
@routing @guidance @post-processing
|
||||
Feature: General Post-Processing related features
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 10 meters
|
||||
|
||||
# this testcase used to crash geometry generation (at that time handled during intersection generation)
|
||||
Scenario: Regression test #2424
|
||||
Given the node map
|
||||
| | | e | | | | | | i | | | | |
|
||||
| a | | b | | c | | d | | h | | k | | m |
|
||||
| | | | | f | | | | | | l | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name |
|
||||
| abcd | Fritz-Elsas-Straße |
|
||||
| hkm | Fritz-Elsas-Straße |
|
||||
| dhi | Martin-Luther-Straße |
|
||||
| be | corner |
|
||||
| kl | corner |
|
||||
| cf | corner |
|
||||
@@ -367,3 +367,25 @@ Feature: Basic Roundabout
|
||||
| h,d | gh,cd,cd | depart,roundabout-exit-2,arrive |
|
||||
| h,f | gh,ef,ef | depart,roundabout-exit-1,arrive |
|
||||
|
||||
Scenario: Enter and Exit -- Bearing
|
||||
Given the node map
|
||||
| | | a | | |
|
||||
| | | b | | |
|
||||
| h | g | | c | d |
|
||||
| | | e | | |
|
||||
| | | f | | |
|
||||
|
||||
And the ways
|
||||
| nodes | junction |
|
||||
| ab | |
|
||||
| cd | |
|
||||
| ef | |
|
||||
| gh | |
|
||||
| bgecb | roundabout |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | bearing |
|
||||
| a,d | ab,cd,cd | depart,roundabout turn left exit-3,arrive | 0->180,180->224,90->0 |
|
||||
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive | 0->180,180->224,180->0 |
|
||||
| a,h | ab,gh,gh | depart,roundabout turn right exit-1,arrive | 0->180,180->224,270->0 |
|
||||
|
||||
|
||||
@@ -337,3 +337,103 @@ Feature: Basic Roundabout
|
||||
| a,e | ac,de,de | depart,roundabout-exit-1,arrive |
|
||||
| a,f | ac,bf,bf | depart,roundabout-exit-2,arrive |
|
||||
|
||||
Scenario: Enter and Exit - Bearings
|
||||
Given the node map
|
||||
| | | | a | | | |
|
||||
| | | | | | | |
|
||||
| | | i | b | l | | |
|
||||
| h | | g | | c | | d |
|
||||
| | | j | e | k | | |
|
||||
| | | | | | | |
|
||||
| | | | f | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | junction |
|
||||
| ab | |
|
||||
| cd | |
|
||||
| ef | |
|
||||
| gh | |
|
||||
| bigjekclb | roundabout |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | bearing |
|
||||
| a,d | ab,cd,cd | depart,roundabout-exit-3,arrive | 0->180,180->270,90->0 |
|
||||
| a,f | ab,ef,ef | depart,roundabout-exit-2,arrive | 0->180,180->270,180->0 |
|
||||
| a,h | ab,gh,gh | depart,roundabout-exit-1,arrive | 0->180,180->270,270->0 |
|
||||
|
||||
Scenario: Motorway Roundabout
|
||||
#See 39.933742 -75.082345
|
||||
Given the node map
|
||||
| | | | | l | | | | a | | i |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | b | | | | |
|
||||
| | | | c | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | h | | |
|
||||
| n | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | d | | | | | | | | j |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | m | | | g | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | e | | f | | | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | junction | name | highway | oneway | ref |
|
||||
| ab | | crescent | trunk | yes | US 130 |
|
||||
| bcd | roundabout | crescent | trunk | yes | US 130 |
|
||||
| de | | crescent | trunk | yes | US 130 |
|
||||
| fg | | crescent | trunk | yes | US 130 |
|
||||
| gh | roundabout | crescent | trunk | yes | US 130 |
|
||||
| hi | | crescent | trunk | yes | US 130 |
|
||||
| jh | | | trunk_link | yes | NJ 38 |
|
||||
| hb | roundabout | | trunk_link | yes | NJ 38 |
|
||||
| bl | | | trunk_link | yes | NJ 38 |
|
||||
| cnd | | kaighns | trunk_link | yes | |
|
||||
| dmg | roundabout | | trunk_link | yes | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,e | crescent (US 130),crescent (US 130),crescent (US 130) | depart,roundabout-exit-3,arrive |
|
||||
| j,l | NJ 38,NJ 38,NJ 38 | depart,roundabout-exit-2,arrive |
|
||||
|
||||
Scenario: Double Roundabout with through-lane
|
||||
#http://map.project-osrm.org/?z=18¢er=38.911752%2C-77.048667&loc=38.912003%2C-77.050831&loc=38.909277%2C-77.042516&hl=en&alt=0
|
||||
Given the node map
|
||||
| | | | | o | | | | | | | | | | | | n | | | | |
|
||||
| | | | | e | | | | | | | | | | | | j | | | | |
|
||||
| | | | | | | | | | | | | | | | | | | | | |
|
||||
| | | | | | | q | | | | | | | | | | | | | | |
|
||||
| a | | b | | | | | | s | | f | | | | g | | | | i | | k |
|
||||
| | | | | | | r | | | | | | | | | | | p | | | |
|
||||
| | | | | | | | | | | t | | | | | | | | | | |
|
||||
| | | | | c | | d | | | | | | | | | | h | | | | |
|
||||
| | | | | l | | | | | | | | | | | | m | | | | |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| i | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | junction | name | oneway |
|
||||
| bcdrqeb | roundabout | sheridan circle | yes |
|
||||
| ghi | roundabout | dupont circle | yes |
|
||||
| ijg | roundabout | dupont circle | yes |
|
||||
| ab | | massachusetts | no |
|
||||
| sfgpik | | massachusetts | no |
|
||||
| cl | | 23rd street | no |
|
||||
| oe | | r street | no |
|
||||
| jn | | new hampshire | no |
|
||||
| mh | | new hampshire | yes |
|
||||
| rsq | | massachusetts | yes |
|
||||
| ft | | suppressed | no |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | sfgpik | ijg | i | no_left_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,k | massachusetts,massachusetts,massachusetts,massachusetts | depart,sheridan circle-exit-2,dupont circle-exit-1,arrive |
|
||||
|
||||
@@ -0,0 +1,686 @@
|
||||
@routing @guidance @turn-lanes
|
||||
Feature: Turn Lane Guidance
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 20 meters
|
||||
|
||||
@bug
|
||||
Scenario: Basic Turn Lane 3-way Turn with empty lanes
|
||||
Given the node map
|
||||
| a | | b | | c |
|
||||
| | | d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes | turn:lanes:forward | turn:lanes:backward | name |
|
||||
| ab | | through\|right | | in |
|
||||
| bc | | | left\|through\|\| | straight |
|
||||
| bd | | | left\|right | right |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,straight:true right:false, |
|
||||
| a,d | in,right,right | depart,turn right,arrive | ,straight:false right:true, |
|
||||
| c,a | straight,in,in | depart,new name straight,arrive | ,left:false straight:true none:true none:true, |
|
||||
| c,d | straight,right,right | depart,turn left,arrive | ,left:true straight:false none:false none:false, |
|
||||
|
||||
Scenario: Basic Turn Lane 4-Way Turn
|
||||
Given the node map
|
||||
| | | e | | |
|
||||
| a | | b | | c |
|
||||
| | | d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes | turn:lanes:forward | turn:lanes:backward | name |
|
||||
| ab | | \|right | | in |
|
||||
| bc | | | | straight |
|
||||
| bd | | | left\| | right |
|
||||
| be | | | | left |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,none:true right:false, |
|
||||
| a,d | in,right,right | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,e | in,left,left | depart,turn left,arrive | ,none:true right:false, |
|
||||
| d,a | right,in,in | depart,turn left,arrive | ,left:true none:false, |
|
||||
| d,e | right,left,left | depart,new name straight,arrive | ,left:false none:true, |
|
||||
| d,c | right,straight,straight | depart,turn right,arrive | ,left:false none:true, |
|
||||
|
||||
Scenario: Basic Turn Lane 4-Way Turn using none
|
||||
Given the node map
|
||||
| | | e | | |
|
||||
| a | | b | | c |
|
||||
| | | d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes | turn:lanes:forward | turn:lanes:backward | name |
|
||||
| ab | | none\|right | | in |
|
||||
| bc | | | | straight |
|
||||
| bd | | | left\|none | right |
|
||||
| be | | | | left |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | in,straight,straight | depart,new name straight,arrive | ,none:true right:false, |
|
||||
| a,d | in,right,right | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,e | in,left,left | depart,turn left,arrive | ,none:true right:false, |
|
||||
|
||||
Scenario: Basic Turn Lane 4-Way With U-Turn Lane
|
||||
Given the node map
|
||||
| | | e | | |
|
||||
| a | 1 | b | | c |
|
||||
| | | d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | turn:lanes | turn:lanes:forward | name |
|
||||
| ab | | reverse;left\|through;right | in |
|
||||
| bc | | | straight |
|
||||
| bd | | | right |
|
||||
| be | | | left |
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | turns | lanes |
|
||||
| a | c | 180,180 180,180 | in,straight,straight | depart,new name straight,arrive | ,left;uturn:false straight;right:true, |
|
||||
| a | d | 180,180 180,180 | in,right,right | depart,turn right,arrive | ,left;uturn:false straight;right:true, |
|
||||
| a | e | 180,180 180,180 | in,left,left | depart,turn left,arrive | ,left;uturn:true straight;right:false, |
|
||||
| 1 | a | 90,2 270,2 | in,in,in | depart,turn uturn,arrive | ,left;uturn:true straight;right:false, |
|
||||
|
||||
|
||||
#this next test requires decision on how to announce lanes for going straight if there is no turn
|
||||
@TODO
|
||||
Scenario: Turn with Bus-Lane
|
||||
Given the node map
|
||||
| a | | b | | c |
|
||||
| | | | | |
|
||||
| | | d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | lanes:psv:forward |
|
||||
| ab | road | through\|right\| | 1 |
|
||||
| bc | road | | |
|
||||
| bd | turn | | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
|
||||
| a,c | road,road,road | depart,use lane straight,arrive | ,straight:true right:false, |
|
||||
|
||||
@PROFILE @LANES
|
||||
Scenario: Turn with Bus-Lane but without lanes
|
||||
Given the node map
|
||||
| a | | b | | c |
|
||||
| | | | | |
|
||||
| | | d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | lanes:psv |
|
||||
| ab | road | 1 |
|
||||
| bc | road | yes |
|
||||
| bd | turn | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | road,turn,turn | depart,turn right,arrive |
|
||||
| a,c | road,road | depart,arrive |
|
||||
|
||||
#turn lanes are often drawn at the incoming road, even though the actual turn requires crossing the intersection first
|
||||
@todo @bug
|
||||
Scenario: Turn Lanes at Segregated Road
|
||||
Given the node map
|
||||
| | | i | l | | |
|
||||
| | | | | | |
|
||||
| h | | g | f | | e |
|
||||
| a | | b | c | | d |
|
||||
| | | | | | |
|
||||
| | | j | k | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|through\|right | yes |
|
||||
| bc | road | left\|through | yes |
|
||||
| cd | road | | yes |
|
||||
| ef | road | \|through\|through;right | yes |
|
||||
| fg | road | left;through\|through\| | yes |
|
||||
| gh | road | | yes |
|
||||
| ig | cross | | yes |
|
||||
| gb | cross | left\|through | yes |
|
||||
| bj | cross | | yes |
|
||||
| kc | cross | left\|through;right | yes |
|
||||
| cf | cross | left\|through | yes |
|
||||
| fl | cross | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,left:false straight:true right:false, |
|
||||
| a,l | road,cross,cross | depart,turn left,arrive | ,left:true straight:false right:false, |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,left:true straight:false right:false, |
|
||||
| k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, |
|
||||
| k,l | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight;right:true, |
|
||||
| k,h | cross,road,road | depart,turn left,arrive | ,left:true straight;right:false, |
|
||||
| k,j | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight;right:false, |
|
||||
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, |
|
||||
| e,h | road,road | depart,arrive | ,none:false straight:true straight;right:true |
|
||||
| e,j | road,cross,cross | depart,turn left,arrive | ,none:true straight:false straight;right:false, |
|
||||
| e,d | road,road,road | depart,continue uturn,arrive | ,none:true straight:false straight;right:false, |
|
||||
| i,h | cross,road,road | depart,turn right,arrive | ,, |
|
||||
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight:true, |
|
||||
| i,d | cross,road,road | depart,turn left,arrive | ,left:true straight:false, |
|
||||
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, |
|
||||
|
||||
#copy of former case to prevent further regression
|
||||
Scenario: Turn Lanes at Segregated Road
|
||||
Given the node map
|
||||
| | | i | l | | |
|
||||
| | | | | | |
|
||||
| h | | g | f | | e |
|
||||
| a | | b | c | | d |
|
||||
| | | | | | |
|
||||
| | | j | k | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|through\|right | yes |
|
||||
| bc | road | left\|through | yes |
|
||||
| cd | road | | yes |
|
||||
| ef | road | \|through\|through;right | yes |
|
||||
| fg | road | left;through\|through\| | yes |
|
||||
| gh | road | | yes |
|
||||
| ig | cross | | yes |
|
||||
| gb | cross | left\|through | yes |
|
||||
| bj | cross | | yes |
|
||||
| kc | cross | left\|through;right | yes |
|
||||
| cf | cross | left\|through | yes |
|
||||
| fl | cross | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
|
||||
| k,d | cross,road,road | depart,turn right,arrive | ,left:false straight;right:true, |
|
||||
| e,l | road,cross,cross | depart,turn right,arrive | ,none:false straight:false straight;right:true, |
|
||||
| i,h | cross,road,road | depart,turn right,arrive | ,, |
|
||||
| i,j | cross,cross,cross | depart,use lane straight,arrive | ,left:false straight:true, |
|
||||
| i,l | cross,cross,cross | depart,continue uturn,arrive | ,left:true straight:false, |
|
||||
|
||||
Scenario: Turn Lanes at Segregated Road
|
||||
Given the node map
|
||||
| | | g | f | | |
|
||||
| a | | b | c | | d |
|
||||
| | | | | | |
|
||||
| | | j | k | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|through\|right | yes |
|
||||
| bc | road | | yes |
|
||||
| cd | road | | yes |
|
||||
| gb | cross | | yes |
|
||||
| bj | cross | | yes |
|
||||
| kc | cross | | yes |
|
||||
| cf | cross | | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | road,cross,cross | depart,turn right,arrive | ,left:false straight:false right:true, |
|
||||
|
||||
#this can happen due to traffic lights / lanes not drawn up to the intersection itself
|
||||
Scenario: Turn Lanes Given earlier than actual turn
|
||||
Given the node map
|
||||
| a | | b | c | | d |
|
||||
| | | | | | |
|
||||
| | | | e | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward |
|
||||
| ab | road | \|right |
|
||||
| bc | road | |
|
||||
| cd | road | |
|
||||
| ce | turn | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,e | road,turn,turn | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,none:true right:false, |
|
||||
|
||||
Scenario: Turn Lanes Given earlier than actual turn
|
||||
Given the node map
|
||||
| a | | b | c | d | | e | | f | g | h | | i |
|
||||
| | | j | | | | | | | | k | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | turn:lanes:backward |
|
||||
| abc | road | | |
|
||||
| cd | road | | left\| |
|
||||
| def | road | | |
|
||||
| fg | road | \|right | |
|
||||
| ghi | road | | |
|
||||
| bj | first-turn | | |
|
||||
| hk | second-turn | | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,k | road,second-turn,second-turn | depart,turn right,arrive | ,none:false right:true, |
|
||||
| a,i | road,road,road | depart,use lane straight,arrive | ,none:true right:false, |
|
||||
| i,j | road,first-turn,first-turn | depart,turn left,arrive | ,left:true none:false, |
|
||||
| i,a | road,road,road | depart,use lane straight,arrive | ,left:false none:true, |
|
||||
|
||||
Scenario: Passing a one-way street
|
||||
Given the node map
|
||||
| e | | | f | |
|
||||
| a | | b | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|through | no |
|
||||
| bcd | road | | no |
|
||||
| eb | owi | | yes |
|
||||
| cf | turn | | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true straight:false, |
|
||||
|
||||
Scenario: Passing a one-way street, partly pulled back lanes
|
||||
Given the node map
|
||||
| e | | | f | |
|
||||
| a | | b | c | d |
|
||||
| | | g | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|through;right | no |
|
||||
| bcd | road | | no |
|
||||
| eb | owi | | yes |
|
||||
| cf | turn | | no |
|
||||
| bg | right | | no |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true straight;right:false, |
|
||||
| a,g | road,right,right | depart,turn right,arrive | ,left:false straight;right:true, |
|
||||
|
||||
Scenario: Passing a one-way street, partly pulled back lanes, no through
|
||||
Given the node map
|
||||
| e | | | f |
|
||||
| a | | b | c |
|
||||
| | | g | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway |
|
||||
| ab | road | left\|right | no |
|
||||
| bc | road | | no |
|
||||
| eb | owi | | yes |
|
||||
| cf | turn | | no |
|
||||
| bg | right | | no |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | road,turn,turn | depart,turn left,arrive | ,left:true right:false, |
|
||||
| a,g | road,right,right | depart,turn right,arrive | ,left:false right:true, |
|
||||
|
||||
@todo @bug
|
||||
Scenario: Narrowing Turn Lanes
|
||||
Given the node map
|
||||
| | | | | g | |
|
||||
| | | | | | |
|
||||
| a | | b | c | d | e |
|
||||
| | | | f | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward |
|
||||
| ab | road | left\|through\|right |
|
||||
| bc | road | |
|
||||
| cd | road | left\|through |
|
||||
| de | through | |
|
||||
| dg | left | |
|
||||
| cf | right | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,g | road,left,left | depart,turn left,arrive | ,left:true straight:false right:false, |
|
||||
| a,e | road,through,through | depart,new name straight,arrive | ,left:false straight:true right:false, |
|
||||
| a,f | road,right,right | depart,turn right,arrive | ,left:false straight:false right:true, |
|
||||
|
||||
Scenario: Turn at a traffic light
|
||||
Given the node map
|
||||
| a | b | c | d |
|
||||
| | | e | |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| b | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward |
|
||||
| ab | road | through\|right |
|
||||
| bc | road | |
|
||||
| cd | road | |
|
||||
| ce | turn | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,straight:true right:false, |
|
||||
| a,e | road,turn,turn | depart,turn right,arrive | ,straight:false right:true, |
|
||||
|
||||
@bug @todo
|
||||
Scenario: Theodor Heuss Platz
|
||||
Given the node map
|
||||
| | | | i | o | | | l | |
|
||||
| | | b | | | | a | | m |
|
||||
| | c | | | | | | | |
|
||||
| | | | | | | | h | |
|
||||
| | | | | | | | | |
|
||||
| j | | | | | | | | |
|
||||
| | | | | | | | g | |
|
||||
| | | | | | | | | |
|
||||
| | d | | | | | | | |
|
||||
| | | e | | | | f | | |
|
||||
| | | | | k | | | | n |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| g | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | junction | oneway | highway |
|
||||
| abcdef | roundabout | | roundabout | yes | primary |
|
||||
| gha | roundabout | | roundabout | yes | primary |
|
||||
| fg | roundabout | slight_left\|slight_left;slight_right\|slight_right\|slight_right | roundabout | yes | primary |
|
||||
| aoib | top | | | yes | primary |
|
||||
| cjd | left | | | yes | primary |
|
||||
| ekf | bottom | | | yes | primary |
|
||||
| fng | bottom-right | | | yes | primary |
|
||||
| hma | top-right | | | yes | primary |
|
||||
| hl | top-right-out | | | yes | secondary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| i,m | top,top-right,top-right | depart,roundabout-exit-4,arrive | ,slight left:false slight left;slight right:true slight right:true slight right:true, |
|
||||
| i,l | top,top-right-out,top-right-out | depart,roundabout-exit-4,arrive | ,slight left:true slight left;slight right:true slight right:false slight right:false, |
|
||||
| i,o | top,top,top | depart,roundabout-exit-5,arrive | ,, |
|
||||
|
||||
Scenario: Turn Lanes Breaking up
|
||||
Given the node map
|
||||
| | | | g | |
|
||||
| | | | | |
|
||||
| | | | c | |
|
||||
| a | b | | d | e |
|
||||
| | | | | |
|
||||
| | | | f | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway | highway |
|
||||
| ab | road | left\|left\|through\|through | yes | primary |
|
||||
| bd | road | through\|through | yes | primary |
|
||||
| bc | road | left\|left | yes | primary |
|
||||
| de | road | | yes | primary |
|
||||
| fdcg | cross | | | secondary |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | bd | fdcg | d | no_left_turn |
|
||||
| restriction | bc | fdcg | c | no_right_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,g | road,cross,cross | depart,turn left,arrive | ,left:true left:true straight:false straight:false, |
|
||||
| a,e | road,road,road | depart,use lane straight,arrive | ,left:false left:false straight:true straight:true, |
|
||||
|
||||
Scenario: U-Turn Road at Intersection
|
||||
Given the node map
|
||||
| | | | | | h | |
|
||||
| | | | | f | e | j |
|
||||
| a | b | | | | | |
|
||||
| | | | | c | d | i |
|
||||
| | | | | | g | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway | highway |
|
||||
| ab | road | | no | primary |
|
||||
| di | road | | yes | primary |
|
||||
| bc | road | \|through\|right | yes | primary |
|
||||
| cd | road | \|through\|right | yes | primary |
|
||||
| fc | road | | no | tertiary |
|
||||
| jefb | road | | yes | primary |
|
||||
| gdeh | cross | | no | primary |
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | turns | lanes |
|
||||
| a | g | 180,180 180,180 | road,cross,cross | depart,turn right,arrive | ,none:false straight:false right:true, |
|
||||
| a | h | 180,180 180,180 | road,cross,cross | depart,turn left,arrive | ,none:true straight:false right:false, |
|
||||
| a | i | 180,180 180,180 | road,road,road | depart,use lane straight,arrive | ,none:true straight:true right:false, |
|
||||
| b | a | 90,2 270,2 | road,road,road | depart,continue uturn,arrive | ,none:true straight:false right:false, |
|
||||
|
||||
Scenario: Segregated Intersection Merges With Lanes
|
||||
Given the node map
|
||||
| | | | | | | f |
|
||||
| | | | | | | |
|
||||
| e | | | d | | | |
|
||||
| | | | | | c | g |
|
||||
| a | | | b | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | h | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway | highway |
|
||||
| abc | road | left\|left\|left\|through\|through | yes | primary |
|
||||
| cde | road | | yes | primary |
|
||||
| hc | cross | | yes | secondary |
|
||||
| cg | straight | | no | tertiary |
|
||||
| cf | left | | yes | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,f | road,left,left | depart,turn left,arrive | ,left:true left:true left:true straight:false straight:false, |
|
||||
| a,e | road,road,road | depart,turn uturn,arrive | ,left:true left:false left:false straight:false straight:false, |
|
||||
| a,g | road,straight,straight | depart,new name straight,arrive | ,left:false left:false left:false straight:true straight:true, |
|
||||
|
||||
@bug @todo
|
||||
Scenario: Passing Through a Roundabout
|
||||
Given the node map
|
||||
| | | h | | g | | |
|
||||
| | a | | | | f | k |
|
||||
| i | | | | | | |
|
||||
| | | | | | | |
|
||||
| | b | | | | e | |
|
||||
| | | c | | d | | |
|
||||
| | | | | j | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | oneway | highway | junction |
|
||||
| efgha | round | | yes | primary | roundabout |
|
||||
| ab | round | | yes | primary | roundabout |
|
||||
| bc | round | slight_left\|slight_left\|slight_right | yes | primary | roundabout |
|
||||
| cd | round | | yes | primary | roundabout |
|
||||
| de | round | slight_left\|slight_right | yes | primary | roundabout |
|
||||
| ib | left | slight_left\|slight_left\|slight_right | yes | primary | |
|
||||
| cj | bottom | | yes | primary | |
|
||||
| ek | right | | yes | primary | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| i,j | left,bottom,bottom | depart,round-exit-1,arrive | ,0, |
|
||||
| i,k | left,right,right | depart,round-exit-2,arrive | ,1, |
|
||||
|
||||
Scenario: Crossing Traffic Light
|
||||
Given the node map
|
||||
| a | | b | | c | | d |
|
||||
| | | | | | | e |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| b | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway |
|
||||
| abc | road | through\|through\|through;slight_right\|slight_right | primary |
|
||||
| cd | road | | primary |
|
||||
| ce | cross | | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | road,road,road | depart,use lane straight,arrive | ,straight:true straight:true straight;slight right:true slight right:false, |
|
||||
| a,e | road,cross,cross | depart,turn slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
|
||||
|
||||
Scenario: Highway Ramp
|
||||
Given the node map
|
||||
| a | | b | | c | | d |
|
||||
| | | | | | | e |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway |
|
||||
| abc | hwy | through\|through\|through;slight_right\|slight_right | motorway |
|
||||
| cd | hwy | | motorway |
|
||||
| ce | ramp | | motorway_link |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | hwy,hwy,hwy | depart,use lane straight,arrive | ,straight:true straight:true straight;slight right:true slight right:false, |
|
||||
| a,e | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false straight;slight right:true slight right:true, |
|
||||
|
||||
@bug @todo
|
||||
Scenario: Turning Off Ramp
|
||||
Given the node map
|
||||
| | a | |
|
||||
| d | c | b |
|
||||
| e | f | g |
|
||||
| | h | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway | oneway |
|
||||
| ac | off | left\|right | motorway_link | yes |
|
||||
| bcd | road | | primary | yes |
|
||||
| cf | road | | primary | |
|
||||
| efg | road | | primary | yes |
|
||||
| fh | on | | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,d | off,road,road | depart,turn_right,arrive | ,left:false right:true, |
|
||||
| a,g | off,road,road | depart,turn_left,arrive | ,left:true right:false, |
|
||||
| a,h | | | |
|
||||
|
||||
Scenario: Off Ramp In a Turn
|
||||
Given the node map
|
||||
| a | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | |
|
||||
| | | | | | b | | | | | | c |
|
||||
| | | | | | | | | | | d | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway | oneway |
|
||||
| ab | hwy | through\|through\|slight_right | motorway | yes |
|
||||
| bc | hwy | | motorway | yes |
|
||||
| bd | ramp | | motorway_link | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,c | hwy,hwy,hwy | depart,use lane slight left,arrive | ,straight:true straight:true slight right:false, |
|
||||
| a,d | hwy,ramp,ramp | depart,off ramp slight right,arrive | ,straight:false straight:false slight right:true, |
|
||||
|
||||
Scenario: Reverse Lane in Segregated Road
|
||||
Given the node map
|
||||
| h | | | | | g | | | | | | f |
|
||||
| | | | | | | | e | | | | |
|
||||
| | | | | | | | d | | | | |
|
||||
| a | | | | | b | | | | | | c |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway | oneway |
|
||||
| ab | road | reverse\|through\|through | primary | yes |
|
||||
| bc | road | | primary | yes |
|
||||
| bdeg | road | | primary_link | yes |
|
||||
| fgh | road | | primary | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false straight:false,|
|
||||
|
||||
Scenario: Reverse Lane in Segregated Road with none
|
||||
Given the node map
|
||||
| h | | | | | g | | | | | | f |
|
||||
| | | | | | | | e | | | | |
|
||||
| | | | | | | | d | | | | |
|
||||
| a | | | | | b | | | | | | c |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway | oneway |
|
||||
| ab | road | reverse\|through\|none | primary | yes |
|
||||
| bc | road | | primary | yes |
|
||||
| bdeg | road | | primary_link | yes |
|
||||
| fgh | road | | primary | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false, |
|
||||
|
||||
Scenario: Reverse Lane in Segregated Road with none, Service Turn Prior
|
||||
Given the node map
|
||||
| h | | | | | g | | | | | | f |
|
||||
| | | | | | | | e | | | | |
|
||||
| | | | | | | | d | | | | |
|
||||
| a | | j | | | b | | | | | | c |
|
||||
| | | i | | | | | | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | turn:lanes:forward | highway | oneway |
|
||||
| ajb | road | reverse\|through\|none | primary | yes |
|
||||
| bc | road | | primary | yes |
|
||||
| bdeg | road | | primary_link | yes |
|
||||
| fgh | road | | primary | yes |
|
||||
| ji | park | | service | no |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,h | road,road,road | depart,continue uturn,arrive | ,uturn:true straight:false none:false, |
|
||||
|
||||
Scenario: Don't collapse everything to u-turn / too wide
|
||||
Given the node map
|
||||
| a | | b | | e |
|
||||
| | | | | |
|
||||
| d | | c | | f |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | turn:lanes:forward |
|
||||
| ab | primary | road | through\|right |
|
||||
| bc | primary | road | |
|
||||
| dc | primary | road | left\|through |
|
||||
| be | secondary | top | |
|
||||
| cf | secondary | bottom | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route | lanes |
|
||||
| a,d | depart,continue right,turn right,arrive | road,road,road,road | ,straight:false right:true,, |
|
||||
| d,a | depart,continue left,turn left,arrive | road,road,road,road | ,left:true straight:false,, |
|
||||
|
||||
Scenario: Merge Lanes Onto Freeway
|
||||
Given the node map
|
||||
| a | | | b | c |
|
||||
| | d | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | turn:lanes:forward |
|
||||
| abc | motorway | Hwy | |
|
||||
| db | motorway_link | ramp | slight_right\|slight_right |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route | lanes |
|
||||
| d,c | depart,merge slight left,arrive | ramp,Hwy,Hwy | ,slight right:true slight right:true, |
|
||||
|
||||
Scenario: Fork on motorway links - don't fork on through but use lane
|
||||
Given the node map
|
||||
| i | | | | | a |
|
||||
| j | | c | b | | x |
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway | turn:lanes:forward |
|
||||
| xb | xbcj | motorway_link | |
|
||||
| bc | xbcj | motorway_link | none\|slight_right |
|
||||
| cj | xbcj | motorway_link | |
|
||||
| ci | off | motorway_link | |
|
||||
| ab | on | motorway_link | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | lanes |
|
||||
| a,j | on,xbcj,xbcj,xbcj | depart,merge slight left,use lane straight,arrive | ,,none:true slight right:false, |
|
||||
| a,i | on,xbcj,off,off | depart,merge slight left,turn slight right,arrive | ,,none:false slight right:true, |
|
||||
@@ -806,3 +806,76 @@ Feature: Simple Turns
|
||||
| a,e | abc,be,be | depart,turn right,arrive |
|
||||
| a,f | abc,bf,bf | depart,turn slight right,arrive |
|
||||
|
||||
Scenario: Turn Lane on Splitting up Road
|
||||
Given the node map
|
||||
| | | | | | | | | | | | | | | |
|
||||
| g | | | | f | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | | | |
|
||||
| | | | | | h | | | e | | | c | | | d |
|
||||
| a | | | b | | | | | | | | | | | |
|
||||
| | | | i | | | | | | | | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | oneway | name |
|
||||
| ab | secondary | yes | road |
|
||||
| be | secondary | yes | road |
|
||||
| ecd | secondary | no | road |
|
||||
| efg | secondary | yes | road |
|
||||
| ehb | secondary_link | yes | road |
|
||||
| bi | tertiary | no | cross |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | ehb | be | b | no_left_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,d | road,road | depart,arrive |
|
||||
| d,i | road,cross,cross | depart,turn left,arrive |
|
||||
| d,g | road,road | depart,arrive |
|
||||
|
||||
Scenario: Go onto turning major road
|
||||
Given the node map
|
||||
| | | | c |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| a | | | b |
|
||||
| | | | |
|
||||
| | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abc | primary | road |
|
||||
| bd | residential | in |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| a,c | depart,arrive | road,road |
|
||||
| d,a | depart,turn left,arrive | in,road,road |
|
||||
| d,c | depart,new name straight,arrive | in,road,road |
|
||||
|
||||
Scenario: Channing Street
|
||||
Given the node map
|
||||
| | | g | f | |
|
||||
| | | | | |
|
||||
| d | | c | b | a |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | h | e | |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| c | traffic_signals |
|
||||
| b | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway | oneway |
|
||||
| ab | Channing Street Northeast | residential | no |
|
||||
| bcd | Channing Street Northwest | residential | yes |
|
||||
| ebf | North Capitol Street Northeast | primary | yes |
|
||||
| gch | North Capitol Street Northeast | primary | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| a,d | depart,arrive | Channing Street Northeast,Channing Street Northwest |
|
||||
| a,h | depart,turn left,arrive | Channing Street Northeast,North Capitol Street Northeast,North Capitol Street Northeast |
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
@prepare @options @files
|
||||
Feature: osrm-contract command line options: datasources
|
||||
# expansions:
|
||||
# {extracted_base} => path to current extracted input file
|
||||
# {profile} => path to current profile script
|
||||
|
||||
Background:
|
||||
Given the profile "testbot"
|
||||
Given the extract extra arguments "--generate-edge-lookup"
|
||||
And the node map
|
||||
| a | b |
|
||||
And the ways
|
||||
| nodes |
|
||||
| ab |
|
||||
And the speed file
|
||||
"""
|
||||
1,2,27
|
||||
2,1,27
|
||||
2,3,27
|
||||
3,2,27
|
||||
1,4,27
|
||||
4,1,27
|
||||
"""
|
||||
And the data has been extracted
|
||||
|
||||
Scenario: osrm-contract - Passing base file
|
||||
When I run "osrm-contract --segment-speed-file speeds.csv {extracted_base}.osrm"
|
||||
Then stderr should be empty
|
||||
And datasource names should contain "lua profile,speeds"
|
||||
And it should exit with code 0
|
||||
@@ -17,7 +17,7 @@ module.exports = function () {
|
||||
this.setContractArgs(args, callback);
|
||||
});
|
||||
|
||||
this.Given(/^a grid size of (\d+) meters$/, (meters, callback) => {
|
||||
this.Given(/^a grid size of ([0-9.]+) meters$/, (meters, callback) => {
|
||||
this.setGridSize(meters);
|
||||
callback();
|
||||
});
|
||||
@@ -228,14 +228,17 @@ module.exports = function () {
|
||||
});
|
||||
|
||||
this.Given(/^the raster source$/, (data, callback) => {
|
||||
this.updateFingerprintExtract(data);
|
||||
fs.writeFile(path.resolve(this.TEST_FOLDER, 'rastersource.asc'), data, callback);
|
||||
});
|
||||
|
||||
this.Given(/^the speed file$/, (data, callback) => {
|
||||
this.updateFingerprintContract(data);
|
||||
fs.writeFile(path.resolve(this.TEST_FOLDER, 'speeds.csv'), data, callback);
|
||||
});
|
||||
|
||||
this.Given(/^the turn penalty file$/, (data, callback) => {
|
||||
this.updateFingerprintContract(data);
|
||||
fs.writeFile(path.resolve(this.TEST_FOLDER, 'penalties.csv'), data, callback);
|
||||
});
|
||||
|
||||
@@ -249,9 +252,11 @@ module.exports = function () {
|
||||
});
|
||||
|
||||
this.Given(/^the data has been extracted$/, (callback) => {
|
||||
this.writeAndExtract((err) => {
|
||||
if (err) this.processError = err;
|
||||
callback();
|
||||
this.osmData.populate(() => {
|
||||
this.writeAndExtract((err) => {
|
||||
if (err) this.processError = err;
|
||||
callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -15,16 +15,4 @@ module.exports = function () {
|
||||
this.setOrigin(this.DEFAULT_ORIGIN);
|
||||
callback();
|
||||
});
|
||||
|
||||
this.Before('@ignore-platform-windows', () => {
|
||||
this.skipThisScenario();
|
||||
});
|
||||
|
||||
this.Before('@ignore-platform-unix', () => {
|
||||
this.skipThisScenario();
|
||||
});
|
||||
|
||||
this.Before('@ignore-platform-mac', () => {
|
||||
this.skipThisScenario();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
var util = require('util');
|
||||
var d3 = require('d3-queue');
|
||||
var polyline = require('polyline');
|
||||
|
||||
module.exports = function () {
|
||||
this.When(/^I match I should get$/, (table, callback) => {
|
||||
@@ -33,7 +34,11 @@ module.exports = function () {
|
||||
var subMatchings = [],
|
||||
turns = '',
|
||||
route = '',
|
||||
duration = '';
|
||||
duration = '',
|
||||
annotation = '',
|
||||
geometry = '',
|
||||
OSMIDs = '';
|
||||
|
||||
|
||||
if (res.statusCode === 200) {
|
||||
if (headers.has('matchings')) {
|
||||
@@ -54,6 +59,21 @@ module.exports = function () {
|
||||
if (json.matchings.length != 1) throw new Error('*** Checking duration only supported for matchings with one subtrace');
|
||||
duration = json.matchings[0].duration;
|
||||
}
|
||||
|
||||
if (headers.has('annotation')) {
|
||||
if (json.matchings.length != 1) throw new Error('*** Checking annotation only supported for matchings with one subtrace');
|
||||
annotation = this.annotationList(json.matchings[0]);
|
||||
}
|
||||
|
||||
if (headers.has('geometry')) {
|
||||
if (json.matchings.length != 1) throw new Error('*** Checking geometry only supported for matchings with one subtrace');
|
||||
geometry = json.matchings[0].geometry;
|
||||
}
|
||||
|
||||
if (headers.has('OSM IDs')) {
|
||||
if (json.matchings.length != 1) throw new Error('*** CHecking annotation only supported for matchings with one subtrace');
|
||||
OSMIDs = this.OSMIDList(json.matchings[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (headers.has('turns')) {
|
||||
@@ -68,6 +88,21 @@ module.exports = function () {
|
||||
got.duration = duration.toString();
|
||||
}
|
||||
|
||||
if (headers.has('annotation')) {
|
||||
got.annotation = annotation.toString();
|
||||
}
|
||||
|
||||
if (headers.has('geometry')) {
|
||||
if (this.queryParams['geometries'] === 'polyline')
|
||||
got.geometry = polyline.decode(geometry).toString();
|
||||
else
|
||||
got.geometry = geometry;
|
||||
}
|
||||
|
||||
if (headers.has('OSM IDs')) {
|
||||
got['OSM IDs'] = OSMIDs;
|
||||
}
|
||||
|
||||
var ok = true;
|
||||
var encodedResult = '',
|
||||
extendedTarget = '';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
var assert = require('assert');
|
||||
var fs = require('fs');
|
||||
|
||||
module.exports = function () {
|
||||
this.When(/^I run "osrm\-routed\s?(.*?)"$/, { timeout: this.TIMEOUT }, (options, callback) => {
|
||||
@@ -59,6 +60,11 @@ module.exports = function () {
|
||||
assert.equal(this.stdout.split('\n').length - 1, parseInt(lines));
|
||||
});
|
||||
|
||||
this.Then(/^datasource names should contain "(.+)"$/, (expectedData) => {
|
||||
var actualData = fs.readFileSync(this.osmData.extractedFile + '.osrm.datasource_names', {encoding:'UTF-8'}).trim().split('\n').join(',');
|
||||
assert.equal(actualData, expectedData);
|
||||
});
|
||||
|
||||
this.Given(/^the query options$/, (table, callback) => {
|
||||
table.raw().forEach(tuple => {
|
||||
this.queryParams[tuple[0]] = tuple[1];
|
||||
|
||||
@@ -12,7 +12,8 @@ module.exports = function () {
|
||||
throw new Error('*** routability table must contain either "forw", "backw" or "bothw" column');
|
||||
}
|
||||
|
||||
this.reprocessAndLoadData(() => {
|
||||
this.reprocessAndLoadData((e) => {
|
||||
if (e) callback(e);
|
||||
var testRow = (row, i, cb) => {
|
||||
var outputRow = row;
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ module.exports = function () {
|
||||
if (headers.has('trips')) {
|
||||
subTrips = json.trips.filter(t => !!t).map(t => t.legs).map(tl => Array.prototype.concat.apply([], tl.map((sl, i) => {
|
||||
var toAdd = [];
|
||||
if (i === 0) toAdd.push(sl.steps[0].maneuver.location);
|
||||
toAdd.push(sl.steps[sl.steps.length-1].maneuver.location);
|
||||
if (i === 0) toAdd.push(sl.steps[0].intersections[0].location);
|
||||
toAdd.push(sl.steps[sl.steps.length-1].intersections[0].location);
|
||||
return toAdd;
|
||||
})));
|
||||
}
|
||||
|
||||
+22
-13
@@ -50,22 +50,27 @@ module.exports = function () {
|
||||
};
|
||||
|
||||
var hashExtract = (cb) => {
|
||||
this.hashOfFiles(util.format('%s/osrm-extract%s', this.BIN_PATH, this.EXE), (hash) => {
|
||||
var files = [ util.format('%s/osrm-extract%s', this.BIN_PATH, this.EXE),
|
||||
util.format('%s/libosrm_extract%s', this.BIN_PATH, this.LIB) ];
|
||||
this.hashOfFiles(files, (hash) => {
|
||||
this.binExtractHash = hash;
|
||||
cb();
|
||||
});
|
||||
};
|
||||
|
||||
var hashContract = (cb) => {
|
||||
this.hashOfFiles(util.format('%s/osrm-contract%s', this.BIN_PATH, this.EXE), (hash) => {
|
||||
var files = [ util.format('%s/osrm-contract%s', this.BIN_PATH, this.EXE),
|
||||
util.format('%s/libosrm_contract%s', this.BIN_PATH, this.LIB) ];
|
||||
this.hashOfFiles(files, (hash) => {
|
||||
this.binContractHash = hash;
|
||||
this.fingerprintContract = this.hashString(this.binContractHash);
|
||||
cb();
|
||||
});
|
||||
};
|
||||
|
||||
var hashRouted = (cb) => {
|
||||
this.hashOfFiles(util.format('%s/osrm-routed%s', this.BIN_PATH, this.EXE), (hash) => {
|
||||
var files = [ util.format('%s/osrm-routed%s', this.BIN_PATH, this.EXE),
|
||||
util.format('%s/libosrm%s', this.BIN_PATH, this.LIB) ];
|
||||
this.hashOfFiles(files, (hash) => {
|
||||
this.binRoutedHash = hash;
|
||||
this.fingerprintRoute = this.hashString(this.binRoutedHash);
|
||||
cb();
|
||||
@@ -79,16 +84,18 @@ module.exports = function () {
|
||||
.defer(hashContract)
|
||||
.defer(hashRouted)
|
||||
.awaitAll(() => {
|
||||
this.fingerprintExtract = this.hashString([this.profileHash, this.luaLibHash, this.binExtractHash].join('-'));
|
||||
this.AfterConfiguration(() => {
|
||||
callback();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.setProfileBasedHashes = () => {
|
||||
this.fingerprintExtract = this.hashString([this.profileHash, this.luaLibHash, this.binExtractHash].join('-'));
|
||||
this.fingerprintContract = this.hashString(this.binContractHash);
|
||||
this.updateFingerprintExtract = (str) => {
|
||||
this.fingerprintExtract = this.hashString([this.fingerprintExtract, str].join('-'));
|
||||
};
|
||||
|
||||
this.updateFingerprintContract = (str) => {
|
||||
this.fingerprintContract = this.hashString([this.fingerprintContract, str].join('-'));
|
||||
};
|
||||
|
||||
this.setProfile = (profile, cb) => {
|
||||
@@ -97,22 +104,24 @@ module.exports = function () {
|
||||
this.profile = profile;
|
||||
this.hashProfile((hash) => {
|
||||
this.profileHash = hash;
|
||||
this.setProfileBasedHashes();
|
||||
this.updateFingerprintExtract(this.profileHash);
|
||||
cb();
|
||||
});
|
||||
} else cb();
|
||||
} else {
|
||||
this.updateFingerprintExtract(this.profileHash);
|
||||
cb();
|
||||
}
|
||||
};
|
||||
|
||||
this.setExtractArgs = (args, callback) => {
|
||||
this.extractArgs = args;
|
||||
this.forceExtract = true;
|
||||
this.forceContract = true;
|
||||
this.updateFingerprintExtract(args);
|
||||
callback();
|
||||
};
|
||||
|
||||
this.setContractArgs = (args, callback) => {
|
||||
this.contractArgs = args;
|
||||
this.forceContract = true;
|
||||
this.updateFingerprintContract(args);
|
||||
callback();
|
||||
};
|
||||
};
|
||||
|
||||
+45
-30
@@ -194,8 +194,8 @@ module.exports = function () {
|
||||
this.extractData = (callback) => {
|
||||
this.logPreprocessInfo();
|
||||
this.log(util.format('== Extracting %s.osm...', this.osmData.osmFile), 'preprocess');
|
||||
var cmd = util.format('%s%s/osrm-extract %s.osm %s --profile %s/%s.lua >>%s 2>&1',
|
||||
this.LOAD_LIBRARIES, this.BIN_PATH, this.osmData.osmFile, this.extractArgs || '', this.PROFILES_PATH, this.profile, this.PREPROCESS_LOG_FILE);
|
||||
var cmd = util.format('%s/osrm-extract %s.osm %s --profile %s/%s.lua >>%s 2>&1',
|
||||
this.BIN_PATH, this.osmData.osmFile, this.extractArgs || '', this.PROFILES_PATH, this.profile, this.PREPROCESS_LOG_FILE);
|
||||
this.log(cmd);
|
||||
process.chdir(this.TEST_FOLDER);
|
||||
exec(cmd, (err) => {
|
||||
@@ -222,11 +222,12 @@ module.exports = function () {
|
||||
});
|
||||
};
|
||||
|
||||
['osrm','osrm.names','osrm.restrictions','osrm.ebg','osrm.enw','osrm.edges','osrm.fileIndex','osrm.geometry','osrm.nodes','osrm.ramIndex','osrm.properties'].forEach(file => {
|
||||
q.defer(rename, file);
|
||||
});
|
||||
['osrm', 'osrm.ebg', 'osrm.edges', 'osrm.enw', 'osrm.fileIndex', 'osrm.geometry', 'osrm.icd',
|
||||
'osrm.names', 'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions', 'osrm.tld', 'osrm.tls'].forEach(file => {
|
||||
q.defer(rename, file);
|
||||
});
|
||||
|
||||
['osrm.edge_segment_lookup','osrm.edge_penalties'].forEach(file => {
|
||||
['osrm.edge_penalties', 'osrm.edge_segment_lookup'].forEach(file => {
|
||||
q.defer(renameIfExists, file);
|
||||
});
|
||||
|
||||
@@ -241,8 +242,8 @@ module.exports = function () {
|
||||
this.contractData = (callback) => {
|
||||
this.logPreprocessInfo();
|
||||
this.log(util.format('== Contracting %s.osm...', this.osmData.extractedFile), 'preprocess');
|
||||
var cmd = util.format('%s%s/osrm-contract %s %s.osrm >>%s 2>&1',
|
||||
this.LOAD_LIBRARIES, this.BIN_PATH, this.contractArgs || '', this.osmData.extractedFile, this.PREPROCESS_LOG_FILE);
|
||||
var cmd = util.format('%s/osrm-contract %s %s.osrm >>%s 2>&1',
|
||||
this.BIN_PATH, this.contractArgs || '', this.osmData.extractedFile, this.PREPROCESS_LOG_FILE);
|
||||
this.log(cmd);
|
||||
process.chdir(this.TEST_FOLDER);
|
||||
exec(cmd, (err) => {
|
||||
@@ -260,6 +261,13 @@ module.exports = function () {
|
||||
});
|
||||
};
|
||||
|
||||
var renameIfExists = (file, cb) => {
|
||||
fs.stat([this.osmData.extractedFile, file].join('.'), (doesNotExistErr, exists) => {
|
||||
if (exists) rename(file, cb);
|
||||
else cb();
|
||||
});
|
||||
};
|
||||
|
||||
var copy = (file, cb) => {
|
||||
this.log(util.format('Copying %s.%s to %s.%s', this.osmData.extractedFile, file, this.osmData.contractedFile, file), 'preprocess');
|
||||
fs.createReadStream([this.osmData.extractedFile, file].join('.'))
|
||||
@@ -273,11 +281,17 @@ module.exports = function () {
|
||||
|
||||
var q = d3.queue();
|
||||
|
||||
['osrm.hsgr','osrm.fileIndex','osrm.geometry','osrm.nodes','osrm.ramIndex','osrm.core','osrm.edges','osrm.datasource_indexes','osrm.datasource_names','osrm.level'].forEach((file) => {
|
||||
q.defer(rename, file);
|
||||
['osrm', 'osrm.core', 'osrm.datasource_indexes', 'osrm.datasource_names', 'osrm.ebg','osrm.edges',
|
||||
'osrm.enw', 'osrm.fileIndex', 'osrm.geometry', 'osrm.hsgr', 'osrm.icd','osrm.level', 'osrm.names',
|
||||
'osrm.nodes', 'osrm.properties', 'osrm.ramIndex', 'osrm.restrictions', 'osrm.tld', 'osrm.tls'].forEach((file) => {
|
||||
q.defer(rename, file);
|
||||
});
|
||||
|
||||
['osrm.edge_penalties', 'osrm.edge_segment_lookup'].forEach(file => {
|
||||
q.defer(renameIfExists, file);
|
||||
});
|
||||
|
||||
['osrm.names','osrm.restrictions','osrm.properties','osrm'].forEach((file) => {
|
||||
[].forEach((file) => {
|
||||
q.defer(copy, file);
|
||||
});
|
||||
|
||||
@@ -292,32 +306,33 @@ module.exports = function () {
|
||||
var noop = (cb) => cb();
|
||||
|
||||
this.reprocess = (callback) => {
|
||||
this.writeAndExtract((e) => {
|
||||
if (e) return callback(e);
|
||||
this.osmData.populate(() => {
|
||||
this.isContracted((isContracted) => {
|
||||
var contractFn = (isContracted && !this.forceContract) ? noop : this.contractData;
|
||||
if (isContracted) this.log('Already contracted ' + this.osmData.contractedFile, 'preprocess');
|
||||
contractFn((e) => {
|
||||
this.forceContract = false;
|
||||
if (e) return callback(e);
|
||||
this.logPreprocessDone();
|
||||
if (!isContracted) {
|
||||
this.writeAndExtract((e) => {
|
||||
if (e) return callback(e);
|
||||
this.contractData((e) => {
|
||||
if (e) return callback(e);
|
||||
this.logPreprocessDone();
|
||||
callback();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.log('Already contracted ' + this.osmData.contractedFile, 'preprocess');
|
||||
callback();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.writeAndExtract = (callback) => {
|
||||
this.osmData.populate(() => {
|
||||
this.writeInputData((e) => {
|
||||
if (e) return callback(e);
|
||||
this.isExtracted((isExtracted) => {
|
||||
var extractFn = (isExtracted && !this.forceExtract) ? noop : this.extractData;
|
||||
if (isExtracted) this.log('Already extracted ' + this.osmData.extractedFile, 'preprocess');
|
||||
extractFn((e) => {
|
||||
this.forceExtract = false;
|
||||
callback(e);
|
||||
});
|
||||
this.writeInputData((e) => {
|
||||
if (e) return callback(e);
|
||||
this.isExtracted((isExtracted) => {
|
||||
var extractFn = isExtracted ? noop : this.extractData;
|
||||
if (isExtracted) this.log('Already extracted ' + this.osmData.extractedFile, 'preprocess');
|
||||
extractFn((e) => {
|
||||
callback(e);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,24 +52,91 @@ module.exports = {
|
||||
match (got, want) {
|
||||
var matchPercent = want.match(/(.*)\s+~(.+)%$/),
|
||||
matchAbs = want.match(/(.*)\s+\+\-(.+)$/),
|
||||
matchRe = want.match(/^\/(.*)\/$/);
|
||||
matchRe = want.match(/^\/(.*)\/$/),
|
||||
// we use this for matching before/after bearing
|
||||
matchBearingListAbs = want.match(/^((\d+)->(\d+))(,(\d+)->(\d+))*\s+\+\-(.+)$/),
|
||||
matchIntersectionListAbs = want.match(/^(((((true|false):\d+)\s{0,1})+,{0,1})+;{0,1})+\s+\+\-(.+)$/);
|
||||
|
||||
function inRange(margin, got, want) {
|
||||
var fromR = parseFloat(want) - margin,
|
||||
toR = parseFloat(want) + margin;
|
||||
return parseFloat(got) >= fromR && parseFloat(got) <= toR;
|
||||
}
|
||||
function parseIntersectionString(str) {
|
||||
return str.split(';')
|
||||
.map((turn_intersections) => turn_intersections
|
||||
.split(',')
|
||||
.map((intersection) => intersection
|
||||
.split(' ')
|
||||
.map((entry_bearing_pair) => entry_bearing_pair
|
||||
.split(':'))));
|
||||
}
|
||||
|
||||
if (got === want) {
|
||||
return true;
|
||||
} else if (matchBearingListAbs) {
|
||||
let want_and_margin = want.split('+-'),
|
||||
margin = parseFloat(want_and_margin[1].trim()),
|
||||
want_pairs = want_and_margin[0].trim().split(',').map((pair) => pair.split('->')),
|
||||
got_pairs = got.split(',').map((pair) => pair.split('->'));
|
||||
if (want_pairs.length != got_pairs.length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < want_pairs.length; ++i)
|
||||
{
|
||||
if (!inRange(margin, got_pairs[i][0], want_pairs[i][0]) ||
|
||||
!inRange(margin, got_pairs[i][1], want_pairs[i][1]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (matchIntersectionListAbs) {
|
||||
let margin = parseFloat(want.split('+-')[1]),
|
||||
want_intersections = parseIntersectionString(want.split('+-')[0].trim()),
|
||||
got_intersections = parseIntersectionString(got);
|
||||
if (want_intersections.length != got_intersections.length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (let step_idx = 0; step_idx < want_intersections.length; ++step_idx)
|
||||
{
|
||||
if (want_intersections[step_idx].length != got_intersections[step_idx].length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (let intersection_idx = 0; intersection_idx < want_intersections[step_idx].length; ++intersection_idx)
|
||||
{
|
||||
if (want_intersections[step_idx][intersection_idx].length != got_intersections[step_idx][intersection_idx].length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (let pair_idx = 0; pair_idx < want_intersections[step_idx][intersection_idx].length; ++pair_idx)
|
||||
{
|
||||
let want_pair = want_intersections[step_idx][intersection_idx][pair_idx],
|
||||
got_pair = got_intersections[step_idx][intersection_idx][pair_idx];
|
||||
if (got_pair[0] != want_pair[0] ||
|
||||
!inRange(margin, got_pair[1], want_pair[1]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (matchPercent) { // percentage range: 100 ~ 5%
|
||||
var target = parseFloat(matchPercent[1]),
|
||||
percentage = parseFloat(matchPercent[2]);
|
||||
if (target === 0) {
|
||||
return true;
|
||||
} else {
|
||||
var ratio = Math.abs(1 - parseFloat(got) / target);
|
||||
let ratio = Math.abs(1 - parseFloat(got) / target);
|
||||
return 100 * ratio < percentage;
|
||||
}
|
||||
} else if (matchAbs) { // absolute range: 100 +-5
|
||||
var margin = parseFloat(matchAbs[2]),
|
||||
fromR = parseFloat(matchAbs[1]) - margin,
|
||||
toR = parseFloat(matchAbs[1]) + margin;
|
||||
return parseFloat(got) >= fromR && parseFloat(got) <= toR;
|
||||
let margin = parseFloat(matchAbs[2]);
|
||||
return inRange(margin, got, matchAbs[1]);
|
||||
} else if (matchRe) { // regex: /a,b,.*/
|
||||
return got.match(matchRe[1]);
|
||||
} else {
|
||||
|
||||
@@ -7,7 +7,7 @@ var d3 = require('d3-queue');
|
||||
module.exports = function () {
|
||||
this.initializeEnv = (callback) => {
|
||||
this.OSRM_PORT = process.env.OSRM_PORT && parseInt(process.env.OSRM_PORT) || 5000;
|
||||
this.TIMEOUT = process.env.CUCUMBER_TIMEOUT && parseInt(process.env.CUCUMBER_TIMEOUT) || 3000;
|
||||
this.TIMEOUT = process.env.CUCUMBER_TIMEOUT && parseInt(process.env.CUCUMBER_TIMEOUT) || 5000;
|
||||
this.setDefaultTimeout(this.TIMEOUT);
|
||||
this.ROOT_FOLDER = process.cwd();
|
||||
this.OSM_USER = 'osrm';
|
||||
@@ -21,26 +21,23 @@ module.exports = function () {
|
||||
this.DEFAULT_GRID_SIZE = 100; // meters
|
||||
this.PROFILES_PATH = path.resolve(this.ROOT_FOLDER, 'profiles');
|
||||
this.FIXTURES_PATH = path.resolve(this.ROOT_FOLDER, 'unit_tests/fixtures');
|
||||
this.BIN_PATH = path.resolve(this.ROOT_FOLDER, 'build');
|
||||
this.BIN_PATH = process.env.OSRM_BUILD_DIR && process.env.OSRM_BUILD_DIR || path.resolve(this.ROOT_FOLDER, 'build');
|
||||
this.DEFAULT_INPUT_FORMAT = 'osm';
|
||||
this.DEFAULT_ORIGIN = [1,1];
|
||||
this.DEFAULT_LOAD_METHOD = 'datastore';
|
||||
this.OSRM_ROUTED_LOG_FILE = path.resolve(this.TEST_FOLDER, 'osrm-routed.log');
|
||||
this.ERROR_LOG_FILE = path.resolve(this.TEST_FOLDER, 'error.log');
|
||||
|
||||
// OS X shim to ensure shared libraries from custom locations can be loaded
|
||||
// This is needed in OS X >= 10.11 because DYLD_LIBRARY_PATH is blocked
|
||||
// https://forums.developer.apple.com/thread/9233
|
||||
this.LOAD_LIBRARIES = process.env.OSRM_SHARED_LIBRARY_PATH ? util.format('DYLD_LIBRARY_PATH=%s ', process.env.OSRM_SHARED_LIBRARY_PATH) : '';
|
||||
|
||||
// TODO make sure this works on win
|
||||
if (process.platform.match(/indows.*/)) {
|
||||
this.TERMSIGNAL = 9;
|
||||
this.EXE = '.exe';
|
||||
this.LIB = '.dll';
|
||||
this.QQ = '"';
|
||||
} else {
|
||||
this.TERMSIGNAL = 'SIGTERM';
|
||||
this.EXE = '';
|
||||
this.LIB = '.so';
|
||||
this.QQ = '';
|
||||
}
|
||||
|
||||
@@ -65,7 +62,7 @@ module.exports = function () {
|
||||
var binPath = path.resolve(util.format('%s/%s%s', this.BIN_PATH, bin, this.EXE));
|
||||
fs.exists(binPath, (exists) => {
|
||||
if (!exists) throw new Error(util.format('%s is missing. Build failed?', binPath));
|
||||
var helpPath = util.format('%s%s --help > /dev/null 2>&1', this.LOAD_LIBRARIES, binPath);
|
||||
var helpPath = util.format('%s --help > /dev/null 2>&1', binPath);
|
||||
exec(helpPath, (err) => {
|
||||
if (err) {
|
||||
this.log(util.format('*** Exited with code %d', err.code), 'preprocess');
|
||||
|
||||
@@ -6,14 +6,19 @@ var d3 = require('d3-queue');
|
||||
module.exports = function () {
|
||||
this.hashOfFiles = (paths, cb) => {
|
||||
paths = Array.isArray(paths) ? paths : [paths];
|
||||
var shasum = crypto.createHash('sha1');
|
||||
var shasum = crypto.createHash('sha1'), hashedFiles = false;
|
||||
|
||||
var q = d3.queue(1);
|
||||
|
||||
var addFile = (path, cb) => {
|
||||
fs.readFile(path, (err, data) => {
|
||||
shasum.update(data);
|
||||
cb(err);
|
||||
if (err && err.code === 'ENOENT') cb(); // ignore non-existing files
|
||||
else if (err) cb(err);
|
||||
else {
|
||||
shasum.update(data);
|
||||
hashedFiles = true;
|
||||
cb();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -21,6 +26,7 @@ module.exports = function () {
|
||||
|
||||
q.awaitAll(err => {
|
||||
if (err) throw new Error('*** Error reading files:', err);
|
||||
if (!hashedFiles) throw new Error('*** No files found: [' + paths.join(', ') + ']');
|
||||
cb(shasum.digest('hex'));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -20,6 +20,8 @@ module.exports = function () {
|
||||
this.hasLoggedScenarioInfo = false;
|
||||
this.setGridSize(this.DEFAULT_GRID_SIZE);
|
||||
this.setOrigin(this.DEFAULT_ORIGIN);
|
||||
this.fingerprintExtract = this.hashString([this.luaLibHash, this.binExtractHash].join('-'));
|
||||
this.fingerprintContract = this.hashString(this.binContractHash);
|
||||
callback();
|
||||
});
|
||||
|
||||
@@ -31,9 +33,4 @@ module.exports = function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
this.Around('@stress', (scenario, callback) => {
|
||||
// TODO implement stress timeout? Around support is being dropped in cucumber-js anyway
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var net = require('net');
|
||||
var spawn = require('child_process').spawn;
|
||||
var util = require('util');
|
||||
var net = require('net');
|
||||
var Timeout = require('node-timeout');
|
||||
|
||||
var OSRMBaseLoader = class {
|
||||
@@ -15,9 +15,7 @@ var OSRMBaseLoader = class {
|
||||
var limit = Timeout(this.scope.TIMEOUT, { err: this.scope.RoutedError('Launching osrm-routed timed out.') });
|
||||
|
||||
var runLaunch = (cb) => {
|
||||
this.osrmUp(() => {
|
||||
this.waitForConnection(cb);
|
||||
});
|
||||
this.osrmUp(() => { this.waitForConnection(cb); });
|
||||
};
|
||||
|
||||
runLaunch(limit((e) => { if (e) callback(e); else callback(); }));
|
||||
@@ -46,18 +44,21 @@ var OSRMBaseLoader = class {
|
||||
}
|
||||
|
||||
waitForConnection (callback) {
|
||||
net.connect({
|
||||
port: this.scope.OSRM_PORT,
|
||||
host: '127.0.0.1'
|
||||
})
|
||||
.on('connect', () => {
|
||||
callback();
|
||||
})
|
||||
.on('error', (e) => {
|
||||
setTimeout(() => {
|
||||
callback(e);
|
||||
}, 100);
|
||||
});
|
||||
var retryCount = 0;
|
||||
var connectWithRetry = () => {
|
||||
net.connect({ port: this.scope.OSRM_PORT, host: '127.0.0.1' })
|
||||
.on('connect', () => { callback(); })
|
||||
.on('error', () => {
|
||||
if (retryCount < 2) {
|
||||
retryCount++;
|
||||
setTimeout(connectWithRetry, 100);
|
||||
} else {
|
||||
callback(new Error('Could not connect to osrm-routed after three retires'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
connectWithRetry();
|
||||
}
|
||||
|
||||
waitForShutdown (callback) {
|
||||
@@ -86,7 +87,7 @@ var OSRMDirectLoader = class extends OSRMBaseLoader {
|
||||
fs.appendFile(this.scope.OSRM_ROUTED_LOG_FILE, data, (err) => { if (err) throw err; });
|
||||
};
|
||||
|
||||
var child = spawn(util.format('%s%s/osrm-routed', this.scope.LOAD_LIBRARIES, this.scope.BIN_PATH), [this.inputFile, util.format('-p%d', this.scope.OSRM_PORT)]);
|
||||
var child = spawn(util.format('%s/osrm-routed', this.scope.BIN_PATH), [this.inputFile, util.format('-p%d', this.scope.OSRM_PORT)]);
|
||||
this.scope.pid = child.pid;
|
||||
child.stdout.on('data', writeToLog);
|
||||
child.stderr.on('data', writeToLog);
|
||||
@@ -122,7 +123,7 @@ var OSRMDatastoreLoader = class extends OSRMBaseLoader {
|
||||
fs.appendFile(this.scope.OSRM_ROUTED_LOG_FILE, data, (err) => { if (err) throw err; });
|
||||
};
|
||||
|
||||
var child = spawn(util.format('%s%s/osrm-routed', this.scope.LOAD_LIBRARIES, this.scope.BIN_PATH), ['--shared-memory=1', util.format('-p%d', this.scope.OSRM_PORT)]);
|
||||
var child = spawn(util.format('%s/osrm-routed', this.scope.BIN_PATH), ['--shared-memory=1', util.format('-p%d', this.scope.OSRM_PORT)]);
|
||||
this.child = child;
|
||||
this.scope.pid = child.pid;
|
||||
child.stdout.on('data', writeToLog);
|
||||
@@ -148,7 +149,7 @@ module.exports = {
|
||||
this.loader = new OSRMDirectLoader(this.scope);
|
||||
this.loader.load(inputFile, callback);
|
||||
} else {
|
||||
throw new Error('*** Unknown load method ' + method);
|
||||
callback(new Error('*** Unknown load method ' + method));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var Timeout = require('node-timeout');
|
||||
var request = require('request');
|
||||
|
||||
@@ -137,8 +139,44 @@ module.exports = function () {
|
||||
return this.extractInstructionList(instructions, s => s.name);
|
||||
};
|
||||
|
||||
this.pronunciationList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, s => s.pronunciation || '');
|
||||
};
|
||||
|
||||
this.destinationsList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, s => s.destinations || '');
|
||||
};
|
||||
|
||||
this.bearingList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, s => s.maneuver.bearing_after);
|
||||
return this.extractInstructionList(instructions, s => s.maneuver.bearing_before + '->' + s.maneuver.bearing_after);
|
||||
};
|
||||
|
||||
this.annotationList = (instructions) => {
|
||||
function zip(list_1, list_2)
|
||||
{
|
||||
let pairs = [];
|
||||
for (let i = 0; i < list_1.length; ++i) {
|
||||
pairs.push([list_1[i], list_2[i]]);
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
return instructions.legs.map(l => {return zip(l.annotation.duration, l.annotation.distance).map(p => { return p.join(':'); }).join(','); }).join(',');
|
||||
};
|
||||
|
||||
this.OSMIDList = (instructions) => {
|
||||
// OSM node IDs also come from the annotation list
|
||||
return instructions.legs.map(l => l.annotation.nodes.map(n => n.toString()).join(',')).join(',');
|
||||
};
|
||||
|
||||
this.lanesList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, instruction => {
|
||||
if( 'lanes' in instruction.maneuver )
|
||||
{
|
||||
return instruction.maneuver.lanes.map( p => { return (p.indications).join(';') + ':' + p.valid; } ).join(' ');
|
||||
} else
|
||||
{
|
||||
return '';
|
||||
}});
|
||||
};
|
||||
|
||||
this.turnList = (instructions) => {
|
||||
@@ -168,6 +206,19 @@ module.exports = function () {
|
||||
.join(',');
|
||||
};
|
||||
|
||||
this.intersectionList = (instructions) => {
|
||||
return instructions.legs.reduce((m, v) => m.concat(v.steps), [])
|
||||
.map( v => {
|
||||
return v.intersections
|
||||
.map( intersection => {
|
||||
var string = intersection.entry[0]+':'+intersection.bearings[0], i;
|
||||
for( i = 1; i < intersection.bearings.length; ++i )
|
||||
string = string + ' ' + intersection.entry[i]+':'+intersection.bearings[i];
|
||||
return string;
|
||||
}).join(',');
|
||||
}).join(';');
|
||||
};
|
||||
|
||||
this.modeList = (instructions) => {
|
||||
return this.extractInstructionList(instructions, s => s.mode);
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@ module.exports = function () {
|
||||
opts = opts.replace('{profile}', [this.PROFILES_PATH, this.profile + '.lua'].join('/'));
|
||||
}
|
||||
|
||||
var cmd = util.format('%s%s%s/%s%s%s %s 2>%s', this.QQ, this.LOAD_LIBRARIES, this.BIN_PATH, bin, this.EXE, this.QQ, opts, this.ERROR_LOG_FILE);
|
||||
var cmd = util.format('%s%s/%s%s%s %s 2>%s', this.QQ, this.BIN_PATH, bin, this.EXE, this.QQ, opts, this.ERROR_LOG_FILE);
|
||||
process.chdir(this.TEST_FOLDER);
|
||||
exec(cmd, (err, stdout, stderr) => {
|
||||
this.stdout = stdout.toString();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
var assert = require('assert');
|
||||
|
||||
@@ -31,19 +33,24 @@ module.exports = function () {
|
||||
var afterRequest = (err, res, body) => {
|
||||
if (err) return cb(err);
|
||||
if (body && body.length) {
|
||||
var instructions, bearings, turns, modes, times, distances, summary;
|
||||
let destinations, pronunciations, instructions, bearings, turns, modes, times,
|
||||
distances, summary, intersections, lanes;
|
||||
|
||||
var json = JSON.parse(body);
|
||||
let json = JSON.parse(body);
|
||||
|
||||
var hasRoute = json.code === 'Ok';
|
||||
let hasRoute = json.code === 'Ok';
|
||||
|
||||
if (hasRoute) {
|
||||
instructions = this.wayList(json.routes[0]);
|
||||
pronunciations = this.pronunciationList(json.routes[0]);
|
||||
destinations = this.destinationsList(json.routes[0]);
|
||||
bearings = this.bearingList(json.routes[0]);
|
||||
turns = this.turnList(json.routes[0]);
|
||||
intersections = this.intersectionList(json.routes[0]);
|
||||
modes = this.modeList(json.routes[0]);
|
||||
times = this.timeList(json.routes[0]);
|
||||
distances = this.distanceList(json.routes[0]);
|
||||
lanes = this.lanesList(json.routes[0]);
|
||||
summary = this.summary(json.routes[0]);
|
||||
}
|
||||
|
||||
@@ -97,6 +104,10 @@ module.exports = function () {
|
||||
got.time = instructions ? util.format('%ds', time) : '';
|
||||
}
|
||||
|
||||
if (headers.has('lanes')) {
|
||||
got.lanes = (lanes || '').trim();
|
||||
}
|
||||
|
||||
if (headers.has('speed')) {
|
||||
if (row.speed !== '' && instructions) {
|
||||
if (!row.speed.match(/\d+ km\/h/))
|
||||
@@ -108,6 +119,10 @@ module.exports = function () {
|
||||
}
|
||||
}
|
||||
|
||||
if (headers.has('intersections')) {
|
||||
got.intersections = (intersections || '').trim();
|
||||
}
|
||||
|
||||
var putValue = (key, value) => {
|
||||
if (headers.has(key)) got[key] = instructions ? value : '';
|
||||
};
|
||||
@@ -117,6 +132,8 @@ module.exports = function () {
|
||||
putValue('modes', modes);
|
||||
putValue('times', times);
|
||||
putValue('distances', distances);
|
||||
putValue('pronunciations', pronunciations);
|
||||
putValue('destinations', destinations);
|
||||
}
|
||||
|
||||
var ok = true;
|
||||
|
||||
@@ -3,6 +3,7 @@ Feature: Alternative route
|
||||
|
||||
Background:
|
||||
Given the profile "testbot"
|
||||
And a grid size of 200 meters
|
||||
|
||||
And the node map
|
||||
| | b | c | d | | |
|
||||
@@ -17,11 +18,11 @@ Feature: Alternative route
|
||||
| dz |
|
||||
| ag |
|
||||
| gh |
|
||||
| ck |
|
||||
| kh |
|
||||
| hi |
|
||||
| ij |
|
||||
| jz |
|
||||
| ck |
|
||||
| kh |
|
||||
|
||||
Scenario: Enabled alternative
|
||||
Given the query options
|
||||
|
||||
@@ -56,7 +56,7 @@ Feature: Basic Routing
|
||||
|
||||
Scenario: Two ways connected in a straight line
|
||||
Given the node map
|
||||
| a | b | c |
|
||||
| a | | b | | c |
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
@@ -233,7 +233,7 @@ Feature: Basic Routing
|
||||
| d | a | abcd,abcd |
|
||||
| a | m | aeim,aeim |
|
||||
| m | a | aeim,aeim |
|
||||
|
||||
|
||||
Scenario: Testbot - Triangle challenge
|
||||
Given the node map
|
||||
| | | | d |
|
||||
@@ -251,3 +251,39 @@ Feature: Basic Routing
|
||||
| from | to | route |
|
||||
| d | c | de,ce,ce |
|
||||
| e | d | de,de |
|
||||
|
||||
Scenario: Ambiguous edge weights - Use minimal edge weight
|
||||
Given the node map
|
||||
| a | b |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| ab | tertiary | |
|
||||
| ab | primary | |
|
||||
| ab | secondary | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
| a | b | , | 10s |
|
||||
| b | a | , | 10s |
|
||||
|
||||
Scenario: Ambiguous edge names - Use lexicographically smallest name
|
||||
Given the node map
|
||||
| a | b | c |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| ab | primary | |
|
||||
| ab | primary | Αβγ |
|
||||
| ab | primary | |
|
||||
| ab | primary | Abc |
|
||||
| ab | primary | |
|
||||
| ab | primary | Абв |
|
||||
| bc | primary | Ηθι |
|
||||
| bc | primary | Δεζ |
|
||||
| bc | primary | Где |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| a | c | Abc,Δεζ,Δεζ |
|
||||
| c | a | Δεζ,Abc,Abc |
|
||||
|
||||
@@ -14,8 +14,8 @@ Feature: Compass bearing
|
||||
| ab |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | bearing |
|
||||
| a | b | ab,ab | 315,0 |
|
||||
| from | to | route | bearing |
|
||||
| a | b | ab,ab | 0->315,315->0|
|
||||
|
||||
Scenario: Bearing when going west
|
||||
Given the node map
|
||||
@@ -26,8 +26,8 @@ Feature: Compass bearing
|
||||
| ab |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | bearing |
|
||||
| a | b | ab,ab | 270,0 |
|
||||
| from | to | route | bearing |
|
||||
| a | b | ab,ab | 0->270,270->0|
|
||||
|
||||
Scenario: Bearing af 45 degree intervals
|
||||
Given the node map
|
||||
@@ -48,21 +48,21 @@ Feature: Compass bearing
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | bearing |
|
||||
| x | a | xa,xa | 0,0 |
|
||||
| x | b | xb,xb | 315,0 |
|
||||
| x | c | xc,xc | 270,0 |
|
||||
| x | d | xd,xd | 225,0 |
|
||||
| x | e | xe,xe | 180,0 |
|
||||
| x | f | xf,xf | 135,0 |
|
||||
| x | g | xg,xg | 90,0 |
|
||||
| x | h | xh,xh | 45,0 |
|
||||
| x | a | xa,xa | 0->0,0->0|
|
||||
| x | b | xb,xb | 0->315,315->0|
|
||||
| x | c | xc,xc | 0->270,270->0|
|
||||
| x | d | xd,xd | 0->225,225->0|
|
||||
| x | e | xe,xe | 0->180,180->0|
|
||||
| x | f | xf,xf | 0->135,135->0|
|
||||
| x | g | xg,xg | 0->90,90->0|
|
||||
| x | h | xh,xh | 0->45,45->0|
|
||||
|
||||
Scenario: Bearing in a roundabout
|
||||
Given the node map
|
||||
| | d | c | |
|
||||
| k | d | c | j |
|
||||
| e | | | b |
|
||||
| f | | | a |
|
||||
| | g | h | |
|
||||
| l | g | h | i |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
@@ -74,16 +74,26 @@ Feature: Compass bearing
|
||||
| fg | yes |
|
||||
| gh | yes |
|
||||
| ha | yes |
|
||||
| dk | no |
|
||||
| ke | no |
|
||||
| fl | no |
|
||||
| lg | no |
|
||||
| hi | no |
|
||||
| ia | no |
|
||||
| bj | no |
|
||||
| cj | no |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | bearing |
|
||||
| c | b | cd,de,ef,fg,gh,ha,ab,ab | 270,225,180,135,90,45,0,0 |
|
||||
| g | f | gh,ha,ab,bc,cd,de,ef,ef | 90,45,0,315,270,225,180,0 |
|
||||
| from | to | route | bearing |
|
||||
| c | b | cd,de,ef,fg,gh,ha,ab,ab | 0->270,270->225,225->180,180->135,135->90,90->45,45->0,0->0 |
|
||||
| g | f | gh,ha,ab,bc,cd,de,ef,ef | 0->90,90->45,45->0,0->315,315->270,270->225,225->180,180->0 |
|
||||
|
||||
Scenario: Bearing should stay constant when zig-zagging
|
||||
Given the node map
|
||||
| i | j | k | |
|
||||
| b | d | f | h |
|
||||
| a | c | e | g |
|
||||
| | m | n | o |
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
@@ -94,10 +104,16 @@ Feature: Compass bearing
|
||||
| ef |
|
||||
| fg |
|
||||
| gh |
|
||||
| bi |
|
||||
| cm |
|
||||
| dj |
|
||||
| en |
|
||||
| fk |
|
||||
| go |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | bearing |
|
||||
| a | h | ab,bc,cd,de,ef,fg,gh,gh | 0,135,0,135,0,135,0,0 |
|
||||
| a | h | ab,bc,cd,de,ef,fg,gh,gh | 0->0,0->135,135->0,0->135,135->0,0->135,135->0,0->0 |
|
||||
|
||||
Scenario: Bearings on an east-west way.
|
||||
Given the node map
|
||||
@@ -108,37 +124,37 @@ Feature: Compass bearing
|
||||
| abcdef |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | bearing |
|
||||
| a | b | abcdef,abcdef | 90,0 |
|
||||
| a | c | abcdef,abcdef | 90,0 |
|
||||
| a | d | abcdef,abcdef | 90,0 |
|
||||
| a | e | abcdef,abcdef | 90,0 |
|
||||
| a | f | abcdef,abcdef | 90,0 |
|
||||
| b | a | abcdef,abcdef | 270,0 |
|
||||
| b | c | abcdef,abcdef | 90,0 |
|
||||
| b | d | abcdef,abcdef | 90,0 |
|
||||
| b | e | abcdef,abcdef | 90,0 |
|
||||
| b | f | abcdef,abcdef | 90,0 |
|
||||
| c | a | abcdef,abcdef | 270,0 |
|
||||
| c | b | abcdef,abcdef | 270,0 |
|
||||
| c | d | abcdef,abcdef | 90,0 |
|
||||
| c | e | abcdef,abcdef | 90,0 |
|
||||
| c | f | abcdef,abcdef | 90,0 |
|
||||
| d | a | abcdef,abcdef | 270,0 |
|
||||
| d | b | abcdef,abcdef | 270,0 |
|
||||
| d | c | abcdef,abcdef | 270,0 |
|
||||
| d | e | abcdef,abcdef | 90,0 |
|
||||
| d | f | abcdef,abcdef | 90,0 |
|
||||
| e | a | abcdef,abcdef | 270,0 |
|
||||
| e | b | abcdef,abcdef | 270,0 |
|
||||
| e | c | abcdef,abcdef | 270,0 |
|
||||
| e | d | abcdef,abcdef | 270,0 |
|
||||
| e | f | abcdef,abcdef | 90,0 |
|
||||
| f | a | abcdef,abcdef | 270,0 |
|
||||
| f | b | abcdef,abcdef | 270,0 |
|
||||
| f | c | abcdef,abcdef | 270,0 |
|
||||
| f | d | abcdef,abcdef | 270,0 |
|
||||
| f | e | abcdef,abcdef | 270,0 |
|
||||
| from | to | route | bearing |
|
||||
| a | b | abcdef,abcdef | 0->90,90->0 |
|
||||
| a | c | abcdef,abcdef | 0->90,90->0 |
|
||||
| a | d | abcdef,abcdef | 0->90,90->0 |
|
||||
| a | e | abcdef,abcdef | 0->90,90->0 |
|
||||
| a | f | abcdef,abcdef | 0->90,90->0 |
|
||||
| b | a | abcdef,abcdef | 0->270,270->0 |
|
||||
| b | c | abcdef,abcdef | 0->90,90->0 |
|
||||
| b | d | abcdef,abcdef | 0->90,90->0 |
|
||||
| b | e | abcdef,abcdef | 0->90,90->0 |
|
||||
| b | f | abcdef,abcdef | 0->90,90->0 |
|
||||
| c | a | abcdef,abcdef | 0->270,270->0 |
|
||||
| c | b | abcdef,abcdef | 0->270,270->0 |
|
||||
| c | d | abcdef,abcdef | 0->90,90->0 |
|
||||
| c | e | abcdef,abcdef | 0->90,90->0 |
|
||||
| c | f | abcdef,abcdef | 0->90,90->0 |
|
||||
| d | a | abcdef,abcdef | 0->270,270->0 |
|
||||
| d | b | abcdef,abcdef | 0->270,270->0 |
|
||||
| d | c | abcdef,abcdef | 0->270,270->0 |
|
||||
| d | e | abcdef,abcdef | 0->90,90->0 |
|
||||
| d | f | abcdef,abcdef | 0->90,90->0 |
|
||||
| e | a | abcdef,abcdef | 0->270,270->0 |
|
||||
| e | b | abcdef,abcdef | 0->270,270->0 |
|
||||
| e | c | abcdef,abcdef | 0->270,270->0 |
|
||||
| e | d | abcdef,abcdef | 0->270,270->0 |
|
||||
| e | f | abcdef,abcdef | 0->90,90->0 |
|
||||
| f | a | abcdef,abcdef | 0->270,270->0 |
|
||||
| f | b | abcdef,abcdef | 0->270,270->0 |
|
||||
| f | c | abcdef,abcdef | 0->270,270->0 |
|
||||
| f | d | abcdef,abcdef | 0->270,270->0 |
|
||||
| f | e | abcdef,abcdef | 0->270,270->0 |
|
||||
|
||||
Scenario: Bearings at high latitudes
|
||||
# The coordinas below was calculated using http://www.movable-type.co.uk/scripts/latlong.html,
|
||||
@@ -161,19 +177,19 @@ Feature: Compass bearing
|
||||
| bd |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | bearing |
|
||||
| a | b | ab,ab | 0,0 |
|
||||
| b | c | bc,bc | 90,0 |
|
||||
| c | d | cd,cd | 180,0 |
|
||||
| d | a | da,da | 270,0 |
|
||||
| b | a | ab,ab | 180,0 |
|
||||
| c | b | bc,bc | 270,0 |
|
||||
| d | c | cd,cd | 0,0 |
|
||||
| a | d | da,da | 90,0 |
|
||||
| a | c | ac,ac | 45,0 |
|
||||
| c | a | ac,ac | 225,0 |
|
||||
| b | d | bd,bd | 135,0 |
|
||||
| d | b | bd,bd | 315,0 |
|
||||
| from | to | route | bearing |
|
||||
| a | b | ab,ab | 0->0,0->0 |
|
||||
| b | c | bc,bc | 0->90,90->0 |
|
||||
| c | d | cd,cd | 0->180,180->0 |
|
||||
| d | a | da,da | 0->270,270->0 |
|
||||
| b | a | ab,ab | 0->180,180->0 |
|
||||
| c | b | bc,bc | 0->270,270->0 |
|
||||
| d | c | cd,cd | 0->0,0->0 |
|
||||
| a | d | da,da | 0->90,90->0 |
|
||||
| a | c | ac,ac | 0->45,45->0 |
|
||||
| c | a | ac,ac | 0->225,225->0 |
|
||||
| b | d | bd,bd | 0->135,135->0 |
|
||||
| d | b | bd,bd | 0->315,315->0 |
|
||||
|
||||
Scenario: Bearings at high negative latitudes
|
||||
# The coordinas below was calculated using http://www.movable-type.co.uk/scripts/latlong.html,
|
||||
@@ -196,16 +212,16 @@ Feature: Compass bearing
|
||||
| bd |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | bearing |
|
||||
| a | b | ab,ab | 180,0 |
|
||||
| b | c | bc,bc | 90,0 |
|
||||
| c | d | cd,cd | 0,0 |
|
||||
| d | a | da,da | 270,0 |
|
||||
| b | a | ab,ab | 0,0 |
|
||||
| c | b | bc,bc | 270,0 |
|
||||
| d | c | cd,cd | 180,0 |
|
||||
| a | d | da,da | 90,0 |
|
||||
| a | c | ac,ac | 135,0 |
|
||||
| c | a | ac,ac | 315,0 |
|
||||
| b | d | bd,bd | 45,0 |
|
||||
| d | b | bd,bd | 225,0 |
|
||||
| from | to | route | bearing |
|
||||
| a | b | ab,ab | 0->180,180->0 |
|
||||
| b | c | bc,bc | 0->90,90->0 |
|
||||
| c | d | cd,cd | 0->0,0->0 |
|
||||
| d | a | da,da | 0->270,270->0 |
|
||||
| b | a | ab,ab | 0->0,0->0 |
|
||||
| c | b | bc,bc | 0->270,270->0 |
|
||||
| d | c | cd,cd | 0->180,180->0 |
|
||||
| a | d | da,da | 0->90,90->0 |
|
||||
| a | c | ac,ac | 0->135,135->0 |
|
||||
| c | a | ac,ac | 0->315,315->0 |
|
||||
| b | d | bd,bd | 0->45,45->0 |
|
||||
| d | b | bd,bd | 0->225,225->0 |
|
||||
|
||||
@@ -14,12 +14,12 @@ Feature: Bearing parameter
|
||||
| ad |
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | bearing |
|
||||
| b | c | 90 90 | ad,ad | 90,0 |
|
||||
| b | c | 180 90 | | |
|
||||
| b | c | 80 100 | ad,ad | 90,0 |
|
||||
| b | c | 79 100 | | |
|
||||
| b | c | 79,11 100 | ad,ad | 90,0 |
|
||||
| from | to | bearings | route | bearing |
|
||||
| b | c | 90 90 | ad,ad | 0->90,90->0|
|
||||
| b | c | 180 90 | | |
|
||||
| b | c | 80 100 | ad,ad | 0->90,90->0|
|
||||
| b | c | 79 100 | | |
|
||||
| b | c | 79,11 100 | ad,ad | 0->90,90->0|
|
||||
|
||||
Scenario: Testbot - Intial bearing in simple case
|
||||
Given the node map
|
||||
@@ -33,18 +33,18 @@ Feature: Bearing parameter
|
||||
| bc |
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | bearing |
|
||||
| 0 | c | 0 0 | | |
|
||||
| 0 | c | 45 45 | bc,bc | 45 ~3% |
|
||||
| 0 | c | 85 85 | | |
|
||||
| 0 | c | 95 95 | | |
|
||||
| 0 | c | 135 135 | ac,ac | 135 ~1% |
|
||||
| 0 | c | 180 180 | | |
|
||||
| from | to | bearings | route | bearing |
|
||||
| 0 | c | 0 0 | | |
|
||||
| 0 | c | 45 45 | bc,bc | 0->44,44->0 +- 1 |
|
||||
| 0 | c | 85 85 | | |
|
||||
| 0 | c | 95 95 | | |
|
||||
| 0 | c | 135 135 | ac,ac | 0->135,135->0 +- 1|
|
||||
| 0 | c | 180 180 | | |
|
||||
|
||||
Scenario: Testbot - Initial bearing on split way
|
||||
Given the node map
|
||||
| d | | | | | 1 | | | | | c |
|
||||
| a | | | | | 0 | | | | | b |
|
||||
| g | d | | | | | 1 | | | | | c | f |
|
||||
| h | a | | | | | 0 | | | | | b | e |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
@@ -52,23 +52,27 @@ Feature: Bearing parameter
|
||||
| bc | yes |
|
||||
| cd | yes |
|
||||
| da | yes |
|
||||
| be | yes |
|
||||
| fc | yes |
|
||||
| dg | yes |
|
||||
| ha | yes |
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | bearing |
|
||||
| 0 | b | 10 10 | bc,bc | 0,0 |
|
||||
| 0 | b | 90 90 | ab,ab | 90,0 |
|
||||
| from | to | bearings | route | bearing |
|
||||
| 0 | b | 10 10 | bc,bc | 0->0,0->0 |
|
||||
| 0 | b | 90 90 | ab,ab | 0->90,90->0 |
|
||||
# The returned bearing is wrong here, it's based on the snapped
|
||||
# coordinates, not the acutal edge bearing. This should be
|
||||
# fixed one day, but it's only a problem when we snap two vias
|
||||
# to the same point - DP
|
||||
#| 0 | b | 170 170 | da | 180 |
|
||||
#| 0 | b | 189 189 | da | 180 |
|
||||
| 0 | 1 | 90 270 | ab,bc,cd,cd | 90,0,270,0 |
|
||||
| 1 | d | 10 10 | bc,bc | 0,0 |
|
||||
| 1 | d | 90 90 | ab,bc,cd,da,da | 90,0,270,180,0 |
|
||||
| 1 | 0 | 189 189 | da,da | 180,0 |
|
||||
| 1 | d | 270 270 | cd,cd | 270,0 |
|
||||
| 1 | d | 349 349 | | |
|
||||
#| 0 | b | 170 170 | da | 180 |
|
||||
#| 0 | b | 189 189 | da | 180 |
|
||||
| 0 | 1 | 90 270 | ab,bc,cd,cd | 0->90,90->0,0->270,270->0 |
|
||||
| 1 | d | 10 10 | bc,bc | 0->0,0->0 |
|
||||
| 1 | d | 90 90 | ab,bc,cd,da,da | 0->90,90->0,0->270,270->180,180->0 |
|
||||
| 1 | 0 | 189 189 | da,da | 0->180,180->0 |
|
||||
| 1 | d | 270 270 | cd,cd | 0->270,270->0 |
|
||||
| 1 | d | 349 349 | | |
|
||||
|
||||
Scenario: Testbot - Initial bearing in all direction
|
||||
Given the node map
|
||||
@@ -81,31 +85,31 @@ Feature: Bearing parameter
|
||||
| f | | | e | | | d |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| ia | yes |
|
||||
| jb | yes |
|
||||
| kc | yes |
|
||||
| ld | yes |
|
||||
| me | yes |
|
||||
| nf | yes |
|
||||
| og | yes |
|
||||
| ph | yes |
|
||||
| ab | yes |
|
||||
| bc | yes |
|
||||
| cd | yes |
|
||||
| de | yes |
|
||||
| ef | yes |
|
||||
| fg | yes |
|
||||
| gh | yes |
|
||||
| ha | yes |
|
||||
| nodes | oneway | name |
|
||||
| ia | yes | ia |
|
||||
| jb | yes | jb |
|
||||
| kc | yes | kc |
|
||||
| ld | yes | ld |
|
||||
| me | yes | me |
|
||||
| nf | yes | nf |
|
||||
| og | yes | og |
|
||||
| ph | yes | ph |
|
||||
| ab | yes | ring |
|
||||
| bc | yes | ring |
|
||||
| cd | yes | ring |
|
||||
| de | yes | ring |
|
||||
| ef | yes | ring |
|
||||
| fg | yes | ring |
|
||||
| gh | yes | ring |
|
||||
| ha | yes | ring |
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | bearing |
|
||||
| 0 | q | 0 90 | ia,ab,bc,cd,de,ef,fg,gh,ha,ha | 0,90,180,180,270,270,0,0,90,0 |
|
||||
| 0 | a | 45 90 | jb,bc,cd,de,ef,fg,gh,ha,ha | 45,180,180,270,270,0,0,90,0 |
|
||||
| 0 | q | 90 90 | kc,cd,de,ef,fg,gh,ha,ha | 90,180,270,270,0,0,90,0 |
|
||||
| 0 | a | 135 90 | ld,de,ef,fg,gh,ha,ha | 135,270,270,0,0,90,0 |
|
||||
| 0 | a | 180 90 | me,ef,fg,gh,ha,ha | 180,270,0,0,90,0 |
|
||||
| 0 | a | 225 90 | nf,fg,gh,ha,ha | 225,0,0,90,0 |
|
||||
| 0 | a | 270 90 | og,gh,ha,ha | 270,0,90,0 |
|
||||
| 0 | a | 315 90 | ph,ha,ha | 315,90,0 |
|
||||
| from | to | bearings | route | bearing |
|
||||
| 0 | q | 0 90 | ia,ring,ring,ring,ring,ring | 0->0,0->90,180->270,270->0,0->90,90->0 |
|
||||
| 0 | a | 45 90 | jb,ring,ring,ring,ring,ring | 0->45,45->180,180->270,270->0,0->90,90->0 |
|
||||
| 0 | q | 90 90 | kc,ring,ring,ring,ring | 0->90,90->180,270->0,0->90,90->0 |
|
||||
| 0 | a | 135 90 | ld,ring,ring,ring,ring | 0->135,135->270,270->0,0->90,90->0 |
|
||||
| 0 | a | 180 90 | me,ring,ring,ring | 0->180,180->270,0->90,90->0 |
|
||||
| 0 | a | 225 90 | nf,ring,ring,ring | 0->225,225->0,0->90,90->0 |
|
||||
| 0 | a | 270 90 | og,ring,ring | 0->270,270->0,90->0 |
|
||||
| 0 | a | 315 90 | ph,ring,ring | 0->315,315->90,90->0 |
|
||||
|
||||
@@ -18,5 +18,5 @@ Feature: Geometry Compression
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | distance | speed |
|
||||
| b | e | abcdef,abcdef | 589m | 36 km/h |
|
||||
| e | b | abcdef,abcdef | 589m | 36 km/h |
|
||||
| b | e | abcdef,abcdef | 588.8m | 36 km/h |
|
||||
| e | b | abcdef,abcdef | 588.8m | 36 km/h |
|
||||
|
||||
@@ -3,6 +3,7 @@ Feature: U-turns at via points
|
||||
|
||||
Background:
|
||||
Given the profile "testbot"
|
||||
Given a grid size of 250 meters
|
||||
|
||||
Scenario: Continue straight at waypoints enabled by default
|
||||
Given the node map
|
||||
|
||||
@@ -24,3 +24,18 @@ Feature: Fixed bugs, kept to check for regressions
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| x | y | abc,abc |
|
||||
|
||||
Scenario: Step trimming with very short segments
|
||||
Given a grid size of 0.1 meters
|
||||
Given the node map
|
||||
| a | 1 | b | c | d | 2 | e |
|
||||
|
||||
Given the ways
|
||||
| nodes | oneway |
|
||||
| ab | yes |
|
||||
| bcd | yes |
|
||||
| de | yes |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| 1 | 2 | bcd,bcd |
|
||||
|
||||
@@ -75,12 +75,12 @@ Feature: Avoid weird loops caused by rounding errors
|
||||
And the node map
|
||||
| a | | |
|
||||
| b | e | |
|
||||
| | | 1 |
|
||||
| h | | 1 |
|
||||
| | | |
|
||||
| | | 2 |
|
||||
| | | |
|
||||
| g | | |
|
||||
| | c | f |
|
||||
| | d | |
|
||||
| d | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
@@ -90,6 +90,8 @@ Feature: Avoid weird loops caused by rounding errors
|
||||
| be | primary |
|
||||
| ef | primary |
|
||||
| cf | primary |
|
||||
| cg | primary |
|
||||
| bh | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route |
|
||||
|
||||
@@ -104,3 +104,45 @@ Feature: Basic Map Matching
|
||||
| trace | matchings |
|
||||
| dcba | hg,gf,fe |
|
||||
| efgh | ab,bc,cd |
|
||||
|
||||
Scenario: Testbot - Duration details
|
||||
Given the query options
|
||||
| annotations | true |
|
||||
|
||||
Given the node map
|
||||
| a | b | c | d | e | | g | h |
|
||||
| | | i | | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| abcdegh | no |
|
||||
| ci | no |
|
||||
|
||||
When I match I should get
|
||||
| trace | matchings | annotation |
|
||||
| abeh | abcedgh | 1:9.897633,0:0,1:10.008842,1:10.008842,1:10.008842,0:0,2:20.017685,1:10.008842 |
|
||||
| abci | abc,ci | 1:9.897633,0:0,1:10.008842,0:0.111209,1:10.010367 |
|
||||
|
||||
# The following is the same as the above, but separated for readability (line length)
|
||||
When I match I should get
|
||||
| trace | matchings | OSM IDs |
|
||||
| abeh | abcedgh | 1,2,3,2,3,4,5,4,5,6,7 |
|
||||
| abci | abc,ci | 1,2,3,2,3,8,3,8 |
|
||||
|
||||
Scenario: Testbot - Geometry details
|
||||
Given the query options
|
||||
| overview | full |
|
||||
| geometries | polyline |
|
||||
|
||||
Given the node map
|
||||
| a | b | c |
|
||||
| | d | |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| abc | no |
|
||||
| bd | no |
|
||||
|
||||
When I match I should get
|
||||
| trace | matchings | geometry |
|
||||
| abd | abd | 1,1,1,1.00009,1,1.00009,0.99991,1.00009 |
|
||||
|
||||
@@ -11,6 +11,7 @@ Feature: Testbot - Travel mode
|
||||
|
||||
Background:
|
||||
Given the profile "testbot"
|
||||
Given a grid size of 200 meters
|
||||
|
||||
Scenario: Testbot - Always announce mode change
|
||||
Given the node map
|
||||
@@ -72,9 +73,9 @@ Feature: Testbot - Travel mode
|
||||
| ab | steps |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | modes | time |
|
||||
| 0 | 1 | ab,ab | steps down,steps down | 60s +-1 |
|
||||
| 1 | 0 | ab,ab | steps up,steps up | 60s +-1 |
|
||||
| from | to | route | modes | time |
|
||||
| 0 | 1 | ab,ab | steps down,steps down | 120s +-1 |
|
||||
| 1 | 0 | ab,ab | steps up,steps up | 120s +-1 |
|
||||
|
||||
@oneway
|
||||
Scenario: Testbot - Modes for oneway, different forward/backward speeds
|
||||
|
||||
@@ -3,6 +3,7 @@ Feature: Testbot - oneways
|
||||
|
||||
Background:
|
||||
Given the profile "testbot"
|
||||
Given a grid size of 250 meters
|
||||
|
||||
Scenario: Routing on a oneway roundabout
|
||||
Given the node map
|
||||
@@ -59,8 +60,8 @@ Feature: Testbot - oneways
|
||||
|
||||
Scenario: Testbot - Around the Block
|
||||
Given the node map
|
||||
| a | b |
|
||||
| d | c |
|
||||
| | a | b | |
|
||||
| e | d | c | f |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway | foot |
|
||||
@@ -68,6 +69,8 @@ Feature: Testbot - oneways
|
||||
| bc | | no |
|
||||
| cd | | no |
|
||||
| da | | no |
|
||||
| de | | no |
|
||||
| cf | | no |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
|
||||
@@ -24,12 +24,12 @@ Feature: Projection to nearest point on road
|
||||
Scenario: Projection onto way at high latitudes, 1km distance
|
||||
When I route I should get
|
||||
| from | to | route | bearing | distance |
|
||||
| b | a | abc,abc | 225,0 +-1 | 1000m +- 7 |
|
||||
| b | c | abc,abc | 45,0 +-1 | 1000m +- 7 |
|
||||
| a | d | abc,abc | 45,0 +-1 | 1000m +- 7 |
|
||||
| d | a | abc,abc | 225,0 +-1 | 1000m +- 7 |
|
||||
| c | d | abc,abc | 225,0 +-1 | 1000m +- 8 |
|
||||
| d | c | abc,abc | 45 +-1 | 1000m +- 8 |
|
||||
| b | a | abc,abc | 0->225,225->0 | 1000m +- 7 |
|
||||
| b | c | abc,abc | 0->45,45->0 | 1000m +- 7 |
|
||||
| a | d | abc,abc | 0->45,45->0 | 1000m +- 7 |
|
||||
| d | a | abc,abc | 0->225,225->0 | 1000m +- 7 |
|
||||
| c | d | abc,abc | 0->225,224->0 | 1000m +- 8 |
|
||||
| d | c | abc,abc | 0->44,45->0 | 1000m +- 8 |
|
||||
|
||||
Scenario: Projection onto way at high latitudes, no distance
|
||||
When I route I should get
|
||||
|
||||
@@ -3,11 +3,12 @@ Feature: Basic Routing
|
||||
|
||||
Background:
|
||||
Given the profile "testbot"
|
||||
Given a grid size of 200 meters
|
||||
|
||||
@smallest
|
||||
Scenario: Checking
|
||||
Scenario: Checking
|
||||
Given the node map
|
||||
| a | b | | c | d | e |
|
||||
| a | b | 1 | c | d | e |
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
@@ -22,12 +23,13 @@ Feature: Basic Routing
|
||||
| e | a | de,cd,bc,ab,ab | de, bc |
|
||||
| a | b | ab,ab | ab |
|
||||
| b | d | bc,cd,cd | bc, cd |
|
||||
| 1 | c | bc,bc | bc |
|
||||
|
||||
@smallest
|
||||
Scenario: Check handling empty values
|
||||
Given the node map
|
||||
| a | b | | c | | d | f |
|
||||
| | | | | | e |
|
||||
| | | | | | e | |
|
||||
|
||||
And the ways
|
||||
| nodes | name |
|
||||
|
||||
@@ -145,14 +145,16 @@ Feature: Estimation of travel time
|
||||
|
||||
Scenario: Time of travel on a series of ways
|
||||
Given the node map
|
||||
| a | b | |
|
||||
| | c | d |
|
||||
| a | b | e |
|
||||
| f | c | d |
|
||||
|
||||
And the ways
|
||||
| nodes | highway |
|
||||
| ab | primary |
|
||||
| bc | primary |
|
||||
| cd | primary |
|
||||
| be | primary |
|
||||
| cf | primary |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
|
||||
@@ -85,13 +85,16 @@ Feature: Via points
|
||||
Scenario: Via points on ring of oneways
|
||||
# xa it to avoid only having a single ring, which cna trigger edge cases
|
||||
Given the node map
|
||||
| x | | | | | | |
|
||||
| a | 1 | b | 2 | c | 3 | d |
|
||||
| f | | | | | | e |
|
||||
| | x | | | | | | g | |
|
||||
| | a | 1 | b | 2 | c | 3 | d | |
|
||||
| i | f | | | | | | e | h |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| xa | |
|
||||
| if | |
|
||||
| gd | |
|
||||
| eh | |
|
||||
| ab | yes |
|
||||
| bc | yes |
|
||||
| cd | yes |
|
||||
@@ -110,13 +113,16 @@ Feature: Via points
|
||||
Scenario: Via points on ring on the same oneway
|
||||
# xa it to avoid only having a single ring, which cna trigger edge cases
|
||||
Given the node map
|
||||
| x | | | | |
|
||||
| a | 1 | 2 | 3 | b |
|
||||
| d | | | | c |
|
||||
| | x | | | | e | |
|
||||
| | a | 1 | 2 | 3 | b | |
|
||||
| g | d | | | | c | f |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| xa | |
|
||||
| eb | |
|
||||
| cf | |
|
||||
| dg | |
|
||||
| ab | yes |
|
||||
| bc | yes |
|
||||
| cd | yes |
|
||||
|
||||
@@ -32,11 +32,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "contractor/query_edge.hpp"
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "extractor/edge_based_node.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
#include "util/deallocating_vector.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
@@ -78,7 +78,7 @@ class Contractor
|
||||
private:
|
||||
ContractorConfig config;
|
||||
|
||||
std::size_t
|
||||
EdgeID
|
||||
LoadEdgeExpandedGraph(const std::string &edge_based_graph_path,
|
||||
util::DeallocatingVector<extractor::EdgeBasedEdge> &edge_based_edge_list,
|
||||
const std::string &edge_segment_lookup_path,
|
||||
|
||||
@@ -82,6 +82,9 @@ class IteratorbasedCRC32
|
||||
: "0"(crc), "c"(*str));
|
||||
++str;
|
||||
}
|
||||
#else
|
||||
(void)str;
|
||||
(void)len;
|
||||
#endif
|
||||
return crc;
|
||||
}
|
||||
@@ -95,8 +98,11 @@ class IteratorbasedCRC32
|
||||
}
|
||||
|
||||
#if defined(__MINGW64__) || defined(_MSC_VER) || !defined(__x86_64__)
|
||||
inline void
|
||||
__get_cpuid(int param, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) const
|
||||
inline void __get_cpuid(int /*param*/,
|
||||
unsigned * /*eax*/,
|
||||
unsigned * /*ebx*/,
|
||||
unsigned *ecx,
|
||||
unsigned * /*edx*/) const
|
||||
{
|
||||
*ecx = 0;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#ifndef GRAPH_CONTRACTOR_HPP
|
||||
#define GRAPH_CONTRACTOR_HPP
|
||||
|
||||
#include "contractor/query_edge.hpp"
|
||||
#include "util/binary_heap.hpp"
|
||||
#include "util/deallocating_vector.hpp"
|
||||
#include "util/dynamic_graph.hpp"
|
||||
#include "util/percent.hpp"
|
||||
#include "contractor/query_edge.hpp"
|
||||
#include "util/xor_fast_hash.hpp"
|
||||
#include "util/xor_fast_hash_storage.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/percent.hpp"
|
||||
#include "util/simple_logger.hpp"
|
||||
#include "util/timing_util.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
#include "util/xor_fast_hash.hpp"
|
||||
#include "util/xor_fast_hash_storage.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
@@ -165,14 +165,22 @@ class GraphContractor
|
||||
<< static_cast<unsigned int>(diter->target);
|
||||
}
|
||||
#endif
|
||||
edges.emplace_back(diter->source, diter->target,
|
||||
static_cast<unsigned int>(std::max(diter->weight, 1)), 1,
|
||||
diter->edge_id, false, diter->forward ? true : false,
|
||||
edges.emplace_back(diter->source,
|
||||
diter->target,
|
||||
static_cast<unsigned int>(std::max(diter->weight, 1)),
|
||||
1,
|
||||
diter->edge_id,
|
||||
false,
|
||||
diter->forward ? true : false,
|
||||
diter->backward ? true : false);
|
||||
|
||||
edges.emplace_back(diter->target, diter->source,
|
||||
static_cast<unsigned int>(std::max(diter->weight, 1)), 1,
|
||||
diter->edge_id, false, diter->backward ? true : false,
|
||||
edges.emplace_back(diter->target,
|
||||
diter->source,
|
||||
static_cast<unsigned int>(std::max(diter->weight, 1)),
|
||||
1,
|
||||
diter->edge_id,
|
||||
false,
|
||||
diter->backward ? true : false,
|
||||
diter->forward ? true : false);
|
||||
}
|
||||
// clear input vector
|
||||
@@ -276,8 +284,7 @@ class GraphContractor
|
||||
std::vector<RemainingNodeData> remaining_nodes(number_of_nodes);
|
||||
// initialize priorities in parallel
|
||||
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, InitGrainSize),
|
||||
[this, &remaining_nodes](const tbb::blocked_range<int> &range)
|
||||
{
|
||||
[this, &remaining_nodes](const tbb::blocked_range<int> &range) {
|
||||
for (int x = range.begin(), end = range.end(); x != end; ++x)
|
||||
{
|
||||
remaining_nodes[x].id = x;
|
||||
@@ -299,9 +306,8 @@ class GraphContractor
|
||||
|
||||
std::cout << "initializing elimination PQ ..." << std::flush;
|
||||
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, PQGrainSize),
|
||||
[this, &node_priorities, &node_depth,
|
||||
&thread_data_list](const tbb::blocked_range<int> &range)
|
||||
{
|
||||
[this, &node_priorities, &node_depth, &thread_data_list](
|
||||
const tbb::blocked_range<int> &range) {
|
||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||
for (int x = range.begin(), end = range.end(); x != end; ++x)
|
||||
{
|
||||
@@ -342,7 +348,8 @@ class GraphContractor
|
||||
// remaining graph
|
||||
std::vector<NodeID> new_node_id_from_orig_id_map(number_of_nodes, SPECIAL_NODEID);
|
||||
|
||||
for (const auto new_node_id : util::irange<std::size_t>(0UL, remaining_nodes.size()))
|
||||
for (const auto new_node_id :
|
||||
util::irange<std::size_t>(0UL, remaining_nodes.size()))
|
||||
{
|
||||
auto &node = remaining_nodes[new_node_id];
|
||||
BOOST_ASSERT(node_priorities.size() > node.id);
|
||||
@@ -352,7 +359,8 @@ class GraphContractor
|
||||
}
|
||||
|
||||
// build forward and backward renumbering map and remap ids in remaining_nodes
|
||||
for (const auto new_node_id : util::irange<std::size_t>(0UL, remaining_nodes.size()))
|
||||
for (const auto new_node_id :
|
||||
util::irange<std::size_t>(0UL, remaining_nodes.size()))
|
||||
{
|
||||
auto &node = remaining_nodes[new_node_id];
|
||||
// create renumbering maps in both directions
|
||||
@@ -378,7 +386,8 @@ class GraphContractor
|
||||
// node is not yet contracted.
|
||||
// add (renumbered) outgoing edges to new util::DynamicGraph.
|
||||
ContractorEdge new_edge = {new_node_id_from_orig_id_map[source],
|
||||
new_node_id_from_orig_id_map[target], data};
|
||||
new_node_id_from_orig_id_map[target],
|
||||
data};
|
||||
|
||||
new_edge.data.is_original_via_node_ID = true;
|
||||
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_node_id_from_orig_id_map[source],
|
||||
@@ -421,9 +430,8 @@ class GraphContractor
|
||||
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<std::size_t>(0, remaining_nodes.size(), IndependentGrainSize),
|
||||
[this, &node_priorities, &remaining_nodes,
|
||||
&thread_data_list](const tbb::blocked_range<std::size_t> &range)
|
||||
{
|
||||
[this, &node_priorities, &remaining_nodes, &thread_data_list](
|
||||
const tbb::blocked_range<std::size_t> &range) {
|
||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||
// determine independent node set
|
||||
for (auto i = range.begin(), end = range.end(); i != end; ++i)
|
||||
@@ -436,8 +444,7 @@ class GraphContractor
|
||||
|
||||
// sort all remaining nodes to the beginning of the sequence
|
||||
const auto begin_independent_nodes = stable_partition(
|
||||
remaining_nodes.begin(), remaining_nodes.end(), [](RemainingNodeData node_data)
|
||||
{
|
||||
remaining_nodes.begin(), remaining_nodes.end(), [](RemainingNodeData node_data) {
|
||||
return !node_data.is_independent;
|
||||
});
|
||||
auto begin_independent_nodes_idx =
|
||||
@@ -448,11 +455,10 @@ class GraphContractor
|
||||
{
|
||||
// write out contraction level
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<std::size_t>(begin_independent_nodes_idx,
|
||||
end_independent_nodes_idx, ContractGrainSize),
|
||||
[this, remaining_nodes, flushed_contractor,
|
||||
current_level](const tbb::blocked_range<std::size_t> &range)
|
||||
{
|
||||
tbb::blocked_range<std::size_t>(
|
||||
begin_independent_nodes_idx, end_independent_nodes_idx, ContractGrainSize),
|
||||
[this, remaining_nodes, flushed_contractor, current_level](
|
||||
const tbb::blocked_range<std::size_t> &range) {
|
||||
if (flushed_contractor)
|
||||
{
|
||||
for (int position = range.begin(), end = range.end(); position != end;
|
||||
@@ -475,26 +481,24 @@ class GraphContractor
|
||||
}
|
||||
|
||||
// contract independent nodes
|
||||
tbb::parallel_for(tbb::blocked_range<std::size_t>(begin_independent_nodes_idx,
|
||||
end_independent_nodes_idx,
|
||||
ContractGrainSize),
|
||||
[this, &remaining_nodes,
|
||||
&thread_data_list](const tbb::blocked_range<std::size_t> &range)
|
||||
{
|
||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||
for (int position = range.begin(), end = range.end();
|
||||
position != end; ++position)
|
||||
{
|
||||
const NodeID x = remaining_nodes[position].id;
|
||||
this->ContractNode<false>(data, x);
|
||||
}
|
||||
});
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<std::size_t>(
|
||||
begin_independent_nodes_idx, end_independent_nodes_idx, ContractGrainSize),
|
||||
[this, &remaining_nodes, &thread_data_list](
|
||||
const tbb::blocked_range<std::size_t> &range) {
|
||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||
for (int position = range.begin(), end = range.end(); position != end;
|
||||
++position)
|
||||
{
|
||||
const NodeID x = remaining_nodes[position].id;
|
||||
this->ContractNode<false>(data, x);
|
||||
}
|
||||
});
|
||||
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<int>(begin_independent_nodes_idx, end_independent_nodes_idx,
|
||||
DeleteGrainSize),
|
||||
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int> &range)
|
||||
{
|
||||
tbb::blocked_range<int>(
|
||||
begin_independent_nodes_idx, end_independent_nodes_idx, DeleteGrainSize),
|
||||
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int> &range) {
|
||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||
for (int position = range.begin(), end = range.end(); position != end;
|
||||
++position)
|
||||
@@ -507,8 +511,7 @@ class GraphContractor
|
||||
// make sure we really sort each block
|
||||
tbb::parallel_for(
|
||||
thread_data_list.data.range(),
|
||||
[&](const ThreadDataContainer::EnumerableThreadData::range_type &range)
|
||||
{
|
||||
[&](const ThreadDataContainer::EnumerableThreadData::range_type &range) {
|
||||
for (auto &data : range)
|
||||
tbb::parallel_sort(data->inserted_edges.begin(),
|
||||
data->inserted_edges.end());
|
||||
@@ -542,11 +545,11 @@ class GraphContractor
|
||||
if (!use_cached_node_priorities)
|
||||
{
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<int>(begin_independent_nodes_idx, end_independent_nodes_idx,
|
||||
tbb::blocked_range<int>(begin_independent_nodes_idx,
|
||||
end_independent_nodes_idx,
|
||||
NeighboursGrainSize),
|
||||
[this, &node_priorities, &remaining_nodes, &node_depth,
|
||||
&thread_data_list](const tbb::blocked_range<int> &range)
|
||||
{
|
||||
[this, &node_priorities, &remaining_nodes, &node_depth, &thread_data_list](
|
||||
const tbb::blocked_range<int> &range) {
|
||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||
for (int position = range.begin(), end = range.end(); position != end;
|
||||
++position)
|
||||
@@ -570,8 +573,7 @@ class GraphContractor
|
||||
if (orig_node_id_from_new_node_id_map.size() > 0)
|
||||
{
|
||||
tbb::parallel_for(tbb::blocked_range<int>(0, remaining_nodes.size(), InitGrainSize),
|
||||
[this, &remaining_nodes](const tbb::blocked_range<int> &range)
|
||||
{
|
||||
[this, &remaining_nodes](const tbb::blocked_range<int> &range) {
|
||||
for (int x = range.begin(), end = range.end(); x != end; ++x)
|
||||
{
|
||||
const auto orig_id = remaining_nodes[x].id;
|
||||
@@ -583,8 +585,7 @@ class GraphContractor
|
||||
else
|
||||
{
|
||||
tbb::parallel_for(tbb::blocked_range<int>(0, remaining_nodes.size(), InitGrainSize),
|
||||
[this, &remaining_nodes](const tbb::blocked_range<int> &range)
|
||||
{
|
||||
[this, &remaining_nodes](const tbb::blocked_range<int> &range) {
|
||||
for (int x = range.begin(), end = range.end(); x != end; ++x)
|
||||
{
|
||||
const auto orig_id = remaining_nodes[x].id;
|
||||
@@ -843,15 +844,25 @@ class GraphContractor
|
||||
// guarantees that source is not connected to another node that is
|
||||
// contracted
|
||||
node_weights[source] = path_distance; // make sure to prune better
|
||||
inserted_edges.emplace_back(
|
||||
source, target, path_distance,
|
||||
out_data.originalEdges + in_data.originalEdges, node, SHORTCUT_ARC,
|
||||
FORWARD_DIRECTION_ENABLED, REVERSE_DIRECTION_DISABLED);
|
||||
inserted_edges.emplace_back(source,
|
||||
target,
|
||||
path_distance,
|
||||
out_data.originalEdges +
|
||||
in_data.originalEdges,
|
||||
node,
|
||||
SHORTCUT_ARC,
|
||||
FORWARD_DIRECTION_ENABLED,
|
||||
REVERSE_DIRECTION_DISABLED);
|
||||
|
||||
inserted_edges.emplace_back(
|
||||
target, source, path_distance,
|
||||
out_data.originalEdges + in_data.originalEdges, node, SHORTCUT_ARC,
|
||||
FORWARD_DIRECTION_DISABLED, REVERSE_DIRECTION_ENABLED);
|
||||
inserted_edges.emplace_back(target,
|
||||
source,
|
||||
path_distance,
|
||||
out_data.originalEdges +
|
||||
in_data.originalEdges,
|
||||
node,
|
||||
SHORTCUT_ARC,
|
||||
FORWARD_DIRECTION_DISABLED,
|
||||
REVERSE_DIRECTION_ENABLED);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
@@ -867,8 +878,8 @@ class GraphContractor
|
||||
if (RUNSIMULATION)
|
||||
{
|
||||
const int constexpr SIMULATION_SEARCH_SPACE_SIZE = 1000;
|
||||
Dijkstra(max_distance, number_of_targets, SIMULATION_SEARCH_SPACE_SIZE, *data,
|
||||
node);
|
||||
Dijkstra(
|
||||
max_distance, number_of_targets, SIMULATION_SEARCH_SPACE_SIZE, *data, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -898,14 +909,22 @@ class GraphContractor
|
||||
}
|
||||
else
|
||||
{
|
||||
inserted_edges.emplace_back(source, target, path_distance,
|
||||
inserted_edges.emplace_back(source,
|
||||
target,
|
||||
path_distance,
|
||||
out_data.originalEdges + in_data.originalEdges,
|
||||
node, SHORTCUT_ARC, FORWARD_DIRECTION_ENABLED,
|
||||
node,
|
||||
SHORTCUT_ARC,
|
||||
FORWARD_DIRECTION_ENABLED,
|
||||
REVERSE_DIRECTION_DISABLED);
|
||||
|
||||
inserted_edges.emplace_back(target, source, path_distance,
|
||||
inserted_edges.emplace_back(target,
|
||||
source,
|
||||
path_distance,
|
||||
out_data.originalEdges + in_data.originalEdges,
|
||||
node, SHORTCUT_ARC, FORWARD_DIRECTION_DISABLED,
|
||||
node,
|
||||
SHORTCUT_ARC,
|
||||
FORWARD_DIRECTION_DISABLED,
|
||||
REVERSE_DIRECTION_ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,11 +37,10 @@ class BaseAPI
|
||||
waypoints.values[0] = MakeWaypoint(segment_end_coordinates.front().source_phantom);
|
||||
|
||||
auto out_iter = std::next(waypoints.values.begin());
|
||||
boost::range::transform(segment_end_coordinates, out_iter,
|
||||
[this](const PhantomNodes &phantom_pair)
|
||||
{
|
||||
return MakeWaypoint(phantom_pair.target_phantom);
|
||||
});
|
||||
boost::range::transform(
|
||||
segment_end_coordinates, out_iter, [this](const PhantomNodes &phantom_pair) {
|
||||
return MakeWaypoint(phantom_pair.target_phantom);
|
||||
});
|
||||
return waypoints;
|
||||
}
|
||||
|
||||
@@ -49,7 +48,8 @@ class BaseAPI
|
||||
// protected:
|
||||
util::json::Object MakeWaypoint(const PhantomNode &phantom) const
|
||||
{
|
||||
return json::makeWaypoint(phantom.location, facade.GetNameForID(phantom.name_id),
|
||||
return json::makeWaypoint(phantom.location,
|
||||
facade.GetNameForID(phantom.name_id),
|
||||
Hint{phantom, facade.GetCheckSum()});
|
||||
}
|
||||
|
||||
|
||||
@@ -28,14 +28,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef ENGINE_API_BASE_PARAMETERS_HPP
|
||||
#define ENGINE_API_BASE_PARAMETERS_HPP
|
||||
|
||||
#include "engine/hint.hpp"
|
||||
#include "engine/bearing.hpp"
|
||||
#include "engine/hint.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -72,9 +72,9 @@ struct BaseParameters
|
||||
return (hints.empty() || hints.size() == coordinates.size()) &&
|
||||
(bearings.empty() || bearings.size() == coordinates.size()) &&
|
||||
(radiuses.empty() || radiuses.size() == coordinates.size()) &&
|
||||
std::all_of(bearings.begin(), bearings.end(),
|
||||
[](const boost::optional<Bearing> bearing_and_range)
|
||||
{
|
||||
std::all_of(bearings.begin(),
|
||||
bearings.end(),
|
||||
[](const boost::optional<Bearing> bearing_and_range) {
|
||||
if (bearing_and_range)
|
||||
{
|
||||
return bearing_and_range->IsValid();
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "engine/polyline_compressor.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/route.hpp"
|
||||
#include "engine/guidance/route_leg.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "engine/guidance/step_maneuver.hpp"
|
||||
#include "engine/guidance/route_leg.hpp"
|
||||
#include "engine/guidance/route.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/polyline_compressor.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace json
|
||||
namespace detail
|
||||
{
|
||||
|
||||
std::string instructionTypeToString(extractor::guidance::TurnType type);
|
||||
std::string instructionModifierToString(extractor::guidance::DirectionModifier modifier);
|
||||
std::string instructionTypeToString(extractor::guidance::TurnType::Enum type);
|
||||
std::string instructionModifierToString(extractor::guidance::DirectionModifier::Enum modifier);
|
||||
|
||||
util::json::Array coordinateToLonLat(const util::Coordinate coordinate);
|
||||
|
||||
@@ -57,7 +57,9 @@ util::json::Object makeGeoJSONGeometry(ForwardIter begin, ForwardIter end)
|
||||
{
|
||||
geojson.values["type"] = "LineString";
|
||||
util::json::Array coordinates;
|
||||
std::transform(begin, end, std::back_inserter(coordinates.values), &detail::coordinateToLonLat);
|
||||
coordinates.values.reserve(num_coordinates);
|
||||
std::transform(
|
||||
begin, end, std::back_inserter(coordinates.values), &detail::coordinateToLonLat);
|
||||
geojson.values["coordinates"] = std::move(coordinates);
|
||||
}
|
||||
else if (num_coordinates > 0)
|
||||
@@ -85,7 +87,8 @@ makeWaypoint(const util::Coordinate location, std::string name, const Hint &hint
|
||||
util::json::Object makeRouteLeg(guidance::RouteLeg leg, util::json::Array steps);
|
||||
|
||||
util::json::Array makeRouteLegs(std::vector<guidance::RouteLeg> legs,
|
||||
std::vector<util::json::Value> step_geometries);
|
||||
std::vector<util::json::Value> step_geometries,
|
||||
std::vector<util::json::Object> annotations);
|
||||
}
|
||||
}
|
||||
} // namespace engine
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef ENGINE_API_MATCH_HPP
|
||||
#define ENGINE_API_MATCH_HPP
|
||||
|
||||
#include "engine/api/route_api.hpp"
|
||||
#include "engine/api/match_parameters.hpp"
|
||||
#include "engine/api/route_api.hpp"
|
||||
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ struct MatchParameters : public RouteParameters
|
||||
{
|
||||
MatchParameters()
|
||||
: RouteParameters(false,
|
||||
false,
|
||||
false,
|
||||
RouteParameters::GeometriesType::Polyline,
|
||||
RouteParameters::OverviewType::Simplified,
|
||||
|
||||
@@ -34,10 +34,10 @@ class NearestAPI final : public BaseAPI
|
||||
|
||||
util::json::Array waypoints;
|
||||
waypoints.values.resize(phantom_nodes.front().size());
|
||||
std::transform(phantom_nodes.front().begin(), phantom_nodes.front().end(),
|
||||
std::transform(phantom_nodes.front().begin(),
|
||||
phantom_nodes.front().end(),
|
||||
waypoints.values.begin(),
|
||||
[this](const PhantomNodeWithDistance &phantom_with_distance)
|
||||
{
|
||||
[this](const PhantomNodeWithDistance &phantom_with_distance) {
|
||||
auto waypoint = MakeWaypoint(phantom_with_distance.phantom_node);
|
||||
waypoint.values["distance"] = phantom_with_distance.distance;
|
||||
return waypoint;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "engine/guidance/assemble_overview.hpp"
|
||||
#include "engine/guidance/assemble_route.hpp"
|
||||
#include "engine/guidance/assemble_steps.hpp"
|
||||
#include "engine/guidance/lane_processing.hpp"
|
||||
#include "engine/guidance/post_processing.hpp"
|
||||
|
||||
#include "engine/internal_route_result.hpp"
|
||||
@@ -42,14 +43,16 @@ class RouteAPI : public BaseAPI
|
||||
auto number_of_routes = raw_route.has_alternative() ? 2UL : 1UL;
|
||||
util::json::Array routes;
|
||||
routes.values.resize(number_of_routes);
|
||||
routes.values[0] =
|
||||
MakeRoute(raw_route.segment_end_coordinates, raw_route.unpacked_path_segments,
|
||||
raw_route.source_traversed_in_reverse, raw_route.target_traversed_in_reverse);
|
||||
routes.values[0] = MakeRoute(raw_route.segment_end_coordinates,
|
||||
raw_route.unpacked_path_segments,
|
||||
raw_route.source_traversed_in_reverse,
|
||||
raw_route.target_traversed_in_reverse);
|
||||
if (raw_route.has_alternative())
|
||||
{
|
||||
std::vector<std::vector<PathData>> wrapped_leg(1);
|
||||
wrapped_leg.front() = std::move(raw_route.unpacked_alternative);
|
||||
routes.values[1] = MakeRoute(raw_route.segment_end_coordinates, wrapped_leg,
|
||||
routes.values[1] = MakeRoute(raw_route.segment_end_coordinates,
|
||||
wrapped_leg,
|
||||
raw_route.alt_source_traversed_in_reverse,
|
||||
raw_route.alt_target_traversed_in_reverse);
|
||||
}
|
||||
@@ -93,14 +96,23 @@ class RouteAPI : public BaseAPI
|
||||
|
||||
auto leg_geometry = guidance::assembleGeometry(
|
||||
BaseAPI::facade, path_data, phantoms.source_phantom, phantoms.target_phantom);
|
||||
auto leg = guidance::assembleLeg(facade, path_data, leg_geometry, phantoms.source_phantom,
|
||||
phantoms.target_phantom, reversed_target, parameters.steps);
|
||||
auto leg = guidance::assembleLeg(facade,
|
||||
path_data,
|
||||
leg_geometry,
|
||||
phantoms.source_phantom,
|
||||
phantoms.target_phantom,
|
||||
reversed_target,
|
||||
parameters.steps);
|
||||
|
||||
if (parameters.steps)
|
||||
{
|
||||
auto steps = guidance::assembleSteps(
|
||||
BaseAPI::facade, path_data, leg_geometry, phantoms.source_phantom,
|
||||
phantoms.target_phantom, reversed_source, reversed_target);
|
||||
auto steps = guidance::assembleSteps(BaseAPI::facade,
|
||||
path_data,
|
||||
leg_geometry,
|
||||
phantoms.source_phantom,
|
||||
phantoms.target_phantom,
|
||||
reversed_source,
|
||||
reversed_target);
|
||||
|
||||
/* Perform step-based post-processing.
|
||||
*
|
||||
@@ -133,9 +145,12 @@ class RouteAPI : public BaseAPI
|
||||
guidance::trimShortSegments(steps, leg_geometry);
|
||||
leg.steps = guidance::postProcess(std::move(steps));
|
||||
leg.steps = guidance::collapseTurns(std::move(leg.steps));
|
||||
leg.steps = guidance::assignRelativeLocations(std::move(leg.steps), leg_geometry,
|
||||
leg.steps = guidance::buildIntersections(std::move(leg.steps));
|
||||
leg.steps = guidance::assignRelativeLocations(std::move(leg.steps),
|
||||
leg_geometry,
|
||||
phantoms.source_phantom,
|
||||
phantoms.target_phantom);
|
||||
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
|
||||
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps);
|
||||
}
|
||||
|
||||
@@ -160,8 +175,13 @@ class RouteAPI : public BaseAPI
|
||||
for (const auto idx : util::irange<std::size_t>(0UL, legs.size()))
|
||||
{
|
||||
auto &leg_geometry = leg_geometries[idx];
|
||||
|
||||
step_geometries.reserve(step_geometries.size() + legs[idx].steps.size());
|
||||
|
||||
std::transform(
|
||||
legs[idx].steps.begin(), legs[idx].steps.end(), std::back_inserter(step_geometries),
|
||||
legs[idx].steps.begin(),
|
||||
legs[idx].steps.end(),
|
||||
std::back_inserter(step_geometries),
|
||||
[this, &leg_geometry](const guidance::RouteStep &step) {
|
||||
if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
|
||||
{
|
||||
@@ -176,9 +196,48 @@ class RouteAPI : public BaseAPI
|
||||
});
|
||||
}
|
||||
|
||||
return json::makeRoute(route,
|
||||
json::makeRouteLegs(std::move(legs), std::move(step_geometries)),
|
||||
std::move(json_overview));
|
||||
std::vector<util::json::Object> annotations;
|
||||
|
||||
if (parameters.annotations)
|
||||
{
|
||||
for (const auto idx : util::irange<std::size_t>(0UL, leg_geometries.size()))
|
||||
{
|
||||
util::json::Array durations;
|
||||
util::json::Array distances;
|
||||
util::json::Array nodes;
|
||||
auto &leg_geometry = leg_geometries[idx];
|
||||
|
||||
durations.values.reserve(leg_geometry.annotations.size());
|
||||
distances.values.reserve(leg_geometry.annotations.size());
|
||||
nodes.values.reserve(leg_geometry.osm_node_ids.size());
|
||||
|
||||
std::for_each(
|
||||
leg_geometry.annotations.begin(),
|
||||
leg_geometry.annotations.end(),
|
||||
[this, &durations, &distances](const guidance::LegGeometry::Annotation &step) {
|
||||
durations.values.push_back(step.duration);
|
||||
distances.values.push_back(step.distance);
|
||||
});
|
||||
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));
|
||||
});
|
||||
util::json::Object annotation;
|
||||
annotation.values["distance"] = std::move(distances);
|
||||
annotation.values["duration"] = std::move(durations);
|
||||
annotation.values["nodes"] = std::move(nodes);
|
||||
annotations.push_back(std::move(annotation));
|
||||
}
|
||||
}
|
||||
|
||||
auto result = json::makeRoute(route,
|
||||
json::makeRouteLegs(std::move(legs),
|
||||
std::move(step_geometries),
|
||||
std::move(annotations)),
|
||||
std::move(json_overview));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const RouteParameters ¶meters;
|
||||
|
||||
@@ -72,17 +72,20 @@ struct RouteParameters : public BaseParameters
|
||||
template <typename... Args>
|
||||
RouteParameters(const bool steps_,
|
||||
const bool alternatives_,
|
||||
const bool annotations_,
|
||||
const GeometriesType geometries_,
|
||||
const OverviewType overview_,
|
||||
const boost::optional<bool> continue_straight_,
|
||||
Args... args_)
|
||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||
geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_}
|
||||
annotations{annotations_}, geometries{geometries_}, overview{overview_},
|
||||
continue_straight{continue_straight_}
|
||||
{
|
||||
}
|
||||
|
||||
bool steps = false;
|
||||
bool alternatives = false;
|
||||
bool annotations = false;
|
||||
GeometriesType geometries = GeometriesType::Polyline;
|
||||
OverviewType overview = OverviewType::Simplified;
|
||||
boost::optional<bool> continue_straight;
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
#define ENGINE_API_TABLE_HPP
|
||||
|
||||
#include "engine/api/base_api.hpp"
|
||||
#include "engine/api/table_parameters.hpp"
|
||||
#include "engine/api/json_factory.hpp"
|
||||
#include "engine/api/table_parameters.hpp"
|
||||
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
|
||||
#include "engine/guidance/assemble_leg.hpp"
|
||||
#include "engine/guidance/assemble_route.hpp"
|
||||
#include "engine/guidance/assemble_geometry.hpp"
|
||||
#include "engine/guidance/assemble_leg.hpp"
|
||||
#include "engine/guidance/assemble_overview.hpp"
|
||||
#include "engine/guidance/assemble_route.hpp"
|
||||
#include "engine/guidance/assemble_steps.hpp"
|
||||
|
||||
#include "engine/internal_route_result.hpp"
|
||||
@@ -78,11 +78,10 @@ class TableAPI final : public BaseAPI
|
||||
json_waypoints.values.reserve(phantoms.size());
|
||||
BOOST_ASSERT(phantoms.size() == parameters.coordinates.size());
|
||||
|
||||
boost::range::transform(phantoms, std::back_inserter(json_waypoints.values),
|
||||
[this](const PhantomNode &phantom)
|
||||
{
|
||||
return BaseAPI::MakeWaypoint(phantom);
|
||||
});
|
||||
boost::range::transform(
|
||||
phantoms,
|
||||
std::back_inserter(json_waypoints.values),
|
||||
[this](const PhantomNode &phantom) { return BaseAPI::MakeWaypoint(phantom); });
|
||||
return json_waypoints;
|
||||
}
|
||||
|
||||
@@ -91,9 +90,9 @@ class TableAPI final : public BaseAPI
|
||||
{
|
||||
util::json::Array json_waypoints;
|
||||
json_waypoints.values.reserve(indices.size());
|
||||
boost::range::transform(indices, std::back_inserter(json_waypoints.values),
|
||||
[this, phantoms](const std::size_t idx)
|
||||
{
|
||||
boost::range::transform(indices,
|
||||
std::back_inserter(json_waypoints.values),
|
||||
[this, phantoms](const std::size_t idx) {
|
||||
BOOST_ASSERT(idx < phantoms.size());
|
||||
return BaseAPI::MakeWaypoint(phantoms[idx]);
|
||||
});
|
||||
@@ -111,9 +110,10 @@ class TableAPI final : public BaseAPI
|
||||
auto row_begin_iterator = values.begin() + (row * number_of_columns);
|
||||
auto row_end_iterator = values.begin() + ((row + 1) * number_of_columns);
|
||||
json_row.values.resize(number_of_columns);
|
||||
std::transform(row_begin_iterator, row_end_iterator, json_row.values.begin(),
|
||||
[](const EdgeWeight duration)
|
||||
{
|
||||
std::transform(row_begin_iterator,
|
||||
row_end_iterator,
|
||||
json_row.values.begin(),
|
||||
[](const EdgeWeight duration) {
|
||||
if (duration == INVALID_EDGE_WEIGHT)
|
||||
{
|
||||
return util::json::Value(util::json::Null());
|
||||
|
||||
@@ -89,10 +89,7 @@ struct TableParameters : public BaseParameters
|
||||
return false;
|
||||
|
||||
// 3/ 0 <= index < len(locations)
|
||||
const auto not_in_range = [this](const std::size_t x)
|
||||
{
|
||||
return x >= coordinates.size();
|
||||
};
|
||||
const auto not_in_range = [this](const std::size_t x) { return x >= coordinates.size(); };
|
||||
|
||||
if (std::any_of(begin(sources), end(sources), not_in_range))
|
||||
return false;
|
||||
|
||||
@@ -79,8 +79,7 @@ class TripAPI final : public RouteAPI
|
||||
std::vector<TripIndex> input_idx_to_trip_idx(parameters.coordinates.size());
|
||||
for (auto sub_trip_index : util::irange<unsigned>(0u, sub_trips.size()))
|
||||
{
|
||||
for (auto point_index :
|
||||
util::irange<unsigned>(0u, sub_trips[sub_trip_index].size()))
|
||||
for (auto point_index : util::irange<unsigned>(0u, sub_trips[sub_trip_index].size()))
|
||||
{
|
||||
input_idx_to_trip_idx[sub_trips[sub_trip_index][point_index]] =
|
||||
TripIndex{sub_trip_index, point_index};
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#ifndef OSRM_BASE64_HPP
|
||||
#define OSRM_BASE64_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include <cstddef>
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/archive/iterators/binary_from_base64.hpp>
|
||||
#include <boost/archive/iterators/base64_from_binary.hpp>
|
||||
#include <boost/archive/iterators/transform_width.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/archive/iterators/base64_from_binary.hpp>
|
||||
#include <boost/archive/iterators/binary_from_base64.hpp>
|
||||
#include <boost/archive/iterators/transform_width.hpp>
|
||||
#include <boost/range/algorithm/copy.hpp>
|
||||
|
||||
namespace osrm
|
||||
|
||||
@@ -3,13 +3,16 @@
|
||||
|
||||
// Exposes all data access interfaces to the algorithms via base class ptr
|
||||
|
||||
#include "contractor/query_edge.hpp"
|
||||
#include "extractor/edge_based_node.hpp"
|
||||
#include "extractor/external_memory_node.hpp"
|
||||
#include "contractor/query_edge.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "util/exception.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/string_util.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
@@ -17,9 +20,9 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -65,6 +68,7 @@ class BaseDataFacade
|
||||
|
||||
// node and edge information access
|
||||
virtual util::Coordinate GetCoordinateOfNode(const unsigned id) const = 0;
|
||||
virtual OSMNodeID GetOSMNodeIDOfNode(const unsigned id) const = 0;
|
||||
|
||||
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const = 0;
|
||||
|
||||
@@ -113,14 +117,15 @@ class BaseDataFacade
|
||||
const int bearing,
|
||||
const int bearing_range) const = 0;
|
||||
virtual std::vector<PhantomNodeWithDistance>
|
||||
NearestPhantomNodes(const util::Coordinate input_coordinate, const unsigned max_results) const = 0;
|
||||
NearestPhantomNodes(const util::Coordinate input_coordinate,
|
||||
const unsigned max_results) const = 0;
|
||||
virtual std::vector<PhantomNodeWithDistance>
|
||||
NearestPhantomNodes(const util::Coordinate input_coordinate,
|
||||
const unsigned max_results,
|
||||
const double max_distance) const = 0;
|
||||
|
||||
virtual std::pair<PhantomNode, PhantomNode>
|
||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate) const = 0;
|
||||
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||
const util::Coordinate input_coordinate) const = 0;
|
||||
virtual std::pair<PhantomNode, PhantomNode>
|
||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||
const double max_distance) const = 0;
|
||||
@@ -129,8 +134,15 @@ class BaseDataFacade
|
||||
const double max_distance,
|
||||
const int bearing,
|
||||
const int bearing_range) const = 0;
|
||||
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||
const util::Coordinate input_coordinate, const int bearing, const int bearing_range) const = 0;
|
||||
virtual std::pair<PhantomNode, PhantomNode>
|
||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||
const int bearing,
|
||||
const int bearing_range) const = 0;
|
||||
|
||||
virtual bool hasLaneData(const EdgeID id) const = 0;
|
||||
virtual util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const = 0;
|
||||
virtual extractor::guidance::TurnLaneDescription
|
||||
GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0;
|
||||
|
||||
virtual unsigned GetCheckSum() const = 0;
|
||||
|
||||
@@ -140,11 +152,24 @@ class BaseDataFacade
|
||||
|
||||
virtual std::string GetNameForID(const unsigned name_id) const = 0;
|
||||
|
||||
virtual std::string GetPronunciationForID(const unsigned name_id) const = 0;
|
||||
|
||||
virtual std::string GetDestinationsForID(const unsigned name_id) const = 0;
|
||||
|
||||
virtual std::size_t GetCoreSize() const = 0;
|
||||
|
||||
virtual std::string GetTimestamp() const = 0;
|
||||
|
||||
virtual bool GetContinueStraightDefault() const = 0;
|
||||
|
||||
virtual BearingClassID GetBearingClassID(const NodeID id) const = 0;
|
||||
|
||||
virtual util::guidance::BearingClass
|
||||
GetBearingClass(const BearingClassID bearing_class_id) const = 0;
|
||||
|
||||
virtual EntryClassID GetEntryClassID(const EdgeID eid) const = 0;
|
||||
|
||||
virtual util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,21 +6,26 @@
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
|
||||
#include "storage/storage_config.hpp"
|
||||
#include "engine/geospatial_query.hpp"
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/original_edge_data.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "contractor/query_edge.hpp"
|
||||
#include "storage/storage_config.hpp"
|
||||
#include "engine/geospatial_query.hpp"
|
||||
#include "util/graph_loader.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/io.hpp"
|
||||
#include "util/packed_vector.hpp"
|
||||
#include "util/range_table.hpp"
|
||||
#include "util/rectangle.hpp"
|
||||
#include "util/shared_memory_vector_wrapper.hpp"
|
||||
#include "util/simple_logger.hpp"
|
||||
#include "util/static_graph.hpp"
|
||||
#include "util/static_rtree.hpp"
|
||||
#include "util/range_table.hpp"
|
||||
#include "util/graph_loader.hpp"
|
||||
#include "util/simple_logger.hpp"
|
||||
#include "util/rectangle.hpp"
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "osrm/coordinate.hpp"
|
||||
|
||||
@@ -70,9 +75,12 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
std::string m_timestamp;
|
||||
|
||||
util::ShM<util::Coordinate, false>::vector m_coordinate_list;
|
||||
util::PackedVector<OSMNodeID, false> m_osmnodeid_list;
|
||||
util::ShM<NodeID, false>::vector m_via_node_list;
|
||||
util::ShM<unsigned, false>::vector m_name_ID_list;
|
||||
util::ShM<extractor::guidance::TurnInstruction, false>::vector m_turn_instruction_list;
|
||||
util::ShM<LaneDataID, false>::vector m_lane_data_id;
|
||||
util::ShM<util::guidance::LaneTupelIdPair, false>::vector m_lane_tupel_id_pairs;
|
||||
util::ShM<extractor::TravelMode, false>::vector m_travel_mode_list;
|
||||
util::ShM<char, false>::vector m_names_char_list;
|
||||
util::ShM<unsigned, false>::vector m_geometry_indices;
|
||||
@@ -81,6 +89,8 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
util::ShM<unsigned, false>::vector m_segment_weights;
|
||||
util::ShM<uint8_t, false>::vector m_datasource_list;
|
||||
util::ShM<std::string, false>::vector m_datasource_names;
|
||||
util::ShM<std::uint32_t, false>::vector m_lane_description_offsets;
|
||||
util::ShM<extractor::guidance::TurnLaneType::Mask, false>::vector m_lane_description_masks;
|
||||
extractor::ProfileProperties m_profile_properties;
|
||||
|
||||
std::unique_ptr<InternalRTree> m_static_rtree;
|
||||
@@ -89,6 +99,18 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
boost::filesystem::path file_index_path;
|
||||
util::RangeTable<16, false> m_name_table;
|
||||
|
||||
// bearing classes by node based node
|
||||
util::ShM<BearingClassID, false>::vector m_bearing_class_id_table;
|
||||
// entry class IDs by edge based egde
|
||||
util::ShM<EntryClassID, false>::vector m_entry_class_id_list;
|
||||
// the look-up table for entry classes. An entry class lists the possibility of entry for all
|
||||
// available turns. For every turn, there is an associated entry class.
|
||||
util::ShM<util::guidance::EntryClass, false>::vector m_entry_class_table;
|
||||
// the look-up table for distinct bearing classes. A bearing class lists the available bearings
|
||||
// at an intersection
|
||||
util::RangeTable<16, false> m_bearing_ranges_table;
|
||||
util::ShM<DiscreteBearing, false>::vector m_bearing_values_table;
|
||||
|
||||
void LoadProfileProperties(const boost::filesystem::path &properties_path)
|
||||
{
|
||||
boost::filesystem::ifstream in_stream(properties_path);
|
||||
@@ -97,7 +119,22 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
throw util::exception("Could not open " + properties_path.string() + " for reading.");
|
||||
}
|
||||
|
||||
in_stream.read(reinterpret_cast<char*>(&m_profile_properties), sizeof(m_profile_properties));
|
||||
in_stream.read(reinterpret_cast<char *>(&m_profile_properties),
|
||||
sizeof(m_profile_properties));
|
||||
}
|
||||
|
||||
void LoadLaneTupelIdPairs(const boost::filesystem::path &lane_data_path)
|
||||
{
|
||||
boost::filesystem::ifstream in_stream(lane_data_path);
|
||||
if (!in_stream)
|
||||
{
|
||||
throw util::exception("Could not open " + lane_data_path.string() + " for reading.");
|
||||
}
|
||||
std::uint64_t size;
|
||||
in_stream.read(reinterpret_cast<char *>(&size), sizeof(size));
|
||||
m_lane_tupel_id_pairs.resize(size);
|
||||
in_stream.read(reinterpret_cast<char *>(&m_lane_tupel_id_pairs[0]),
|
||||
sizeof(m_lane_tupel_id_pairs) * size);
|
||||
}
|
||||
|
||||
void LoadTimestamp(const boost::filesystem::path ×tamp_path)
|
||||
@@ -140,10 +177,12 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
unsigned number_of_coordinates = 0;
|
||||
nodes_input_stream.read((char *)&number_of_coordinates, sizeof(unsigned));
|
||||
m_coordinate_list.resize(number_of_coordinates);
|
||||
m_osmnodeid_list.reserve(number_of_coordinates);
|
||||
for (unsigned i = 0; i < number_of_coordinates; ++i)
|
||||
{
|
||||
nodes_input_stream.read((char *)¤t_node, sizeof(extractor::QueryNode));
|
||||
m_coordinate_list[i] = util::Coordinate(current_node.lon, current_node.lat);
|
||||
m_osmnodeid_list.push_back(current_node.node_id);
|
||||
BOOST_ASSERT(m_coordinate_list[i].IsValid());
|
||||
}
|
||||
|
||||
@@ -153,7 +192,9 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
m_via_node_list.resize(number_of_edges);
|
||||
m_name_ID_list.resize(number_of_edges);
|
||||
m_turn_instruction_list.resize(number_of_edges);
|
||||
m_lane_data_id.resize(number_of_edges);
|
||||
m_travel_mode_list.resize(number_of_edges);
|
||||
m_entry_class_id_list.resize(number_of_edges);
|
||||
|
||||
extractor::OriginalEdgeData current_edge_data;
|
||||
for (unsigned i = 0; i < number_of_edges; ++i)
|
||||
@@ -163,7 +204,9 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
m_via_node_list[i] = current_edge_data.via_node;
|
||||
m_name_ID_list[i] = current_edge_data.name_id;
|
||||
m_turn_instruction_list[i] = current_edge_data.turn_instruction;
|
||||
m_lane_data_id[i] = current_edge_data.lane_data_id;
|
||||
m_travel_mode_list[i] = current_edge_data.travel_mode;
|
||||
m_entry_class_id_list[i] = current_edge_data.entry_classid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,13 +267,14 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
boost::filesystem::ifstream datasources_stream(datasource_indexes_file, std::ios::binary);
|
||||
if (!datasources_stream)
|
||||
{
|
||||
throw util::exception("Could not open " + datasource_indexes_file.string() + " for reading!");
|
||||
throw util::exception("Could not open " + datasource_indexes_file.string() +
|
||||
" for reading!");
|
||||
}
|
||||
BOOST_ASSERT(datasources_stream);
|
||||
|
||||
std::size_t number_of_datasources = 0;
|
||||
std::uint64_t number_of_datasources = 0;
|
||||
datasources_stream.read(reinterpret_cast<char *>(&number_of_datasources),
|
||||
sizeof(std::size_t));
|
||||
sizeof(number_of_datasources));
|
||||
if (number_of_datasources > 0)
|
||||
{
|
||||
m_datasource_list.resize(number_of_datasources);
|
||||
@@ -241,7 +285,8 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
boost::filesystem::ifstream datasourcenames_stream(datasource_names_file, std::ios::binary);
|
||||
if (!datasourcenames_stream)
|
||||
{
|
||||
throw util::exception("Could not open " + datasource_names_file.string() + " for reading!");
|
||||
throw util::exception("Could not open " + datasource_names_file.string() +
|
||||
" for reading!");
|
||||
}
|
||||
BOOST_ASSERT(datasourcenames_stream);
|
||||
std::string name;
|
||||
@@ -260,6 +305,15 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
new InternalGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
|
||||
}
|
||||
|
||||
void LoadLaneDescriptions(const boost::filesystem::path &lane_description_file)
|
||||
{
|
||||
if (!util::deserializeAdjacencyArray(lane_description_file.string(),
|
||||
m_lane_description_offsets,
|
||||
m_lane_description_masks))
|
||||
util::SimpleLogger().Write(logWARNING) << "Failed to read turn lane descriptions from "
|
||||
<< lane_description_file.string();
|
||||
}
|
||||
|
||||
void LoadStreetNames(const boost::filesystem::path &names_file)
|
||||
{
|
||||
boost::filesystem::ifstream name_stream(names_file, std::ios::binary);
|
||||
@@ -277,6 +331,55 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
}
|
||||
}
|
||||
|
||||
void LoadIntersectionClasses(const boost::filesystem::path &intersection_class_file)
|
||||
{
|
||||
std::ifstream intersection_stream(intersection_class_file.string(), std::ios::binary);
|
||||
if (!intersection_stream)
|
||||
throw util::exception("Could not open " + intersection_class_file.string() +
|
||||
" for reading.");
|
||||
|
||||
if (!util::readAndCheckFingerprint(intersection_stream))
|
||||
throw util::exception("Fingeprint does not match in " +
|
||||
intersection_class_file.string());
|
||||
|
||||
{
|
||||
util::SimpleLogger().Write(logINFO) << "Loading Bearing Class IDs";
|
||||
std::vector<BearingClassID> bearing_class_id;
|
||||
if (!util::deserializeVector(intersection_stream, bearing_class_id))
|
||||
throw util::exception("Reading from " + intersection_class_file.string() +
|
||||
" failed.");
|
||||
|
||||
m_bearing_class_id_table.resize(bearing_class_id.size());
|
||||
std::copy(
|
||||
bearing_class_id.begin(), bearing_class_id.end(), &m_bearing_class_id_table[0]);
|
||||
}
|
||||
{
|
||||
util::SimpleLogger().Write(logINFO) << "Loading Bearing Classes";
|
||||
// read the range table
|
||||
intersection_stream >> m_bearing_ranges_table;
|
||||
std::vector<util::guidance::BearingClass> bearing_classes;
|
||||
// and the actual bearing values
|
||||
std::uint64_t num_bearings;
|
||||
intersection_stream >> num_bearings;
|
||||
m_bearing_values_table.resize(num_bearings);
|
||||
intersection_stream.read(reinterpret_cast<char *>(&m_bearing_values_table[0]),
|
||||
sizeof(m_bearing_values_table[0]) * num_bearings);
|
||||
if (!static_cast<bool>(intersection_stream))
|
||||
throw util::exception("Reading from " + intersection_class_file.string() +
|
||||
" failed.");
|
||||
}
|
||||
{
|
||||
util::SimpleLogger().Write(logINFO) << "Loading Entry Classes";
|
||||
std::vector<util::guidance::EntryClass> entry_classes;
|
||||
if (!util::deserializeVector(intersection_stream, entry_classes))
|
||||
throw util::exception("Reading from " + intersection_class_file.string() +
|
||||
" failed.");
|
||||
|
||||
m_entry_class_table.resize(entry_classes.size());
|
||||
std::copy(entry_classes.begin(), entry_classes.end(), &m_entry_class_table[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~InternalDataFacade()
|
||||
{
|
||||
@@ -284,7 +387,7 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
m_geospatial_query.reset();
|
||||
}
|
||||
|
||||
explicit InternalDataFacade(const storage::StorageConfig& config)
|
||||
explicit InternalDataFacade(const storage::StorageConfig &config)
|
||||
{
|
||||
ram_index_path = config.ram_index_path;
|
||||
file_index_path = config.file_index_path;
|
||||
@@ -302,8 +405,7 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
LoadGeometries(config.geometries_path);
|
||||
|
||||
util::SimpleLogger().Write() << "loading datasource info";
|
||||
LoadDatasourceInfo(config.datasource_names_path,
|
||||
config.datasource_indexes_path);
|
||||
LoadDatasourceInfo(config.datasource_names_path, config.datasource_indexes_path);
|
||||
|
||||
util::SimpleLogger().Write() << "loading timestamp";
|
||||
LoadTimestamp(config.timestamp_path);
|
||||
@@ -314,8 +416,17 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
util::SimpleLogger().Write() << "loading street names";
|
||||
LoadStreetNames(config.names_data_path);
|
||||
|
||||
util::SimpleLogger().Write() << "loading lane tags";
|
||||
LoadLaneDescriptions(config.turn_lane_description_path);
|
||||
|
||||
util::SimpleLogger().Write() << "loading rtree";
|
||||
LoadRTree();
|
||||
|
||||
util::SimpleLogger().Write() << "loading intersection class data";
|
||||
LoadIntersectionClasses(config.intersection_class_path);
|
||||
|
||||
util::SimpleLogger().Write() << "Loading Lane Data Pairs";
|
||||
LoadLaneTupelIdPairs(config.turn_lane_data_path);
|
||||
}
|
||||
|
||||
// search graph access
|
||||
@@ -367,6 +478,11 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
return m_coordinate_list[id];
|
||||
}
|
||||
|
||||
OSMNodeID GetOSMNodeIDOfNode(const unsigned id) const override final
|
||||
{
|
||||
return m_osmnodeid_list.at(id);
|
||||
}
|
||||
|
||||
extractor::guidance::TurnInstruction
|
||||
GetTurnInstructionForEdgeID(const unsigned id) const override final
|
||||
{
|
||||
@@ -382,8 +498,8 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
const util::Coordinate north_east) const override final
|
||||
{
|
||||
BOOST_ASSERT(m_geospatial_query.get());
|
||||
const util::RectangleInt2D bbox{south_west.lon, north_east.lon, south_west.lat,
|
||||
north_east.lat};
|
||||
const util::RectangleInt2D bbox{
|
||||
south_west.lon, north_east.lon, south_west.lat, north_east.lat};
|
||||
return m_geospatial_query->Search(bbox);
|
||||
}
|
||||
|
||||
@@ -404,8 +520,8 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
{
|
||||
BOOST_ASSERT(m_geospatial_query.get());
|
||||
|
||||
return m_geospatial_query->NearestPhantomNodesInRange(input_coordinate, max_distance,
|
||||
bearing, bearing_range);
|
||||
return m_geospatial_query->NearestPhantomNodesInRange(
|
||||
input_coordinate, max_distance, bearing, bearing_range);
|
||||
}
|
||||
|
||||
std::vector<PhantomNodeWithDistance>
|
||||
@@ -435,8 +551,8 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
{
|
||||
BOOST_ASSERT(m_geospatial_query.get());
|
||||
|
||||
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, bearing,
|
||||
bearing_range);
|
||||
return m_geospatial_query->NearestPhantomNodes(
|
||||
input_coordinate, max_results, bearing, bearing_range);
|
||||
}
|
||||
|
||||
std::vector<PhantomNodeWithDistance>
|
||||
@@ -448,13 +564,12 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
{
|
||||
BOOST_ASSERT(m_geospatial_query.get());
|
||||
|
||||
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance,
|
||||
bearing, bearing_range);
|
||||
return m_geospatial_query->NearestPhantomNodes(
|
||||
input_coordinate, max_results, max_distance, bearing, bearing_range);
|
||||
}
|
||||
|
||||
std::pair<PhantomNode, PhantomNode>
|
||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||
const double max_distance) const override final
|
||||
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||
const util::Coordinate input_coordinate, const double max_distance) const override final
|
||||
{
|
||||
BOOST_ASSERT(m_geospatial_query.get());
|
||||
|
||||
@@ -515,11 +630,30 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
{
|
||||
result.resize(range.back() - range.front() + 1);
|
||||
std::copy(m_names_char_list.begin() + range.front(),
|
||||
m_names_char_list.begin() + range.back() + 1, result.begin());
|
||||
m_names_char_list.begin() + range.back() + 1,
|
||||
result.begin());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string GetPronunciationForID(const unsigned name_id) const override final
|
||||
{
|
||||
// We store the pronunciation after the name and destination of a street.
|
||||
// We do this to get around the street length limit of 255 which would hit
|
||||
// if we concatenate these. Order (see extractor_callbacks):
|
||||
// name (0), destination (1), pronunciation (2)
|
||||
return GetNameForID(name_id + 2);
|
||||
}
|
||||
|
||||
std::string GetDestinationsForID(const unsigned name_id) const override final
|
||||
{
|
||||
// We store the destination after the name of a street.
|
||||
// We do this to get around the street length limit of 255 which would hit
|
||||
// if we concatenate these. Order (see extractor_callbacks):
|
||||
// name (0), destination (1), pronunciation (2)
|
||||
return GetNameForID(name_id + 1);
|
||||
}
|
||||
|
||||
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const override final
|
||||
{
|
||||
return m_via_node_list.at(id);
|
||||
@@ -547,9 +681,9 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
|
||||
result_nodes.clear();
|
||||
result_nodes.reserve(end - begin);
|
||||
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end,
|
||||
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge)
|
||||
{
|
||||
std::for_each(m_geometry_list.begin() + begin,
|
||||
m_geometry_list.begin() + end,
|
||||
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) {
|
||||
result_nodes.emplace_back(edge.node_id);
|
||||
});
|
||||
}
|
||||
@@ -563,9 +697,9 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
|
||||
result_weights.clear();
|
||||
result_weights.reserve(end - begin);
|
||||
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end,
|
||||
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge)
|
||||
{
|
||||
std::for_each(m_geometry_list.begin() + begin,
|
||||
m_geometry_list.begin() + end,
|
||||
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) {
|
||||
result_weights.emplace_back(edge.weight);
|
||||
});
|
||||
}
|
||||
@@ -592,11 +726,10 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
}
|
||||
else
|
||||
{
|
||||
std::for_each(m_datasource_list.begin() + begin, m_datasource_list.begin() + end,
|
||||
[&](const uint8_t &datasource_id)
|
||||
{
|
||||
result_datasources.push_back(datasource_id);
|
||||
});
|
||||
std::for_each(
|
||||
m_datasource_list.begin() + begin,
|
||||
m_datasource_list.begin() + end,
|
||||
[&](const uint8_t &datasource_id) { result_datasources.push_back(datasource_id); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -609,7 +742,64 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
|
||||
std::string GetTimestamp() const override final { return m_timestamp; }
|
||||
|
||||
bool GetContinueStraightDefault() const override final { return m_profile_properties.continue_straight_at_waypoint; }
|
||||
bool GetContinueStraightDefault() const override final
|
||||
{
|
||||
return m_profile_properties.continue_straight_at_waypoint;
|
||||
}
|
||||
|
||||
BearingClassID GetBearingClassID(const NodeID nid) const override final
|
||||
{
|
||||
return m_bearing_class_id_table.at(nid);
|
||||
}
|
||||
|
||||
util::guidance::BearingClass
|
||||
GetBearingClass(const BearingClassID bearing_class_id) const override final
|
||||
{
|
||||
BOOST_ASSERT(bearing_class_id != INVALID_BEARING_CLASSID);
|
||||
auto range = m_bearing_ranges_table.GetRange(bearing_class_id);
|
||||
|
||||
util::guidance::BearingClass result;
|
||||
|
||||
for (auto itr = m_bearing_values_table.begin() + range.front();
|
||||
itr != m_bearing_values_table.begin() + range.back() + 1;
|
||||
++itr)
|
||||
result.add(*itr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
EntryClassID GetEntryClassID(const EdgeID eid) const override final
|
||||
{
|
||||
return m_entry_class_id_list.at(eid);
|
||||
}
|
||||
|
||||
util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const override final
|
||||
{
|
||||
return m_entry_class_table.at(entry_class_id);
|
||||
}
|
||||
|
||||
bool hasLaneData(const EdgeID id) const override final
|
||||
{
|
||||
return m_lane_data_id[id] != INVALID_LANE_DATAID;
|
||||
}
|
||||
|
||||
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const override final
|
||||
{
|
||||
BOOST_ASSERT(hasLaneData(id));
|
||||
return m_lane_tupel_id_pairs[m_lane_data_id[id]];
|
||||
}
|
||||
|
||||
extractor::guidance::TurnLaneDescription
|
||||
GetTurnDescription(const LaneDescriptionID lane_description_id) const override final
|
||||
{
|
||||
if (lane_description_id == INVALID_LANE_DESCRIPTIONID)
|
||||
return {};
|
||||
else
|
||||
return extractor::guidance::TurnLaneDescription(
|
||||
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id],
|
||||
m_lane_description_masks.begin() +
|
||||
m_lane_description_offsets[lane_description_id + 1]);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,21 +3,26 @@
|
||||
|
||||
// implements all data storage when shared memory _IS_ used
|
||||
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "storage/shared_datatype.hpp"
|
||||
#include "storage/shared_memory.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include "engine/geospatial_query.hpp"
|
||||
#include "util/make_unique.hpp"
|
||||
#include "util/range_table.hpp"
|
||||
#include "util/rectangle.hpp"
|
||||
#include "util/simple_logger.hpp"
|
||||
#include "util/static_graph.hpp"
|
||||
#include "util/static_rtree.hpp"
|
||||
#include "util/make_unique.hpp"
|
||||
#include "util/simple_logger.hpp"
|
||||
#include "util/rectangle.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
@@ -30,9 +35,9 @@
|
||||
#include <vector>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/thread/lock_guard.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -49,7 +54,7 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
using QueryGraph = util::StaticGraph<EdgeData, true>;
|
||||
using GraphNode = QueryGraph::NodeArrayEntry;
|
||||
using GraphEdge = QueryGraph::EdgeArrayEntry;
|
||||
using NameIndexBlock = util::RangeTable<16, true>::BlockT;
|
||||
using IndexBlock = util::RangeTable<16, true>::BlockT;
|
||||
using InputEdge = QueryGraph::InputEdge;
|
||||
using RTreeLeaf = super::RTreeLeaf;
|
||||
using SharedRTree =
|
||||
@@ -73,8 +78,10 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
extractor::ProfileProperties *m_profile_properties;
|
||||
|
||||
util::ShM<util::Coordinate, true>::vector m_coordinate_list;
|
||||
util::PackedVector<OSMNodeID, true> m_osmnodeid_list;
|
||||
util::ShM<NodeID, true>::vector m_via_node_list;
|
||||
util::ShM<unsigned, true>::vector m_name_ID_list;
|
||||
util::ShM<LaneDataID, true>::vector m_lane_data_id;
|
||||
util::ShM<extractor::guidance::TurnInstruction, true>::vector m_turn_instruction_list;
|
||||
util::ShM<extractor::TravelMode, true>::vector m_travel_mode_list;
|
||||
util::ShM<char, true>::vector m_names_char_list;
|
||||
@@ -83,10 +90,13 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, true>::vector m_geometry_list;
|
||||
util::ShM<bool, true>::vector m_is_core_node;
|
||||
util::ShM<uint8_t, true>::vector m_datasource_list;
|
||||
util::ShM<std::uint32_t, true>::vector m_lane_description_offsets;
|
||||
util::ShM<extractor::guidance::TurnLaneType::Mask, true>::vector m_lane_description_masks;
|
||||
|
||||
util::ShM<char, true>::vector m_datasource_name_data;
|
||||
util::ShM<std::size_t, true>::vector m_datasource_name_offsets;
|
||||
util::ShM<std::size_t, true>::vector m_datasource_name_lengths;
|
||||
util::ShM<util::guidance::LaneTupelIdPair, true>::vector m_lane_tupel_id_pairs;
|
||||
|
||||
std::unique_ptr<SharedRTree> m_static_rtree;
|
||||
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
|
||||
@@ -94,6 +104,18 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
|
||||
std::shared_ptr<util::RangeTable<16, true>> m_name_table;
|
||||
|
||||
// bearing classes by node based node
|
||||
util::ShM<BearingClassID, true>::vector m_bearing_class_id_table;
|
||||
// entry class IDs
|
||||
util::ShM<EntryClassID, true>::vector m_entry_class_id_list;
|
||||
// the look-up table for entry classes. An entry class lists the possibility of entry for all
|
||||
// available turns. Such a class id is stored with every edge.
|
||||
util::ShM<util::guidance::EntryClass, true>::vector m_entry_class_table;
|
||||
// the look-up table for distinct bearing classes. A bearing class lists the available bearings
|
||||
// at an intersection
|
||||
std::shared_ptr<util::RangeTable<16, true>> m_bearing_ranges_table;
|
||||
util::ShM<DiscreteBearing, true>::vector m_bearing_values_table;
|
||||
|
||||
void LoadChecksum()
|
||||
{
|
||||
m_check_sum = *data_layout->GetBlockPtr<unsigned>(shared_memory,
|
||||
@@ -123,9 +145,11 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
|
||||
auto tree_ptr = data_layout->GetBlockPtr<RTreeNode>(
|
||||
shared_memory, storage::SharedDataLayout::R_SEARCH_TREE);
|
||||
m_static_rtree.reset(new SharedRTree(
|
||||
tree_ptr, data_layout->num_entries[storage::SharedDataLayout::R_SEARCH_TREE],
|
||||
file_index_path, m_coordinate_list));
|
||||
m_static_rtree.reset(
|
||||
new SharedRTree(tree_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::R_SEARCH_TREE],
|
||||
file_index_path,
|
||||
m_coordinate_list));
|
||||
m_geospatial_query.reset(
|
||||
new SharedGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
|
||||
}
|
||||
@@ -149,7 +173,17 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
{
|
||||
auto coordinate_list_ptr = data_layout->GetBlockPtr<util::Coordinate>(
|
||||
shared_memory, storage::SharedDataLayout::COORDINATE_LIST);
|
||||
m_coordinate_list.reset(coordinate_list_ptr,
|
||||
m_coordinate_list.reset(
|
||||
coordinate_list_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::COORDINATE_LIST]);
|
||||
|
||||
auto osmnodeid_list_ptr = data_layout->GetBlockPtr<std::uint64_t>(
|
||||
shared_memory, storage::SharedDataLayout::OSM_NODE_ID_LIST);
|
||||
m_osmnodeid_list.reset(
|
||||
osmnodeid_list_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::OSM_NODE_ID_LIST]);
|
||||
// We (ab)use the number of coordinates here because we know we have the same amount of ids
|
||||
m_osmnodeid_list.set_number_of_entries(
|
||||
data_layout->num_entries[storage::SharedDataLayout::COORDINATE_LIST]);
|
||||
|
||||
auto travel_mode_list_ptr = data_layout->GetBlockPtr<extractor::TravelMode>(
|
||||
@@ -158,6 +192,19 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
travel_mode_list_ptr, data_layout->num_entries[storage::SharedDataLayout::TRAVEL_MODE]);
|
||||
m_travel_mode_list = std::move(travel_mode_list);
|
||||
|
||||
auto lane_data_id_ptr = data_layout->GetBlockPtr<LaneDataID>(
|
||||
shared_memory, storage::SharedDataLayout::LANE_DATA_ID);
|
||||
util::ShM<LaneDataID, true>::vector lane_data_id(
|
||||
lane_data_id_ptr, data_layout->num_entries[storage::SharedDataLayout::LANE_DATA_ID]);
|
||||
m_lane_data_id = std::move(lane_data_id);
|
||||
|
||||
auto lane_tupel_id_pair_ptr = data_layout->GetBlockPtr<util::guidance::LaneTupelIdPair>(
|
||||
shared_memory, storage::SharedDataLayout::TURN_LANE_DATA);
|
||||
util::ShM<util::guidance::LaneTupelIdPair, true>::vector lane_tupel_id_pair(
|
||||
lane_tupel_id_pair_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::TURN_LANE_DATA]);
|
||||
m_lane_tupel_id_pairs = std::move(lane_tupel_id_pair);
|
||||
|
||||
auto turn_instruction_list_ptr =
|
||||
data_layout->GetBlockPtr<extractor::guidance::TurnInstruction>(
|
||||
shared_memory, storage::SharedDataLayout::TURN_INSTRUCTION);
|
||||
@@ -171,6 +218,13 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
util::ShM<unsigned, true>::vector name_id_list(
|
||||
name_id_list_ptr, data_layout->num_entries[storage::SharedDataLayout::NAME_ID_LIST]);
|
||||
m_name_ID_list = std::move(name_id_list);
|
||||
|
||||
auto entry_class_id_list_ptr = data_layout->GetBlockPtr<EntryClassID>(
|
||||
shared_memory, storage::SharedDataLayout::ENTRY_CLASSID);
|
||||
typename util::ShM<EntryClassID, true>::vector entry_class_id_list(
|
||||
entry_class_id_list_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::ENTRY_CLASSID]);
|
||||
m_entry_class_id_list = std::move(entry_class_id_list);
|
||||
}
|
||||
|
||||
void LoadViaNodeList()
|
||||
@@ -186,11 +240,11 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
{
|
||||
auto offsets_ptr = data_layout->GetBlockPtr<unsigned>(
|
||||
shared_memory, storage::SharedDataLayout::NAME_OFFSETS);
|
||||
auto blocks_ptr = data_layout->GetBlockPtr<NameIndexBlock>(
|
||||
auto blocks_ptr = data_layout->GetBlockPtr<IndexBlock>(
|
||||
shared_memory, storage::SharedDataLayout::NAME_BLOCKS);
|
||||
util::ShM<unsigned, true>::vector name_offsets(
|
||||
offsets_ptr, data_layout->num_entries[storage::SharedDataLayout::NAME_OFFSETS]);
|
||||
util::ShM<NameIndexBlock, true>::vector name_blocks(
|
||||
util::ShM<IndexBlock, true>::vector name_blocks(
|
||||
blocks_ptr, data_layout->num_entries[storage::SharedDataLayout::NAME_BLOCKS]);
|
||||
|
||||
auto names_list_ptr = data_layout->GetBlockPtr<char>(
|
||||
@@ -203,6 +257,23 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
m_names_char_list = std::move(names_char_list);
|
||||
}
|
||||
|
||||
void LoadTurnLaneDescriptions()
|
||||
{
|
||||
auto offsets_ptr = data_layout->GetBlockPtr<std::uint32_t>(
|
||||
shared_memory, storage::SharedDataLayout::LANE_DESCRIPTION_OFFSETS);
|
||||
util::ShM<std::uint32_t, true>::vector offsets(
|
||||
offsets_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::LANE_DESCRIPTION_OFFSETS]);
|
||||
m_lane_description_offsets = std::move(offsets);
|
||||
|
||||
auto masks_ptr = data_layout->GetBlockPtr<extractor::guidance::TurnLaneType::Mask>(
|
||||
shared_memory, storage::SharedDataLayout::LANE_DESCRIPTION_MASKS);
|
||||
|
||||
util::ShM<extractor::guidance::TurnLaneType::Mask, true>::vector masks(
|
||||
masks_ptr, data_layout->num_entries[storage::SharedDataLayout::LANE_DESCRIPTION_MASKS]);
|
||||
m_lane_description_masks = std::move(masks);
|
||||
}
|
||||
|
||||
void LoadCoreInformation()
|
||||
{
|
||||
if (data_layout->num_entries[storage::SharedDataLayout::CORE_MARKER] <= 0)
|
||||
@@ -263,6 +334,40 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
m_datasource_name_lengths = std::move(datasource_name_lengths);
|
||||
}
|
||||
|
||||
void LoadIntersectionClasses()
|
||||
{
|
||||
auto bearing_class_id_ptr = data_layout->GetBlockPtr<BearingClassID>(
|
||||
shared_memory, storage::SharedDataLayout::BEARING_CLASSID);
|
||||
typename util::ShM<BearingClassID, true>::vector bearing_class_id_table(
|
||||
bearing_class_id_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::BEARING_CLASSID]);
|
||||
m_bearing_class_id_table = std::move(bearing_class_id_table);
|
||||
|
||||
auto bearing_class_ptr = data_layout->GetBlockPtr<DiscreteBearing>(
|
||||
shared_memory, storage::SharedDataLayout::BEARING_VALUES);
|
||||
typename util::ShM<DiscreteBearing, true>::vector bearing_class_table(
|
||||
bearing_class_ptr, data_layout->num_entries[storage::SharedDataLayout::BEARING_VALUES]);
|
||||
m_bearing_values_table = std::move(bearing_class_table);
|
||||
|
||||
auto offsets_ptr = data_layout->GetBlockPtr<unsigned>(
|
||||
shared_memory, storage::SharedDataLayout::BEARING_OFFSETS);
|
||||
auto blocks_ptr = data_layout->GetBlockPtr<IndexBlock>(
|
||||
shared_memory, storage::SharedDataLayout::BEARING_BLOCKS);
|
||||
util::ShM<unsigned, true>::vector bearing_offsets(
|
||||
offsets_ptr, data_layout->num_entries[storage::SharedDataLayout::BEARING_OFFSETS]);
|
||||
util::ShM<IndexBlock, true>::vector bearing_blocks(
|
||||
blocks_ptr, data_layout->num_entries[storage::SharedDataLayout::BEARING_BLOCKS]);
|
||||
|
||||
m_bearing_ranges_table = util::make_unique<util::RangeTable<16, true>>(
|
||||
bearing_offsets, bearing_blocks, static_cast<unsigned>(m_bearing_values_table.size()));
|
||||
|
||||
auto entry_class_ptr = data_layout->GetBlockPtr<util::guidance::EntryClass>(
|
||||
shared_memory, storage::SharedDataLayout::ENTRY_CLASS);
|
||||
typename util::ShM<util::guidance::EntryClass, true>::vector entry_class_table(
|
||||
entry_class_ptr, data_layout->num_entries[storage::SharedDataLayout::ENTRY_CLASS]);
|
||||
m_entry_class_table = std::move(entry_class_table);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~SharedDataFacade() {}
|
||||
|
||||
@@ -276,8 +381,8 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
"No shared memory blocks found, have you forgotten to run osrm-datastore?");
|
||||
}
|
||||
data_timestamp_ptr = static_cast<storage::SharedDataTimestamp *>(
|
||||
storage::makeSharedMemory(storage::CURRENT_REGIONS,
|
||||
sizeof(storage::SharedDataTimestamp), false, false)
|
||||
storage::makeSharedMemory(
|
||||
storage::CURRENT_REGIONS, sizeof(storage::SharedDataTimestamp), false, false)
|
||||
->Ptr());
|
||||
CURRENT_LAYOUT = storage::LAYOUT_NONE;
|
||||
CURRENT_DATA = storage::DATA_NONE;
|
||||
@@ -347,9 +452,11 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
LoadTimestamp();
|
||||
LoadViaNodeList();
|
||||
LoadNames();
|
||||
LoadTurnLaneDescriptions();
|
||||
LoadCoreInformation();
|
||||
LoadProfileProperties();
|
||||
LoadRTree();
|
||||
LoadIntersectionClasses();
|
||||
|
||||
util::SimpleLogger().Write() << "number of geometries: "
|
||||
<< m_coordinate_list.size();
|
||||
@@ -411,6 +518,11 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
return m_coordinate_list[id];
|
||||
}
|
||||
|
||||
OSMNodeID GetOSMNodeIDOfNode(const unsigned id) const override final
|
||||
{
|
||||
return m_osmnodeid_list.at(id);
|
||||
}
|
||||
|
||||
virtual void GetUncompressedGeometry(const EdgeID id,
|
||||
std::vector<NodeID> &result_nodes) const override final
|
||||
{
|
||||
@@ -419,9 +531,9 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
|
||||
result_nodes.clear();
|
||||
result_nodes.reserve(end - begin);
|
||||
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end,
|
||||
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge)
|
||||
{
|
||||
std::for_each(m_geometry_list.begin() + begin,
|
||||
m_geometry_list.begin() + end,
|
||||
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) {
|
||||
result_nodes.emplace_back(edge.node_id);
|
||||
});
|
||||
}
|
||||
@@ -435,9 +547,9 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
|
||||
result_weights.clear();
|
||||
result_weights.reserve(end - begin);
|
||||
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end,
|
||||
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge)
|
||||
{
|
||||
std::for_each(m_geometry_list.begin() + begin,
|
||||
m_geometry_list.begin() + end,
|
||||
[&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge) {
|
||||
result_weights.emplace_back(edge.weight);
|
||||
});
|
||||
}
|
||||
@@ -462,8 +574,8 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
const util::Coordinate north_east) const override final
|
||||
{
|
||||
BOOST_ASSERT(m_geospatial_query.get());
|
||||
const util::RectangleInt2D bbox{south_west.lon, north_east.lon, south_west.lat,
|
||||
north_east.lat};
|
||||
const util::RectangleInt2D bbox{
|
||||
south_west.lon, north_east.lon, south_west.lat, north_east.lat};
|
||||
return m_geospatial_query->Search(bbox);
|
||||
}
|
||||
|
||||
@@ -484,8 +596,8 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
{
|
||||
BOOST_ASSERT(m_geospatial_query.get());
|
||||
|
||||
return m_geospatial_query->NearestPhantomNodesInRange(input_coordinate, max_distance,
|
||||
bearing, bearing_range);
|
||||
return m_geospatial_query->NearestPhantomNodesInRange(
|
||||
input_coordinate, max_distance, bearing, bearing_range);
|
||||
}
|
||||
|
||||
std::vector<PhantomNodeWithDistance>
|
||||
@@ -515,8 +627,8 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
{
|
||||
BOOST_ASSERT(m_geospatial_query.get());
|
||||
|
||||
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, bearing,
|
||||
bearing_range);
|
||||
return m_geospatial_query->NearestPhantomNodes(
|
||||
input_coordinate, max_results, bearing, bearing_range);
|
||||
}
|
||||
|
||||
std::vector<PhantomNodeWithDistance>
|
||||
@@ -528,8 +640,8 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
{
|
||||
BOOST_ASSERT(m_geospatial_query.get());
|
||||
|
||||
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance,
|
||||
bearing, bearing_range);
|
||||
return m_geospatial_query->NearestPhantomNodes(
|
||||
input_coordinate, max_results, max_distance, bearing, bearing_range);
|
||||
}
|
||||
|
||||
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||
@@ -541,9 +653,8 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
input_coordinate);
|
||||
}
|
||||
|
||||
std::pair<PhantomNode, PhantomNode>
|
||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||
const double max_distance) const override final
|
||||
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||
const util::Coordinate input_coordinate, const double max_distance) const override final
|
||||
{
|
||||
BOOST_ASSERT(m_geospatial_query.get());
|
||||
|
||||
@@ -595,11 +706,30 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
{
|
||||
result.resize(range.back() - range.front() + 1);
|
||||
std::copy(m_names_char_list.begin() + range.front(),
|
||||
m_names_char_list.begin() + range.back() + 1, result.begin());
|
||||
m_names_char_list.begin() + range.back() + 1,
|
||||
result.begin());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string GetPronunciationForID(const unsigned name_id) const override final
|
||||
{
|
||||
// We store the pronunciation after the name and destination of a street.
|
||||
// We do this to get around the street length limit of 255 which would hit
|
||||
// if we concatenate these. Order (see extractor_callbacks):
|
||||
// name (0), destination (1), pronunciation (2)
|
||||
return GetNameForID(name_id + 2);
|
||||
}
|
||||
|
||||
std::string GetDestinationsForID(const unsigned name_id) const override final
|
||||
{
|
||||
// We store the destination after the name of a street.
|
||||
// We do this to get around the street length limit of 255 which would hit
|
||||
// if we concatenate these. Order (see extractor_callbacks):
|
||||
// name (0), destination (1), pronunciation (2)
|
||||
return GetNameForID(name_id + 1);
|
||||
}
|
||||
|
||||
bool IsCoreNode(const NodeID id) const override final
|
||||
{
|
||||
if (m_is_core_node.size() > 0)
|
||||
@@ -634,11 +764,10 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
}
|
||||
else
|
||||
{
|
||||
std::for_each(m_datasource_list.begin() + begin, m_datasource_list.begin() + end,
|
||||
[&](const uint8_t &datasource_id)
|
||||
{
|
||||
result_datasources.push_back(datasource_id);
|
||||
});
|
||||
std::for_each(
|
||||
m_datasource_list.begin() + begin,
|
||||
m_datasource_list.begin() + end,
|
||||
[&](const uint8_t &datasource_id) { result_datasources.push_back(datasource_id); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,6 +792,56 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
{
|
||||
return m_profile_properties->continue_straight_at_waypoint;
|
||||
}
|
||||
|
||||
BearingClassID GetBearingClassID(const NodeID id) const override final
|
||||
{
|
||||
return m_bearing_class_id_table.at(id);
|
||||
}
|
||||
|
||||
util::guidance::BearingClass
|
||||
GetBearingClass(const BearingClassID bearing_class_id) const override final
|
||||
{
|
||||
BOOST_ASSERT(bearing_class_id != INVALID_BEARING_CLASSID);
|
||||
auto range = m_bearing_ranges_table->GetRange(bearing_class_id);
|
||||
util::guidance::BearingClass result;
|
||||
for (auto itr = m_bearing_values_table.begin() + range.front();
|
||||
itr != m_bearing_values_table.begin() + range.back() + 1;
|
||||
++itr)
|
||||
result.add(*itr);
|
||||
return result;
|
||||
}
|
||||
|
||||
EntryClassID GetEntryClassID(const EdgeID eid) const override final
|
||||
{
|
||||
return m_entry_class_id_list.at(eid);
|
||||
}
|
||||
|
||||
util::guidance::EntryClass GetEntryClass(const EntryClassID entry_class_id) const override final
|
||||
{
|
||||
return m_entry_class_table.at(entry_class_id);
|
||||
}
|
||||
|
||||
bool hasLaneData(const EdgeID id) const override final
|
||||
{
|
||||
return INVALID_LANE_DATAID != m_lane_data_id.at(id);
|
||||
}
|
||||
|
||||
util::guidance::LaneTupelIdPair GetLaneData(const EdgeID id) const override final
|
||||
{
|
||||
BOOST_ASSERT(hasLaneData(id));
|
||||
return m_lane_tupel_id_pairs.at(m_lane_data_id.at(id));
|
||||
}
|
||||
|
||||
extractor::guidance::TurnLaneDescription
|
||||
GetTurnDescription(const LaneDescriptionID lane_description_id) const override final
|
||||
{
|
||||
if (lane_description_id == INVALID_LANE_DESCRIPTIONID)
|
||||
return {};
|
||||
else
|
||||
return extractor::guidance::TurnLaneDescription(
|
||||
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id],
|
||||
m_lane_description_masks.begin() + m_lane_description_offsets[lane_description_id + 1]);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#ifndef ENGINE_HPP
|
||||
#define ENGINE_HPP
|
||||
|
||||
#include "engine/status.hpp"
|
||||
#include "storage/shared_barriers.hpp"
|
||||
#include "engine/status.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef GEOSPATIAL_QUERY_HPP
|
||||
#define GEOSPATIAL_QUERY_HPP
|
||||
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "util/bearing.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/rectangle.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
#include "util/web_mercator.hpp"
|
||||
|
||||
#include "osrm/coordinate.hpp"
|
||||
@@ -30,9 +30,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
using CandidateSegment = typename RTreeT::CandidateSegment;
|
||||
|
||||
public:
|
||||
GeospatialQuery(RTreeT &rtree_,
|
||||
const CoordinateList &coordinates_,
|
||||
DataFacadeT &datafacade_)
|
||||
GeospatialQuery(RTreeT &rtree_, const CoordinateList &coordinates_, DataFacadeT &datafacade_)
|
||||
: rtree(rtree_), coordinates(coordinates_), datafacade(datafacade_)
|
||||
{
|
||||
}
|
||||
@@ -45,17 +43,14 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
// Returns nearest PhantomNodes in the given bearing range within max_distance.
|
||||
// Does not filter by small/big component!
|
||||
std::vector<PhantomNodeWithDistance>
|
||||
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, const double max_distance) const
|
||||
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
|
||||
const double max_distance) const
|
||||
{
|
||||
auto results =
|
||||
rtree.Nearest(input_coordinate,
|
||||
[](const CandidateSegment &)
|
||||
{
|
||||
return std::make_pair(true, true);
|
||||
},
|
||||
[](const CandidateSegment &) { return std::make_pair(true, true); },
|
||||
[this, max_distance, input_coordinate](const std::size_t,
|
||||
const CandidateSegment &segment)
|
||||
{
|
||||
const CandidateSegment &segment) {
|
||||
return CheckSegmentDistance(input_coordinate, segment, max_distance);
|
||||
});
|
||||
|
||||
@@ -72,13 +67,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
{
|
||||
auto results = rtree.Nearest(
|
||||
input_coordinate,
|
||||
[this, bearing, bearing_range, max_distance](const CandidateSegment &segment)
|
||||
{
|
||||
[this, bearing, bearing_range, max_distance](const CandidateSegment &segment) {
|
||||
return CheckSegmentBearing(segment, bearing, bearing_range);
|
||||
},
|
||||
[this, max_distance, input_coordinate](const std::size_t,
|
||||
const CandidateSegment &segment)
|
||||
{
|
||||
const CandidateSegment &segment) {
|
||||
return CheckSegmentDistance(input_coordinate, segment, max_distance);
|
||||
});
|
||||
|
||||
@@ -95,12 +88,10 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
{
|
||||
auto results =
|
||||
rtree.Nearest(input_coordinate,
|
||||
[this, bearing, bearing_range](const CandidateSegment &segment)
|
||||
{
|
||||
[this, bearing, bearing_range](const CandidateSegment &segment) {
|
||||
return CheckSegmentBearing(segment, bearing, bearing_range);
|
||||
},
|
||||
[max_results](const std::size_t num_results, const CandidateSegment &)
|
||||
{
|
||||
[max_results](const std::size_t num_results, const CandidateSegment &) {
|
||||
return num_results >= max_results;
|
||||
});
|
||||
|
||||
@@ -119,13 +110,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
{
|
||||
auto results =
|
||||
rtree.Nearest(input_coordinate,
|
||||
[this, bearing, bearing_range](const CandidateSegment &segment)
|
||||
{
|
||||
[this, bearing, bearing_range](const CandidateSegment &segment) {
|
||||
return CheckSegmentBearing(segment, bearing, bearing_range);
|
||||
},
|
||||
[this, max_distance, max_results, input_coordinate](
|
||||
const std::size_t num_results, const CandidateSegment &segment)
|
||||
{
|
||||
const std::size_t num_results, const CandidateSegment &segment) {
|
||||
return num_results >= max_results ||
|
||||
CheckSegmentDistance(input_coordinate, segment, max_distance);
|
||||
});
|
||||
@@ -140,12 +129,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
{
|
||||
auto results =
|
||||
rtree.Nearest(input_coordinate,
|
||||
[](const CandidateSegment &)
|
||||
{
|
||||
return std::make_pair(true, true);
|
||||
},
|
||||
[max_results](const std::size_t num_results, const CandidateSegment &)
|
||||
{
|
||||
[](const CandidateSegment &) { return std::make_pair(true, true); },
|
||||
[max_results](const std::size_t num_results, const CandidateSegment &) {
|
||||
return num_results >= max_results;
|
||||
});
|
||||
|
||||
@@ -161,13 +146,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
{
|
||||
auto results =
|
||||
rtree.Nearest(input_coordinate,
|
||||
[](const CandidateSegment &)
|
||||
{
|
||||
return std::make_pair(true, true);
|
||||
},
|
||||
[](const CandidateSegment &) { return std::make_pair(true, true); },
|
||||
[this, max_distance, max_results, input_coordinate](
|
||||
const std::size_t num_results, const CandidateSegment &segment)
|
||||
{
|
||||
const std::size_t num_results, const CandidateSegment &segment) {
|
||||
return num_results >= max_results ||
|
||||
CheckSegmentDistance(input_coordinate, segment, max_distance);
|
||||
});
|
||||
@@ -185,8 +166,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
bool has_big_component = false;
|
||||
auto results = rtree.Nearest(
|
||||
input_coordinate,
|
||||
[&has_big_component, &has_small_component](const CandidateSegment &segment)
|
||||
{
|
||||
[&has_big_component, &has_small_component](const CandidateSegment &segment) {
|
||||
auto use_segment = (!has_small_component ||
|
||||
(!has_big_component && !segment.data.component.is_tiny));
|
||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||
@@ -196,9 +176,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
|
||||
return use_directions;
|
||||
},
|
||||
[this, &has_big_component, max_distance,
|
||||
input_coordinate](const std::size_t num_results, const CandidateSegment &segment)
|
||||
{
|
||||
[this, &has_big_component, max_distance, input_coordinate](
|
||||
const std::size_t num_results, const CandidateSegment &segment) {
|
||||
return (num_results > 0 && has_big_component) ||
|
||||
CheckSegmentDistance(input_coordinate, segment, max_distance);
|
||||
});
|
||||
@@ -222,8 +201,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
bool has_big_component = false;
|
||||
auto results = rtree.Nearest(
|
||||
input_coordinate,
|
||||
[&has_big_component, &has_small_component](const CandidateSegment &segment)
|
||||
{
|
||||
[&has_big_component, &has_small_component](const CandidateSegment &segment) {
|
||||
auto use_segment = (!has_small_component ||
|
||||
(!has_big_component && !segment.data.component.is_tiny));
|
||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||
@@ -233,8 +211,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
|
||||
return use_directions;
|
||||
},
|
||||
[&has_big_component](const std::size_t num_results, const CandidateSegment &)
|
||||
{
|
||||
[&has_big_component](const std::size_t num_results, const CandidateSegment &) {
|
||||
return num_results > 0 && has_big_component;
|
||||
});
|
||||
|
||||
@@ -257,9 +234,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
bool has_big_component = false;
|
||||
auto results = rtree.Nearest(
|
||||
input_coordinate,
|
||||
[this, bearing, bearing_range, &has_big_component,
|
||||
&has_small_component](const CandidateSegment &segment)
|
||||
{
|
||||
[this, bearing, bearing_range, &has_big_component, &has_small_component](
|
||||
const CandidateSegment &segment) {
|
||||
auto use_segment = (!has_small_component ||
|
||||
(!has_big_component && !segment.data.component.is_tiny));
|
||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||
@@ -276,8 +252,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
|
||||
return use_directions;
|
||||
},
|
||||
[&has_big_component](const std::size_t num_results, const CandidateSegment &)
|
||||
{
|
||||
[&has_big_component](const std::size_t num_results, const CandidateSegment &) {
|
||||
return num_results > 0 && has_big_component;
|
||||
});
|
||||
|
||||
@@ -303,9 +278,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
bool has_big_component = false;
|
||||
auto results = rtree.Nearest(
|
||||
input_coordinate,
|
||||
[this, bearing, bearing_range, &has_big_component,
|
||||
&has_small_component](const CandidateSegment &segment)
|
||||
{
|
||||
[this, bearing, bearing_range, &has_big_component, &has_small_component](
|
||||
const CandidateSegment &segment) {
|
||||
auto use_segment = (!has_small_component ||
|
||||
(!has_big_component && !segment.data.component.is_tiny));
|
||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||
@@ -322,9 +296,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
|
||||
return use_directions;
|
||||
},
|
||||
[this, &has_big_component, max_distance,
|
||||
input_coordinate](const std::size_t num_results, const CandidateSegment &segment)
|
||||
{
|
||||
[this, &has_big_component, max_distance, input_coordinate](
|
||||
const std::size_t num_results, const CandidateSegment &segment) {
|
||||
return (num_results > 0 && has_big_component) ||
|
||||
CheckSegmentDistance(input_coordinate, segment, max_distance);
|
||||
});
|
||||
@@ -345,9 +318,10 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
const std::vector<EdgeData> &results) const
|
||||
{
|
||||
std::vector<PhantomNodeWithDistance> distance_and_phantoms(results.size());
|
||||
std::transform(results.begin(), results.end(), distance_and_phantoms.begin(),
|
||||
[this, &input_coordinate](const EdgeData &data)
|
||||
{
|
||||
std::transform(results.begin(),
|
||||
results.end(),
|
||||
distance_and_phantoms.begin(),
|
||||
[this, &input_coordinate](const EdgeData &data) {
|
||||
return MakePhantomNode(input_coordinate, data);
|
||||
});
|
||||
return distance_and_phantoms;
|
||||
@@ -359,9 +333,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
util::Coordinate point_on_segment;
|
||||
double ratio;
|
||||
const auto current_perpendicular_distance =
|
||||
util::coordinate_calculation::perpendicularDistance(
|
||||
coordinates[data.u], coordinates[data.v], input_coordinate,
|
||||
point_on_segment, ratio);
|
||||
util::coordinate_calculation::perpendicularDistance(coordinates[data.u],
|
||||
coordinates[data.v],
|
||||
input_coordinate,
|
||||
point_on_segment,
|
||||
ratio);
|
||||
|
||||
// Find the node-based-edge that this belongs to, and directly
|
||||
// calculate the forward_weight, forward_offset, reverse_weight, reverse_offset
|
||||
@@ -390,7 +366,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
BOOST_ASSERT(data.fwd_segment_position < reverse_weight_vector.size());
|
||||
|
||||
for (std::size_t i = 0;
|
||||
i < reverse_weight_vector.size() - data.fwd_segment_position - 1; i++)
|
||||
i < reverse_weight_vector.size() - data.fwd_segment_position - 1;
|
||||
i++)
|
||||
{
|
||||
reverse_offset += reverse_weight_vector[i];
|
||||
}
|
||||
@@ -408,9 +385,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
reverse_weight *= 1.0 - ratio;
|
||||
}
|
||||
|
||||
auto transformed = PhantomNodeWithDistance{PhantomNode{data, forward_weight, forward_offset,
|
||||
reverse_weight, reverse_offset,
|
||||
point_on_segment, input_coordinate},
|
||||
auto transformed = PhantomNodeWithDistance{PhantomNode{data,
|
||||
forward_weight,
|
||||
forward_offset,
|
||||
reverse_weight,
|
||||
reverse_offset,
|
||||
point_on_segment,
|
||||
input_coordinate},
|
||||
current_perpendicular_distance};
|
||||
|
||||
return transformed;
|
||||
@@ -449,12 +430,12 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
: (forward_edge_bearing + 180);
|
||||
|
||||
const bool forward_bearing_valid =
|
||||
util::bearing::CheckInBounds(std::round(forward_edge_bearing), filter_bearing,
|
||||
filter_bearing_range) &&
|
||||
util::bearing::CheckInBounds(
|
||||
std::round(forward_edge_bearing), filter_bearing, filter_bearing_range) &&
|
||||
segment.data.forward_segment_id.enabled;
|
||||
const bool backward_bearing_valid =
|
||||
util::bearing::CheckInBounds(std::round(backward_edge_bearing), filter_bearing,
|
||||
filter_bearing_range) &&
|
||||
util::bearing::CheckInBounds(
|
||||
std::round(backward_edge_bearing), filter_bearing, filter_bearing_range) &&
|
||||
segment.data.reverse_segment_id.enabled;
|
||||
return std::make_pair(forward_bearing_valid, backward_bearing_valid);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
#ifndef ENGINE_GUIDANCE_ASSEMBLE_GEOMETRY_HPP
|
||||
#define ENGINE_GUIDANCE_ASSEMBLE_GEOMETRY_HPP
|
||||
|
||||
#include "engine/internal_route_result.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/toolkit.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "engine/guidance/toolkit.hpp"
|
||||
#include "engine/internal_route_result.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -31,11 +32,10 @@ namespace guidance
|
||||
// |---| segment 1
|
||||
// |---| segment 2
|
||||
// |---| segment 3
|
||||
template <typename DataFacadeT>
|
||||
LegGeometry assembleGeometry(const DataFacadeT &facade,
|
||||
const std::vector<PathData> &leg_data,
|
||||
const PhantomNode &source_node,
|
||||
const PhantomNode &target_node)
|
||||
inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
|
||||
const std::vector<PathData> &leg_data,
|
||||
const PhantomNode &source_node,
|
||||
const PhantomNode &target_node)
|
||||
{
|
||||
LegGeometry geometry;
|
||||
|
||||
@@ -43,34 +43,57 @@ LegGeometry assembleGeometry(const DataFacadeT &facade,
|
||||
geometry.segment_offsets.push_back(0);
|
||||
geometry.locations.push_back(source_node.location);
|
||||
|
||||
// Need to get the node ID preceding the source phantom node
|
||||
// TODO: check if this was traversed in reverse?
|
||||
std::vector<NodeID> reverse_geometry;
|
||||
facade.GetUncompressedGeometry(source_node.reverse_packed_geometry_id, reverse_geometry);
|
||||
geometry.osm_node_ids.push_back(facade.GetOSMNodeIDOfNode(
|
||||
reverse_geometry[reverse_geometry.size() - source_node.fwd_segment_position - 1]));
|
||||
|
||||
auto cumulative_distance = 0.;
|
||||
auto current_distance = 0.;
|
||||
auto prev_coordinate = geometry.locations.front();
|
||||
for (const auto &path_point : leg_data)
|
||||
{
|
||||
auto coordinate = facade.GetCoordinateOfNode(path_point.turn_via_node);
|
||||
current_distance +=
|
||||
current_distance =
|
||||
util::coordinate_calculation::haversineDistance(prev_coordinate, coordinate);
|
||||
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)
|
||||
{
|
||||
geometry.segment_distances.push_back(current_distance);
|
||||
geometry.segment_distances.push_back(cumulative_distance);
|
||||
geometry.segment_offsets.push_back(geometry.locations.size());
|
||||
current_distance = 0.;
|
||||
cumulative_distance = 0.;
|
||||
}
|
||||
|
||||
prev_coordinate = coordinate;
|
||||
geometry.annotations.emplace_back(
|
||||
LegGeometry::Annotation{current_distance, path_point.duration_until_turn / 10.});
|
||||
geometry.locations.push_back(std::move(coordinate));
|
||||
geometry.osm_node_ids.push_back(facade.GetOSMNodeIDOfNode(path_point.turn_via_node));
|
||||
}
|
||||
current_distance +=
|
||||
current_distance =
|
||||
util::coordinate_calculation::haversineDistance(prev_coordinate, target_node.location);
|
||||
cumulative_distance += current_distance;
|
||||
// segment leading to the target node
|
||||
geometry.segment_distances.push_back(current_distance);
|
||||
geometry.segment_distances.push_back(cumulative_distance);
|
||||
geometry.annotations.emplace_back(
|
||||
LegGeometry::Annotation{current_distance, target_node.forward_weight / 10.});
|
||||
geometry.segment_offsets.push_back(geometry.locations.size());
|
||||
geometry.locations.push_back(target_node.location);
|
||||
|
||||
// Need to get the node ID following the destination phantom node
|
||||
// TODO: check if this was traversed in reverse??
|
||||
std::vector<NodeID> forward_geometry;
|
||||
facade.GetUncompressedGeometry(target_node.forward_packed_geometry_id, forward_geometry);
|
||||
geometry.osm_node_ids.push_back(
|
||||
facade.GetOSMNodeIDOfNode(forward_geometry[target_node.fwd_segment_position]));
|
||||
|
||||
BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1);
|
||||
BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size());
|
||||
BOOST_ASSERT(geometry.annotations.size() == geometry.locations.size() - 1);
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
@@ -35,11 +35,12 @@ struct NamedSegment
|
||||
|
||||
template <std::size_t SegmentNumber>
|
||||
|
||||
std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathData> &route_data)
|
||||
std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathData> &route_data,
|
||||
const PhantomNode &target_node,
|
||||
const bool target_traversed_in_reverse)
|
||||
{
|
||||
// merges segments with same name id
|
||||
const auto collapse_segments = [](std::vector<NamedSegment> &segments)
|
||||
{
|
||||
const auto collapse_segments = [](std::vector<NamedSegment> &segments) {
|
||||
auto out = segments.begin();
|
||||
auto end = segments.end();
|
||||
|
||||
@@ -69,47 +70,48 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathDa
|
||||
std::vector<NamedSegment> segments(route_data.size());
|
||||
std::uint32_t index = 0;
|
||||
std::transform(
|
||||
route_data.begin(), route_data.end(), segments.begin(), [&index](const PathData &point)
|
||||
{
|
||||
route_data.begin(), route_data.end(), segments.begin(), [&index](const PathData &point) {
|
||||
return NamedSegment{point.duration_until_turn, index++, point.name_id};
|
||||
});
|
||||
const auto target_duration =
|
||||
target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight;
|
||||
if (target_duration > 1)
|
||||
segments.push_back({target_duration, index++, target_node.name_id});
|
||||
// this makes sure that the segment with the lowest position comes first
|
||||
std::sort(segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs)
|
||||
{
|
||||
return lhs.name_id < rhs.name_id ||
|
||||
(lhs.name_id == rhs.name_id && lhs.position < rhs.position);
|
||||
});
|
||||
std::sort(
|
||||
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
|
||||
return lhs.name_id < rhs.name_id ||
|
||||
(lhs.name_id == rhs.name_id && lhs.position < rhs.position);
|
||||
});
|
||||
auto new_end = collapse_segments(segments);
|
||||
segments.resize(new_end - segments.begin());
|
||||
|
||||
// Filter out segments with an empty name (name_id == 0)
|
||||
new_end = std::remove_if(segments.begin(), segments.end(), [](const NamedSegment &segment)
|
||||
{
|
||||
return segment.name_id == 0;
|
||||
});
|
||||
new_end = std::remove_if(segments.begin(), segments.end(), [](const NamedSegment &segment) {
|
||||
return segment.name_id == 0;
|
||||
});
|
||||
segments.resize(new_end - segments.begin());
|
||||
|
||||
// sort descending
|
||||
std::sort(segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs)
|
||||
{
|
||||
return lhs.duration > rhs.duration ||
|
||||
(lhs.duration == rhs.duration && lhs.position < rhs.position);
|
||||
});
|
||||
std::sort(
|
||||
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
|
||||
return lhs.duration > rhs.duration ||
|
||||
(lhs.duration == rhs.duration && lhs.position < rhs.position);
|
||||
});
|
||||
|
||||
// make sure the segments are sorted by position
|
||||
segments.resize(std::min(segments.size(), SegmentNumber));
|
||||
std::sort(segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs)
|
||||
{
|
||||
return lhs.position < rhs.position;
|
||||
});
|
||||
std::sort(
|
||||
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
|
||||
return lhs.position < rhs.position;
|
||||
});
|
||||
|
||||
std::array<std::uint32_t, SegmentNumber> summary;
|
||||
std::fill(summary.begin(), summary.end(), 0);
|
||||
std::transform(segments.begin(), segments.end(), summary.begin(),
|
||||
[](const NamedSegment &segment)
|
||||
{
|
||||
return segment.name_id;
|
||||
});
|
||||
std::transform(segments.begin(),
|
||||
segments.end(),
|
||||
summary.begin(),
|
||||
[](const NamedSegment &segment) { return segment.name_id; });
|
||||
return summary;
|
||||
}
|
||||
}
|
||||
@@ -126,9 +128,11 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
||||
(target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight) /
|
||||
10.;
|
||||
|
||||
auto distance = std::accumulate(leg_geometry.segment_distances.begin(),
|
||||
leg_geometry.segment_distances.end(), 0.);
|
||||
auto duration = std::accumulate(route_data.begin(), route_data.end(), 0.,
|
||||
auto distance = std::accumulate(
|
||||
leg_geometry.segment_distances.begin(), leg_geometry.segment_distances.end(), 0.);
|
||||
auto duration = std::accumulate(route_data.begin(),
|
||||
route_data.end(),
|
||||
0.,
|
||||
[](const double sum, const PathData &data) {
|
||||
return sum + data.duration_until_turn;
|
||||
}) /
|
||||
@@ -166,14 +170,17 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
||||
std::string summary;
|
||||
if (needs_summary)
|
||||
{
|
||||
auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>(route_data);
|
||||
auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>(
|
||||
route_data, target_node, target_traversed_in_reverse);
|
||||
if (route_data.empty())
|
||||
summary_array[0] = source_node.name_id;
|
||||
|
||||
BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0);
|
||||
BOOST_ASSERT(summary_array.begin() != summary_array.end());
|
||||
summary = std::accumulate(std::next(summary_array.begin()), summary_array.end(),
|
||||
summary = std::accumulate(std::next(summary_array.begin()),
|
||||
summary_array.end(),
|
||||
facade.GetNameForID(summary_array.front()),
|
||||
[&facade](std::string previous, const std::uint32_t name_id)
|
||||
{
|
||||
[&facade](std::string previous, const std::uint32_t name_id) {
|
||||
if (name_id != 0)
|
||||
{
|
||||
previous += ", " + facade.GetNameForID(name_id);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef ENGINE_GUIDANCE_ASSEMBLE_ROUTE_HPP
|
||||
#define ENGINE_GUIDANCE_ASSEMBLE_ROUTE_HPP
|
||||
|
||||
#include "engine/guidance/route_leg.hpp"
|
||||
#include "engine/guidance/route.hpp"
|
||||
#include "engine/guidance/route_leg.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
#ifndef ENGINE_GUIDANCE_ASSEMBLE_STEPS_HPP_
|
||||
#define ENGINE_GUIDANCE_ASSEMBLE_STEPS_HPP_
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "engine/guidance/step_maneuver.hpp"
|
||||
#include "engine/guidance/toolkit.hpp"
|
||||
#include "engine/internal_route_result.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "util/bearing.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <cstddef>
|
||||
@@ -25,24 +31,19 @@ namespace guidance
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
|
||||
const LegGeometry &leg_geometry,
|
||||
const std::size_t segment_index);
|
||||
|
||||
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
|
||||
const WaypointType waypoint_type,
|
||||
const LegGeometry &leg_geometry);
|
||||
|
||||
std::pair<short, short> getDepartBearings(const LegGeometry &leg_geometry);
|
||||
std::pair<short, short> getArriveBearings(const LegGeometry &leg_geometry);
|
||||
std::pair<short, short> getIntermediateBearings(const LegGeometry &leg_geometry,
|
||||
const std::size_t segment_index);
|
||||
} // ns detail
|
||||
|
||||
template <typename DataFacadeT>
|
||||
std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
const std::vector<PathData> &leg_data,
|
||||
const LegGeometry &leg_geometry,
|
||||
const PhantomNode &source_node,
|
||||
const PhantomNode &target_node,
|
||||
const bool source_traversed_in_reverse,
|
||||
const bool target_traversed_in_reverse)
|
||||
inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &facade,
|
||||
const std::vector<PathData> &leg_data,
|
||||
const LegGeometry &leg_geometry,
|
||||
const PhantomNode &source_node,
|
||||
const PhantomNode &target_node,
|
||||
const bool source_traversed_in_reverse,
|
||||
const bool target_traversed_in_reverse)
|
||||
{
|
||||
const double constexpr ZERO_DURATION = 0., ZERO_DISTANCE = 0.;
|
||||
const constexpr char *NO_ROTARY_NAME = "";
|
||||
@@ -64,13 +65,24 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
std::size_t segment_index = 0;
|
||||
BOOST_ASSERT(leg_geometry.locations.size() >= 2);
|
||||
|
||||
auto bearings = detail::getDepartBearings(leg_geometry);
|
||||
|
||||
StepManeuver maneuver{source_node.location,
|
||||
bearings.first,
|
||||
bearings.second,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Depart,
|
||||
0,
|
||||
util::guidance::LaneTupel(),
|
||||
{}};
|
||||
Intersection intersection{source_node.location,
|
||||
std::vector<short>({bearings.second}),
|
||||
std::vector<bool>({true}),
|
||||
Intersection::NO_INDEX,
|
||||
0};
|
||||
|
||||
if (leg_data.size() > 0)
|
||||
{
|
||||
|
||||
StepManeuver maneuver = detail::stepManeuverFromGeometry(
|
||||
extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::Depart, leg_geometry);
|
||||
maneuver.location = source_node.location;
|
||||
|
||||
// PathData saves the information we need of the segment _before_ the turn,
|
||||
// but a RouteStep is with regard to the segment after the turn.
|
||||
// We need to skip the first segment because it is already covered by the
|
||||
@@ -90,18 +102,60 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
{
|
||||
BOOST_ASSERT(segment_duration >= 0);
|
||||
const auto name = facade.GetNameForID(step_name_id);
|
||||
const auto pronunciation = facade.GetPronunciationForID(step_name_id);
|
||||
const auto destinations = facade.GetDestinationsForID(step_name_id);
|
||||
const auto distance = leg_geometry.segment_distances[segment_index];
|
||||
steps.push_back(RouteStep{step_name_id, name, NO_ROTARY_NAME,
|
||||
segment_duration / 10.0, distance, path_point.travel_mode,
|
||||
maneuver, leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1});
|
||||
if (leg_data_index + 1 < leg_data.size()){
|
||||
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
std::move(name),
|
||||
std::move(pronunciation),
|
||||
std::move(destinations),
|
||||
NO_ROTARY_NAME,
|
||||
segment_duration / 10.0,
|
||||
distance,
|
||||
path_point.travel_mode,
|
||||
maneuver,
|
||||
leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1,
|
||||
{intersection}});
|
||||
|
||||
if (leg_data_index + 1 < leg_data.size())
|
||||
{
|
||||
step_name_id = leg_data[leg_data_index + 1].name_id;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
step_name_id = target_node.name_id;
|
||||
}
|
||||
maneuver = detail::stepManeuverFromGeometry(path_point.turn_instruction,
|
||||
leg_geometry, segment_index);
|
||||
|
||||
bearings = detail::getIntermediateBearings(leg_geometry, segment_index);
|
||||
const auto entry_class = facade.GetEntryClass(path_point.entry_classid);
|
||||
const auto bearing_class =
|
||||
facade.GetBearingClass(facade.GetBearingClassID(path_point.turn_via_node));
|
||||
intersection.in = bearing_class.findMatchingBearing(
|
||||
util::bearing::reverseBearing(bearings.first));
|
||||
intersection.out = bearing_class.findMatchingBearing(bearings.second);
|
||||
intersection.location = facade.GetCoordinateOfNode(path_point.turn_via_node);
|
||||
intersection.bearings.clear();
|
||||
intersection.bearings.reserve(bearing_class.getAvailableBearings().size());
|
||||
std::copy(bearing_class.getAvailableBearings().begin(),
|
||||
bearing_class.getAvailableBearings().end(),
|
||||
std::back_inserter(intersection.bearings));
|
||||
intersection.entry.clear();
|
||||
for (auto idx : util::irange<std::size_t>(0, intersection.bearings.size()))
|
||||
{
|
||||
intersection.entry.push_back(entry_class.allowsEntry(idx));
|
||||
}
|
||||
maneuver = {intersection.location,
|
||||
bearings.first,
|
||||
bearings.second,
|
||||
path_point.turn_instruction,
|
||||
WaypointType::None,
|
||||
0,
|
||||
path_point.lane_data.first,
|
||||
(path_point.lane_data.second != INVALID_LANE_DESCRIPTIONID
|
||||
? facade.GetTurnDescription(path_point.lane_data.second)
|
||||
: extractor::guidance::TurnLaneDescription())};
|
||||
segment_index++;
|
||||
segment_duration = 0;
|
||||
}
|
||||
@@ -109,10 +163,18 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
const auto distance = leg_geometry.segment_distances[segment_index];
|
||||
const int duration = segment_duration + target_duration;
|
||||
BOOST_ASSERT(duration >= 0);
|
||||
steps.push_back(RouteStep{step_name_id, facade.GetNameForID(step_name_id),
|
||||
NO_ROTARY_NAME, duration / 10., distance, target_mode, maneuver,
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
facade.GetNameForID(step_name_id),
|
||||
facade.GetPronunciationForID(step_name_id),
|
||||
facade.GetDestinationsForID(step_name_id),
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
distance,
|
||||
target_mode,
|
||||
maneuver,
|
||||
leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1});
|
||||
leg_geometry.BackIndex(segment_index) + 1,
|
||||
{intersection}});
|
||||
}
|
||||
// In this case the source + target are on the same edge segment
|
||||
else
|
||||
@@ -123,29 +185,67 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
// |---| source_duration
|
||||
// |---------| target_duration
|
||||
|
||||
StepManeuver maneuver = detail::stepManeuverFromGeometry(
|
||||
extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::Depart, leg_geometry);
|
||||
int duration = target_duration - source_duration;
|
||||
BOOST_ASSERT(duration >= 0);
|
||||
|
||||
steps.push_back(RouteStep{source_node.name_id, facade.GetNameForID(source_node.name_id),
|
||||
NO_ROTARY_NAME, duration / 10.,
|
||||
leg_geometry.segment_distances[segment_index], source_mode,
|
||||
std::move(maneuver), leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1});
|
||||
steps.push_back(RouteStep{source_node.name_id,
|
||||
facade.GetNameForID(source_node.name_id),
|
||||
facade.GetPronunciationForID(source_node.name_id),
|
||||
facade.GetDestinationsForID(source_node.name_id),
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
leg_geometry.segment_distances[segment_index],
|
||||
source_mode,
|
||||
std::move(maneuver),
|
||||
leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1,
|
||||
{intersection}});
|
||||
}
|
||||
|
||||
BOOST_ASSERT(segment_index == number_of_segments - 1);
|
||||
bearings = detail::getArriveBearings(leg_geometry);
|
||||
// This step has length zero, the only reason we need it is the target location
|
||||
auto final_maneuver = detail::stepManeuverFromGeometry(
|
||||
extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::Arrive, leg_geometry);
|
||||
maneuver = {intersection.location,
|
||||
bearings.first,
|
||||
bearings.second,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Arrive,
|
||||
0,
|
||||
util::guidance::LaneTupel(),
|
||||
{}};
|
||||
intersection = {
|
||||
target_node.location,
|
||||
std::vector<short>({static_cast<short>(util::bearing::reverseBearing(bearings.first))}),
|
||||
std::vector<bool>({true}),
|
||||
0,
|
||||
Intersection::NO_INDEX};
|
||||
|
||||
BOOST_ASSERT(!leg_geometry.locations.empty());
|
||||
steps.push_back(RouteStep{target_node.name_id, facade.GetNameForID(target_node.name_id),
|
||||
NO_ROTARY_NAME, ZERO_DURATION, ZERO_DISTANCE, target_mode,
|
||||
final_maneuver, leg_geometry.locations.size() - 1,
|
||||
leg_geometry.locations.size()});
|
||||
steps.push_back(RouteStep{target_node.name_id,
|
||||
facade.GetNameForID(target_node.name_id),
|
||||
facade.GetPronunciationForID(target_node.name_id),
|
||||
facade.GetDestinationsForID(target_node.name_id),
|
||||
NO_ROTARY_NAME,
|
||||
ZERO_DURATION,
|
||||
ZERO_DISTANCE,
|
||||
target_mode,
|
||||
std::move(maneuver),
|
||||
leg_geometry.locations.size() - 1,
|
||||
leg_geometry.locations.size(),
|
||||
{intersection}});
|
||||
|
||||
BOOST_ASSERT(steps.front().intersections.size() == 1);
|
||||
BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1);
|
||||
BOOST_ASSERT(steps.front().intersections.front().entry.size() == 1);
|
||||
BOOST_ASSERT(steps.front().maneuver.waypoint_type == WaypointType::Depart);
|
||||
|
||||
BOOST_ASSERT(steps.back().intersections.size() == 1);
|
||||
BOOST_ASSERT(steps.back().intersections.front().bearings.size() == 1);
|
||||
BOOST_ASSERT(steps.back().intersections.front().entry.size() == 1);
|
||||
BOOST_ASSERT(steps.back().maneuver.waypoint_type == WaypointType::Arrive);
|
||||
BOOST_ASSERT(steps.back().maneuver.lanes.lanes_in_turn == 0);
|
||||
BOOST_ASSERT(steps.back().maneuver.lanes.first_lane_from_the_right == INVALID_LANEID);
|
||||
BOOST_ASSERT(steps.back().maneuver.lane_description.empty());
|
||||
return steps;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
|
||||
#define OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
// Constrains lanes for multi-hop situations where lane changes depend on earlier ones.
|
||||
// Instead of forcing users to change lanes rapidly in a short amount of time,
|
||||
// we anticipate lane changes emitting only matching lanes early on.
|
||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps);
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
#endif /* OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_ */
|
||||
@@ -3,13 +3,14 @@
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -30,6 +31,16 @@ struct LegGeometry
|
||||
std::vector<std::size_t> segment_offsets;
|
||||
// length of the segment in meters
|
||||
std::vector<double> segment_distances;
|
||||
// original OSM node IDs for each coordinate
|
||||
std::vector<OSMNodeID> osm_node_ids;
|
||||
|
||||
// Per-coordinate metadata
|
||||
struct Annotation
|
||||
{
|
||||
double distance;
|
||||
double duration;
|
||||
};
|
||||
std::vector<Annotation> annotations;
|
||||
|
||||
std::size_t FrontIndex(std::size_t segment_index) const
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user