Compare commits
178 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3ef936217f | |||
| 5bcd00a778 | |||
| a6828010ec | |||
| 17adeeecf5 | |||
| edafb0a83c | |||
| f7cc89400a | |||
| 473e4e129c | |||
| 2ac497c6b8 | |||
| defdc8cc4b | |||
| 4c5314676a | |||
| 1da044f3e3 | |||
| 45516ef534 | |||
| 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
|
||||
...
|
||||
|
||||
|
||||
+24
-15
@@ -13,10 +13,13 @@ notifications:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- "5.2"
|
||||
|
||||
cache:
|
||||
ccache: true
|
||||
apt: true
|
||||
directories:
|
||||
- test/cache
|
||||
|
||||
env:
|
||||
global:
|
||||
@@ -37,7 +40,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 +54,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
|
||||
@@ -112,22 +115,27 @@ matrix:
|
||||
#- env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
|
||||
before_install:
|
||||
- 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}
|
||||
- |
|
||||
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}
|
||||
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 +144,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,7 +157,7 @@ install:
|
||||
fi
|
||||
- popd
|
||||
- mkdir example/build && pushd example/build
|
||||
- cmake ..
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
|
||||
- make
|
||||
- popd
|
||||
|
||||
@@ -170,9 +179,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
|
||||
|
||||
+125
@@ -1,3 +1,128 @@
|
||||
# 5.2.6
|
||||
- Bugfixes
|
||||
- Fix numeric overflow in roundabout center calculation which throws an exception
|
||||
|
||||
# 5.2.5
|
||||
- Bugfixes
|
||||
- Fixes a segfault caused by incorrect trimming logic for very short steps.
|
||||
|
||||
# 5.2.4
|
||||
Changes from 5.2.3:
|
||||
- Bugfixes:
|
||||
- Fixed a crash that arised on roundabouts in combination with intermediate intersections and sliproads
|
||||
- Fixed #2518: Invalid bilinear interpolation when using raster data
|
||||
- Fixed #2546: The geometry returned by the match service was missing the last coordinate.
|
||||
|
||||
BREAKING: The data format changed between 5.2.3 and 5.2.4, you need to reprocess.
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
+76
-34
@@ -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,8 +9,24 @@ endif()
|
||||
|
||||
project(OSRM C CXX)
|
||||
set(OSRM_VERSION_MAJOR 5)
|
||||
set(OSRM_VERSION_MINOR 1)
|
||||
set(OSRM_VERSION_PATCH 0)
|
||||
set(OSRM_VERSION_MINOR 2)
|
||||
set(OSRM_VERSION_PATCH 6)
|
||||
|
||||
# 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)
|
||||
@@ -32,7 +49,7 @@ 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)
|
||||
@@ -54,7 +71,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)
|
||||
@@ -163,7 +180,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 +189,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 +221,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 +246,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,16 +303,19 @@ 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})
|
||||
@@ -311,12 +344,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 +445,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
|
||||
|
||||
+92
-6
@@ -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.|
|
||||
|
||||
@@ -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": []
|
||||
"annotation": {
|
||||
"distance": [5,5,10,5,5],
|
||||
"duration": [15,15,40,15,15],
|
||||
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -407,11 +437,39 @@ 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 `Intersections` 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":"depart",
|
||||
"modifier":"left"
|
||||
},
|
||||
"geometry":"{lu_IypwpAVrAvAdI",
|
||||
"mode":"driving",
|
||||
"intersections":[
|
||||
{"location":[13.39677,52.54366],
|
||||
"out":1,
|
||||
"bearings":[66,246],
|
||||
"entry":["true","true"]},
|
||||
{"location":[13.394718,52.543096],
|
||||
"in":0,
|
||||
"out":2,
|
||||
"bearings":[60,150,240,330],
|
||||
"entry":["false","true","true","true"]
|
||||
}
|
||||
]}
|
||||
```
|
||||
|
||||
### StepManeuver
|
||||
|
||||
#### Properties
|
||||
@@ -427,7 +485,7 @@ step.
|
||||
| `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` |
|
||||
| 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`) |
|
||||
@@ -474,11 +532,39 @@ step.
|
||||
| `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` |
|
||||
|
||||
|
||||
New properties (potentially depending on `type`) may be introduced in the future without an API version change.
|
||||
|
||||
### Intersections
|
||||
|
||||
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)
|
||||
|
||||
+5
-5
@@ -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>
|
||||
|
||||
|
||||
@@ -48,22 +48,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 +115,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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
+13
-11
@@ -17,19 +17,21 @@ 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
|
||||
@@ -66,7 +68,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 |
|
||||
|
||||
@@ -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,end of road right,arrive | road,road,road,road |
|
||||
| d,a | depart,continue left,end of road 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,125 @@
|
||||
@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 |
|
||||
| | | | | f | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | d |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | e |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name |
|
||||
| abc | 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 |
|
||||
@@ -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 | |
|
||||
|
||||
@@ -281,3 +281,18 @@ 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 |
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
@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 | turns | intersections |
|
||||
| a,c | through,through | depart,arrive | 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 | turns | intersections |
|
||||
| a,c | through,through | depart,arrive | 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 | turns | intersections |
|
||||
| a,c | through,through | depart,arrive | 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 | turns | intersections |
|
||||
| a,c | through,through | depart,arrive | 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 | turns | intersections |
|
||||
| a,d | through,through | depart,arrive | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
|
||||
|
||||
Scenario: Regression test #2424
|
||||
Given the node map
|
||||
| | | e | | | | | | i | | | | |
|
||||
| a | | b | | c | | d | | h | | k | | m |
|
||||
| | | | | f | | | | | | l | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name |
|
||||
| abcd | Fritz-Elsas-Straße |
|
||||
| hkm | Fritz-Elsas-Straße |
|
||||
| dhi | Martin-Luther-Straße |
|
||||
| be | corner |
|
||||
| kl | corner |
|
||||
| cf | corner |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,m | Fritz-Elsas-Straße,Fritz-Elsas-Straße| depart,arrive |
|
||||
|
||||
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 | turns | intersections |
|
||||
| a,d | through,through | depart,arrive | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 |
|
||||
| f,a | corner,through,through | depart,end of road left,arrive | true:0;true:90 false:180 true:270,true:0 false:90 true:270;true:90 |
|
||||
|
||||
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 | turns | intersections |
|
||||
| e,f | ea,fb,fb | depart,abcda-exit-1,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 |
|
||||
| e,g | ea,gc,gc | depart,abcda-exit-2,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0 |
|
||||
| e,h | ea,hd,hd | depart,abcda-exit-3,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330,true:90 false:210 true:330;true:270 |
|
||||
| e,2 | ea,abcda,abcda | depart,abcda-exit-undefined,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1 |
|
||||
| 1,g | abcda,gc,gc | depart,abcda-exit-2,arrive | true:214;false:30 true:150 true:270,true:30 true:180 false:330;true:0 |
|
||||
| 1,3 | abcda,abcda | depart,arrive | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214 |
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -806,3 +806,30 @@ 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 |
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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'].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'].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';
|
||||
@@ -28,19 +28,16 @@ module.exports = function () {
|
||||
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();
|
||||
});
|
||||
|
||||
|
||||
@@ -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,33 @@ 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.turnList = (instructions) => {
|
||||
@@ -168,6 +195,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,16 +33,19 @@ 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;
|
||||
|
||||
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]);
|
||||
@@ -108,6 +113,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 +126,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 |
|
||||
|
||||
@@ -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,14 +48,14 @@ 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
|
||||
@@ -76,9 +76,9 @@ Feature: Compass bearing
|
||||
| ha | yes |
|
||||
|
||||
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
|
||||
@@ -97,7 +97,7 @@ Feature: Compass bearing
|
||||
|
||||
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 +108,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 +161,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 +196,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 |
|
||||
|
||||
@@ -15,11 +15,11 @@ Feature: Bearing parameter
|
||||
|
||||
When I route I should get
|
||||
| from | to | bearings | route | bearing |
|
||||
| b | c | 90 90 | ad,ad | 90,0 |
|
||||
| b | c | 90 90 | ad,ad | 0->90,90->0|
|
||||
| b | c | 180 90 | | |
|
||||
| b | c | 80 100 | ad,ad | 90,0 |
|
||||
| b | c | 80 100 | ad,ad | 0->90,90->0|
|
||||
| b | c | 79 100 | | |
|
||||
| b | c | 79,11 100 | ad,ad | 90,0 |
|
||||
| b | c | 79,11 100 | ad,ad | 0->90,90->0|
|
||||
|
||||
Scenario: Testbot - Intial bearing in simple case
|
||||
Given the node map
|
||||
@@ -35,16 +35,16 @@ Feature: Bearing parameter
|
||||
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 | 45 45 | bc,bc | 0->44,44->0 +- 1|
|
||||
| 0 | c | 85 85 | | |
|
||||
| 0 | c | 95 95 | | |
|
||||
| 0 | c | 135 135 | ac,ac | 135 ~1% |
|
||||
| 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,22 +52,26 @@ 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 |
|
||||
| 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 |
|
||||
| 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
|
||||
@@ -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 100 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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,6 +23,7 @@ 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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -42,14 +42,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 +95,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,7 +144,9 @@ 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_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps);
|
||||
@@ -160,8 +173,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 +194,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,15 @@
|
||||
|
||||
// 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 "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 +19,9 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -65,6 +67,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 +116,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 +133,10 @@ 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 unsigned GetCheckSum() const = 0;
|
||||
|
||||
@@ -140,11 +146,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,25 @@
|
||||
#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/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,6 +74,7 @@ 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;
|
||||
@@ -89,6 +94,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 +114,8 @@ 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 LoadTimestamp(const boost::filesystem::path ×tamp_path)
|
||||
@@ -140,10 +158,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());
|
||||
}
|
||||
|
||||
@@ -154,6 +174,7 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
m_name_ID_list.resize(number_of_edges);
|
||||
m_turn_instruction_list.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)
|
||||
@@ -164,6 +185,7 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
m_name_ID_list[i] = current_edge_data.name_id;
|
||||
m_turn_instruction_list[i] = current_edge_data.turn_instruction;
|
||||
m_travel_mode_list[i] = current_edge_data.travel_mode;
|
||||
m_entry_class_id_list[i] = current_edge_data.entry_classid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +246,8 @@ 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);
|
||||
|
||||
@@ -241,7 +264,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;
|
||||
@@ -277,6 +301,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 +357,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 +375,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);
|
||||
@@ -316,6 +388,9 @@ class InternalDataFacade final : public BaseDataFacade
|
||||
|
||||
util::SimpleLogger().Write() << "loading rtree";
|
||||
LoadRTree();
|
||||
|
||||
util::SimpleLogger().Write() << "loading intersection class data";
|
||||
LoadIntersectionClasses(config.intersection_class_path);
|
||||
}
|
||||
|
||||
// search graph access
|
||||
@@ -367,6 +442,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 +462,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 +484,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 +515,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 +528,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 +594,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 +645,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 +661,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 +690,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 +706,41 @@ 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,21 +3,24 @@
|
||||
|
||||
// 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/compressed_edge_container.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/profile_properties.hpp"
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.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 +33,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 +52,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,6 +76,7 @@ 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<extractor::guidance::TurnInstruction, true>::vector m_turn_instruction_list;
|
||||
@@ -94,6 +98,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 +139,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,9 +167,18 @@ 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>(
|
||||
shared_memory, storage::SharedDataLayout::TRAVEL_MODE);
|
||||
util::ShM<extractor::TravelMode, true>::vector travel_mode_list(
|
||||
@@ -171,6 +198,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 +220,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>(
|
||||
@@ -263,6 +297,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 +344,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;
|
||||
@@ -350,6 +418,7 @@ class SharedDataFacade final : public BaseDataFacade
|
||||
LoadCoreInformation();
|
||||
LoadProfileProperties();
|
||||
LoadRTree();
|
||||
LoadIntersectionClasses();
|
||||
|
||||
util::SimpleLogger().Write() << "number of geometries: "
|
||||
<< m_coordinate_list.size();
|
||||
@@ -411,6 +480,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 +493,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 +509,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 +536,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 +558,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 +589,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 +602,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 +615,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 +668,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 +726,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 +754,34 @@ 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,18 @@
|
||||
#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/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
|
||||
{
|
||||
@@ -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,20 @@
|
||||
#ifndef ENGINE_GUIDANCE_ASSEMBLE_STEPS_HPP_
|
||||
#define ENGINE_GUIDANCE_ASSEMBLE_STEPS_HPP_
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.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/typedefs.hpp"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <cstddef>
|
||||
@@ -25,14 +28,10 @@ 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>
|
||||
@@ -64,13 +63,22 @@ 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};
|
||||
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 +98,56 @@ 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};
|
||||
segment_index++;
|
||||
segment_duration = 0;
|
||||
}
|
||||
@@ -109,10 +155,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 +177,62 @@ 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};
|
||||
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);
|
||||
return steps;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifndef ENGINE_GUIDANCE_POST_PROCESSING_HPP
|
||||
#define ENGINE_GUIDANCE_POST_PROCESSING_HPP
|
||||
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "engine/guidance/leg_geometry.hpp"
|
||||
#include "engine/guidance/route_step.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -37,7 +37,10 @@ std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps,
|
||||
const PhantomNode &source_node,
|
||||
const PhantomNode &target_node);
|
||||
|
||||
//remove steps invalidated by post-processing
|
||||
// collapse suppressed instructions remaining into intersections array
|
||||
std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps);
|
||||
|
||||
// remove steps invalidated by post-processing
|
||||
std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> steps);
|
||||
|
||||
// postProcess will break the connection between the leg geometry
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#ifndef ROUTE_STEP_HPP
|
||||
#define ROUTE_STEP_HPP
|
||||
|
||||
#include "engine/guidance/step_maneuver.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "engine/guidance/step_maneuver.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
@@ -21,10 +24,33 @@ namespace guidance
|
||||
// Notable exceptions are Departure and Arrival steps.
|
||||
// Departue: s --> a --> b. Represents the segment s,a with location being s.
|
||||
// Arrive: a --> b --> t. The segment (b,t) is already covered by the previous segment.
|
||||
|
||||
// A represenetation of intermediate intersections
|
||||
struct Intersection
|
||||
{
|
||||
static const constexpr std::size_t NO_INDEX = std::numeric_limits<std::size_t>::max();
|
||||
util::Coordinate location;
|
||||
std::vector<short> bearings;
|
||||
std::vector<bool> entry;
|
||||
std::size_t in;
|
||||
std::size_t out;
|
||||
};
|
||||
|
||||
inline Intersection getInvalidIntersection()
|
||||
{
|
||||
return {util::Coordinate{util::FloatLongitude{0.0}, util::FloatLatitude{0.0}},
|
||||
{},
|
||||
{},
|
||||
Intersection::NO_INDEX,
|
||||
Intersection::NO_INDEX};
|
||||
}
|
||||
|
||||
struct RouteStep
|
||||
{
|
||||
unsigned name_id;
|
||||
std::string name;
|
||||
std::string pronunciation;
|
||||
std::string destinations;
|
||||
std::string rotary_name;
|
||||
double duration;
|
||||
double distance;
|
||||
@@ -33,11 +59,23 @@ struct RouteStep
|
||||
// indices into the locations array stored the LegGeometry
|
||||
std::size_t geometry_begin;
|
||||
std::size_t geometry_end;
|
||||
std::vector<Intersection> intersections;
|
||||
};
|
||||
|
||||
inline RouteStep getInvalidRouteStep()
|
||||
{
|
||||
return {0, "", "", 0, 0, TRAVEL_MODE_INACCESSIBLE, getInvalidStepManeuver(), 0, 0};
|
||||
return {0,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
0,
|
||||
0,
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
getInvalidStepManeuver(),
|
||||
0,
|
||||
0,
|
||||
{getInvalidIntersection()}};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,23 +21,14 @@ enum class WaypointType : std::uint8_t
|
||||
Depart,
|
||||
};
|
||||
|
||||
// A represenetation of intermediate intersections
|
||||
struct IntermediateIntersection
|
||||
{
|
||||
double duration;
|
||||
double distance;
|
||||
util::Coordinate location;
|
||||
};
|
||||
|
||||
struct StepManeuver
|
||||
{
|
||||
util::Coordinate location;
|
||||
double bearing_before;
|
||||
double bearing_after;
|
||||
short bearing_before;
|
||||
short bearing_after;
|
||||
extractor::guidance::TurnInstruction instruction;
|
||||
WaypointType waypoint_type;
|
||||
unsigned exit;
|
||||
std::vector<IntermediateIntersection> intersections;
|
||||
};
|
||||
|
||||
inline StepManeuver getInvalidStepManeuver()
|
||||
@@ -47,8 +38,7 @@ inline StepManeuver getInvalidStepManeuver()
|
||||
0,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::None,
|
||||
0,
|
||||
{}};
|
||||
0};
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
|
||||
@@ -49,7 +49,7 @@ inline bool staysOnRoundabout(const extractor::guidance::TurnInstruction instruc
|
||||
return instruction.type == extractor::guidance::TurnType::StayOnRoundabout;
|
||||
}
|
||||
|
||||
inline extractor::guidance::DirectionModifier angleToDirectionModifier(const double bearing)
|
||||
inline extractor::guidance::DirectionModifier::Enum angleToDirectionModifier(const double bearing)
|
||||
{
|
||||
if (bearing < 135)
|
||||
{
|
||||
|
||||
@@ -32,9 +32,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -65,7 +65,8 @@ struct Hint
|
||||
|
||||
static_assert(sizeof(Hint) == 60 + 4, "Hint is bigger than expected");
|
||||
constexpr std::size_t ENCODED_HINT_SIZE = 88;
|
||||
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint), "ENCODED_HINT_SIZE does not match size of Hint");
|
||||
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
|
||||
"ENCODED_HINT_SIZE does not match size of Hint");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifndef RAW_ROUTE_DATA_H
|
||||
#define RAW_ROUTE_DATA_H
|
||||
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "osrm/coordinate.hpp"
|
||||
@@ -29,6 +29,8 @@ struct PathData
|
||||
extractor::guidance::TurnInstruction turn_instruction;
|
||||
// travel mode of the street that leads to the turn
|
||||
extractor::TravelMode travel_mode : 4;
|
||||
// entry class of the turn, indicating possibility of turns
|
||||
EntryClassID entry_classid;
|
||||
};
|
||||
|
||||
struct InternalRouteResult
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
|
||||
|
||||
@@ -149,8 +149,8 @@ struct PhantomNode
|
||||
unsigned reverse_packed_geometry_id;
|
||||
struct ComponentType
|
||||
{
|
||||
std::uint32_t id : 31;
|
||||
std::uint32_t is_tiny : 1;
|
||||
std::uint32_t id : 31;
|
||||
std::uint32_t is_tiny : 1;
|
||||
} component;
|
||||
static_assert(sizeof(ComponentType) == 4, "ComponentType needs to be 4 bytes big");
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef MATCH_HPP
|
||||
#define MATCH_HPP
|
||||
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
#include "engine/api/match_parameters.hpp"
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
|
||||
#include "engine/map_matching/bayes_classifier.hpp"
|
||||
#include "engine/routing_algorithms/map_matching.hpp"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef NEAREST_HPP
|
||||
#define NEAREST_HPP
|
||||
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
#include "engine/api/nearest_parameters.hpp"
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
#include "osrm/json_container.hpp"
|
||||
|
||||
namespace osrm
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#ifndef BASE_PLUGIN_HPP
|
||||
#define BASE_PLUGIN_HPP
|
||||
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/api/base_parameters.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/phantom_node.hpp"
|
||||
#include "engine/status.hpp"
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
@@ -31,11 +31,10 @@ class BasePlugin
|
||||
|
||||
bool CheckAllCoordinates(const std::vector<util::Coordinate> &coordinates)
|
||||
{
|
||||
return !std::any_of(std::begin(coordinates), std::end(coordinates),
|
||||
[](const util::Coordinate coordinate)
|
||||
{
|
||||
return !coordinate.IsValid();
|
||||
});
|
||||
return !std::any_of(
|
||||
std::begin(coordinates), std::end(coordinates), [](const util::Coordinate coordinate) {
|
||||
return !coordinate.IsValid();
|
||||
});
|
||||
}
|
||||
|
||||
Status Error(const std::string &code,
|
||||
@@ -53,43 +52,38 @@ class BasePlugin
|
||||
SnapPhantomNodes(const std::vector<PhantomNodePair> &phantom_node_pair_list) const
|
||||
{
|
||||
const auto check_component_id_is_tiny =
|
||||
[](const std::pair<PhantomNode, PhantomNode> &phantom_pair)
|
||||
{
|
||||
return phantom_pair.first.component.is_tiny;
|
||||
};
|
||||
[](const std::pair<PhantomNode, PhantomNode> &phantom_pair) {
|
||||
return phantom_pair.first.component.is_tiny;
|
||||
};
|
||||
|
||||
// are all phantoms from a tiny cc?
|
||||
const auto check_all_in_same_component =
|
||||
[](const std::vector<std::pair<PhantomNode, PhantomNode>> &nodes)
|
||||
{
|
||||
const auto component_id = nodes.front().first.component.id;
|
||||
[](const std::vector<std::pair<PhantomNode, PhantomNode>> &nodes) {
|
||||
const auto component_id = nodes.front().first.component.id;
|
||||
|
||||
return std::all_of(std::begin(nodes), std::end(nodes),
|
||||
[component_id](const PhantomNodePair &phantom_pair)
|
||||
{
|
||||
return component_id == phantom_pair.first.component.id;
|
||||
});
|
||||
};
|
||||
return std::all_of(std::begin(nodes),
|
||||
std::end(nodes),
|
||||
[component_id](const PhantomNodePair &phantom_pair) {
|
||||
return component_id == phantom_pair.first.component.id;
|
||||
});
|
||||
};
|
||||
|
||||
const auto fallback_to_big_component =
|
||||
[](const std::pair<PhantomNode, PhantomNode> &phantom_pair)
|
||||
{
|
||||
if (phantom_pair.first.component.is_tiny && phantom_pair.second.IsValid() &&
|
||||
!phantom_pair.second.component.is_tiny)
|
||||
{
|
||||
return phantom_pair.second;
|
||||
}
|
||||
return phantom_pair.first;
|
||||
};
|
||||
[](const std::pair<PhantomNode, PhantomNode> &phantom_pair) {
|
||||
if (phantom_pair.first.component.is_tiny && phantom_pair.second.IsValid() &&
|
||||
!phantom_pair.second.component.is_tiny)
|
||||
{
|
||||
return phantom_pair.second;
|
||||
}
|
||||
return phantom_pair.first;
|
||||
};
|
||||
|
||||
const auto use_closed_phantom = [](const std::pair<PhantomNode, PhantomNode> &phantom_pair)
|
||||
{
|
||||
return phantom_pair.first;
|
||||
};
|
||||
const auto use_closed_phantom = [](
|
||||
const std::pair<PhantomNode, PhantomNode> &phantom_pair) { return phantom_pair.first; };
|
||||
|
||||
const bool every_phantom_is_in_tiny_cc =
|
||||
std::all_of(std::begin(phantom_node_pair_list), std::end(phantom_node_pair_list),
|
||||
check_component_id_is_tiny);
|
||||
const bool every_phantom_is_in_tiny_cc = std::all_of(std::begin(phantom_node_pair_list),
|
||||
std::end(phantom_node_pair_list),
|
||||
check_component_id_is_tiny);
|
||||
auto all_in_same_component = check_all_in_same_component(phantom_node_pair_list);
|
||||
|
||||
std::vector<PhantomNode> snapped_phantoms;
|
||||
@@ -99,13 +93,17 @@ class BasePlugin
|
||||
// component
|
||||
if (every_phantom_is_in_tiny_cc && all_in_same_component)
|
||||
{
|
||||
std::transform(phantom_node_pair_list.begin(), phantom_node_pair_list.end(),
|
||||
std::back_inserter(snapped_phantoms), use_closed_phantom);
|
||||
std::transform(phantom_node_pair_list.begin(),
|
||||
phantom_node_pair_list.end(),
|
||||
std::back_inserter(snapped_phantoms),
|
||||
use_closed_phantom);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::transform(phantom_node_pair_list.begin(), phantom_node_pair_list.end(),
|
||||
std::back_inserter(snapped_phantoms), fallback_to_big_component);
|
||||
std::transform(phantom_node_pair_list.begin(),
|
||||
phantom_node_pair_list.end(),
|
||||
std::back_inserter(snapped_phantoms),
|
||||
fallback_to_big_component);
|
||||
}
|
||||
|
||||
return snapped_phantoms;
|
||||
@@ -137,9 +135,11 @@ class BasePlugin
|
||||
}
|
||||
if (use_bearings && parameters.bearings[i])
|
||||
{
|
||||
phantom_nodes[i] = facade.NearestPhantomNodesInRange(
|
||||
parameters.coordinates[i], radiuses[i], parameters.bearings[i]->bearing,
|
||||
parameters.bearings[i]->range);
|
||||
phantom_nodes[i] =
|
||||
facade.NearestPhantomNodesInRange(parameters.coordinates[i],
|
||||
radiuses[i],
|
||||
parameters.bearings[i]->bearing,
|
||||
parameters.bearings[i]->range);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -179,15 +179,18 @@ class BasePlugin
|
||||
{
|
||||
if (use_radiuses && parameters.radiuses[i])
|
||||
{
|
||||
phantom_nodes[i] = facade.NearestPhantomNodes(
|
||||
parameters.coordinates[i], number_of_results, *parameters.radiuses[i],
|
||||
parameters.bearings[i]->bearing, parameters.bearings[i]->range);
|
||||
phantom_nodes[i] = facade.NearestPhantomNodes(parameters.coordinates[i],
|
||||
number_of_results,
|
||||
*parameters.radiuses[i],
|
||||
parameters.bearings[i]->bearing,
|
||||
parameters.bearings[i]->range);
|
||||
}
|
||||
else
|
||||
{
|
||||
phantom_nodes[i] = facade.NearestPhantomNodes(
|
||||
parameters.coordinates[i], number_of_results,
|
||||
parameters.bearings[i]->bearing, parameters.bearings[i]->range);
|
||||
phantom_nodes[i] = facade.NearestPhantomNodes(parameters.coordinates[i],
|
||||
number_of_results,
|
||||
parameters.bearings[i]->bearing,
|
||||
parameters.bearings[i]->range);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -238,14 +241,17 @@ class BasePlugin
|
||||
{
|
||||
phantom_node_pairs[i] =
|
||||
facade.NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||
parameters.coordinates[i], *parameters.radiuses[i],
|
||||
parameters.bearings[i]->bearing, parameters.bearings[i]->range);
|
||||
parameters.coordinates[i],
|
||||
*parameters.radiuses[i],
|
||||
parameters.bearings[i]->bearing,
|
||||
parameters.bearings[i]->range);
|
||||
}
|
||||
else
|
||||
{
|
||||
phantom_node_pairs[i] =
|
||||
facade.NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||
parameters.coordinates[i], parameters.bearings[i]->bearing,
|
||||
parameters.coordinates[i],
|
||||
parameters.bearings[i]->bearing,
|
||||
parameters.bearings[i]->range);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef TILEPLUGIN_HPP
|
||||
#define TILEPLUGIN_HPP
|
||||
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
#include "engine/api/tile_parameters.hpp"
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -4,20 +4,20 @@
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
|
||||
#include "engine/api/trip_parameters.hpp"
|
||||
#include "engine/routing_algorithms/shortest_path.hpp"
|
||||
#include "engine/routing_algorithms/many_to_many.hpp"
|
||||
#include "engine/routing_algorithms/shortest_path.hpp"
|
||||
|
||||
#include "osrm/json_container.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#ifndef VIA_ROUTE_HPP
|
||||
#define VIA_ROUTE_HPP
|
||||
|
||||
#include "engine/api/route_api.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
#include "engine/api/route_api.hpp"
|
||||
|
||||
#include "engine/search_engine_data.hpp"
|
||||
#include "engine/routing_algorithms/shortest_path.hpp"
|
||||
#include "engine/routing_algorithms/alternative_path.hpp"
|
||||
#include "engine/routing_algorithms/direct_shortest_path.hpp"
|
||||
#include "engine/routing_algorithms/shortest_path.hpp"
|
||||
#include "engine/search_engine_data.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
@@ -130,16 +130,22 @@ class AlternativeRouting final
|
||||
{
|
||||
if (0 < forward_heap1.Size())
|
||||
{
|
||||
AlternativeRoutingStep<true>(forward_heap1, reverse_heap1, &middle_node,
|
||||
AlternativeRoutingStep<true>(forward_heap1,
|
||||
reverse_heap1,
|
||||
&middle_node,
|
||||
&upper_bound_to_shortest_path_distance,
|
||||
via_node_candidate_list, forward_search_space,
|
||||
via_node_candidate_list,
|
||||
forward_search_space,
|
||||
min_edge_offset);
|
||||
}
|
||||
if (0 < reverse_heap1.Size())
|
||||
{
|
||||
AlternativeRoutingStep<false>(forward_heap1, reverse_heap1, &middle_node,
|
||||
AlternativeRoutingStep<false>(forward_heap1,
|
||||
reverse_heap1,
|
||||
&middle_node,
|
||||
&upper_bound_to_shortest_path_distance,
|
||||
via_node_candidate_list, reverse_search_space,
|
||||
via_node_candidate_list,
|
||||
reverse_search_space,
|
||||
min_edge_offset);
|
||||
}
|
||||
}
|
||||
@@ -162,18 +168,16 @@ class AlternativeRouting final
|
||||
if (path_is_a_loop)
|
||||
{
|
||||
// Self Loop
|
||||
BOOST_ASSERT(forward_heap1.GetData(middle_node).parent == middle_node &&
|
||||
reverse_heap1.GetData(middle_node).parent == middle_node);
|
||||
packed_forward_path.push_back(middle_node);
|
||||
packed_forward_path.push_back(middle_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
super::RetrievePackedPathFromSingleHeap(forward_heap1, middle_node,
|
||||
packed_forward_path);
|
||||
super::RetrievePackedPathFromSingleHeap(reverse_heap1, middle_node,
|
||||
packed_reverse_path);
|
||||
super::RetrievePackedPathFromSingleHeap(
|
||||
forward_heap1, middle_node, packed_forward_path);
|
||||
super::RetrievePackedPathFromSingleHeap(
|
||||
reverse_heap1, middle_node, packed_reverse_path);
|
||||
}
|
||||
|
||||
// this set is is used as an indicator if a node is on the shortest path
|
||||
@@ -273,8 +277,8 @@ class AlternativeRouting final
|
||||
{
|
||||
std::reverse(packed_shortest_path.begin(), packed_shortest_path.end());
|
||||
packed_shortest_path.emplace_back(middle_node);
|
||||
packed_shortest_path.insert(packed_shortest_path.end(), packed_reverse_path.begin(),
|
||||
packed_reverse_path.end());
|
||||
packed_shortest_path.insert(
|
||||
packed_shortest_path.end(), packed_reverse_path.begin(), packed_reverse_path.end());
|
||||
}
|
||||
std::vector<RankedCandidateNode> ranked_candidates_list;
|
||||
|
||||
@@ -282,8 +286,11 @@ class AlternativeRouting final
|
||||
for (const NodeID node : preselected_node_list)
|
||||
{
|
||||
int length_of_via_path = 0, sharing_of_via_path = 0;
|
||||
ComputeLengthAndSharingOfViaPath(node, &length_of_via_path, &sharing_of_via_path,
|
||||
packed_shortest_path, min_edge_offset);
|
||||
ComputeLengthAndSharingOfViaPath(node,
|
||||
&length_of_via_path,
|
||||
&sharing_of_via_path,
|
||||
packed_shortest_path,
|
||||
min_edge_offset);
|
||||
const int maximum_allowed_sharing =
|
||||
static_cast<int>(upper_bound_to_shortest_path_distance * VIAPATH_GAMMA);
|
||||
if (sharing_of_via_path <= maximum_allowed_sharing &&
|
||||
@@ -299,10 +306,16 @@ class AlternativeRouting final
|
||||
NodeID s_v_middle = SPECIAL_NODEID, v_t_middle = SPECIAL_NODEID;
|
||||
for (const RankedCandidateNode &candidate : ranked_candidates_list)
|
||||
{
|
||||
if (ViaNodeCandidatePassesTTest(
|
||||
forward_heap1, reverse_heap1, forward_heap2, reverse_heap2, candidate,
|
||||
upper_bound_to_shortest_path_distance, &length_of_via_path, &s_v_middle,
|
||||
&v_t_middle, min_edge_offset))
|
||||
if (ViaNodeCandidatePassesTTest(forward_heap1,
|
||||
reverse_heap1,
|
||||
forward_heap2,
|
||||
reverse_heap2,
|
||||
candidate,
|
||||
upper_bound_to_shortest_path_distance,
|
||||
&length_of_via_path,
|
||||
&s_v_middle,
|
||||
&v_t_middle,
|
||||
min_edge_offset))
|
||||
{
|
||||
// select first admissable
|
||||
selected_via_node = candidate.node;
|
||||
@@ -324,7 +337,8 @@ class AlternativeRouting final
|
||||
|
||||
super::UnpackPath(
|
||||
// -- packed input
|
||||
packed_shortest_path.begin(), packed_shortest_path.end(),
|
||||
packed_shortest_path.begin(),
|
||||
packed_shortest_path.end(),
|
||||
// -- start of route
|
||||
phantom_node_pair,
|
||||
// -- unpacked output
|
||||
@@ -336,8 +350,13 @@ class AlternativeRouting final
|
||||
{
|
||||
std::vector<NodeID> packed_alternate_path;
|
||||
// retrieve alternate path
|
||||
RetrievePackedAlternatePath(forward_heap1, reverse_heap1, forward_heap2, reverse_heap2,
|
||||
s_v_middle, v_t_middle, packed_alternate_path);
|
||||
RetrievePackedAlternatePath(forward_heap1,
|
||||
reverse_heap1,
|
||||
forward_heap2,
|
||||
reverse_heap2,
|
||||
s_v_middle,
|
||||
v_t_middle,
|
||||
packed_alternate_path);
|
||||
|
||||
raw_route_data.alt_source_traversed_in_reverse.push_back(
|
||||
(packed_alternate_path.front() !=
|
||||
@@ -347,8 +366,10 @@ class AlternativeRouting final
|
||||
phantom_node_pair.target_phantom.forward_segment_id.id));
|
||||
|
||||
// unpack the alternate path
|
||||
super::UnpackPath(packed_alternate_path.begin(), packed_alternate_path.end(),
|
||||
phantom_node_pair, raw_route_data.unpacked_alternative);
|
||||
super::UnpackPath(packed_alternate_path.begin(),
|
||||
packed_alternate_path.end(),
|
||||
phantom_node_pair,
|
||||
raw_route_data.unpacked_alternative);
|
||||
|
||||
raw_route_data.alternative_path_length = length_of_via_path;
|
||||
}
|
||||
@@ -374,8 +395,8 @@ class AlternativeRouting final
|
||||
packed_path.pop_back(); // remove middle node. It's in both half-paths
|
||||
|
||||
// fetch patched path [v,t]
|
||||
super::RetrievePackedPathFromHeap(forward_heap2, reverse_heap1, v_t_middle,
|
||||
packed_v_t_path);
|
||||
super::RetrievePackedPathFromHeap(
|
||||
forward_heap2, reverse_heap1, v_t_middle, packed_v_t_path);
|
||||
|
||||
packed_path.insert(packed_path.end(), packed_v_t_path.begin(), packed_v_t_path.end());
|
||||
}
|
||||
@@ -412,9 +433,15 @@ class AlternativeRouting final
|
||||
const bool constexpr DO_NOT_FORCE_LOOPS = false;
|
||||
while (!new_reverse_heap.Empty())
|
||||
{
|
||||
super::RoutingStep(new_reverse_heap, existing_forward_heap, s_v_middle,
|
||||
upper_bound_s_v_path_length, min_edge_offset, false,
|
||||
STALLING_ENABLED, DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS);
|
||||
super::RoutingStep(new_reverse_heap,
|
||||
existing_forward_heap,
|
||||
s_v_middle,
|
||||
upper_bound_s_v_path_length,
|
||||
min_edge_offset,
|
||||
false,
|
||||
STALLING_ENABLED,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
DO_NOT_FORCE_LOOPS);
|
||||
}
|
||||
// compute path <v,..,t> by reusing backward search from node t
|
||||
NodeID v_t_middle = SPECIAL_NODEID;
|
||||
@@ -422,9 +449,15 @@ class AlternativeRouting final
|
||||
new_forward_heap.Insert(via_node, 0, via_node);
|
||||
while (!new_forward_heap.Empty())
|
||||
{
|
||||
super::RoutingStep(new_forward_heap, existing_reverse_heap, v_t_middle,
|
||||
upper_bound_of_v_t_path_length, min_edge_offset, true,
|
||||
STALLING_ENABLED, DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS);
|
||||
super::RoutingStep(new_forward_heap,
|
||||
existing_reverse_heap,
|
||||
v_t_middle,
|
||||
upper_bound_of_v_t_path_length,
|
||||
min_edge_offset,
|
||||
true,
|
||||
STALLING_ENABLED,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
DO_NOT_FORCE_LOOPS);
|
||||
}
|
||||
*real_length_of_via_path = upper_bound_s_v_path_length + upper_bound_of_v_t_path_length;
|
||||
|
||||
@@ -434,10 +467,10 @@ class AlternativeRouting final
|
||||
}
|
||||
|
||||
// retrieve packed paths
|
||||
super::RetrievePackedPathFromHeap(existing_forward_heap, new_reverse_heap, s_v_middle,
|
||||
packed_s_v_path);
|
||||
super::RetrievePackedPathFromHeap(new_forward_heap, existing_reverse_heap, v_t_middle,
|
||||
packed_v_t_path);
|
||||
super::RetrievePackedPathFromHeap(
|
||||
existing_forward_heap, new_reverse_heap, s_v_middle, packed_s_v_path);
|
||||
super::RetrievePackedPathFromHeap(
|
||||
new_forward_heap, existing_reverse_heap, v_t_middle, packed_v_t_path);
|
||||
|
||||
// partial unpacking, compute sharing
|
||||
// First partially unpack s-->v until paths deviate, note length of common path.
|
||||
@@ -503,7 +536,8 @@ class AlternativeRouting final
|
||||
if (packed_v_t_path[via_path_index] == packed_shortest_path[shortest_path_index])
|
||||
{
|
||||
super::UnpackEdge(packed_v_t_path[via_path_index - 1],
|
||||
packed_v_t_path[via_path_index], partially_unpacked_via_path);
|
||||
packed_v_t_path[via_path_index],
|
||||
partially_unpacked_via_path);
|
||||
super::UnpackEdge(packed_shortest_path[shortest_path_index - 1],
|
||||
packed_shortest_path[shortest_path_index],
|
||||
partially_unpacked_shortest_path);
|
||||
@@ -701,9 +735,15 @@ class AlternativeRouting final
|
||||
const bool constexpr DO_NOT_FORCE_LOOPS = false;
|
||||
while (new_reverse_heap.Size() > 0)
|
||||
{
|
||||
super::RoutingStep(new_reverse_heap, existing_forward_heap, *s_v_middle,
|
||||
upper_bound_s_v_path_length, min_edge_offset, false,
|
||||
STALLING_ENABLED, DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS);
|
||||
super::RoutingStep(new_reverse_heap,
|
||||
existing_forward_heap,
|
||||
*s_v_middle,
|
||||
upper_bound_s_v_path_length,
|
||||
min_edge_offset,
|
||||
false,
|
||||
STALLING_ENABLED,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
DO_NOT_FORCE_LOOPS);
|
||||
}
|
||||
|
||||
if (INVALID_EDGE_WEIGHT == upper_bound_s_v_path_length)
|
||||
@@ -717,9 +757,15 @@ class AlternativeRouting final
|
||||
new_forward_heap.Insert(candidate.node, 0, candidate.node);
|
||||
while (new_forward_heap.Size() > 0)
|
||||
{
|
||||
super::RoutingStep(new_forward_heap, existing_reverse_heap, *v_t_middle,
|
||||
upper_bound_of_v_t_path_length, min_edge_offset, true,
|
||||
STALLING_ENABLED, DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS);
|
||||
super::RoutingStep(new_forward_heap,
|
||||
existing_reverse_heap,
|
||||
*v_t_middle,
|
||||
upper_bound_of_v_t_path_length,
|
||||
min_edge_offset,
|
||||
true,
|
||||
STALLING_ENABLED,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
DO_NOT_FORCE_LOOPS);
|
||||
}
|
||||
|
||||
if (INVALID_EDGE_WEIGHT == upper_bound_of_v_t_path_length)
|
||||
@@ -730,11 +776,11 @@ class AlternativeRouting final
|
||||
*length_of_via_path = upper_bound_s_v_path_length + upper_bound_of_v_t_path_length;
|
||||
|
||||
// retrieve packed paths
|
||||
super::RetrievePackedPathFromHeap(existing_forward_heap, new_reverse_heap, *s_v_middle,
|
||||
packed_s_v_path);
|
||||
super::RetrievePackedPathFromHeap(
|
||||
existing_forward_heap, new_reverse_heap, *s_v_middle, packed_s_v_path);
|
||||
|
||||
super::RetrievePackedPathFromHeap(new_forward_heap, existing_reverse_heap, *v_t_middle,
|
||||
packed_v_t_path);
|
||||
super::RetrievePackedPathFromHeap(
|
||||
new_forward_heap, existing_reverse_heap, *v_t_middle, packed_v_t_path);
|
||||
|
||||
NodeID s_P = *s_v_middle, t_P = *v_t_middle;
|
||||
if (SPECIAL_NODEID == s_P)
|
||||
@@ -814,7 +860,8 @@ class AlternativeRouting final
|
||||
// Traverse path s-->v
|
||||
BOOST_ASSERT(!packed_v_t_path.empty());
|
||||
for (unsigned i = 0, packed_path_length = static_cast<unsigned>(packed_v_t_path.size() - 1);
|
||||
(i < packed_path_length) && unpack_stack.empty(); ++i)
|
||||
(i < packed_path_length) && unpack_stack.empty();
|
||||
++i)
|
||||
{
|
||||
const EdgeID edgeID =
|
||||
facade->FindEdgeInEitherDirection(packed_v_t_path[i], packed_v_t_path[i + 1]);
|
||||
@@ -886,14 +933,26 @@ class AlternativeRouting final
|
||||
{
|
||||
if (!forward_heap3.Empty())
|
||||
{
|
||||
super::RoutingStep(forward_heap3, reverse_heap3, middle, upper_bound,
|
||||
min_edge_offset, true, STALLING_ENABLED, DO_NOT_FORCE_LOOPS,
|
||||
super::RoutingStep(forward_heap3,
|
||||
reverse_heap3,
|
||||
middle,
|
||||
upper_bound,
|
||||
min_edge_offset,
|
||||
true,
|
||||
STALLING_ENABLED,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
DO_NOT_FORCE_LOOPS);
|
||||
}
|
||||
if (!reverse_heap3.Empty())
|
||||
{
|
||||
super::RoutingStep(reverse_heap3, forward_heap3, middle, upper_bound,
|
||||
min_edge_offset, false, STALLING_ENABLED, DO_NOT_FORCE_LOOPS,
|
||||
super::RoutingStep(reverse_heap3,
|
||||
forward_heap3,
|
||||
middle,
|
||||
upper_bound,
|
||||
min_edge_offset,
|
||||
false,
|
||||
STALLING_ENABLED,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
DO_NOT_FORCE_LOOPS);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user