Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c1eda57c13 | |||
| 8b45ff7a18 | |||
| 4c665b24d9 | |||
| 381d492a8f | |||
| e250c83c21 | |||
| e2e326d15e | |||
| 4abca85474 | |||
| 2c78d862a3 | |||
| b1451a7421 | |||
| da1c251144 | |||
| 1eab7b41d1 | |||
| 1dca8ae76a | |||
| 002e86863d | |||
| 1d82b01816 | |||
| 714719c377 | |||
| 77b4fbb69c | |||
| 11fde865f7 | |||
| 717406043a | |||
| 1ef85c57cc | |||
| d0180517a8 | |||
| 520b7ebbb6 | |||
| 2caba96076 | |||
| 81bc2f41a6 | |||
| 06e010b4d0 | |||
| 92d3ce789b | |||
| 01ca32c81c | |||
| 2e17f3010a | |||
| c4238c4ed6 | |||
| 3d781e6f28 | |||
| 4976233cff | |||
| 98ea2a0b09 | |||
| f978900ab0 | |||
| 8b6580128b | |||
| 4dde9c7bbe | |||
| 973837207b | |||
| 364e35af06 | |||
| 985ab58f45 | |||
| cb1db646f2 | |||
| a67c4bf84d | |||
| 498259b220 | |||
| 5327f8da4e | |||
| 802ccfb497 | |||
| ec369d560a | |||
| 535647e439 | |||
| 954121634f | |||
| 594a45e7e0 | |||
| 96c7b47afe | |||
| b7e7d32361 | |||
| 2f9cb44368 | |||
| d80318f8ea | |||
| b1791d1ab3 | |||
| a53da9095a | |||
| 72e03f9af9 |
@@ -68,6 +68,10 @@ Thumbs.db
|
|||||||
/*.local.bat
|
/*.local.bat
|
||||||
/CMakeSettings.json
|
/CMakeSettings.json
|
||||||
|
|
||||||
|
# Jetbrains related files #
|
||||||
|
###########################
|
||||||
|
.idea/
|
||||||
|
|
||||||
# stxxl related files #
|
# stxxl related files #
|
||||||
#######################
|
#######################
|
||||||
.stxxl
|
.stxxl
|
||||||
|
|||||||
+193
-65
@@ -17,7 +17,7 @@ branches:
|
|||||||
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
yarn: true
|
npm: true
|
||||||
ccache: true
|
ccache: true
|
||||||
apt: true
|
apt: true
|
||||||
directories:
|
directories:
|
||||||
@@ -34,7 +34,11 @@ env:
|
|||||||
- CMAKE_VERSION=3.7.2
|
- CMAKE_VERSION=3.7.2
|
||||||
- MASON="$(pwd)/scripts/mason.sh"
|
- MASON="$(pwd)/scripts/mason.sh"
|
||||||
- ENABLE_NODE_BINDINGS=On
|
- ENABLE_NODE_BINDINGS=On
|
||||||
- NODE="4"
|
- NODE="10"
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- core
|
||||||
|
- optional
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
@@ -43,18 +47,19 @@ matrix:
|
|||||||
include:
|
include:
|
||||||
|
|
||||||
# Debug Builds
|
# Debug Builds
|
||||||
- os: linux
|
- stage: core
|
||||||
|
os: linux
|
||||||
compiler: "format-taginfo-docs"
|
compiler: "format-taginfo-docs"
|
||||||
env: NODE=6
|
env: NODE=10
|
||||||
sudo: false
|
sudo: false
|
||||||
before_install:
|
before_install:
|
||||||
install:
|
install:
|
||||||
|
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
|
||||||
- source $NVM_DIR/nvm.sh
|
- source $NVM_DIR/nvm.sh
|
||||||
- nvm install $NODE
|
- nvm install $NODE
|
||||||
- nvm use $NODE
|
- nvm use $NODE
|
||||||
- npm --version
|
- npm --version
|
||||||
- npm install --ignore-scripts
|
- npm ci --ignore-scripts
|
||||||
- npm link --ignore-scripts
|
|
||||||
script:
|
script:
|
||||||
- ./scripts/check_taginfo.py taginfo.json profiles/car.lua
|
- ./scripts/check_taginfo.py taginfo.json profiles/car.lua
|
||||||
- ${MASON} install clang-format 3.8.1
|
- ${MASON} install clang-format 3.8.1
|
||||||
@@ -156,17 +161,17 @@ matrix:
|
|||||||
|
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode9.2
|
osx_image: xcode9.2
|
||||||
compiler: "mason-osx-release-node-8"
|
compiler: "mason-osx-release-node-10"
|
||||||
# we use the xcode provides clang and don't install our own
|
# we use the xcode provides clang and don't install our own
|
||||||
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="8"
|
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="10"
|
||||||
after_success:
|
after_success:
|
||||||
- ./scripts/travis/publish.sh
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode9.2
|
osx_image: xcode9.2
|
||||||
compiler: "mason-osx-release-node-4"
|
compiler: "mason-osx-release-node-8"
|
||||||
# we use the xcode provides clang and don't install our own
|
# we use the xcode provides clang and don't install our own
|
||||||
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="4"
|
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="8"
|
||||||
after_success:
|
after_success:
|
||||||
- ./scripts/travis/publish.sh
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
@@ -180,54 +185,6 @@ matrix:
|
|||||||
env: CCOMPILER='gcc-7' CXXCOMPILER='g++-7' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
env: CCOMPILER='gcc-7' CXXCOMPILER='g++-7' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||||
|
|
||||||
# Node build jobs. These skip running the tests.
|
# Node build jobs. These skip running the tests.
|
||||||
- os: linux
|
|
||||||
sudo: false
|
|
||||||
compiler: "node-4-mason-linux-release"
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['ubuntu-toolchain-r-test']
|
|
||||||
packages: ['libstdc++-4.9-dev']
|
|
||||||
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="4"
|
|
||||||
install:
|
|
||||||
- pushd ${OSRM_BUILD_DIR}
|
|
||||||
- |
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
|
||||||
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
|
|
||||||
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
|
||||||
-DENABLE_CCACHE=ON \
|
|
||||||
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
|
|
||||||
-DENABLE_GLIBC_WORKAROUND=ON
|
|
||||||
- make --jobs=${JOBS}
|
|
||||||
- popd
|
|
||||||
script:
|
|
||||||
- npm run nodejs-tests
|
|
||||||
after_success:
|
|
||||||
- ./scripts/travis/publish.sh
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
sudo: false
|
|
||||||
compiler: "node-4-mason-linux-debug"
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['ubuntu-toolchain-r-test']
|
|
||||||
packages: ['libstdc++-4.9-dev']
|
|
||||||
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="4"
|
|
||||||
install:
|
|
||||||
- pushd ${OSRM_BUILD_DIR}
|
|
||||||
- |
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
|
||||||
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
|
|
||||||
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
|
||||||
-DENABLE_CCACHE=ON \
|
|
||||||
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
|
|
||||||
-DENABLE_GLIBC_WORKAROUND=ON
|
|
||||||
- make --jobs=${JOBS}
|
|
||||||
- popd
|
|
||||||
script:
|
|
||||||
- npm run nodejs-tests
|
|
||||||
after_success:
|
|
||||||
- ./scripts/travis/publish.sh
|
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
sudo: false
|
sudo: false
|
||||||
compiler: "node-8-mason-linux-release"
|
compiler: "node-8-mason-linux-release"
|
||||||
@@ -276,7 +233,183 @@ matrix:
|
|||||||
after_success:
|
after_success:
|
||||||
- ./scripts/travis/publish.sh
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
compiler: "node-10-mason-linux-release"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: ['libstdc++-4.9-dev']
|
||||||
|
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="10"
|
||||||
|
install:
|
||||||
|
- pushd ${OSRM_BUILD_DIR}
|
||||||
|
- |
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||||
|
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
|
||||||
|
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
||||||
|
-DENABLE_CCACHE=ON \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
|
||||||
|
-DENABLE_GLIBC_WORKAROUND=ON
|
||||||
|
- make --jobs=${JOBS}
|
||||||
|
- popd
|
||||||
|
script:
|
||||||
|
- npm run nodejs-tests
|
||||||
|
after_success:
|
||||||
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
compiler: "node-10-mason-linux-debug"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: ['libstdc++-4.9-dev']
|
||||||
|
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="10"
|
||||||
|
install:
|
||||||
|
- pushd ${OSRM_BUILD_DIR}
|
||||||
|
- |
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||||
|
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
|
||||||
|
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
||||||
|
-DENABLE_CCACHE=ON \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
|
||||||
|
-DENABLE_GLIBC_WORKAROUND=ON
|
||||||
|
- make --jobs=${JOBS}
|
||||||
|
- popd
|
||||||
|
script:
|
||||||
|
- npm run nodejs-tests
|
||||||
|
after_success:
|
||||||
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
stage: optional
|
||||||
|
osx_image: xcode9.2
|
||||||
|
compiler: "mason-osx-release-node-latest"
|
||||||
|
# we use the xcode provides clang and don't install our own
|
||||||
|
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="node"
|
||||||
|
after_success:
|
||||||
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
compiler: "node-latest-mason-linux-release"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: ['libstdc++-4.9-dev']
|
||||||
|
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="node"
|
||||||
|
install:
|
||||||
|
- pushd ${OSRM_BUILD_DIR}
|
||||||
|
- |
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||||
|
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
|
||||||
|
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
||||||
|
-DENABLE_CCACHE=ON \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
|
||||||
|
-DENABLE_GLIBC_WORKAROUND=ON
|
||||||
|
- make --jobs=${JOBS}
|
||||||
|
- popd
|
||||||
|
script:
|
||||||
|
- npm run nodejs-tests
|
||||||
|
after_success:
|
||||||
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
compiler: "node-latest-mason-linux-debug"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: ['libstdc++-4.9-dev']
|
||||||
|
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="node"
|
||||||
|
install:
|
||||||
|
- pushd ${OSRM_BUILD_DIR}
|
||||||
|
- |
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||||
|
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
|
||||||
|
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
||||||
|
-DENABLE_CCACHE=ON \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
|
||||||
|
-DENABLE_GLIBC_WORKAROUND=ON
|
||||||
|
- make --jobs=${JOBS}
|
||||||
|
- popd
|
||||||
|
script:
|
||||||
|
- npm run nodejs-tests
|
||||||
|
after_success:
|
||||||
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode9.2
|
||||||
|
compiler: "mason-osx-release-node-lts"
|
||||||
|
# we use the xcode provides clang and don't install our own
|
||||||
|
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="--lts"
|
||||||
|
after_success:
|
||||||
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
compiler: "node-lts-mason-linux-release"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: ['libstdc++-4.9-dev']
|
||||||
|
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="--lts"
|
||||||
|
install:
|
||||||
|
- pushd ${OSRM_BUILD_DIR}
|
||||||
|
- |
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||||
|
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
|
||||||
|
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
||||||
|
-DENABLE_CCACHE=ON \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
|
||||||
|
-DENABLE_GLIBC_WORKAROUND=ON
|
||||||
|
- make --jobs=${JOBS}
|
||||||
|
- popd
|
||||||
|
script:
|
||||||
|
- npm run nodejs-tests
|
||||||
|
after_success:
|
||||||
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
compiler: "node-lts-mason-linux-debug"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: ['libstdc++-4.9-dev']
|
||||||
|
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="--lts"
|
||||||
|
install:
|
||||||
|
- pushd ${OSRM_BUILD_DIR}
|
||||||
|
- |
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||||
|
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
|
||||||
|
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
||||||
|
-DENABLE_CCACHE=ON \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
|
||||||
|
-DENABLE_GLIBC_WORKAROUND=ON
|
||||||
|
- make --jobs=${JOBS}
|
||||||
|
- popd
|
||||||
|
script:
|
||||||
|
- npm run nodejs-tests
|
||||||
|
after_success:
|
||||||
|
- ./scripts/travis/publish.sh
|
||||||
|
|
||||||
|
allow_failures:
|
||||||
|
- compiler: "mason-osx-release-node-latest"
|
||||||
|
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="node"
|
||||||
|
- compiler: "node-latest-mason-linux-release"
|
||||||
|
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="node"
|
||||||
|
- compiler: "node-latest-mason-linux-debug"
|
||||||
|
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="node"
|
||||||
|
- compiler: "mason-osx-release-node-lts"
|
||||||
|
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="--lts"
|
||||||
|
- compiler: "node-lts-mason-linux-release"
|
||||||
|
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="--lts"
|
||||||
|
- compiler: "node-lts-mason-linux-debug"
|
||||||
|
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="--lts"
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
|
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
|
||||||
- source $NVM_DIR/nvm.sh
|
- source $NVM_DIR/nvm.sh
|
||||||
- nvm install $NODE
|
- nvm install $NODE
|
||||||
- nvm use $NODE
|
- nvm use $NODE
|
||||||
@@ -294,15 +427,10 @@ before_install:
|
|||||||
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
||||||
sudo mdutil -i off /
|
sudo mdutil -i off /
|
||||||
fi
|
fi
|
||||||
- |
|
|
||||||
if [[ ! -f $(which yarn) ]]; then
|
|
||||||
npm install -g yarn
|
|
||||||
fi
|
|
||||||
- export PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)")
|
- export PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)")
|
||||||
- export PUBLISH=$([[ "${TRAVIS_TAG:-}" == "v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off")
|
- export PUBLISH=$([[ "${TRAVIS_TAG:-}" == "v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off")
|
||||||
- echo "Using ${JOBS} jobs"
|
- echo "Using ${JOBS} jobs"
|
||||||
- yarn install --ignore-scripts
|
- npm ci --ignore-scripts
|
||||||
- yarn check --ignore-scripts --integrity
|
|
||||||
# Bootstrap cmake to be able to run mason
|
# Bootstrap cmake to be able to run mason
|
||||||
- CMAKE_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}.tar.gz"
|
- CMAKE_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}.tar.gz"
|
||||||
- CMAKE_DIR="mason_packages/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}"
|
- CMAKE_DIR="mason_packages/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}"
|
||||||
@@ -381,4 +509,4 @@ script:
|
|||||||
fi
|
fi
|
||||||
- |
|
- |
|
||||||
- popd
|
- popd
|
||||||
- yarn test
|
- npm test
|
||||||
|
|||||||
+50
-2
@@ -1,9 +1,57 @@
|
|||||||
# UNRELEASED
|
# Unreleased
|
||||||
|
- Changes from 5.21.0
|
||||||
|
- Build:
|
||||||
|
- ADDED: optionally build Node `lts` and `latest` bindings [#5347](https://github.com/Project-OSRM/osrm-backend/pull/5347)
|
||||||
|
- Features:
|
||||||
|
- ADDED: new waypoints parameter to the `route` plugin, enabling silent waypoints [#5345](https://github.com/Project-OSRM/osrm-backend/pull/5345)
|
||||||
|
- ADDED: data timestamp information in the response (saved in new file `.osrm.timestamp`). [#5115](https://github.com/Project-OSRM/osrm-backend/issues/5115)
|
||||||
|
|
||||||
|
# 5.21.0
|
||||||
|
- Changes from 5.20.0
|
||||||
|
- Features:
|
||||||
|
- ADDED: all waypoints in responses now contain a distance property between the original coordinate and the snapped location. [#5255](https://github.com/Project-OSRM/osrm-backend/pull/5255)
|
||||||
|
- ADDED: if `fallback_speed` is used, a new structure `fallback_speed_cells` will describe which cells contain estimated values [#5259](https://github.com/Project-OSRM/osrm-backend/pull/5259)
|
||||||
|
- REMOVED: we no longer publish Node 4 or 6 binary modules (they are still buildable from source) [#5314](https://github.com/Project-OSRM/osrm-backend/pull/5314)
|
||||||
|
- Table:
|
||||||
|
- ADDED: new parameter `scale_factor` which will scale the cell `duration` values by this factor. [#5298](https://github.com/Project-OSRM/osrm-backend/pull/5298)
|
||||||
|
- FIXED: only trigger `scale_factor` code to scan matrix when necessary. [#5303](https://github.com/Project-OSRM/osrm-backend/pull/5303)
|
||||||
|
- FIXED: fix bug in reverse offset calculation that sometimes lead to negative (and other incorrect) values in distance table results [#5315](https://github.com/Project-OSRM/osrm-backend/pull/5315)
|
||||||
|
- Docker:
|
||||||
|
- FIXED: use consistent boost version between build and runtime [#5311](https://github.com/Project-OSRM/osrm-backend/pull/5311)
|
||||||
|
- FIXED: don't override default permissions on /opt [#5311](https://github.com/Project-OSRM/osrm-backend/pull/5311)
|
||||||
|
- Matching:
|
||||||
|
- CHANGED: matching will now consider edges marked with is_startpoint=false, allowing matching over ferries and other previously non-matchable edge types. [#5297](https://github.com/Project-OSRM/osrm-backend/pull/5297)
|
||||||
|
- Profile:
|
||||||
|
- ADDED: Parse `source:maxspeed` and `maxspeed:type` tags to apply maxspeeds and add belgian flanders rural speed limit. [#5217](https://github.com/Project-OSRM/osrm-backend/pull/5217)
|
||||||
|
- CHANGED: Refactor maxspeed parsing to use common library. [#5144](https://github.com/Project-OSRM/osrm-backend/pull/5144)
|
||||||
|
|
||||||
|
# 5.20.0
|
||||||
|
- Changes from 5.19.0:
|
||||||
|
- Table:
|
||||||
|
- CHANGED: switch to pre-calculated distances for table responses for large speedup and 10% memory increase. [#5251](https://github.com/Project-OSRM/osrm-backend/pull/5251)
|
||||||
|
- ADDED: new parameter `fallback_speed` which will fill `null` cells with estimated value [#5257](https://github.com/Project-OSRM/osrm-backend/pull/5257)
|
||||||
|
- CHANGED: Remove API check for matrix sources/destination length to be less than or equal to coordinates length. [#5298](https://github.com/Project-OSRM/osrm-backend/pull/5289)
|
||||||
|
- FIXED: Fix crashing bug when using fallback_speed parameter with more sources than destinations. [#5291](https://github.com/Project-OSRM/osrm-backend/pull/5291)
|
||||||
|
- Features:
|
||||||
|
- ADDED: direct mmapping of datafiles is now supported via the `--mmap` switch. [#5242](https://github.com/Project-OSRM/osrm-backend/pull/5242)
|
||||||
|
- REMOVED: the previous `--memory_file` switch is now deprecated and will fallback to `--mmap` [#5242](https://github.com/Project-OSRM/osrm-backend/pull/5242)
|
||||||
|
- ADDED: Now publishing Node 10.x LTS binary modules [#5246](https://github.com/Project-OSRM/osrm-backend/pull/5246)
|
||||||
|
- Windows:
|
||||||
|
- FIXED: Windows builds again. [#5249](https://github.com/Project-OSRM/osrm-backend/pull/5249)
|
||||||
|
- Docker:
|
||||||
|
- CHANGED: switch from Alpine Linux to Debian Buster base images [#5281](https://github.com/Project-OSRM/osrm-backend/pull/5281)
|
||||||
|
|
||||||
|
# 5.19.0
|
||||||
- Changes from 5.18.0:
|
- Changes from 5.18.0:
|
||||||
- Optimizations:
|
- Optimizations:
|
||||||
- CHANGED: Map matching is now almost twice as fast. [#5060](https://github.com/Project-OSRM/osrm-backend/pull/5060)
|
|
||||||
- CHANGED: Use Grisu2 for serializing floating point numbers. [#5188](https://github.com/Project-OSRM/osrm-backend/pull/5188)
|
- CHANGED: Use Grisu2 for serializing floating point numbers. [#5188](https://github.com/Project-OSRM/osrm-backend/pull/5188)
|
||||||
- ADDED: Node bindings can return pre-rendered JSON buffer. [#5189](https://github.com/Project-OSRM/osrm-backend/pull/5189)
|
- ADDED: Node bindings can return pre-rendered JSON buffer. [#5189](https://github.com/Project-OSRM/osrm-backend/pull/5189)
|
||||||
|
- Profiles:
|
||||||
|
- CHANGED: Bicycle profile now blacklists barriers instead of whitelisting them [#5076
|
||||||
|
](https://github.com/Project-OSRM/osrm-backend/pull/5076/)
|
||||||
|
- CHANGED: Foot profile now blacklists barriers instead of whitelisting them [#5077
|
||||||
|
](https://github.com/Project-OSRM/osrm-backend/pull/5077/)
|
||||||
|
- CHANGED: Support maxlength and maxweight in car profile [#5101](https://github.com/Project-OSRM/osrm-backend/pull/5101]
|
||||||
- Bugfixes:
|
- Bugfixes:
|
||||||
- FIXED: collapsing of ExitRoundabout instructions [#5114](https://github.com/Project-OSRM/osrm-backend/issues/5114)
|
- FIXED: collapsing of ExitRoundabout instructions [#5114](https://github.com/Project-OSRM/osrm-backend/issues/5114)
|
||||||
- Misc:
|
- Misc:
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ If you want to use the CH pipeline instead replace `osrm-partition` and `osrm-cu
|
|||||||
|
|
||||||
### Using Docker
|
### Using Docker
|
||||||
|
|
||||||
We base our Docker images ([backend](https://hub.docker.com/r/osrm/osrm-backend/), [frontend](https://hub.docker.com/r/osrm/osrm-frontend/)) on Alpine Linux and make sure they are as lightweight as possible.
|
We base our Docker images ([backend](https://hub.docker.com/r/osrm/osrm-backend/), [frontend](https://hub.docker.com/r/osrm/osrm-frontend/)) on Debian and make sure they are as lightweight as possible.
|
||||||
|
|
||||||
Download OpenStreetMap extracts for example from [Geofabrik](http://download.geofabrik.de/)
|
Download OpenStreetMap extracts for example from [Geofabrik](http://download.geofabrik.de/)
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY "FALSE")
|
|||||||
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md")
|
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md")
|
||||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Open Source Routing Machine (OSRM) is a high-performance routing engine. It combines sophisticated routing algorithms with the open and free data of the OpenStreetMap.")
|
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Open Source Routing Machine (OSRM) is a high-performance routing engine. It combines sophisticated routing algorithms with the open and free data of the OpenStreetMap.")
|
||||||
SET(CPACK_PACKAGE_CONTACT "Project OSRM <info@project-osrm.org>")
|
SET(CPACK_PACKAGE_CONTACT "Project OSRM <info@project-osrm.org>")
|
||||||
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENCE.TXT")
|
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.TXT")
|
||||||
|
|
||||||
SET(CPACK_STRIP_FILES "TRUE")
|
SET(CPACK_STRIP_FILES "TRUE")
|
||||||
file(GLOB_RECURSE ProfileGlob ${CMAKE_SOURCE_DIR}/profiles/*)
|
file(GLOB_RECURSE ProfileGlob ${CMAKE_SOURCE_DIR}/profiles/*)
|
||||||
|
|||||||
+19
-15
@@ -1,16 +1,14 @@
|
|||||||
FROM alpine:3.6 as buildstage
|
FROM debian:stretch-slim as builder
|
||||||
|
|
||||||
ARG DOCKER_TAG
|
ARG DOCKER_TAG
|
||||||
|
ARG BUILD_CONCURRENCY
|
||||||
RUN mkdir -p /src && mkdir -p /opt
|
RUN mkdir -p /src && mkdir -p /opt
|
||||||
COPY . /src
|
COPY . /src
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
|
|
||||||
RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
|
RUN NPROC=${BUILD_CONCURRENCY:-$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1)} && \
|
||||||
echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \
|
apt-get update && \
|
||||||
apk update && \
|
apt-get -y --no-install-recommends install cmake make git gcc g++ libbz2-dev libxml2-dev \
|
||||||
apk upgrade && \
|
libzip-dev libboost1.62-all-dev lua5.2 liblua5.2-dev libtbb-dev -o APT::Install-Suggests=0 -o APT::Install-Recommends=0 && \
|
||||||
apk add git cmake wget make libc-dev gcc g++ bzip2-dev boost-dev zlib-dev expat-dev lua5.2-dev libtbb@testing libtbb-dev@testing && \
|
|
||||||
NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
|
|
||||||
echo "Building OSRM ${DOCKER_TAG}" && \
|
echo "Building OSRM ${DOCKER_TAG}" && \
|
||||||
git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \
|
git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \
|
||||||
echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \
|
echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \
|
||||||
@@ -26,20 +24,26 @@ RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
|
|||||||
make -j${NPROC} install && \
|
make -j${NPROC} install && \
|
||||||
cd ../profiles && \
|
cd ../profiles && \
|
||||||
cp -r * /opt && \
|
cp -r * /opt && \
|
||||||
\
|
|
||||||
strip /usr/local/bin/* && \
|
strip /usr/local/bin/* && \
|
||||||
rm -rf /src /usr/local/lib/libosrm*
|
rm -rf /src /usr/local/lib/libosrm*
|
||||||
|
|
||||||
|
|
||||||
# Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
|
# Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
|
||||||
# Only the content below ends up in the image, this helps remove /src from the image (which is large)
|
# Only the content below ends up in the image, this helps remove /src from the image (which is large)
|
||||||
FROM alpine:3.6 as runstage
|
FROM debian:stretch-slim as runstage
|
||||||
RUN mkdir -p /src && mkdir -p /opt
|
RUN mkdir -p /src && mkdir -p /opt
|
||||||
RUN echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \
|
RUN apt-get update && \
|
||||||
apk update && \
|
apt-get install -y --no-install-recommends libboost-program-options1.62.0 libboost-regex1.62.0 \
|
||||||
apk add boost-filesystem boost-program_options boost-regex boost-iostreams boost-thread libgomp lua5.2 expat libtbb@testing
|
libboost-date-time1.62.0 libboost-chrono1.62.0 libboost-filesystem1.62.0 \
|
||||||
COPY --from=buildstage /usr/local /usr/local
|
libboost-iostreams1.62.0 libboost-thread1.62.0 expat liblua5.2-0 libtbb2 &&\
|
||||||
COPY --from=buildstage /opt /opt
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
COPY --from=builder /usr/local /usr/local
|
||||||
|
COPY --from=builder /opt /opt
|
||||||
|
RUN /usr/local/bin/osrm-extract --help && \
|
||||||
|
/usr/local/bin/osrm-routed --help && \
|
||||||
|
/usr/local/bin/osrm-contract --help && \
|
||||||
|
/usr/local/bin/osrm-partition --help && \
|
||||||
|
/usr/local/bin/osrm-customize --help
|
||||||
WORKDIR /opt
|
WORKDIR /opt
|
||||||
|
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
|
|||||||
+1
-1
@@ -6,4 +6,4 @@
|
|||||||
# ensure that "COPY . /src" is referring to the repo root, not the directory
|
# ensure that "COPY . /src" is referring to the repo root, not the directory
|
||||||
# that contains the Dockerfile.
|
# that contains the Dockerfile.
|
||||||
# This script gets executed with a pwd of wherever the Dockerfile is.
|
# This script gets executed with a pwd of wherever the Dockerfile is.
|
||||||
docker build --build-arg DOCKER_TAG=${DOCKER_TAG} -t $IMAGE_NAME -f Dockerfile ..
|
docker build --build-arg BUILD_CONCURRENCY=${CONCURRENCY:-1} --build-arg DOCKER_TAG=${DOCKER_TAG} -t $IMAGE_NAME -f Dockerfile ..
|
||||||
|
|||||||
+20
-4
@@ -70,6 +70,8 @@ curl 'http://router.project-osrm.org/route/v1/driving/polyline(ofp_Ik_vpAilAyu@t
|
|||||||
|
|
||||||
### Responses
|
### Responses
|
||||||
|
|
||||||
|
#### Code
|
||||||
|
|
||||||
Every response object has a `code` property containing one of the strings below or a service dependent code:
|
Every response object has a `code` property containing one of the strings below or a service dependent code:
|
||||||
|
|
||||||
| Type | Description |
|
| Type | Description |
|
||||||
@@ -87,12 +89,17 @@ Every response object has a `code` property containing one of the strings below
|
|||||||
- `message` is a **optional** human-readable error message. All other status types are service dependent.
|
- `message` is a **optional** human-readable error message. All other status types are service dependent.
|
||||||
- In case of an error the HTTP status code will be `400`. Otherwise the HTTP status code will be `200` and `code` will be `Ok`.
|
- In case of an error the HTTP status code will be `400`. Otherwise the HTTP status code will be `200` and `code` will be `Ok`.
|
||||||
|
|
||||||
|
#### Data version
|
||||||
|
|
||||||
|
Every response object has a `data_version` propetry containing timestamp from the original OpenStreetMap file. This field is optional. It can be ommited if data_version parametr was not set on osrm-extract stage or OSM file has not `osmosis_replication_timestamp` section.
|
||||||
|
|
||||||
#### Example response
|
#### Example response
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"code": "Ok",
|
"code": "Ok",
|
||||||
"message": "Everything worked"
|
"message": "Everything worked",
|
||||||
|
"data_version": "2017-11-17T21:43:02Z"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -119,7 +126,6 @@ In addition to the [general options](#general-options) the following options are
|
|||||||
|
|
||||||
- `code` if the request was successful `Ok` otherwise see the service dependent and general status codes.
|
- `code` if the request was successful `Ok` otherwise see the service dependent and general status codes.
|
||||||
- `waypoints` array of `Waypoint` objects sorted by distance to the input coordinate. Each object has at least the following additional properties:
|
- `waypoints` array of `Waypoint` objects sorted by distance to the input coordinate. Each object has at least the following additional properties:
|
||||||
- `distance`: Distance in meters to the supplied input coordinate.
|
|
||||||
- `nodes`: Array of OpenStreetMap node ids.
|
- `nodes`: Array of OpenStreetMap node ids.
|
||||||
|
|
||||||
#### Example Requests
|
#### Example Requests
|
||||||
@@ -196,6 +202,7 @@ In addition to the [general options](#general-options) the following options are
|
|||||||
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|
|geometries |`polyline` (default), `polyline6`, `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.|
|
|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 constraining uturns there even if it would be faster. Default value depends on the profile. |
|
|continue\_straight |`default` (default), `true`, `false` |Forces the route to keep going straight at waypoints constraining uturns there even if it would be faster. Default value depends on the profile. |
|
||||||
|
|waypoints | `{index};{index};{index}...` |Treats input coordinates indicated by given indices as waypoints in returned Match object. Default is to treat all input coordinates as waypoints. |
|
||||||
|
|
||||||
\* Please note that even if alternative routes are requested, a result cannot be guaranteed.
|
\* Please note that even if alternative routes are requested, a result cannot be guaranteed.
|
||||||
|
|
||||||
@@ -236,8 +243,10 @@ In addition to the [general options](#general-options) the following options are
|
|||||||
|------------|--------------------------------------------------|---------------------------------------------|
|
|------------|--------------------------------------------------|---------------------------------------------|
|
||||||
|sources |`{index};{index}[;{index} ...]` or `all` (default)|Use location with given index as source. |
|
|sources |`{index};{index}[;{index} ...]` or `all` (default)|Use location with given index as source. |
|
||||||
|destinations|`{index};{index}[;{index} ...]` or `all` (default)|Use location with given index as destination.|
|
|destinations|`{index};{index}[;{index} ...]` or `all` (default)|Use location with given index as destination.|
|
||||||
|annotations |`duration` (default), `distance`, or `duration,distance`|Return the requested table or tables in response. Note that computing the `distances` table is currently only implemented for CH. If `annotations=distance` or `annotations=duration,distance` is requested when running a MLD router, a `NotImplemented` error will be returned.
|
|annotations |`duration` (default), `distance`, or `duration,distance`|Return the requested table or tables in response. |
|
||||||
|
|
|fallback_speed|`double > 0`| If no route found between a source/destination pair, calculate the as-the-crow-flies distance, then use this speed to estimate duration.|
|
||||||
|
|fallback_coordinate|`input` (default), or `snapped`| When using a `fallback_speed`, use the user-supplied coordinate (`input`), or the snapped location (`snapped`) for calculating distances.|
|
||||||
|
|scale_factor|`double > 0`| Use in conjunction with `annotations=durations`. Scales the table `duration` values by this number.|
|
||||||
|
|
||||||
Unlike other array encoded options, the length of `sources` and `destinations` can be **smaller or equal**
|
Unlike other array encoded options, the length of `sources` and `destinations` can be **smaller or equal**
|
||||||
to number of input locations;
|
to number of input locations;
|
||||||
@@ -283,6 +292,7 @@ curl 'http://router.project-osrm.org/table/v1/driving/13.388860,52.517037;13.397
|
|||||||
the i-th waypoint to the j-th waypoint. Values are given in meters. Can be `null` if no route between `i` and `j` can be found. Note that computing the `distances` table is currently only implemented for CH. If `annotations=distance` or `annotations=duration,distance` is requested when running a MLD router, a `NotImplemented` error will be returned.
|
the i-th waypoint to the j-th waypoint. Values are given in meters. Can be `null` if no route between `i` and `j` can be found. Note that computing the `distances` table is currently only implemented for CH. If `annotations=distance` or `annotations=duration,distance` is requested when running a MLD router, a `NotImplemented` error will be returned.
|
||||||
- `sources` array of `Waypoint` objects describing all sources in order
|
- `sources` array of `Waypoint` objects describing all sources in order
|
||||||
- `destinations` array of `Waypoint` objects describing all destinations in order
|
- `destinations` array of `Waypoint` objects describing all destinations in order
|
||||||
|
- `fallback_speed_cells` (optional) array of arrays containing `i,j` pairs indicating which cells contain estimated values based on `fallback_speed`. Will be absent if `fallback_speed` is not used.
|
||||||
|
|
||||||
In case of error the following `code`s are supported in addition to the general ones:
|
In case of error the following `code`s are supported in addition to the general ones:
|
||||||
|
|
||||||
@@ -383,6 +393,10 @@ All other properties might be undefined.
|
|||||||
2361.73,
|
2361.73,
|
||||||
0
|
0
|
||||||
]
|
]
|
||||||
|
],
|
||||||
|
"fallback_speed_cells": [
|
||||||
|
[ 0, 1 ],
|
||||||
|
[ 1, 0 ]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -551,6 +565,7 @@ Vector tiles contain two layers:
|
|||||||
| `weight ` | `integer` | how long this segment takes to traverse, in units (may differ from `duration` when artificial biasing is applied in the Lua profiles). ACTUAL ROUTING USES THIS VALUE. |
|
| `weight ` | `integer` | how long this segment takes to traverse, in units (may differ from `duration` when artificial biasing is applied in the Lua profiles). ACTUAL ROUTING USES THIS VALUE. |
|
||||||
| `name` | `string` | the name of the road this segment belongs to |
|
| `name` | `string` | the name of the road this segment belongs to |
|
||||||
| `rate` | `float` | the value of `length/weight` - analagous to `speed`, but using the `weight` value rather than `duration`, rounded to the nearest integer |
|
| `rate` | `float` | the value of `length/weight` - analagous to `speed`, but using the `weight` value rather than `duration`, rounded to the nearest integer |
|
||||||
|
| `is_startpoint` | `boolean` | whether this segment can be used as a start/endpoint for routes |
|
||||||
|
|
||||||
`turns` layer:
|
`turns` layer:
|
||||||
|
|
||||||
@@ -905,6 +920,7 @@ Object used to describe waypoint on a route.
|
|||||||
|
|
||||||
- `name` Name of the street the coordinate snapped to
|
- `name` Name of the street the coordinate snapped to
|
||||||
- `location` Array that contains the `[longitude, latitude]` pair of the snapped coordinate
|
- `location` Array that contains the `[longitude, latitude]` pair of the snapped coordinate
|
||||||
|
- `distance` The distance, in metres, from the input coordinate to the snapped coordinate
|
||||||
- `hint` Unique internal identifier of the segment (ephemeral, not constant over data updates)
|
- `hint` Unique internal identifier of the segment (ephemeral, not constant over data updates)
|
||||||
This can be used on subsequent request to significantly speed up the query and to connect multiple services.
|
This can be used on subsequent request to significantly speed up the query and to connect multiple services.
|
||||||
E.g. you can use the `hint` value obtained by the `nearest` query as `hint` values for `route` inputs.
|
E.g. you can use the `hint` value obtained by the `nearest` query as `hint` values for `route` inputs.
|
||||||
|
|||||||
+19
-13
@@ -25,7 +25,9 @@ var osrm = new OSRM('network.osrm');
|
|||||||
Make sure you prepared the dataset with the correct toolchain.
|
Make sure you prepared the dataset with the correct toolchain.
|
||||||
- `options.shared_memory` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore.
|
- `options.shared_memory` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore.
|
||||||
This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
|
This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
|
||||||
- `options.memory_file` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Path to a file on disk to store the memory using mmap.
|
- `options.memory_file` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** *DEPRECATED*
|
||||||
|
Old behaviour: Path to a file on disk to store the memory using mmap. Current behaviour: setting this value is the same as setting `mmap_memory: true`.
|
||||||
|
- `options.mmap_memory` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Map on-disk files to virtual memory addresses (mmap), rather than loading into RAM.
|
||||||
- `options.path` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** The path to the `.osrm` files. This is mutually exclusive with setting {options.shared_memory} to true.
|
- `options.path` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** The path to the `.osrm` files. This is mutually exclusive with setting {options.shared_memory} to true.
|
||||||
- `options.max_locations_trip` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in trip query (default: unlimited).
|
- `options.max_locations_trip` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in trip query (default: unlimited).
|
||||||
- `options.max_locations_viaroute` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in viaroute query (default: unlimited).
|
- `options.max_locations_viaroute` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. locations supported in viaroute query (default: unlimited).
|
||||||
@@ -55,6 +57,7 @@ Returns the fastest route between two or more coordinates while visiting the way
|
|||||||
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
|
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
|
||||||
- `options.continue_straight` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** 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.
|
- `options.continue_straight` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** 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.
|
||||||
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
|
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
|
||||||
|
- `options.waypoints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Indices to coordinates to treat as waypoints. If not supplied, all coordinates are waypoints. Must include first and last coordinate index.
|
||||||
`null`/`true`/`false`
|
`null`/`true`/`false`
|
||||||
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
||||||
|
|
||||||
@@ -127,6 +130,9 @@ tables. Optionally returns distance table.
|
|||||||
- `options.destinations` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** An array of `index` elements (`0 <= integer <
|
- `options.destinations` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** An array of `index` elements (`0 <= integer <
|
||||||
#coordinates`) to use location with given index as destination. Default is to use all.
|
#coordinates`) to use location with given index as destination. Default is to use all.
|
||||||
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
|
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
|
||||||
|
- `options.fallback_speed` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Replace `null` responses in result with as-the-crow-flies estimates based on `fallback_speed`. Value is in metres/second.
|
||||||
|
- `options.fallback_coordinate` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Either `input` (default) or `snapped`. If using a `fallback_speed`, use either the user-supplied coordinate (`input`), or the snapped coordinate (`snapped`) for calculating the as-the-crow-flies diestance between two points.
|
||||||
|
- `options.scale_factor` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Multiply the table duration values in the table by this number for more controlled input into a route optimization solver.
|
||||||
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
@@ -152,6 +158,7 @@ Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refer
|
|||||||
Values are given in seconds.
|
Values are given in seconds.
|
||||||
**`sources`**: array of [`Ẁaypoint`](#waypoint) objects describing all sources in order.
|
**`sources`**: array of [`Ẁaypoint`](#waypoint) objects describing all sources in order.
|
||||||
**`destinations`**: array of [`Ẁaypoint`](#waypoint) objects describing all destinations in order.
|
**`destinations`**: array of [`Ẁaypoint`](#waypoint) objects describing all destinations in order.
|
||||||
|
**`fallback_speed_cells`**: (optional) if `fallback_speed` is used, will be an array of arrays of `row,column` values, indicating which cells contain estimated values.
|
||||||
|
|
||||||
### tile
|
### tile
|
||||||
|
|
||||||
@@ -204,6 +211,7 @@ if they can not be matched successfully.
|
|||||||
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy. Can be `null` for default value `5` meters or `double >= 0`.
|
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy. Can be `null` for default value `5` meters or `double >= 0`.
|
||||||
- `options.gaps` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Allows the input track splitting based on huge timestamp gaps between points. Either `split` or `ignore` (optional, default `split`).
|
- `options.gaps` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Allows the input track splitting based on huge timestamp gaps between points. Either `split` or `ignore` (optional, default `split`).
|
||||||
- `options.tidy` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Allows the input track modification to obtain better matching quality for noisy tracks (optional, default `false`).
|
- `options.tidy` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Allows the input track modification to obtain better matching quality for noisy tracks (optional, default `false`).
|
||||||
|
- `options.waypoints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Indices to coordinates to treat as waypoints. If not supplied, all coordinates are waypoints. Must include first and last coordinate index.
|
||||||
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
@@ -322,16 +330,14 @@ osrm.route(options, { format: "json_buffer" }, function(err, response) {
|
|||||||
|
|
||||||
## Responses
|
## Responses
|
||||||
|
|
||||||
Responses
|
|
||||||
|
|
||||||
### Route
|
### Route
|
||||||
|
|
||||||
Represents a route through (potentially multiple) waypoints.
|
Represents a route through (potentially multiple) waypoints.
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `exteral` **documentation** in
|
- **documentation** in
|
||||||
[`osrm-backend`](../http.md#route)
|
[`osrm-backend`](../http.md#route-object)
|
||||||
|
|
||||||
### RouteLeg
|
### RouteLeg
|
||||||
|
|
||||||
@@ -339,8 +345,8 @@ Represents a route between two waypoints.
|
|||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `exteral` **documentation** in
|
- **documentation** in
|
||||||
[`osrm-backend`](../http.md#routeleg)
|
[`osrm-backend`](../http.md#routeleg-object)
|
||||||
|
|
||||||
### RouteStep
|
### RouteStep
|
||||||
|
|
||||||
@@ -349,15 +355,15 @@ single way to the subsequent step.
|
|||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `exteral` **documentation** in
|
- **documentation** in
|
||||||
[`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#routestep)
|
[`osrm-backend`](../http.md#routestep-object)
|
||||||
|
|
||||||
### StepManeuver
|
### StepManeuver
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `exteral` **documentation** in
|
- **documentation** in
|
||||||
[`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#stepmaneuver)
|
[`osrm-backend`](../http.md#stepmaneuver-object)
|
||||||
|
|
||||||
### Waypoint
|
### Waypoint
|
||||||
|
|
||||||
@@ -365,5 +371,5 @@ Object used to describe waypoint on a route.
|
|||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `exteral` **documentation** in
|
- **documentation** in
|
||||||
[`osrm-backend`](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#waypoint)
|
[`osrm-backend`](../http.md#waypoint-object)
|
||||||
|
|||||||
@@ -109,3 +109,12 @@ Feature: Car - Handle ferry routes
|
|||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | modes | time |
|
| from | to | route | modes | time |
|
||||||
| c | d | bcde,bcde | ferry,ferry | 600s |
|
| c | d | bcde,bcde | ferry,ferry | 600s |
|
||||||
|
|
||||||
|
Given the query options
|
||||||
|
| geometries | geojson |
|
||||||
|
| overview | full |
|
||||||
|
|
||||||
|
# Note that matching *should* work across unsnappable ferries
|
||||||
|
When I match I should get
|
||||||
|
| trace | geometry | duration |
|
||||||
|
| abcdef| 1,1,1.000899,1,1.000899,1,1.002697,1,1.002697,1,1.003596,1,1.003596,1,1.005394,1,1.005394,1,1.006293,1 | 610.9 |
|
||||||
|
|||||||
@@ -137,3 +137,28 @@ OSRM will use 4/5 of the projected free-flow speed.
|
|||||||
| primary | | | 30 | -1 | | 23 km/h | | 6.7 |
|
| primary | | | 30 | -1 | | 23 km/h | | 6.7 |
|
||||||
| primary | 20 | 30 | | -1 | | 15 km/h | | 4.4 |
|
| primary | 20 | 30 | | -1 | | 15 km/h | | 4.4 |
|
||||||
| primary | 20 | | 30 | -1 | | 23 km/h | | 6.7 |
|
| primary | 20 | | 30 | -1 | | 23 km/h | | 6.7 |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Car - Respect source:maxspeed
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b c d e f g
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | source:maxspeed | maxspeed |
|
||||||
|
| ab | trunk | | |
|
||||||
|
| bc | trunk | | 60 |
|
||||||
|
| cd | trunk | FR:urban | |
|
||||||
|
| de | trunk | CH:rural | |
|
||||||
|
| ef | trunk | CH:trunk | |
|
||||||
|
| fg | trunk | CH:motorway | |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | route | speed |
|
||||||
|
| a | b | ab,ab | 85 km/h |
|
||||||
|
| b | c | bc,bc | 48 km/h |
|
||||||
|
| c | d | cd,cd | 40 km/h |
|
||||||
|
| d | e | de,de | 64 km/h |
|
||||||
|
| e | f | ef,ef | 80 km/h |
|
||||||
|
| f | g | fg,fg | 96 km/h |
|
||||||
@@ -35,3 +35,28 @@ Feature: Car - Allowed start/end modes
|
|||||||
| from | to | route | modes |
|
| from | to | route | modes |
|
||||||
| 1 | 2 | ab,ab | driving,driving |
|
| 1 | 2 | ab,ab | driving,driving |
|
||||||
| 2 | 1 | ab,ab | driving,driving |
|
| 2 | 1 | ab,ab | driving,driving |
|
||||||
|
|
||||||
|
Scenario: Car - URL override of non-startpoints
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a 1 b c 2 d
|
||||||
|
"""
|
||||||
|
|
||||||
|
Given the query options
|
||||||
|
| snapping | any |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | access |
|
||||||
|
| ab | service | private |
|
||||||
|
| bc | primary | |
|
||||||
|
| cd | service | private |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | 2 | c |
|
||||||
|
| 1 | 59.1 | 35.1 |
|
||||||
|
| b | 35.1 | 11.1 |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | route |
|
||||||
|
| 1 | 2 | ab,bc,cd |
|
||||||
|
| 2 | 1 | cd,bc,ab |
|
||||||
|
|||||||
@@ -84,7 +84,47 @@ class OSRMDirectLoader extends OSRMBaseLoader {
|
|||||||
throw new Error(util.format('osrm-routed %s: %s', errorReason(err), err.cmd));
|
throw new Error(util.format('osrm-routed %s: %s', errorReason(err), err.cmd));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
callback();
|
|
||||||
|
this.child.readyFunc = (data) => {
|
||||||
|
if (/running and waiting for requests/.test(data)) {
|
||||||
|
this.child.stdout.removeListener('data', this.child.readyFunc);
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.child.stdout.on('data',this.child.readyFunc);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class OSRMmmapLoader extends OSRMBaseLoader {
|
||||||
|
constructor (scope) {
|
||||||
|
super(scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
load (inputFile, callback) {
|
||||||
|
this.inputFile = inputFile;
|
||||||
|
this.shutdown(() => {
|
||||||
|
this.launch(callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
osrmUp (callback) {
|
||||||
|
if (this.osrmIsRunning()) return callback(new Error("osrm-routed already running!"));
|
||||||
|
|
||||||
|
const command_arguments = util.format('%s -p %d -i %s -a %s --mmap', this.inputFile, this.scope.OSRM_PORT, this.scope.OSRM_IP, this.scope.ROUTING_ALGORITHM);
|
||||||
|
this.child = this.scope.runBin('osrm-routed', command_arguments, this.scope.environment, (err) => {
|
||||||
|
if (err && err.signal !== 'SIGINT') {
|
||||||
|
this.child = null;
|
||||||
|
throw new Error(util.format('osrm-routed %s: %s', errorReason(err), err.cmd));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.child.readyFunc = (data) => {
|
||||||
|
if (/running and waiting for requests/.test(data)) {
|
||||||
|
this.child.stdout.removeListener('data', this.child.readyFunc);
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.child.stdout.on('data',this.child.readyFunc);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -135,22 +175,32 @@ class OSRMLoader {
|
|||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.sharedLoader = new OSRMDatastoreLoader(this.scope);
|
this.sharedLoader = new OSRMDatastoreLoader(this.scope);
|
||||||
this.directLoader = new OSRMDirectLoader(this.scope);
|
this.directLoader = new OSRMDirectLoader(this.scope);
|
||||||
|
this.mmapLoader = new OSRMmmapLoader(this.scope);
|
||||||
this.method = scope.DEFAULT_LOAD_METHOD;
|
this.method = scope.DEFAULT_LOAD_METHOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
load (inputFile, callback) {
|
load (inputFile, callback) {
|
||||||
|
if (!this.loader) {
|
||||||
|
this.loader = {shutdown: (cb) => cb() };
|
||||||
|
}
|
||||||
if (this.method === 'datastore') {
|
if (this.method === 'datastore') {
|
||||||
this.directLoader.shutdown((err) => {
|
this.loader.shutdown((err) => {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
this.loader = this.sharedLoader;
|
this.loader = this.sharedLoader;
|
||||||
this.sharedLoader.load(inputFile, callback);
|
this.sharedLoader.load(inputFile, callback);
|
||||||
});
|
});
|
||||||
} else if (this.method === 'directly') {
|
} else if (this.method === 'directly') {
|
||||||
this.sharedLoader.shutdown((err) => {
|
this.loader.shutdown((err) => {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
this.loader = this.directLoader;
|
this.loader = this.directLoader;
|
||||||
this.directLoader.load(inputFile, callback);
|
this.directLoader.load(inputFile, callback);
|
||||||
});
|
});
|
||||||
|
} else if (this.method === 'mmap') {
|
||||||
|
this.loader.shutdown((err) => {
|
||||||
|
if (err) return callback(err);
|
||||||
|
this.loader = this.mmapLoader;
|
||||||
|
this.mmapLoader.load(inputFile, callback);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
callback(new Error('*** Unknown load method ' + method));
|
callback(new Error('*** Unknown load method ' + method));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ module.exports = function () {
|
|||||||
this.reprocess(callback);
|
this.reprocess(callback);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.Given(/^osrm\-routed is stopped$/, (callback) => {
|
this.Given(/^osrm-routed is stopped$/, (callback) => {
|
||||||
this.OSRMLoader.shutdown(callback);
|
this.OSRMLoader.shutdown(callback);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,22 +3,25 @@ var util = require('util');
|
|||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
const durationsRegex = new RegExp(/^I request a travel time matrix I should get$/);
|
const durationsRegex = new RegExp(/^I request a travel time matrix I should get$/);
|
||||||
const distancesRegex = new RegExp(/^I request a travel distance matrix I should get$/);
|
const distancesRegex = new RegExp(/^I request a travel distance matrix I should get$/);
|
||||||
|
const estimatesRegex = new RegExp(/^I request a travel time matrix I should get estimates for$/);
|
||||||
|
|
||||||
const DURATIONS_NO_ROUTE = 2147483647; // MAX_INT
|
const DURATIONS_NO_ROUTE = 2147483647; // MAX_INT
|
||||||
const DISTANCES_NO_ROUTE = 3.40282e+38; // MAX_FLOAT
|
const DISTANCES_NO_ROUTE = 3.40282e+38; // MAX_FLOAT
|
||||||
|
|
||||||
this.When(durationsRegex, function(table, callback) {tableParse.call(this, table, DURATIONS_NO_ROUTE, 'durations', callback);}.bind(this));
|
this.When(durationsRegex, function(table, callback) {tableParse.call(this, table, DURATIONS_NO_ROUTE, 'durations', callback);}.bind(this));
|
||||||
this.When(distancesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'distances', callback);}.bind(this));
|
this.When(distancesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'distances', callback);}.bind(this));
|
||||||
|
this.When(estimatesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'fallback_speed_cells', callback);}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
const durationsParse = function(v) { return isNaN(parseInt(v)); };
|
const durationsParse = function(v) { return isNaN(parseInt(v)); };
|
||||||
const distancesParse = function(v) { return isNaN(parseFloat(v)); };
|
const distancesParse = function(v) { return isNaN(parseFloat(v)); };
|
||||||
|
const estimatesParse = function(v) { return isNaN(parseFloat(v)); };
|
||||||
|
|
||||||
function tableParse(table, noRoute, annotation, callback) {
|
function tableParse(table, noRoute, annotation, callback) {
|
||||||
|
|
||||||
const parse = annotation == 'distances' ? distancesParse : durationsParse;
|
const parse = annotation == 'distances' ? distancesParse : (annotation == 'durations' ? durationsParse : estimatesParse);
|
||||||
const params = this.queryParams;
|
const params = this.queryParams;
|
||||||
params.annotations = annotation == 'distances' ? 'distance' : 'duration';
|
params.annotations = ['durations','fallback_speed_cells'].indexOf(annotation) !== -1 ? 'duration' : 'distance';
|
||||||
|
|
||||||
var tableRows = table.raw();
|
var tableRows = table.raw();
|
||||||
|
|
||||||
@@ -61,11 +64,26 @@ function tableParse(table, noRoute, annotation, callback) {
|
|||||||
|
|
||||||
var json = JSON.parse(response.body);
|
var json = JSON.parse(response.body);
|
||||||
|
|
||||||
var result = json[annotation].map(row => {
|
var result = {};
|
||||||
var hashes = {};
|
if (annotation === 'fallback_speed_cells') {
|
||||||
row.forEach((v, i) => { hashes[tableRows[0][i+1]] = parse(v) ? '' : v; });
|
result = table.raw().map(row => row.map(() => ''));
|
||||||
return hashes;
|
json[annotation].forEach(pair => {
|
||||||
});
|
result[pair[0]+1][pair[1]+1] = 'Y';
|
||||||
|
});
|
||||||
|
result = result.slice(1).map(row => {
|
||||||
|
var hashes = {};
|
||||||
|
row.slice(1).forEach((v,i) => {
|
||||||
|
hashes[tableRows[0][i+1]] = v;
|
||||||
|
});
|
||||||
|
return hashes;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
result = json[annotation].map(row => {
|
||||||
|
var hashes = {};
|
||||||
|
row.forEach((v, i) => { hashes[tableRows[0][i+1]] = parse(v) ? '' : v; });
|
||||||
|
return hashes;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var testRow = (row, ri, cb) => {
|
var testRow = (row, ri, cb) => {
|
||||||
for (var k in result[ri]) {
|
for (var k in result[ri]) {
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ module.exports = function () {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.When(/^I run "osrm\-routed\s?(.*?)"$/, { timeout: this.TIMEOUT }, (options, callback) => {
|
this.When(/^I run "osrm-routed\s?(.*?)"$/, { timeout: this.TIMEOUT }, (options, callback) => {
|
||||||
this.runAndSafeOutput('osrm-routed', options, callback);
|
this.runAndSafeOutput('osrm-routed', options, callback);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.When(/^I run "osrm\-(extract|contract|partition|customize)\s?(.*?)"$/, (binary, options, callback) => {
|
this.When(/^I run "osrm-(extract|contract|partition|customize)\s?(.*?)"$/, (binary, options, callback) => {
|
||||||
const stamp = this.processedCacheFile + '.stamp_' + binary;
|
const stamp = this.processedCacheFile + '.stamp_' + binary;
|
||||||
this.runAndSafeOutput('osrm-' + binary, options, (err) => {
|
this.runAndSafeOutput('osrm-' + binary, options, (err) => {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
@@ -33,11 +33,11 @@ module.exports = function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.When(/^I try to run "(osrm\-[a-z]+)\s?(.*?)"$/, (binary, options, callback) => {
|
this.When(/^I try to run "(osrm-[a-z]+)\s?(.*?)"$/, (binary, options, callback) => {
|
||||||
this.runAndSafeOutput(binary, options, () => { callback(); });
|
this.runAndSafeOutput(binary, options, () => { callback(); });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.When(/^I run "osrm\-datastore\s?(.*?)"(?: with input "([^"]*)")?$/, (options, input, callback) => {
|
this.When(/^I run "osrm-datastore\s?(.*?)"(?: with input "([^"]*)")?$/, (options, input, callback) => {
|
||||||
let child = this.runAndSafeOutput('osrm-datastore', options, callback);
|
let child = this.runAndSafeOutput('osrm-datastore', options, callback);
|
||||||
if (input !== undefined)
|
if (input !== undefined)
|
||||||
child.stdin.write(input);
|
child.stdin.write(input);
|
||||||
@@ -55,13 +55,13 @@ module.exports = function () {
|
|||||||
this.Then(/^stdout should( not)? contain "(.*?)"$/, (not, str) => {
|
this.Then(/^stdout should( not)? contain "(.*?)"$/, (not, str) => {
|
||||||
const contains = this.stdout.indexOf(str) > -1;
|
const contains = this.stdout.indexOf(str) > -1;
|
||||||
assert.ok(typeof not === 'undefined' ? contains : !contains,
|
assert.ok(typeof not === 'undefined' ? contains : !contains,
|
||||||
'stdout ' + (typeof not === 'undefined' ? 'does not contain' : 'contains') + ' "' + str + '"');
|
'stdout ' + (typeof not === 'undefined' ? 'does not contain' : 'contains') + ' "' + str + '"');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.Then(/^stderr should( not)? contain "(.*?)"$/, (not, str) => {
|
this.Then(/^stderr should( not)? contain "(.*?)"$/, (not, str) => {
|
||||||
const contains = this.stderr.indexOf(str) > -1;
|
const contains = this.stderr.indexOf(str) > -1;
|
||||||
assert.ok(typeof not === 'undefined' ? contains : !contains,
|
assert.ok(typeof not === 'undefined' ? contains : !contains,
|
||||||
'stderr ' + (typeof not === 'undefined' ? 'does not contain' : 'contains') + ' "' + str + '"');
|
'stderr ' + (typeof not === 'undefined' ? 'does not contain' : 'contains') + ' "' + str + '"');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.Then(/^stdout should contain \/(.*)\/$/, (regexStr) => {
|
this.Then(/^stdout should contain \/(.*)\/$/, (regexStr) => {
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ module.exports = function () {
|
|||||||
outputRow[direction] = result[direction].status ?
|
outputRow[direction] = result[direction].status ?
|
||||||
'x' : '';
|
'x' : '';
|
||||||
break;
|
break;
|
||||||
case /^[\d\.]+ s/.test(want):
|
case /^[\d.]+ s/.test(want):
|
||||||
// the result here can come back as a non-number value like
|
// the result here can come back as a non-number value like
|
||||||
// `diff`, but we only want to apply the unit when it comes
|
// `diff`, but we only want to apply the unit when it comes
|
||||||
// back as a number, for tableDiff's literal comparison
|
// back as a number, for tableDiff's literal comparison
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ module.exports = function() {
|
|||||||
|
|
||||||
// setup cache for feature data
|
// setup cache for feature data
|
||||||
// if OSRM_PROFILE is set to force a specific profile, then
|
// if OSRM_PROFILE is set to force a specific profile, then
|
||||||
// include the profile name in the hash of the profile file
|
// include the profile name in the hash of the profile file
|
||||||
hash.hashOfFile(uri, this.OSRM_PROFILE, (err, hash) => {
|
hash.hashOfFile(uri, this.OSRM_PROFILE, (err, hash) => {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
|
|
||||||
@@ -45,10 +45,10 @@ module.exports = function() {
|
|||||||
this.featureProcessedCacheDirectories[uri] = featureProcessedCacheDirectory;
|
this.featureProcessedCacheDirectories[uri] = featureProcessedCacheDirectory;
|
||||||
|
|
||||||
d3.queue(1)
|
d3.queue(1)
|
||||||
.defer(mkdirp, featureProcessedCacheDirectory)
|
.defer(mkdirp, featureProcessedCacheDirectory)
|
||||||
.defer(this.cleanupFeatureCache.bind(this), featureCacheDirectory, hash)
|
.defer(this.cleanupFeatureCache.bind(this), featureCacheDirectory, hash)
|
||||||
.defer(this.cleanupProcessedFeatureCache.bind(this), featureProcessedCacheDirectory, this.osrmHash)
|
.defer(this.cleanupProcessedFeatureCache.bind(this), featureProcessedCacheDirectory, this.osrmHash)
|
||||||
.awaitAll(callback);
|
.awaitAll(callback);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ module.exports = function() {
|
|||||||
fs.readdir(parentPath, (err, files) => {
|
fs.readdir(parentPath, (err, files) => {
|
||||||
let q = d3.queue();
|
let q = d3.queue();
|
||||||
files.filter(name => { return name !== featureHash;})
|
files.filter(name => { return name !== featureHash;})
|
||||||
.map((f) => { q.defer(rimraf, path.join(parentPath, f)); });
|
.map((f) => { q.defer(rimraf, path.join(parentPath, f)); });
|
||||||
q.awaitAll(callback);
|
q.awaitAll(callback);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -145,7 +145,7 @@ module.exports = function() {
|
|||||||
|
|
||||||
// converts the scenario titles in file prefixes
|
// converts the scenario titles in file prefixes
|
||||||
this.getScenarioID = (scenario) => {
|
this.getScenarioID = (scenario) => {
|
||||||
let name = scenario.getName().toLowerCase().replace(/[\/\-'=,\(\):\*#]/g, '')
|
let name = scenario.getName().toLowerCase().replace(/[/\-'=,():*#]/g, '')
|
||||||
.replace(/\s/g, '_').replace(/__/g, '_').replace(/\.\./g, '.')
|
.replace(/\s/g, '_').replace(/__/g, '_').replace(/\.\./g, '.')
|
||||||
.substring(0, 64);
|
.substring(0, 64);
|
||||||
return util.format('%d_%s', scenario.getLine(), name);
|
return util.format('%d_%s', scenario.getLine(), name);
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ module.exports = {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
var matchPercent = want.match(/(.*)\s+~(.+)%$/),
|
var matchPercent = want.match(/(.*)\s+~(.+)%$/),
|
||||||
matchAbs = want.match(/(.*)\s+\+\-(.+)$/),
|
matchAbs = want.match(/(.*)\s+\+-(.+)$/),
|
||||||
matchRe = want.match(/^\/(.*)\/$/),
|
matchRe = want.match(/^\/(.*)\/$/),
|
||||||
// we use this for matching before/after bearing
|
// we use this for matching before/after bearing
|
||||||
matchBearingListAbs = want.match(/^((\d+)->(\d+))(,(\d+)->(\d+))*\s+\+\-(.+)$/),
|
matchBearingListAbs = want.match(/^((\d+)->(\d+))(,(\d+)->(\d+))*\s+\+-(.+)$/),
|
||||||
matchIntersectionListAbs = want.match(/^(((((true|false):\d+)\s{0,1})+,{0,1})+;{0,1})+\s+\+\-(.+)$/),
|
matchIntersectionListAbs = want.match(/^(((((true|false):\d+)\s{0,1})+,{0,1})+;{0,1})+\s+\+-(.+)$/),
|
||||||
matchRangeNumbers = want.match(/\d+\+\-\d+/);
|
matchRangeNumbers = want.match(/\d+\+-\d+/);
|
||||||
|
|
||||||
function inRange(margin, got, want) {
|
function inRange(margin, got, want) {
|
||||||
var fromR = parseFloat(want) - margin,
|
var fromR = parseFloat(want) - margin,
|
||||||
@@ -31,12 +31,12 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
function parseIntersectionString(str) {
|
function parseIntersectionString(str) {
|
||||||
return str.split(';')
|
return str.split(';')
|
||||||
.map((turn_intersections) => turn_intersections
|
.map((turn_intersections) => turn_intersections
|
||||||
.split(',')
|
.split(',')
|
||||||
.map((intersection) => intersection
|
.map((intersection) => intersection
|
||||||
.split(' ')
|
.split(' ')
|
||||||
.map((entry_bearing_pair) => entry_bearing_pair
|
.map((entry_bearing_pair) => entry_bearing_pair
|
||||||
.split(':'))));
|
.split(':'))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (got === want) {
|
if (got === want) {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ module.exports = function () {
|
|||||||
this.DEFAULT_ENVIRONMENT = Object.assign({STXXLCFG: stxxl_config}, process.env);
|
this.DEFAULT_ENVIRONMENT = Object.assign({STXXLCFG: stxxl_config}, process.env);
|
||||||
this.DEFAULT_PROFILE = 'bicycle';
|
this.DEFAULT_PROFILE = 'bicycle';
|
||||||
this.DEFAULT_INPUT_FORMAT = 'osm';
|
this.DEFAULT_INPUT_FORMAT = 'osm';
|
||||||
this.DEFAULT_LOAD_METHOD = 'datastore';
|
this.DEFAULT_LOAD_METHOD = process.argv[process.argv.indexOf('-m') +1].match('mmap') ? 'mmap' : 'datastore';
|
||||||
this.DEFAULT_ORIGIN = [1,1];
|
this.DEFAULT_ORIGIN = [1,1];
|
||||||
this.OSM_USER = 'osrm';
|
this.OSM_USER = 'osrm';
|
||||||
this.OSM_UID = 1;
|
this.OSM_UID = 1;
|
||||||
@@ -80,7 +80,7 @@ module.exports = function () {
|
|||||||
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.info(util.format('Node Version', process.version));
|
console.info(util.format('Node Version', process.version));
|
||||||
if (parseInt(process.version.match(/v(\d)/)[1]) < 4) throw new Error('*** Please upgrade to Node 4.+ to run OSRM cucumber tests');
|
if (parseInt(process.version.match(/v(\d+)/)[1]) < 4) throw new Error('*** Please upgrade to Node 4.+ to run OSRM cucumber tests');
|
||||||
|
|
||||||
fs.exists(this.TEST_PATH, (exists) => {
|
fs.exists(this.TEST_PATH, (exists) => {
|
||||||
if (exists)
|
if (exists)
|
||||||
|
|||||||
@@ -75,6 +75,10 @@ module.exports = function () {
|
|||||||
got.message = json.message || '';
|
got.message = json.message || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (headers.has('data_version')) {
|
||||||
|
got.data_version = json.data_version || '';
|
||||||
|
}
|
||||||
|
|
||||||
if (headers.has('#')) {
|
if (headers.has('#')) {
|
||||||
// comment column
|
// comment column
|
||||||
got['#'] = row['#'];
|
got['#'] = row['#'];
|
||||||
@@ -115,7 +119,7 @@ module.exports = function () {
|
|||||||
|
|
||||||
if (headers.has('weight')) {
|
if (headers.has('weight')) {
|
||||||
if (row.weight.length) {
|
if (row.weight.length) {
|
||||||
if (!row.weight.match(/[\d\.]+/))
|
if (!row.weight.match(/[\d.]+/))
|
||||||
return cb(new Error('*** Weight must be specified as a numeric value. (ex: 8)'));
|
return cb(new Error('*** Weight must be specified as a numeric value. (ex: 8)'));
|
||||||
got.weight = instructions ? util.format('%d', weight) : '';
|
got.weight = instructions ? util.format('%d', weight) : '';
|
||||||
} else {
|
} else {
|
||||||
@@ -151,7 +155,7 @@ module.exports = function () {
|
|||||||
if (headers.has('locations')){
|
if (headers.has('locations')){
|
||||||
got.locations = (locations || '').trim();
|
got.locations = (locations || '').trim();
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
if (headers.has('approaches')){
|
if (headers.has('approaches')){
|
||||||
got.approaches = (approaches || '').trim();
|
got.approaches = (approaches || '').trim();
|
||||||
}*/
|
}*/
|
||||||
|
|||||||
@@ -17,9 +17,26 @@ Feature: Basic Routing
|
|||||||
| ab |
|
| ab |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route |
|
| from | to | route | data_version |
|
||||||
| a | b | ab,ab |
|
| a | b | ab,ab | |
|
||||||
| b | a | ab,ab |
|
| b | a | ab,ab | |
|
||||||
|
|
||||||
|
Scenario: Data_version test
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the extract extra arguments "--data_version cucumber_data_version"
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | route | data_version |
|
||||||
|
| a | b | ab,ab | cucumber_data_version |
|
||||||
|
| b | a | ab,ab | cucumber_data_version |
|
||||||
|
|
||||||
Scenario: Routing in between two nodes of way
|
Scenario: Routing in between two nodes of way
|
||||||
Given the node map
|
Given the node map
|
||||||
|
|||||||
@@ -5,21 +5,49 @@ Feature: Basic Distance Matrix
|
|||||||
Background:
|
Background:
|
||||||
Given the profile "testbot"
|
Given the profile "testbot"
|
||||||
And the partition extra arguments "--small-component-size 1 --max-cell-sizes 2,4,8,16"
|
And the partition extra arguments "--small-component-size 1 --max-cell-sizes 2,4,8,16"
|
||||||
|
Scenario: Testbot - Travel distance matrix of small grid
|
||||||
Scenario: Testbot - Travel distance matrix of minimal network
|
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
a b
|
a b c
|
||||||
|
d e f
|
||||||
"""
|
"""
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes |
|
| nodes |
|
||||||
| ab |
|
| abc |
|
||||||
|
| def |
|
||||||
|
| ad |
|
||||||
|
| be |
|
||||||
|
| cf |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b |
|
| | a | b | e | f |
|
||||||
| a | 0 | 100+-1 |
|
| a | 0 | 100.1 | 199.5 | 299.5 |
|
||||||
| b | 100+-1 | 0 |
|
| b | 100.1 | 0 | 99.4 | 199.5 |
|
||||||
|
| e | 199.5 | 99.4 | 0 | 100.1 |
|
||||||
|
| f | 299.5 | 199.5 | 100.1 | 0 |
|
||||||
|
|
||||||
|
Scenario: Testbot - Travel distance matrix of minimal network exact distances
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a z
|
||||||
|
b
|
||||||
|
c
|
||||||
|
d
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| az |
|
||||||
|
| zbcd |
|
||||||
|
|
||||||
|
When I request a travel distance matrix I should get
|
||||||
|
| | a | z | b | c | d |
|
||||||
|
| a | 0 | 100.1 | 199.5 | 298.9 | 398.3 |
|
||||||
|
| z | 100.1 | 0 | 99.4 | 198.8 | 298.2 |
|
||||||
|
| b | 199.5 | 99.4 | 0 | 99.4 | 198.8 |
|
||||||
|
| c | 298.9 | 198.8 | 99.4 | 0 | 99.4 |
|
||||||
|
| d | 398.3 | 298.2 | 198.8 | 99.4 | 0 |
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance matrix of minimal network with toll exclude
|
Scenario: Testbot - Travel distance matrix of minimal network with toll exclude
|
||||||
Given the query options
|
Given the query options
|
||||||
@@ -39,11 +67,11 @@ Feature: Basic Distance Matrix
|
|||||||
| bd | motorway | yes | not drivable for exclude=toll and exclude=motorway,toll |
|
| bd | motorway | yes | not drivable for exclude=toll and exclude=motorway,toll |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | c | d |
|
| | a | b | c | d |
|
||||||
| a | 0 | 100+-1 | | |
|
| a | 0 | 100.1 | | |
|
||||||
| b | 100+-1 | 0 | | |
|
| b | 100.1 | 0 | | |
|
||||||
| c | | | 0 | 100+-1 |
|
| c | | | 0 | 100.1 |
|
||||||
| d | | | 100+-1 | 0 |
|
| d | | | 100.1 | 0 |
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance matrix of minimal network with motorway exclude
|
Scenario: Testbot - Travel distance matrix of minimal network with motorway exclude
|
||||||
Given the query options
|
Given the query options
|
||||||
@@ -63,8 +91,8 @@ Feature: Basic Distance Matrix
|
|||||||
| bd | residential | |
|
| bd | residential | |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | c | d |
|
| | a | b | c | d |
|
||||||
| a | 0 | 300+-2 | 100+-2 | 200+-2 |
|
| a | 0 | 298.9 | 99.4 | 199.5 |
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance matrix of minimal network disconnected motorway exclude
|
Scenario: Testbot - Travel distance matrix of minimal network disconnected motorway exclude
|
||||||
Given the query options
|
Given the query options
|
||||||
@@ -84,8 +112,8 @@ Feature: Basic Distance Matrix
|
|||||||
| efgh | residential | |
|
| efgh | residential | |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | e |
|
| | a | b | e |
|
||||||
| a | 0 | 50+-1 | |
|
| a | 0 | 50.1 | |
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance matrix of minimal network with motorway and toll excludes
|
Scenario: Testbot - Travel distance matrix of minimal network with motorway and toll excludes
|
||||||
Given the query options
|
Given the query options
|
||||||
@@ -106,7 +134,7 @@ Feature: Basic Distance Matrix
|
|||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | e | g |
|
| | a | b | e | g |
|
||||||
| a | 0 | 100+-1 | | |
|
| a | 0 | 100.1 | | |
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance matrix with different way speeds
|
Scenario: Testbot - Travel distance matrix with different way speeds
|
||||||
Given the node map
|
Given the node map
|
||||||
@@ -121,22 +149,22 @@ Feature: Basic Distance Matrix
|
|||||||
| cd | tertiary |
|
| cd | tertiary |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | c | d |
|
| | a | b | c | d |
|
||||||
| a | 0 | 100+-1 | 200+-1 | 300+-1 |
|
| a | 0 | 100.1 | 200.1 | 300.2 |
|
||||||
| b | 100+-1 | 0 | 100+-1 | 200+-1 |
|
| b | 100.1 | 0 | 100.1 | 200.1 |
|
||||||
| c | 200+-1 | 100+-1 | 0 | 100+-1 |
|
| c | 200.1 | 100.1 | 0 | 100.1 |
|
||||||
| d | 300+-1 | 200+-1 | 100+-1 | 0 |
|
| d | 300.2 | 200.1 | 100.1 | 0 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | c | d |
|
| | a | b | c | d |
|
||||||
| a | 0 | 100+-1 | 200+-1 | 300+-1 |
|
| a | 0 | 100.1 | 200.1 | 300.2 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a |
|
| | a |
|
||||||
| a | 0 |
|
| a | 0 |
|
||||||
| b | 100+-1 |
|
| b | 100.1 |
|
||||||
| c | 200+-1 |
|
| c | 200.1 |
|
||||||
| d | 300+-1 |
|
| d | 300.2 |
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance matrix of small grid
|
Scenario: Testbot - Travel distance matrix of small grid
|
||||||
Given the node map
|
Given the node map
|
||||||
@@ -154,11 +182,11 @@ Feature: Basic Distance Matrix
|
|||||||
| cf |
|
| cf |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | e | f |
|
| | a | b | e | f |
|
||||||
| a | 0 | 100+-1 | 200+-1 | 300+-1 |
|
| a | 0 | 100.1 | 199.5 | 299.5 |
|
||||||
| b | 100+-1 | 0 | 100+-1 | 200+-1 |
|
| b | 100.1 | 0 | 99.4 | 199.5 |
|
||||||
| e | 200+-1 | 100+-1 | 0 | 100+-1 |
|
| e | 199.5 | 99.4 | 0 | 100.1 |
|
||||||
| f | 300+-1 | 200+-1 | 100+-1 | 0 |
|
| f | 299.5 | 199.5 | 100.1 | 0 |
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance matrix of network with unroutable parts
|
Scenario: Testbot - Travel distance matrix of network with unroutable parts
|
||||||
Given the node map
|
Given the node map
|
||||||
@@ -172,7 +200,7 @@ Feature: Basic Distance Matrix
|
|||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b |
|
| | a | b |
|
||||||
| a | 0 | 100+-1 |
|
| a | 0 | 100.1 |
|
||||||
| b | | 0 |
|
| b | | 0 |
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance matrix of network with oneways
|
Scenario: Testbot - Travel distance matrix of network with oneways
|
||||||
@@ -189,11 +217,11 @@ Feature: Basic Distance Matrix
|
|||||||
| by | |
|
| by | |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | x | y | d | e |
|
| | x | y | d | e |
|
||||||
| x | 0 | 300+-2 | 400+-2 | 300+-2 |
|
| x | 0 | 300.2 | 399.6 | 299.5 |
|
||||||
| y | 500+-2 | 0 | 300+-2 | 200+-2 |
|
| y | 499 | 0 | 299.5 | 199.5 |
|
||||||
| d | 200+-2 | 300+-2 | 0 | 300+-2 |
|
| d | 199.5 | 299.5 | 0 | 298.9 |
|
||||||
| e | 300+-2 | 400+-2 | 100+-2 | 0 |
|
| e | 299.5 | 399.6 | 100.1 | 0 |
|
||||||
|
|
||||||
Scenario: Testbot - Rectangular travel distance matrix
|
Scenario: Testbot - Rectangular travel distance matrix
|
||||||
Given the node map
|
Given the node map
|
||||||
@@ -212,53 +240,53 @@ Feature: Basic Distance Matrix
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | distance |
|
| from | to | distance |
|
||||||
| e | a | 200m +- 1 |
|
| e | a | 200m |
|
||||||
| e | b | 100m +- 1 |
|
| e | b | 100m |
|
||||||
| f | a | 300m +- 1 |
|
| f | a | 299.9m |
|
||||||
| f | b | 200m +- 1 |
|
| f | b | 200m |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | e | f |
|
| | a | b | e | f |
|
||||||
| a | 0 | 100+-1 | 200+-1 | 300+-1 |
|
| a | 0 | 100.1 | 199.5 | 299.5 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a |
|
| | a |
|
||||||
| a | 0 |
|
| a | 0 |
|
||||||
| b | 100+-1 |
|
| b | 100.1 |
|
||||||
| e | 200+-1 |
|
| e | 199.5 |
|
||||||
| f | 300+-1 |
|
| f | 299.5 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | e | f |
|
| | a | b | e | f |
|
||||||
| a | 0 | 100+-1 | 200+-1 | 300+-1 |
|
| a | 0 | 100.1 | 199.5 | 299.5 |
|
||||||
| b | 100+-1 | 0 | 100+-1 | 200+-1 |
|
| b | 100.1 | 0 | 99.4 | 199.5 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b |
|
| | a | b |
|
||||||
| a | 0 | 100+-1 |
|
| a | 0 | 100.1 |
|
||||||
| b | 100+-1 | 0 |
|
| b | 100.1 | 0 |
|
||||||
| e | 200+-1 | 100+-1 |
|
| e | 199.5 | 99.4 |
|
||||||
| f | 300+-1 | 200+-1 |
|
| f | 299.5 | 199.5 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | e | f |
|
| | a | b | e | f |
|
||||||
| a | 0 | 100+-1 | 200+-1 | 300+-1 |
|
| a | 0 | 100.1 | 199.5 | 299.5 |
|
||||||
| b | 100+-1 | 0 | 100+-1 | 200+-1 |
|
| b | 100.1 | 0 | 99.4 | 199.5 |
|
||||||
| e | 200+-1 | 100+-1 | 0 | 100+-1 |
|
| e | 199.5 | 99.4 | 0 | 100.1 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | e |
|
| | a | b | e |
|
||||||
| a | 0 | 100+-1 | 200+-1 |
|
| a | 0 | 100.1 | 199.5 |
|
||||||
| b | 100+-1 | 0 | 100+-1 |
|
| b | 100.1 | 0 | 99.4 |
|
||||||
| e | 200+-1 | 100+-1 | 0 |
|
| e | 199.5 | 99.4 | 0 |
|
||||||
| f | 300+-1 | 200+-1 | 100+-1 |
|
| f | 299.5 | 199.5 | 100.1 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | e | f |
|
| | a | b | e | f |
|
||||||
| a | 0 | 100+-1 | 200+-1 | 300+-1 |
|
| a | 0 | 100.1 | 199.5 | 299.5 |
|
||||||
| b | 100+-1 | 0 | 100+-1 | 200+-1 |
|
| b | 100.1 | 0 | 99.4 | 199.5 |
|
||||||
| e | 200+-1 | 100+-1 | 0 | 100+-1 |
|
| e | 199.5 | 99.4 | 0 | 100.1 |
|
||||||
| f | 300+-1 | 200+-1 | 100+-1 | 0 |
|
| f | 299.5 | 199.5 | 100.1 | 0 |
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance 3x2 matrix
|
Scenario: Testbot - Travel distance 3x2 matrix
|
||||||
Given the node map
|
Given the node map
|
||||||
@@ -277,9 +305,9 @@ Feature: Basic Distance Matrix
|
|||||||
|
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | b | e | f |
|
| | b | e | f |
|
||||||
| a | 100+-1 | 200+-1 | 300+-1 |
|
| a | 100.1 | 199.5 | 299.5 |
|
||||||
| b | 0 | 100+-1 | 200+-1 |
|
| b | 0 | 99.4 | 199.5 |
|
||||||
|
|
||||||
Scenario: Testbot - All coordinates are from same small component
|
Scenario: Testbot - All coordinates are from same small component
|
||||||
Given a grid size of 300 meters
|
Given a grid size of 300 meters
|
||||||
@@ -299,9 +327,9 @@ Feature: Basic Distance Matrix
|
|||||||
| fg |
|
| fg |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | f | g |
|
| | f | g |
|
||||||
| f | 0 | 300+-2 |
|
| f | 0 | 298.2 |
|
||||||
| g | 300+-2 | 0 |
|
| g | 298.2 | 0 |
|
||||||
|
|
||||||
Scenario: Testbot - Coordinates are from different small component and snap to big CC
|
Scenario: Testbot - Coordinates are from different small component and snap to big CC
|
||||||
Given a grid size of 300 meters
|
Given a grid size of 300 meters
|
||||||
@@ -333,11 +361,11 @@ Feature: Basic Distance Matrix
|
|||||||
| i | h | 300m |
|
| i | h | 300m |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | f | g | h | i |
|
| | f | g | h | i |
|
||||||
| f | 0 | 300+-2 | 0 | 300+-2 |
|
| f | 0 | 298.2 | 0 | 298.2 |
|
||||||
| g | 300+-2 | 0 | 300+-2 | 0 |
|
| g | 298.2 | 0 | 298.2 | 0 |
|
||||||
| h | 0 | 300+-2 | 0 | 300+-2 |
|
| h | 0 | 298.2 | 0 | 298.2 |
|
||||||
| i | 300+-2 | 0 | 300+-2 | 0 |
|
| i | 298.2 | 0 | 298.2 | 0 |
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance matrix with loops
|
Scenario: Testbot - Travel distance matrix with loops
|
||||||
Given the node map
|
Given the node map
|
||||||
@@ -354,11 +382,11 @@ Feature: Basic Distance Matrix
|
|||||||
| da | yes |
|
| da | yes |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | 1 | 2 | 3 | 4 |
|
| | 1 | 2 | 3 | 4 |
|
||||||
| 1 | 0 | 100+-1 | 400+-1 | 500+-1 |
|
| 1 | 0 | 100.1 | 399.6 | 499.7 |
|
||||||
| 2 | 700+-1 | 0 | 300+-1 | 400+-1 |
|
| 2 | 699.1 | 0 | 299.5 | 399.6 |
|
||||||
| 3 | 400+-1 | 500+-1 | 0 | 100+-1 |
|
| 3 | 399.6 | 499.7 | 0 | 100.1 |
|
||||||
| 4 | 300+-1 | 400+-1 | 700+-1 | 0 |
|
| 4 | 299.5 | 399.6 | 699.1 | 0 |
|
||||||
|
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance matrix based on segment durations
|
Scenario: Testbot - Travel distance matrix based on segment durations
|
||||||
@@ -395,12 +423,12 @@ Feature: Basic Distance Matrix
|
|||||||
| ce |
|
| ce |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | c | d | e |
|
| | a | b | c | d | e |
|
||||||
| a | 0 | 100+-2 | 200+-2 | 300+-2 | 400+-2 |
|
| a | 0 | 100.1 | 200.1 | 300.2 | 398.9 |
|
||||||
| b | 100+-2 | 0 | 100+-2 | 200+-2 | 300+-2 |
|
| b | 100.1 | 0 | 100.1 | 200.1 | 298.9 |
|
||||||
| c | 200+-2 | 100+-2 | 0 | 100+-2 | 200+-2 |
|
| c | 200.1 | 100.1 | 0 | 100.1 | 198.8 |
|
||||||
| d | 300+-2 | 200+-2 | 100+-2 | 0 | 300+-2 |
|
| d | 300.2 | 200.1 | 100.1 | 0 | 298.9 |
|
||||||
| e | 400+-2 | 300+-2 | 200+-2 | 300+-2 | 0 |
|
| e | 398.9 | 298.9 | 198.8 | 298.9 | 0 |
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance matrix for alternative loop paths
|
Scenario: Testbot - Travel distance matrix for alternative loop paths
|
||||||
Given the profile file
|
Given the profile file
|
||||||
@@ -439,26 +467,26 @@ Feature: Basic Distance Matrix
|
|||||||
| ca | yes |
|
| ca | yes |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||||
| 1 | 0 | 1100+-5 | 300+-5 | 200+-5 | 600+-5 | 500+-5 | 900+-5 | 800+-5 |
|
| 1 | 0 | 1096.7 | 298.9 | 199.5 | 598.4 | 498.3 | 897.3 | 797.9 |
|
||||||
| 2 | 100+-5 | 0 | 400+-5 | 300+-5 | 700+-5 | 600+-5 | 1000+-5 | 900+-5 |
|
| 2 | 100.1 | 0 | 398.9 | 299.5 | 698.5 | 598.4 | 997.3 | 897.9 |
|
||||||
| 3 | 900+-5 | 800+-5 | 0 | 1100+-5 | 300+-5 | 200+-5 | 600+-5 | 500+-5 |
|
| 3 | 897.9 | 797.9 | 0 | 1097.4 | 299.5 | 199.5 | 598.4 | 499 |
|
||||||
| 4 | 1000+-5 | 900+-5 | 100+-5 | 0 | 400+-5 | 300+-5 | 700+-5 | 600+-5 |
|
| 4 | 997.3 | 897.3 | 99.4 | 0 | 398.9 | 298.9 | 697.8 | 598.4 |
|
||||||
| 5 | 600+-5 | 500+-5 | 900+-5 | 800+-5 | 0 | 1100+-5 | 300+-5 | 200+-5 |
|
| 5 | 598.4 | 498.3 | 897.3 | 797.9 | 0 | 1096.7 | 298.9 | 199.5 |
|
||||||
| 6 | 700+-5 | 600+-5 | 1000+-5 | 900+-5 | 100+-5 | 0 | 400+-5 | 300+-5 |
|
| 6 | 698.5 | 598.4 | 997.3 | 897.9 | 100.1 | 0 | 398.9 | 299.5 |
|
||||||
| 7 | 300+-5 | 200+-5 | 600+-5 | 500+-5 | 900+-5 | 800+-5 | 0 | 1100+-5 |
|
| 7 | 299.5 | 199.5 | 598.4 | 499 | 897.9 | 797.9 | 0 | 1097.4 |
|
||||||
| 8 | 400+-5 | 300+-5 | 700+-5 | 600+-5 | 1000+-5 | 900+-5 | 100+-5 | 0 |
|
| 8 | 398.9 | 298.9 | 697.8 | 598.4 | 997.3 | 897.3 | 99.4 | 0 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | 1 |
|
| | 1 |
|
||||||
| 1 | 0 |
|
| 1 | 0 |
|
||||||
| 2 | 100+-5 |
|
| 2 | 100.1 |
|
||||||
| 3 | 900+-5 |
|
| 3 | 897.9 |
|
||||||
| 4 | 1000+-5 |
|
| 4 | 997.3 |
|
||||||
| 5 | 600+-5 |
|
| 5 | 598.4 |
|
||||||
| 6 | 700+-5 |
|
| 6 | 698.5 |
|
||||||
| 7 | 300+-5 |
|
| 7 | 299.5 |
|
||||||
| 8 | 400+-5 |
|
| 8 | 398.9 |
|
||||||
|
|
||||||
Scenario: Testbot - Travel distance matrix with ties
|
Scenario: Testbot - Travel distance matrix with ties
|
||||||
Given the node map
|
Given the node map
|
||||||
@@ -480,26 +508,26 @@ Feature: Basic Distance Matrix
|
|||||||
| a | c | ac,ac | 200m | 20s | 20 |
|
| a | c | ac,ac | 200m | 20s | 20 |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | distance |
|
| from | to | route | distance |
|
||||||
| a | b | ab,ab | 450m |
|
| a | b | ab,ab | 450m |
|
||||||
| a | c | ac,ac | 200m |
|
| a | c | ac,ac | 200m |
|
||||||
| a | d | ac,dc,dc | 500m +- 1 |
|
| a | d | ac,dc,dc | 499.9m |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | c | d |
|
| | a | b | c | d |
|
||||||
| a | 0 | 450+-2 | 200+-2 | 500+-2 |
|
| a | 0 | 450.3 | 198.8 | 499 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a |
|
| | a |
|
||||||
| a | 0 |
|
| a | 0 |
|
||||||
| b | 450+-2 |
|
| b | 450.3 |
|
||||||
| c | 200+-2 |
|
| c | 198.8 |
|
||||||
| d | 500+-2 |
|
| d | 499 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | c |
|
| | a | c |
|
||||||
| a | 0 | 200+-2 |
|
| a | 0 | 198.8 |
|
||||||
| c | 200+-2 | 0 |
|
| c | 198.8 | 0 |
|
||||||
|
|
||||||
|
|
||||||
# Check rounding errors
|
# Check rounding errors
|
||||||
@@ -515,8 +543,8 @@ Feature: Basic Distance Matrix
|
|||||||
| abcd |
|
| abcd |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | c | d |
|
| | a | b | c | d |
|
||||||
| a | 0 | 1000+-3 | 2000+-3 | 3000+-3 |
|
| a | 0 | 1000.7 | 2001.4 | 3002.1 |
|
||||||
|
|
||||||
|
|
||||||
Scenario: Testbot - OneToMany vs ManyToOne
|
Scenario: Testbot - OneToMany vs ManyToOne
|
||||||
@@ -560,10 +588,138 @@ Feature: Basic Distance Matrix
|
|||||||
| fd | |
|
| fd | |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | b | c | d | e | f |
|
| | a | b | c | d | e | f |
|
||||||
| a | 0 | 100+-1 | 300+-1 | 650+-1 | 1930+-1 | 1533+-1 |
|
| a | 0 | 100.1 | 300.2 | 650.5 | 1930.6 | 1533 |
|
||||||
| b | 760+-1 | 0 | 200+-1 | 550+-1 | 1830+-1 | 1433+-1 |
|
| b | 759 | 0 | 200.1 | 550.4 | 1830.5 | 1432.9 |
|
||||||
| c | 560+-2 | 660+-2 | 0 | 350+-1 | 1630+-1 | 1233+-1 |
|
| c | 558.8 | 658.9 | 0 | 350.3 | 1630.4 | 1232.8 |
|
||||||
| d | 1480+-2 | 1580+-1 | 1780+-1 | 0 | 1280+-1 | 883+-1 |
|
| d | 1478.9 | 1579 | 1779.1 | 0 | 1280.1 | 882.5 |
|
||||||
| e | 200+-2 | 300+-2 | 500+-1 | 710+-1 | 0 | 1593+-1 |
|
| e | 198.8 | 298.9 | 499 | 710.3 | 0 | 1592.8 |
|
||||||
| f | 597+-1 | 696+-1 | 896+-1 | 1108+-1 | 400+-3 | 0 |
|
| f | 596.4 | 696.5 | 896.6 | 1107.9 | 397.6 | 0 |
|
||||||
|
|
||||||
|
Scenario: Testbot - Filling in noroutes with estimates (defaults to input coordinate location)
|
||||||
|
Given a grid size of 300 meters
|
||||||
|
Given the extract extra arguments "--small-component-size 4"
|
||||||
|
Given the query options
|
||||||
|
| fallback_speed | 5 |
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b f h 1
|
||||||
|
d e g i
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| abeda |
|
||||||
|
| fhigf |
|
||||||
|
|
||||||
|
When I request a travel distance matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 300.2 | 900.7 | 1501.1 |
|
||||||
|
| b | 300.2 | 0 | 600.5 | 1200.9 |
|
||||||
|
| f | 900.7 | 600.5 | 0 | 300.2 |
|
||||||
|
| 1 | 1501.1 | 1200.9 | 300.2 | 0 |
|
||||||
|
|
||||||
|
When I request a travel distance matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 300.2 | 900.7 | 1501.1 |
|
||||||
|
|
||||||
|
When I request a travel distance matrix I should get
|
||||||
|
| | a |
|
||||||
|
| a | 0 |
|
||||||
|
| b | 300.2 |
|
||||||
|
| f | 900.7 |
|
||||||
|
| 1 | 1501.1 |
|
||||||
|
|
||||||
|
Scenario: Testbot - Fise input coordinate
|
||||||
|
Given a grid size of 300 meters
|
||||||
|
Given the extract extra arguments "--small-component-size 4"
|
||||||
|
Given the query options
|
||||||
|
| fallback_speed | 5 |
|
||||||
|
| fallback_coordinate | input |
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b f h 1
|
||||||
|
d e g i
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| abeda |
|
||||||
|
| fhigf |
|
||||||
|
|
||||||
|
When I request a travel distance matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 300.2 | 900.7 | 1501.1 |
|
||||||
|
| b | 300.2 | 0 | 600.5 | 1200.9 |
|
||||||
|
| f | 900.7 | 600.5 | 0 | 300.2 |
|
||||||
|
| 1 | 1501.1 | 1200.9 | 300.2 | 0 |
|
||||||
|
|
||||||
|
When I request a travel distance matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 300.2 | 900.7 | 1501.1 |
|
||||||
|
|
||||||
|
When I request a travel distance matrix I should get
|
||||||
|
| | a |
|
||||||
|
| a | 0 |
|
||||||
|
| b | 300.2 |
|
||||||
|
| f | 900.7 |
|
||||||
|
| 1 | 1501.1 |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Testbot - Filling in noroutes with estimates - use snapped coordinate
|
||||||
|
Given a grid size of 300 meters
|
||||||
|
Given the extract extra arguments "--small-component-size 4"
|
||||||
|
Given the query options
|
||||||
|
| fallback_speed | 5 |
|
||||||
|
| fallback_coordinate | snapped |
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b f h 1
|
||||||
|
d e g i
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| abeda |
|
||||||
|
| fhigf |
|
||||||
|
|
||||||
|
When I request a travel distance matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 300.2 | 900.7 | 1200.9 |
|
||||||
|
| b | 300.2 | 0 | 600.5 | 900.7 |
|
||||||
|
| f | 900.7 | 600.5 | 0 | 300.2 |
|
||||||
|
| 1 | 1200.9 | 900.7 | 300.2 | 0 |
|
||||||
|
|
||||||
|
When I request a travel distance matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 300.2 | 900.7 | 1200.9 |
|
||||||
|
|
||||||
|
When I request a travel distance matrix I should get
|
||||||
|
| | a |
|
||||||
|
| a | 0 |
|
||||||
|
| b | 300.2 |
|
||||||
|
| f | 900.7 |
|
||||||
|
| 1 | 1200.9 |
|
||||||
|
|
||||||
|
Scenario: Ensure consistency with route, and make sure offsets work in both directions
|
||||||
|
Given a grid size of 100 meters
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b c d e f g h i j
|
||||||
|
1 2
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| abcdef |
|
||||||
|
| fghij |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | route | distance |
|
||||||
|
| 1 | 2 | abcdef,fghij,fghij | 999.9m |
|
||||||
|
|
||||||
|
# TODO: this is "correct", but inconsistent with viaroute
|
||||||
|
When I request a travel distance matrix I should get
|
||||||
|
| | 1 | 2 |
|
||||||
|
| 1 | 0 | 1000.7 |
|
||||||
|
| 2 | 1000.7 | 0 |
|
||||||
@@ -510,3 +510,268 @@ Feature: Basic Duration Matrix
|
|||||||
| | a |
|
| | a |
|
||||||
| a | 0 |
|
| a | 0 |
|
||||||
| b | 24.1 |
|
| b | 24.1 |
|
||||||
|
|
||||||
|
Scenario: Testbot - Filling in noroutes with estimates (defaults to input coordinate location)
|
||||||
|
Given a grid size of 300 meters
|
||||||
|
Given the extract extra arguments "--small-component-size 4"
|
||||||
|
Given the query options
|
||||||
|
| fallback_speed | 5 |
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b f h 1
|
||||||
|
d e g i
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| abeda |
|
||||||
|
| fhigf |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 30 | 18 | 30 |
|
||||||
|
| b | 30 | 0 | 12 | 24 |
|
||||||
|
| f | 18 | 12 | 0 | 30 |
|
||||||
|
| 1 | 30 | 24 | 30 | 0 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 30 | 18 | 30 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a |
|
||||||
|
| a | 0 |
|
||||||
|
| b | 30 |
|
||||||
|
| f | 18 |
|
||||||
|
| 1 | 30 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get estimates for
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | | | Y | Y |
|
||||||
|
| b | | | Y | Y |
|
||||||
|
| f | Y | Y | | |
|
||||||
|
| 1 | Y | Y | | |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get estimates for
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | | | Y | Y |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get estimates for
|
||||||
|
| | a |
|
||||||
|
| a | |
|
||||||
|
| b | |
|
||||||
|
| f | Y |
|
||||||
|
| 1 | Y |
|
||||||
|
|
||||||
|
Scenario: Testbot - Filling in noroutes with estimates - use input coordinate
|
||||||
|
Given a grid size of 300 meters
|
||||||
|
Given the extract extra arguments "--small-component-size 4"
|
||||||
|
Given the query options
|
||||||
|
| fallback_speed | 5 |
|
||||||
|
| fallback_coordinate | input |
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b f h 1
|
||||||
|
d e g i
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| abeda |
|
||||||
|
| fhigf |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 30 | 18 | 30 |
|
||||||
|
| b | 30 | 0 | 12 | 24 |
|
||||||
|
| f | 18 | 12 | 0 | 30 |
|
||||||
|
| 1 | 30 | 24 | 30 | 0 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 30 | 18 | 30 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a |
|
||||||
|
| a | 0 |
|
||||||
|
| b | 30 |
|
||||||
|
| f | 18 |
|
||||||
|
| 1 | 30 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get estimates for
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | | | Y | Y |
|
||||||
|
| b | | | Y | Y |
|
||||||
|
| f | Y | Y | | |
|
||||||
|
| 1 | Y | Y | | |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get estimates for
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | | | Y | Y |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get estimates for
|
||||||
|
| | a |
|
||||||
|
| a | |
|
||||||
|
| b | |
|
||||||
|
| f | Y |
|
||||||
|
| 1 | Y |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Testbot - Filling in noroutes with estimates - use snapped coordinate
|
||||||
|
Given a grid size of 300 meters
|
||||||
|
Given the extract extra arguments "--small-component-size 4"
|
||||||
|
Given the query options
|
||||||
|
| fallback_speed | 5 |
|
||||||
|
| fallback_coordinate | snapped |
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b f h 1
|
||||||
|
d e g i
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| abeda |
|
||||||
|
| fhigf |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 30 | 18 | 24 |
|
||||||
|
| b | 30 | 0 | 12 | 18 |
|
||||||
|
| f | 18 | 12 | 0 | 30 |
|
||||||
|
| 1 | 24 | 18 | 30 | 0 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 30 | 18 | 24 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a |
|
||||||
|
| a | 0 |
|
||||||
|
| b | 30 |
|
||||||
|
| f | 18 |
|
||||||
|
| 1 | 24 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get estimates for
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | | | Y | Y |
|
||||||
|
| b | | | Y | Y |
|
||||||
|
| f | Y | Y | | |
|
||||||
|
| 1 | Y | Y | | |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get estimates for
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | | | Y | Y |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get estimates for
|
||||||
|
| | a |
|
||||||
|
| a | |
|
||||||
|
| b | |
|
||||||
|
| f | Y |
|
||||||
|
| 1 | Y |
|
||||||
|
|
||||||
|
Scenario: Testbot - Travel time matrix of minimal network with scale factor
|
||||||
|
Given the query options
|
||||||
|
| scale_factor | 2 |
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b
|
||||||
|
"""
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | b |
|
||||||
|
| a | 0 | 20 |
|
||||||
|
| b | 20 | 0 |
|
||||||
|
Scenario: Testbot - Test fallback speeds and scale factor
|
||||||
|
Given a grid size of 300 meters
|
||||||
|
Given the extract extra arguments "--small-component-size 4"
|
||||||
|
Given the query options
|
||||||
|
| scale_factor | 2 |
|
||||||
|
| fallback_speed | 5 |
|
||||||
|
| fallback_coordinate | snapped |
|
||||||
|
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b f h 1
|
||||||
|
d e g i
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| abeda |
|
||||||
|
| fhigf |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 60 | 36 | 48 |
|
||||||
|
| b | 60 | 0 | 24 | 36 |
|
||||||
|
| f | 36 | 24 | 0 | 60 |
|
||||||
|
| 1 | 48 | 36 | 60 | 0 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | 0 | 60 | 36 | 48 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a |
|
||||||
|
| a | 0 |
|
||||||
|
| b | 60 |
|
||||||
|
| f | 36 |
|
||||||
|
| 1 | 48 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get estimates for
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | | | Y | Y |
|
||||||
|
| b | | | Y | Y |
|
||||||
|
| f | Y | Y | | |
|
||||||
|
| 1 | Y | Y | | |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get estimates for
|
||||||
|
| | a | b | f | 1 |
|
||||||
|
| a | | | Y | Y |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get estimates for
|
||||||
|
| | a |
|
||||||
|
| a | |
|
||||||
|
| b | |
|
||||||
|
| f | Y |
|
||||||
|
| 1 | Y |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Testbot - Travel time matrix of minimal network with overflow scale factor
|
||||||
|
Given the query options
|
||||||
|
| scale_factor | 2147483647 |
|
||||||
|
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | b |
|
||||||
|
| a | 0 | 214748364.6 |
|
||||||
|
| b | 214748364.6 | 0 |
|
||||||
|
|
||||||
|
Scenario: Testbot - Travel time matrix of minimal network with fraction scale factor
|
||||||
|
Given the query options
|
||||||
|
| scale_factor | 0.5 |
|
||||||
|
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a b
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | b |
|
||||||
|
| a | 0 | 5 |
|
||||||
|
| b | 5 | 0 |
|
||||||
|
|||||||
@@ -38,15 +38,15 @@ Feature: Multi level routing
|
|||||||
Scenario: Testbot - Multi level routing
|
Scenario: Testbot - Multi level routing
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
a───b e───f
|
a────b e─────f
|
||||||
│ │ │ │
|
\ │ │ /
|
||||||
d───c h───g
|
d───c h───g
|
||||||
╲ ╱
|
╲ ╱
|
||||||
╳
|
╳
|
||||||
╱ ╲
|
╱ ╲
|
||||||
i───j m───n
|
i───j m───n
|
||||||
│ │ │ │
|
/ │ │ \
|
||||||
l───k───p───o
|
l─────k───p─────o
|
||||||
"""
|
"""
|
||||||
|
|
||||||
And the nodes
|
And the nodes
|
||||||
@@ -67,78 +67,76 @@ Feature: Multi level routing
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | time |
|
| from | to | route | time |
|
||||||
| a | b | abcda,abcda | 20s |
|
| a | b | abcda,abcda | 25s |
|
||||||
| a | f | abcda,cm,mnopm,kp,ijkli,hj,efghe,efghe | 229.4s |
|
| a | f | abcda,cm,mnopm,kp,ijkli,hj,efghe,efghe | 239.2s |
|
||||||
| a | l | abcda,cm,mnopm,kp,ijkli,ijkli | 144.7s |
|
| a | l | abcda,cm,mnopm,kp,ijkli,ijkli | 157.1s |
|
||||||
| a | o | abcda,cm,mnopm,mnopm,mnopm | 124.7s |
|
| a | o | abcda,cm,mnopm,mnopm,mnopm | 137.1s |
|
||||||
| f | l | efghe,hj,ijkli,ijkli,ijkli | 124.7s |
|
| f | l | efghe,hj,ijkli,ijkli | 136.7s |
|
||||||
| f | o | efghe,hj,ijkli,kp,mnopm,mnopm | 144.7s |
|
| f | o | efghe,hj,ijkli,kp,mnopm,mnopm | 162.1s |
|
||||||
| l | o | ijkli,kp,mnopm,mnopm | 60s |
|
| l | o | ijkli,kp,mnopm,mnopm | 80s |
|
||||||
| c | m | cm,cm | 44.7s |
|
| c | m | cm,cm | 44.7s |
|
||||||
|
| f | a | efghe,hj,ijkli,kp,mnopm,cm,abcda,abcda | 239.2s |
|
||||||
|
| l | a | ijkli,kp,mnopm,cm,abcda,abcda | 157.1s |
|
||||||
|
|
||||||
When I request a travel time matrix I should get
|
When I request a travel time matrix I should get
|
||||||
| | a | f | l | o |
|
| | a | f | l | o |
|
||||||
| a | 0 | 229.4 | 144.7 | 124.7 |
|
| a | 0 | 239.2 | 157.1 | 137.1 |
|
||||||
| f | 229.4 | 0 | 124.7 | 144.7 |
|
| f | 239.2 | 0 | 136.7 | 162.1 |
|
||||||
| l | 144.7 | 124.7 | 0 | 60 |
|
| l | 157.1 | 136.7 | 0 | 80 |
|
||||||
| o | 124.7 | 144.7 | 60 | 0 |
|
| o | 137.1 | 162.1 | 80 | 0 |
|
||||||
|
|
||||||
When I request a travel time matrix I should get
|
When I request a travel time matrix I should get
|
||||||
| | a | f | l | o |
|
| | a | f | l | o |
|
||||||
| a | 0 | 229.4 | 144.7 | 124.7 |
|
| a | 0 | 239.2 | 157.1 | 137.1 |
|
||||||
|
|
||||||
When I request a travel time matrix I should get
|
When I request a travel time matrix I should get
|
||||||
| | a |
|
| | a |
|
||||||
| a | 0 |
|
| a | 0 |
|
||||||
| f | 229.4 |
|
| f | 239.2 |
|
||||||
| l | 144.7 |
|
| l | 157.1 |
|
||||||
| o | 124.7 |
|
| o | 137.1 |
|
||||||
|
|
||||||
When I request a travel time matrix I should get
|
When I request a travel time matrix I should get
|
||||||
| | a | f | l | o |
|
| | a | f | l | o |
|
||||||
| a | 0 | 229.4 | 144.7 | 124.7 |
|
| a | 0 | 239.2 | 157.1 | 137.1 |
|
||||||
| o | 124.7 | 144.7 | 60 | 0 |
|
| o | 137.1 | 162.1 | 80 | 0 |
|
||||||
|
|
||||||
When I request a travel time matrix I should get
|
When I request a travel time matrix I should get
|
||||||
| | a | o |
|
| | a | o |
|
||||||
| a | 0 | 124.7 |
|
| a | 0 | 137.1 |
|
||||||
| f | 229.4 | 144.7 |
|
| f | 239.2 | 162.1 |
|
||||||
| l | 144.7 | 60 |
|
| l | 157.1 | 80 |
|
||||||
| o | 124.7 | 0 |
|
| o | 137.1 | 0 |
|
||||||
|
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | f | l | o |
|
| | a | f | l | o |
|
||||||
| a | 0+-2 | 2287+-2 | 1443+-2 | 1243+-2 |
|
| a | 0 | 2383.7 | 1566.9 | 1366.8 |
|
||||||
| f | 2284+-2 | 0+-2 | 1241+-2 | 1443+-2 |
|
| f | 2383.7 | 0 | 1293.3 | 1617.3 |
|
||||||
| l | 1443+-2 | 1244+-2 | 0+-2 | 600+-2 |
|
| l | 1566.9 | 1293.3 | 0 | 800.5 |
|
||||||
| o | 1243+-2 | 1444+-2 | 600+-2 | 0+-2 |
|
| o | 1366.8 | 1617.3 | 800.5 | 0 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | f | l | o |
|
| | a | f | l | o |
|
||||||
| a | 0 | 2287.2+-2 | 1443+-2 | 1243+-2 |
|
| a | 0 | 2383.7 | 1566.9 | 1366.8 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a |
|
| | a |
|
||||||
| a | 0 |
|
| a | 0 |
|
||||||
| f | 2284.5+-2 |
|
| f | 2383.7 |
|
||||||
| l | 1443.1 |
|
| l | 1566.9 |
|
||||||
| o | 1243 |
|
| o | 1366.8 |
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | f | l | o |
|
| | a | f | l | o |
|
||||||
| a | 0 | 2287+-2 | 1443+-2 | 1243+-2 |
|
| a | 0 | 2383.7 | 1566.9 | 1366.8 |
|
||||||
| o | 1243 | 1444+-2 | 600+-2 | 0+-2 |
|
| f | 2383.7 | 0 | 1293.3 | 1617.3 |
|
||||||
|
|
||||||
|
|
||||||
When I request a travel distance matrix I should get
|
When I request a travel distance matrix I should get
|
||||||
| | a | o |
|
| | a | o |
|
||||||
| a | 0+-2 | 1243+-2 |
|
| a | 0 | 1366.8 |
|
||||||
| f | 2284+-2 | 1443+-2 |
|
| f | 2383.7 | 1617.3 |
|
||||||
| l | 1443+-2 | 600+-2 |
|
| l | 1566.9 | 800.5 |
|
||||||
| o | 1243+-2 | 0+-2 |
|
| o | 1366.8 | 0 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Scenario: Testbot - Multi level routing: horizontal road
|
Scenario: Testbot - Multi level routing: horizontal road
|
||||||
Given the node map
|
Given the node map
|
||||||
|
|||||||
@@ -18,6 +18,53 @@ Feature: Via points
|
|||||||
| waypoints | route |
|
| waypoints | route |
|
||||||
| a,b,c | abc,abc,abc,abc |
|
| a,b,c | abc,abc,abc,abc |
|
||||||
|
|
||||||
|
Scenario: Simple via point with waypoints collapsing
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a
|
||||||
|
|
||||||
|
b 1c d
|
||||||
|
2
|
||||||
|
|
||||||
|
e
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ace |
|
||||||
|
| bcd |
|
||||||
|
|
||||||
|
Given the query options
|
||||||
|
| waypoints | 0;2 |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| b,1,e | bcd,ace,ace | depart,turn right,arrive |
|
||||||
|
| b,2,e | bcd,ace,ace | depart,turn right,arrive |
|
||||||
|
|
||||||
|
Scenario: Simple via point with waypoints collapsing
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a 2 b
|
||||||
|
|
||||||
|
c d
|
||||||
|
1 3
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bd |
|
||||||
|
| cd |
|
||||||
|
| ac |
|
||||||
|
|
||||||
|
Given the query options
|
||||||
|
| waypoints | 0;2 |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| 1,2,3 | cd,ac,ab,bd,cd | depart,new name right,new name right,new name right,arrive |
|
||||||
|
|
||||||
Scenario: Simple via point with core factor
|
Scenario: Simple via point with core factor
|
||||||
Given the contract extra arguments "--core 0.8"
|
Given the contract extra arguments "--core 0.8"
|
||||||
Given the node map
|
Given the node map
|
||||||
|
|||||||
@@ -12,23 +12,26 @@ namespace contractor
|
|||||||
struct ContractorEdgeData
|
struct ContractorEdgeData
|
||||||
{
|
{
|
||||||
ContractorEdgeData()
|
ContractorEdgeData()
|
||||||
: weight(0), duration(0), id(0), originalEdges(0), shortcut(0), forward(0), backward(0)
|
: weight(0), duration(0), distance(0), id(0), originalEdges(0), shortcut(0), forward(0),
|
||||||
|
backward(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
ContractorEdgeData(EdgeWeight weight,
|
ContractorEdgeData(EdgeWeight weight,
|
||||||
EdgeWeight duration,
|
EdgeWeight duration,
|
||||||
|
EdgeDistance distance,
|
||||||
unsigned original_edges,
|
unsigned original_edges,
|
||||||
unsigned id,
|
unsigned id,
|
||||||
bool shortcut,
|
bool shortcut,
|
||||||
bool forward,
|
bool forward,
|
||||||
bool backward)
|
bool backward)
|
||||||
: weight(weight), duration(duration), id(id),
|
: weight(weight), duration(duration), distance(distance), id(id),
|
||||||
originalEdges(std::min((1u << 29) - 1u, original_edges)), shortcut(shortcut),
|
originalEdges(std::min((1u << 29) - 1u, original_edges)), shortcut(shortcut),
|
||||||
forward(forward), backward(backward)
|
forward(forward), backward(backward)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
EdgeWeight weight;
|
EdgeWeight weight;
|
||||||
EdgeWeight duration;
|
EdgeWeight duration;
|
||||||
|
EdgeDistance distance;
|
||||||
unsigned id;
|
unsigned id;
|
||||||
unsigned originalEdges : 29;
|
unsigned originalEdges : 29;
|
||||||
bool shortcut : 1;
|
bool shortcut : 1;
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
|||||||
input_edge.target,
|
input_edge.target,
|
||||||
std::max(input_edge.data.weight, 1),
|
std::max(input_edge.data.weight, 1),
|
||||||
input_edge.data.duration,
|
input_edge.data.duration,
|
||||||
|
input_edge.data.distance,
|
||||||
1,
|
1,
|
||||||
input_edge.data.turn_id,
|
input_edge.data.turn_id,
|
||||||
false,
|
false,
|
||||||
@@ -51,6 +52,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
|||||||
input_edge.source,
|
input_edge.source,
|
||||||
std::max(input_edge.data.weight, 1),
|
std::max(input_edge.data.weight, 1),
|
||||||
input_edge.data.duration,
|
input_edge.data.duration,
|
||||||
|
input_edge.data.distance,
|
||||||
1,
|
1,
|
||||||
input_edge.data.turn_id,
|
input_edge.data.turn_id,
|
||||||
false,
|
false,
|
||||||
@@ -82,6 +84,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
|||||||
forward_edge.data.originalEdges = reverse_edge.data.originalEdges = 1;
|
forward_edge.data.originalEdges = reverse_edge.data.originalEdges = 1;
|
||||||
forward_edge.data.weight = reverse_edge.data.weight = INVALID_EDGE_WEIGHT;
|
forward_edge.data.weight = reverse_edge.data.weight = INVALID_EDGE_WEIGHT;
|
||||||
forward_edge.data.duration = reverse_edge.data.duration = MAXIMAL_EDGE_DURATION;
|
forward_edge.data.duration = reverse_edge.data.duration = MAXIMAL_EDGE_DURATION;
|
||||||
|
forward_edge.data.distance = reverse_edge.data.distance = MAXIMAL_EDGE_DISTANCE;
|
||||||
// remove parallel edges
|
// remove parallel edges
|
||||||
while (i < edges.size() && edges[i].source == source && edges[i].target == target)
|
while (i < edges.size() && edges[i].source == source && edges[i].target == target)
|
||||||
{
|
{
|
||||||
@@ -90,12 +93,16 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
|||||||
forward_edge.data.weight = std::min(edges[i].data.weight, forward_edge.data.weight);
|
forward_edge.data.weight = std::min(edges[i].data.weight, forward_edge.data.weight);
|
||||||
forward_edge.data.duration =
|
forward_edge.data.duration =
|
||||||
std::min(edges[i].data.duration, forward_edge.data.duration);
|
std::min(edges[i].data.duration, forward_edge.data.duration);
|
||||||
|
forward_edge.data.distance =
|
||||||
|
std::min(edges[i].data.distance, forward_edge.data.distance);
|
||||||
}
|
}
|
||||||
if (edges[i].data.backward)
|
if (edges[i].data.backward)
|
||||||
{
|
{
|
||||||
reverse_edge.data.weight = std::min(edges[i].data.weight, reverse_edge.data.weight);
|
reverse_edge.data.weight = std::min(edges[i].data.weight, reverse_edge.data.weight);
|
||||||
reverse_edge.data.duration =
|
reverse_edge.data.duration =
|
||||||
std::min(edges[i].data.duration, reverse_edge.data.duration);
|
std::min(edges[i].data.duration, reverse_edge.data.duration);
|
||||||
|
reverse_edge.data.distance =
|
||||||
|
std::min(edges[i].data.distance, reverse_edge.data.distance);
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
@@ -151,6 +158,7 @@ template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT g
|
|||||||
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid");
|
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid");
|
||||||
new_edge.data.weight = data.weight;
|
new_edge.data.weight = data.weight;
|
||||||
new_edge.data.duration = data.duration;
|
new_edge.data.duration = data.duration;
|
||||||
|
new_edge.data.distance = data.distance;
|
||||||
new_edge.data.shortcut = data.shortcut;
|
new_edge.data.shortcut = data.shortcut;
|
||||||
new_edge.data.turn_id = data.id;
|
new_edge.data.turn_id = data.id;
|
||||||
BOOST_ASSERT_MSG(new_edge.data.turn_id != INT_MAX, // 2^31
|
BOOST_ASSERT_MSG(new_edge.data.turn_id != INT_MAX, // 2^31
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ struct QueryEdge
|
|||||||
struct EdgeData
|
struct EdgeData
|
||||||
{
|
{
|
||||||
explicit EdgeData()
|
explicit EdgeData()
|
||||||
: turn_id(0), shortcut(false), weight(0), duration(0), forward(false), backward(false)
|
: turn_id(0), shortcut(false), weight(0), duration(0), forward(false), backward(false),
|
||||||
|
distance(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,10 +26,11 @@ struct QueryEdge
|
|||||||
const bool shortcut,
|
const bool shortcut,
|
||||||
const EdgeWeight weight,
|
const EdgeWeight weight,
|
||||||
const EdgeWeight duration,
|
const EdgeWeight duration,
|
||||||
|
const EdgeDistance distance,
|
||||||
const bool forward,
|
const bool forward,
|
||||||
const bool backward)
|
const bool backward)
|
||||||
: turn_id(turn_id), shortcut(shortcut), weight(weight), duration(duration),
|
: turn_id(turn_id), shortcut(shortcut), weight(weight), duration(duration),
|
||||||
forward(forward), backward(backward)
|
forward(forward), backward(backward), distance(distance)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,6 +42,7 @@ struct QueryEdge
|
|||||||
turn_id = other.id;
|
turn_id = other.id;
|
||||||
forward = other.forward;
|
forward = other.forward;
|
||||||
backward = other.backward;
|
backward = other.backward;
|
||||||
|
distance = other.distance;
|
||||||
}
|
}
|
||||||
// this ID is either the middle node of the shortcut, or the ID of the edge based node (node
|
// this ID is either the middle node of the shortcut, or the ID of the edge based node (node
|
||||||
// based edge) storing the appropriate data. If `shortcut` is set to true, we get the middle
|
// based edge) storing the appropriate data. If `shortcut` is set to true, we get the middle
|
||||||
@@ -50,6 +53,7 @@ struct QueryEdge
|
|||||||
EdgeWeight duration : 30;
|
EdgeWeight duration : 30;
|
||||||
std::uint32_t forward : 1;
|
std::uint32_t forward : 1;
|
||||||
std::uint32_t backward : 1;
|
std::uint32_t backward : 1;
|
||||||
|
EdgeDistance distance;
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
QueryEdge() : source(SPECIAL_NODEID), target(SPECIAL_NODEID) {}
|
QueryEdge() : source(SPECIAL_NODEID), target(SPECIAL_NODEID) {}
|
||||||
@@ -69,7 +73,8 @@ struct QueryEdge
|
|||||||
return (source == right.source && target == right.target &&
|
return (source == right.source && target == right.target &&
|
||||||
data.weight == right.data.weight && data.duration == right.data.duration &&
|
data.weight == right.data.weight && data.duration == right.data.duration &&
|
||||||
data.shortcut == right.data.shortcut && data.forward == right.data.forward &&
|
data.shortcut == right.data.shortcut && data.forward == right.data.forward &&
|
||||||
data.backward == right.data.backward && data.turn_id == right.data.turn_id);
|
data.backward == right.data.backward && data.turn_id == right.data.turn_id &&
|
||||||
|
data.distance == right.data.distance);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class CellCustomizer
|
|||||||
{
|
{
|
||||||
bool from_clique;
|
bool from_clique;
|
||||||
EdgeDuration duration;
|
EdgeDuration duration;
|
||||||
|
EdgeDistance distance;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -60,7 +61,7 @@ class CellCustomizer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
heap.Clear();
|
heap.Clear();
|
||||||
heap.Insert(source, 0, {false, 0});
|
heap.Insert(source, 0, {false, 0, 0});
|
||||||
|
|
||||||
// explore search space
|
// explore search space
|
||||||
while (!heap.Empty() && !destinations_set.empty())
|
while (!heap.Empty() && !destinations_set.empty())
|
||||||
@@ -68,8 +69,18 @@ class CellCustomizer
|
|||||||
const NodeID node = heap.DeleteMin();
|
const NodeID node = heap.DeleteMin();
|
||||||
const EdgeWeight weight = heap.GetKey(node);
|
const EdgeWeight weight = heap.GetKey(node);
|
||||||
const EdgeDuration duration = heap.GetData(node).duration;
|
const EdgeDuration duration = heap.GetData(node).duration;
|
||||||
|
const EdgeDistance distance = heap.GetData(node).distance;
|
||||||
|
|
||||||
RelaxNode(graph, cells, allowed_nodes, metric, heap, level, node, weight, duration);
|
RelaxNode(graph,
|
||||||
|
cells,
|
||||||
|
allowed_nodes,
|
||||||
|
metric,
|
||||||
|
heap,
|
||||||
|
level,
|
||||||
|
node,
|
||||||
|
weight,
|
||||||
|
duration,
|
||||||
|
distance);
|
||||||
|
|
||||||
destinations_set.erase(node);
|
destinations_set.erase(node);
|
||||||
}
|
}
|
||||||
@@ -77,21 +88,27 @@ class CellCustomizer
|
|||||||
// fill a map of destination nodes to placeholder pointers
|
// fill a map of destination nodes to placeholder pointers
|
||||||
auto weights = cell.GetOutWeight(source);
|
auto weights = cell.GetOutWeight(source);
|
||||||
auto durations = cell.GetOutDuration(source);
|
auto durations = cell.GetOutDuration(source);
|
||||||
|
auto distances = cell.GetOutDistance(source);
|
||||||
for (auto &destination : destinations)
|
for (auto &destination : destinations)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!weights.empty());
|
BOOST_ASSERT(!weights.empty());
|
||||||
BOOST_ASSERT(!durations.empty());
|
BOOST_ASSERT(!durations.empty());
|
||||||
|
BOOST_ASSERT(!distances.empty());
|
||||||
|
|
||||||
const bool inserted = heap.WasInserted(destination);
|
const bool inserted = heap.WasInserted(destination);
|
||||||
weights.front() = inserted ? heap.GetKey(destination) : INVALID_EDGE_WEIGHT;
|
weights.front() = inserted ? heap.GetKey(destination) : INVALID_EDGE_WEIGHT;
|
||||||
durations.front() =
|
durations.front() =
|
||||||
inserted ? heap.GetData(destination).duration : MAXIMAL_EDGE_DURATION;
|
inserted ? heap.GetData(destination).duration : MAXIMAL_EDGE_DURATION;
|
||||||
|
distances.front() =
|
||||||
|
inserted ? heap.GetData(destination).distance : INVALID_EDGE_DISTANCE;
|
||||||
|
|
||||||
weights.advance_begin(1);
|
weights.advance_begin(1);
|
||||||
durations.advance_begin(1);
|
durations.advance_begin(1);
|
||||||
|
distances.advance_begin(1);
|
||||||
}
|
}
|
||||||
BOOST_ASSERT(weights.empty());
|
BOOST_ASSERT(weights.empty());
|
||||||
BOOST_ASSERT(durations.empty());
|
BOOST_ASSERT(durations.empty());
|
||||||
|
BOOST_ASSERT(distances.empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +145,8 @@ class CellCustomizer
|
|||||||
LevelID level,
|
LevelID level,
|
||||||
NodeID node,
|
NodeID node,
|
||||||
EdgeWeight weight,
|
EdgeWeight weight,
|
||||||
EdgeDuration duration) const
|
EdgeDuration duration,
|
||||||
|
EdgeDistance distance) const
|
||||||
{
|
{
|
||||||
auto first_level = level == 1;
|
auto first_level = level == 1;
|
||||||
BOOST_ASSERT(heap.WasInserted(node));
|
BOOST_ASSERT(heap.WasInserted(node));
|
||||||
@@ -149,6 +167,7 @@ class CellCustomizer
|
|||||||
auto subcell = cells.GetCell(metric, level - 1, subcell_id);
|
auto subcell = cells.GetCell(metric, level - 1, subcell_id);
|
||||||
auto subcell_destination = subcell.GetDestinationNodes().begin();
|
auto subcell_destination = subcell.GetDestinationNodes().begin();
|
||||||
auto subcell_duration = subcell.GetOutDuration(node).begin();
|
auto subcell_duration = subcell.GetOutDuration(node).begin();
|
||||||
|
auto subcell_distance = subcell.GetOutDistance(node).begin();
|
||||||
for (auto subcell_weight : subcell.GetOutWeight(node))
|
for (auto subcell_weight : subcell.GetOutWeight(node))
|
||||||
{
|
{
|
||||||
if (subcell_weight != INVALID_EDGE_WEIGHT)
|
if (subcell_weight != INVALID_EDGE_WEIGHT)
|
||||||
@@ -161,20 +180,24 @@ class CellCustomizer
|
|||||||
|
|
||||||
const EdgeWeight to_weight = weight + subcell_weight;
|
const EdgeWeight to_weight = weight + subcell_weight;
|
||||||
const EdgeDuration to_duration = duration + *subcell_duration;
|
const EdgeDuration to_duration = duration + *subcell_duration;
|
||||||
|
const EdgeDistance to_distance = distance + *subcell_distance;
|
||||||
if (!heap.WasInserted(to))
|
if (!heap.WasInserted(to))
|
||||||
{
|
{
|
||||||
heap.Insert(to, to_weight, {true, to_duration});
|
heap.Insert(to, to_weight, {true, to_duration, to_distance});
|
||||||
}
|
}
|
||||||
else if (std::tie(to_weight, to_duration) <
|
else if (std::tie(to_weight, to_duration, to_distance) <
|
||||||
std::tie(heap.GetKey(to), heap.GetData(to).duration))
|
std::tie(heap.GetKey(to),
|
||||||
|
heap.GetData(to).duration,
|
||||||
|
heap.GetData(to).distance))
|
||||||
{
|
{
|
||||||
heap.DecreaseKey(to, to_weight);
|
heap.DecreaseKey(to, to_weight);
|
||||||
heap.GetData(to) = {true, to_duration};
|
heap.GetData(to) = {true, to_duration, to_distance};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++subcell_destination;
|
++subcell_destination;
|
||||||
++subcell_duration;
|
++subcell_duration;
|
||||||
|
++subcell_distance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,15 +218,18 @@ class CellCustomizer
|
|||||||
{
|
{
|
||||||
const EdgeWeight to_weight = weight + data.weight;
|
const EdgeWeight to_weight = weight + data.weight;
|
||||||
const EdgeDuration to_duration = duration + data.duration;
|
const EdgeDuration to_duration = duration + data.duration;
|
||||||
|
const EdgeDistance to_distance = distance + data.distance;
|
||||||
if (!heap.WasInserted(to))
|
if (!heap.WasInserted(to))
|
||||||
{
|
{
|
||||||
heap.Insert(to, to_weight, {false, duration + data.duration});
|
heap.Insert(
|
||||||
|
to, to_weight, {false, duration + data.duration, distance + data.distance});
|
||||||
}
|
}
|
||||||
else if (std::tie(to_weight, to_duration) <
|
else if (std::tie(to_weight, to_duration, to_distance) <
|
||||||
std::tie(heap.GetKey(to), heap.GetData(to).duration))
|
std::tie(
|
||||||
|
heap.GetKey(to), heap.GetData(to).duration, heap.GetData(to).distance))
|
||||||
{
|
{
|
||||||
heap.DecreaseKey(to, to_weight);
|
heap.DecreaseKey(to, to_weight);
|
||||||
heap.GetData(to) = {false, to_duration};
|
heap.GetData(to) = {false, to_duration, to_distance};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ template <storage::Ownership Ownership> struct CellMetricImpl
|
|||||||
|
|
||||||
Vector<EdgeWeight> weights;
|
Vector<EdgeWeight> weights;
|
||||||
Vector<EdgeDuration> durations;
|
Vector<EdgeDuration> durations;
|
||||||
|
Vector<EdgeDistance> distances;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,8 +58,10 @@ class MultiLevelGraph : public partitioner::MultiLevelGraph<EdgeDataT, Ownership
|
|||||||
|
|
||||||
MultiLevelGraph(PartitionerGraphT &&graph,
|
MultiLevelGraph(PartitionerGraphT &&graph,
|
||||||
Vector<EdgeWeight> node_weights_,
|
Vector<EdgeWeight> node_weights_,
|
||||||
Vector<EdgeDuration> node_durations_)
|
Vector<EdgeDuration> node_durations_,
|
||||||
: node_weights(std::move(node_weights_)), node_durations(std::move(node_durations_))
|
Vector<EdgeDistance> node_distances_)
|
||||||
|
: node_weights(std::move(node_weights_)), node_durations(std::move(node_durations_)),
|
||||||
|
node_distances(std::move(node_distances_))
|
||||||
{
|
{
|
||||||
util::ViewOrVector<PartitionerGraphT::EdgeArrayEntry, storage::Ownership::Container>
|
util::ViewOrVector<PartitionerGraphT::EdgeArrayEntry, storage::Ownership::Container>
|
||||||
original_edge_array;
|
original_edge_array;
|
||||||
@@ -83,11 +85,13 @@ class MultiLevelGraph : public partitioner::MultiLevelGraph<EdgeDataT, Ownership
|
|||||||
Vector<EdgeOffset> node_to_edge_offset_,
|
Vector<EdgeOffset> node_to_edge_offset_,
|
||||||
Vector<EdgeWeight> node_weights_,
|
Vector<EdgeWeight> node_weights_,
|
||||||
Vector<EdgeDuration> node_durations_,
|
Vector<EdgeDuration> node_durations_,
|
||||||
|
Vector<EdgeDistance> node_distances_,
|
||||||
Vector<bool> is_forward_edge_,
|
Vector<bool> is_forward_edge_,
|
||||||
Vector<bool> is_backward_edge_)
|
Vector<bool> is_backward_edge_)
|
||||||
: SuperT(std::move(node_array_), std::move(edge_array_), std::move(node_to_edge_offset_)),
|
: SuperT(std::move(node_array_), std::move(edge_array_), std::move(node_to_edge_offset_)),
|
||||||
node_weights(std::move(node_weights_)), node_durations(std::move(node_durations_)),
|
node_weights(std::move(node_weights_)), node_durations(std::move(node_durations_)),
|
||||||
is_forward_edge(is_forward_edge_), is_backward_edge(is_backward_edge_)
|
node_distances(std::move(node_distances_)), is_forward_edge(is_forward_edge_),
|
||||||
|
is_backward_edge(is_backward_edge_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +99,8 @@ class MultiLevelGraph : public partitioner::MultiLevelGraph<EdgeDataT, Ownership
|
|||||||
|
|
||||||
EdgeWeight GetNodeDuration(NodeID node) const { return node_durations[node]; }
|
EdgeWeight GetNodeDuration(NodeID node) const { return node_durations[node]; }
|
||||||
|
|
||||||
|
EdgeDistance GetNodeDistance(NodeID node) const { return node_distances[node]; }
|
||||||
|
|
||||||
bool IsForwardEdge(EdgeID edge) const { return is_forward_edge[edge]; }
|
bool IsForwardEdge(EdgeID edge) const { return is_forward_edge[edge]; }
|
||||||
|
|
||||||
bool IsBackwardEdge(EdgeID edge) const { return is_backward_edge[edge]; }
|
bool IsBackwardEdge(EdgeID edge) const { return is_backward_edge[edge]; }
|
||||||
@@ -111,6 +117,7 @@ class MultiLevelGraph : public partitioner::MultiLevelGraph<EdgeDataT, Ownership
|
|||||||
protected:
|
protected:
|
||||||
Vector<EdgeWeight> node_weights;
|
Vector<EdgeWeight> node_weights;
|
||||||
Vector<EdgeDuration> node_durations;
|
Vector<EdgeDuration> node_durations;
|
||||||
|
Vector<EdgeDistance> node_distances;
|
||||||
Vector<bool> is_forward_edge;
|
Vector<bool> is_forward_edge;
|
||||||
Vector<bool> is_backward_edge;
|
Vector<bool> is_backward_edge;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ inline void read(storage::tar::FileReader &reader,
|
|||||||
{
|
{
|
||||||
storage::serialization::read(reader, name + "/weights", metric.weights);
|
storage::serialization::read(reader, name + "/weights", metric.weights);
|
||||||
storage::serialization::read(reader, name + "/durations", metric.durations);
|
storage::serialization::read(reader, name + "/durations", metric.durations);
|
||||||
|
storage::serialization::read(reader, name + "/distances", metric.distances);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <storage::Ownership Ownership>
|
template <storage::Ownership Ownership>
|
||||||
@@ -32,6 +33,7 @@ inline void write(storage::tar::FileWriter &writer,
|
|||||||
{
|
{
|
||||||
storage::serialization::write(writer, name + "/weights", metric.weights);
|
storage::serialization::write(writer, name + "/weights", metric.weights);
|
||||||
storage::serialization::write(writer, name + "/durations", metric.durations);
|
storage::serialization::write(writer, name + "/durations", metric.durations);
|
||||||
|
storage::serialization::write(writer, name + "/distances", metric.distances);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename EdgeDataT, storage::Ownership Ownership>
|
template <typename EdgeDataT, storage::Ownership Ownership>
|
||||||
@@ -42,6 +44,7 @@ inline void read(storage::tar::FileReader &reader,
|
|||||||
storage::serialization::read(reader, name + "/node_array", graph.node_array);
|
storage::serialization::read(reader, name + "/node_array", graph.node_array);
|
||||||
storage::serialization::read(reader, name + "/node_weights", graph.node_weights);
|
storage::serialization::read(reader, name + "/node_weights", graph.node_weights);
|
||||||
storage::serialization::read(reader, name + "/node_durations", graph.node_durations);
|
storage::serialization::read(reader, name + "/node_durations", graph.node_durations);
|
||||||
|
storage::serialization::read(reader, name + "/node_distances", graph.node_distances);
|
||||||
storage::serialization::read(reader, name + "/edge_array", graph.edge_array);
|
storage::serialization::read(reader, name + "/edge_array", graph.edge_array);
|
||||||
storage::serialization::read(reader, name + "/is_forward_edge", graph.is_forward_edge);
|
storage::serialization::read(reader, name + "/is_forward_edge", graph.is_forward_edge);
|
||||||
storage::serialization::read(reader, name + "/is_backward_edge", graph.is_backward_edge);
|
storage::serialization::read(reader, name + "/is_backward_edge", graph.is_backward_edge);
|
||||||
@@ -56,6 +59,7 @@ inline void write(storage::tar::FileWriter &writer,
|
|||||||
storage::serialization::write(writer, name + "/node_array", graph.node_array);
|
storage::serialization::write(writer, name + "/node_array", graph.node_array);
|
||||||
storage::serialization::write(writer, name + "/node_weights", graph.node_weights);
|
storage::serialization::write(writer, name + "/node_weights", graph.node_weights);
|
||||||
storage::serialization::write(writer, name + "/node_durations", graph.node_durations);
|
storage::serialization::write(writer, name + "/node_durations", graph.node_durations);
|
||||||
|
storage::serialization::write(writer, name + "/node_distances", graph.node_distances);
|
||||||
storage::serialization::write(writer, name + "/edge_array", graph.edge_array);
|
storage::serialization::write(writer, name + "/edge_array", graph.edge_array);
|
||||||
storage::serialization::write(writer, name + "/is_forward_edge", graph.is_forward_edge);
|
storage::serialization::write(writer, name + "/is_forward_edge", graph.is_forward_edge);
|
||||||
storage::serialization::write(writer, name + "/is_backward_edge", graph.is_backward_edge);
|
storage::serialization::write(writer, name + "/is_backward_edge", graph.is_backward_edge);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "engine/api/json_factory.hpp"
|
#include "engine/api/json_factory.hpp"
|
||||||
#include "engine/hint.hpp"
|
#include "engine/hint.hpp"
|
||||||
|
#include "util/coordinate_calculation.hpp"
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/range/algorithm/transform.hpp>
|
#include <boost/range/algorithm/transform.hpp>
|
||||||
@@ -53,6 +54,8 @@ class BaseAPI
|
|||||||
// TODO: check forward/reverse
|
// TODO: check forward/reverse
|
||||||
return json::makeWaypoint(
|
return json::makeWaypoint(
|
||||||
phantom.location,
|
phantom.location,
|
||||||
|
util::coordinate_calculation::fccApproximateDistance(phantom.location,
|
||||||
|
phantom.input_location),
|
||||||
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)).to_string(),
|
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)).to_string(),
|
||||||
Hint{phantom, facade.GetCheckSum()});
|
Hint{phantom, facade.GetCheckSum()});
|
||||||
}
|
}
|
||||||
@@ -61,6 +64,8 @@ class BaseAPI
|
|||||||
// TODO: check forward/reverse
|
// TODO: check forward/reverse
|
||||||
return json::makeWaypoint(
|
return json::makeWaypoint(
|
||||||
phantom.location,
|
phantom.location,
|
||||||
|
util::coordinate_calculation::fccApproximateDistance(phantom.location,
|
||||||
|
phantom.input_location),
|
||||||
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id))
|
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id))
|
||||||
.to_string());
|
.to_string());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,13 @@ namespace api
|
|||||||
*/
|
*/
|
||||||
struct BaseParameters
|
struct BaseParameters
|
||||||
{
|
{
|
||||||
|
|
||||||
|
enum class SnappingType
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
Any
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<util::Coordinate> coordinates;
|
std::vector<util::Coordinate> coordinates;
|
||||||
std::vector<boost::optional<Hint>> hints;
|
std::vector<boost::optional<Hint>> hints;
|
||||||
std::vector<boost::optional<double>> radiuses;
|
std::vector<boost::optional<double>> radiuses;
|
||||||
@@ -73,15 +80,19 @@ struct BaseParameters
|
|||||||
// Adds hints to response which can be included in subsequent requests, see `hints` above.
|
// Adds hints to response which can be included in subsequent requests, see `hints` above.
|
||||||
bool generate_hints = true;
|
bool generate_hints = true;
|
||||||
|
|
||||||
|
SnappingType snapping = SnappingType::Default;
|
||||||
|
|
||||||
BaseParameters(const std::vector<util::Coordinate> coordinates_ = {},
|
BaseParameters(const std::vector<util::Coordinate> coordinates_ = {},
|
||||||
const std::vector<boost::optional<Hint>> hints_ = {},
|
const std::vector<boost::optional<Hint>> hints_ = {},
|
||||||
std::vector<boost::optional<double>> radiuses_ = {},
|
std::vector<boost::optional<double>> radiuses_ = {},
|
||||||
std::vector<boost::optional<Bearing>> bearings_ = {},
|
std::vector<boost::optional<Bearing>> bearings_ = {},
|
||||||
std::vector<boost::optional<Approach>> approaches_ = {},
|
std::vector<boost::optional<Approach>> approaches_ = {},
|
||||||
bool generate_hints_ = true,
|
bool generate_hints_ = true,
|
||||||
std::vector<std::string> exclude = {})
|
std::vector<std::string> exclude = {},
|
||||||
|
const SnappingType snapping_ = SnappingType::Default)
|
||||||
: coordinates(coordinates_), hints(hints_), radiuses(radiuses_), bearings(bearings_),
|
: coordinates(coordinates_), hints(hints_), radiuses(radiuses_), bearings(bearings_),
|
||||||
approaches(approaches_), exclude(std::move(exclude)), generate_hints(generate_hints_)
|
approaches(approaches_), exclude(std::move(exclude)), generate_hints(generate_hints_),
|
||||||
|
snapping(snapping_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace json
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
util::json::Array coordinateToLonLat(const util::Coordinate coordinate);
|
util::json::Array coordinateToLonLat(const util::Coordinate &coordinate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that a bearing value is a whole number, and clamped to the range 0-359
|
* Ensures that a bearing value is a whole number, and clamped to the range 0-359
|
||||||
@@ -86,11 +86,14 @@ util::json::Object makeRoute(const guidance::Route &route,
|
|||||||
const char *weight_name);
|
const char *weight_name);
|
||||||
|
|
||||||
// Creates a Waypoint without Hint, see the Hint overload below
|
// Creates a Waypoint without Hint, see the Hint overload below
|
||||||
util::json::Object makeWaypoint(const util::Coordinate location, std::string name);
|
util::json::Object
|
||||||
|
makeWaypoint(const util::Coordinate &location, const double &distance, std::string name);
|
||||||
|
|
||||||
// Creates a Waypoint with Hint, see the overload above when Hint is not needed
|
// Creates a Waypoint with Hint, see the overload above when Hint is not needed
|
||||||
util::json::Object
|
util::json::Object makeWaypoint(const util::Coordinate &location,
|
||||||
makeWaypoint(const util::Coordinate location, std::string name, const Hint &hint);
|
const double &distance,
|
||||||
|
std::string name,
|
||||||
|
const Hint &hint);
|
||||||
|
|
||||||
util::json::Object makeRouteLeg(guidance::RouteLeg leg, util::json::Array steps);
|
util::json::Object makeRouteLeg(guidance::RouteLeg leg, util::json::Array steps);
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ struct MatchParameters : public RouteParameters
|
|||||||
RouteParameters::GeometriesType::Polyline,
|
RouteParameters::GeometriesType::Polyline,
|
||||||
RouteParameters::OverviewType::Simplified,
|
RouteParameters::OverviewType::Simplified,
|
||||||
{}),
|
{}),
|
||||||
gaps(GapsType::Split), tidy(false), waypoints()
|
gaps(GapsType::Split), tidy(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,24 +79,19 @@ struct MatchParameters : public RouteParameters
|
|||||||
bool tidy_,
|
bool tidy_,
|
||||||
std::vector<std::size_t> waypoints_,
|
std::vector<std::size_t> waypoints_,
|
||||||
Args... args_)
|
Args... args_)
|
||||||
: RouteParameters{std::forward<Args>(args_)...}, timestamps{std::move(timestamps_)},
|
: RouteParameters{std::forward<Args>(args_)..., waypoints_},
|
||||||
gaps(gaps_), tidy(tidy_), waypoints{std::move(waypoints_)}
|
timestamps{std::move(timestamps_)}, gaps(gaps_), tidy(tidy_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned> timestamps;
|
std::vector<unsigned> timestamps;
|
||||||
GapsType gaps;
|
GapsType gaps;
|
||||||
bool tidy;
|
bool tidy;
|
||||||
std::vector<std::size_t> waypoints;
|
|
||||||
|
|
||||||
bool IsValid() const
|
bool IsValid() const
|
||||||
{
|
{
|
||||||
const auto valid_waypoints =
|
|
||||||
std::all_of(waypoints.begin(), waypoints.end(), [this](const auto &w) {
|
|
||||||
return w < coordinates.size();
|
|
||||||
});
|
|
||||||
return RouteParameters::IsValid() &&
|
return RouteParameters::IsValid() &&
|
||||||
(timestamps.empty() || timestamps.size() == coordinates.size()) && valid_waypoints;
|
(timestamps.empty() || timestamps.size() == coordinates.size());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ class NearestAPI final : public BaseAPI
|
|||||||
[this](const PhantomNodeWithDistance &phantom_with_distance) {
|
[this](const PhantomNodeWithDistance &phantom_with_distance) {
|
||||||
auto &phantom_node = phantom_with_distance.phantom_node;
|
auto &phantom_node = phantom_with_distance.phantom_node;
|
||||||
auto waypoint = MakeWaypoint(phantom_node);
|
auto waypoint = MakeWaypoint(phantom_node);
|
||||||
waypoint.values["distance"] = phantom_with_distance.distance;
|
|
||||||
|
|
||||||
util::json::Array nodes;
|
util::json::Array nodes;
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,11 @@ class RouteAPI : public BaseAPI
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakeResponse(const InternalManyRoutesResult &raw_routes,
|
void
|
||||||
util::json::Object &response) const
|
MakeResponse(const InternalManyRoutesResult &raw_routes,
|
||||||
|
const std::vector<PhantomNodes>
|
||||||
|
&all_start_end_points, // all used coordinates, ignoring waypoints= parameter
|
||||||
|
util::json::Object &response) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!raw_routes.routes.empty());
|
BOOST_ASSERT(!raw_routes.routes.empty());
|
||||||
|
|
||||||
@@ -62,10 +65,14 @@ class RouteAPI : public BaseAPI
|
|||||||
route.target_traversed_in_reverse));
|
route.target_traversed_in_reverse));
|
||||||
}
|
}
|
||||||
|
|
||||||
response.values["waypoints"] =
|
response.values["waypoints"] = BaseAPI::MakeWaypoints(all_start_end_points);
|
||||||
BaseAPI::MakeWaypoints(raw_routes.routes[0].segment_end_coordinates);
|
|
||||||
response.values["routes"] = std::move(jsRoutes);
|
response.values["routes"] = std::move(jsRoutes);
|
||||||
response.values["code"] = "Ok";
|
response.values["code"] = "Ok";
|
||||||
|
auto data_timestamp = facade.GetTimestamp();
|
||||||
|
if (!data_timestamp.empty())
|
||||||
|
{
|
||||||
|
response.values["data_version"] = data_timestamp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -98,7 +98,8 @@ struct RouteParameters : public BaseParameters
|
|||||||
annotations_type{AnnotationsType::None},
|
annotations_type{AnnotationsType::None},
|
||||||
geometries{geometries_},
|
geometries{geometries_},
|
||||||
overview{overview_},
|
overview{overview_},
|
||||||
continue_straight{continue_straight_}
|
continue_straight{continue_straight_},
|
||||||
|
waypoints()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +115,9 @@ struct RouteParameters : public BaseParameters
|
|||||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||||
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
|
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
|
||||||
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
|
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
|
||||||
geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_}
|
geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_},
|
||||||
|
waypoints()
|
||||||
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +134,43 @@ struct RouteParameters : public BaseParameters
|
|||||||
number_of_alternatives{alternatives_ ? 1u : 0u},
|
number_of_alternatives{alternatives_ ? 1u : 0u},
|
||||||
annotations{annotations_ == AnnotationsType::None ? false : true},
|
annotations{annotations_ == AnnotationsType::None ? false : true},
|
||||||
annotations_type{annotations_}, geometries{geometries_}, overview{overview_},
|
annotations_type{annotations_}, geometries{geometries_}, overview{overview_},
|
||||||
continue_straight{continue_straight_}
|
continue_straight{continue_straight_}, waypoints()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// RouteParameters constructor adding the `waypoints` parameter
|
||||||
|
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_,
|
||||||
|
std::vector<std::size_t> waypoints_,
|
||||||
|
const Args... args_)
|
||||||
|
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||||
|
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
|
||||||
|
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
|
||||||
|
geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_},
|
||||||
|
waypoints{waypoints_}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// RouteParameters constructor adding the `waypoints` parameter
|
||||||
|
template <typename... Args>
|
||||||
|
RouteParameters(const bool steps_,
|
||||||
|
const bool alternatives_,
|
||||||
|
const AnnotationsType annotations_,
|
||||||
|
const GeometriesType geometries_,
|
||||||
|
const OverviewType overview_,
|
||||||
|
const boost::optional<bool> continue_straight_,
|
||||||
|
std::vector<std::size_t> waypoints_,
|
||||||
|
Args... args_)
|
||||||
|
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||||
|
number_of_alternatives{alternatives_ ? 1u : 0u},
|
||||||
|
annotations{annotations_ == AnnotationsType::None ? false : true},
|
||||||
|
annotations_type{annotations_}, geometries{geometries_}, overview{overview_},
|
||||||
|
continue_straight{continue_straight_}, waypoints{waypoints_}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,12 +183,17 @@ struct RouteParameters : public BaseParameters
|
|||||||
GeometriesType geometries = GeometriesType::Polyline;
|
GeometriesType geometries = GeometriesType::Polyline;
|
||||||
OverviewType overview = OverviewType::Simplified;
|
OverviewType overview = OverviewType::Simplified;
|
||||||
boost::optional<bool> continue_straight;
|
boost::optional<bool> continue_straight;
|
||||||
|
std::vector<std::size_t> waypoints;
|
||||||
|
|
||||||
bool IsValid() const
|
bool IsValid() const
|
||||||
{
|
{
|
||||||
const auto coordinates_ok = coordinates.size() >= 2;
|
const auto coordinates_ok = coordinates.size() >= 2;
|
||||||
const auto base_params_ok = BaseParameters::IsValid();
|
const auto base_params_ok = BaseParameters::IsValid();
|
||||||
return coordinates_ok && base_params_ok;
|
const auto valid_waypoints =
|
||||||
|
std::all_of(waypoints.begin(), waypoints.end(), [this](const auto &w) {
|
||||||
|
return w < coordinates.size();
|
||||||
|
});
|
||||||
|
return coordinates_ok && base_params_ok && valid_waypoints;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -173,8 +217,8 @@ inline RouteParameters::AnnotationsType operator|=(RouteParameters::AnnotationsT
|
|||||||
{
|
{
|
||||||
return lhs = lhs | rhs;
|
return lhs = lhs | rhs;
|
||||||
}
|
}
|
||||||
}
|
} // ns api
|
||||||
}
|
} // ns engine
|
||||||
}
|
} // ns osrm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -31,6 +31,15 @@ namespace api
|
|||||||
class TableAPI final : public BaseAPI
|
class TableAPI final : public BaseAPI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct TableCellRef
|
||||||
|
{
|
||||||
|
TableCellRef(const std::size_t &row, const std::size_t &column) : row{row}, column{column}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::size_t row;
|
||||||
|
std::size_t column;
|
||||||
|
};
|
||||||
|
|
||||||
TableAPI(const datafacade::BaseDataFacade &facade_, const TableParameters ¶meters_)
|
TableAPI(const datafacade::BaseDataFacade &facade_, const TableParameters ¶meters_)
|
||||||
: BaseAPI(facade_, parameters_), parameters(parameters_)
|
: BaseAPI(facade_, parameters_), parameters(parameters_)
|
||||||
{
|
{
|
||||||
@@ -39,6 +48,7 @@ class TableAPI final : public BaseAPI
|
|||||||
virtual void
|
virtual void
|
||||||
MakeResponse(const std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> &tables,
|
MakeResponse(const std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> &tables,
|
||||||
const std::vector<PhantomNode> &phantoms,
|
const std::vector<PhantomNode> &phantoms,
|
||||||
|
const std::vector<TableCellRef> &fallback_speed_cells,
|
||||||
util::json::Object &response) const
|
util::json::Object &response) const
|
||||||
{
|
{
|
||||||
auto number_of_sources = parameters.sources.size();
|
auto number_of_sources = parameters.sources.size();
|
||||||
@@ -77,6 +87,11 @@ class TableAPI final : public BaseAPI
|
|||||||
MakeDistanceTable(tables.second, number_of_sources, number_of_destinations);
|
MakeDistanceTable(tables.second, number_of_sources, number_of_destinations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parameters.fallback_speed != INVALID_FALLBACK_SPEED && parameters.fallback_speed > 0)
|
||||||
|
{
|
||||||
|
response.values["fallback_speed_cells"] = MakeEstimatesTable(fallback_speed_cells);
|
||||||
|
}
|
||||||
|
|
||||||
response.values["code"] = "Ok";
|
response.values["code"] = "Ok";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,6 +178,20 @@ class TableAPI final : public BaseAPI
|
|||||||
return json_table;
|
return json_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual util::json::Array
|
||||||
|
MakeEstimatesTable(const std::vector<TableCellRef> &fallback_speed_cells) const
|
||||||
|
{
|
||||||
|
util::json::Array json_table;
|
||||||
|
std::for_each(
|
||||||
|
fallback_speed_cells.begin(), fallback_speed_cells.end(), [&](const auto &cell) {
|
||||||
|
util::json::Array row;
|
||||||
|
row.values.push_back(util::json::Number(cell.row));
|
||||||
|
row.values.push_back(util::json::Number(cell.column));
|
||||||
|
json_table.values.push_back(std::move(row));
|
||||||
|
});
|
||||||
|
return json_table;
|
||||||
|
}
|
||||||
|
|
||||||
const TableParameters ¶meters;
|
const TableParameters ¶meters;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,15 @@ struct TableParameters : public BaseParameters
|
|||||||
{
|
{
|
||||||
std::vector<std::size_t> sources;
|
std::vector<std::size_t> sources;
|
||||||
std::vector<std::size_t> destinations;
|
std::vector<std::size_t> destinations;
|
||||||
|
double fallback_speed = INVALID_FALLBACK_SPEED;
|
||||||
|
|
||||||
|
enum class FallbackCoordinateType
|
||||||
|
{
|
||||||
|
Input = 0,
|
||||||
|
Snapped = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
FallbackCoordinateType fallback_coordinate_type = FallbackCoordinateType::Input;
|
||||||
|
|
||||||
enum class AnnotationsType
|
enum class AnnotationsType
|
||||||
{
|
{
|
||||||
@@ -70,6 +79,8 @@ struct TableParameters : public BaseParameters
|
|||||||
|
|
||||||
AnnotationsType annotations = AnnotationsType::Duration;
|
AnnotationsType annotations = AnnotationsType::Duration;
|
||||||
|
|
||||||
|
double scale_factor = 1;
|
||||||
|
|
||||||
TableParameters() = default;
|
TableParameters() = default;
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
TableParameters(std::vector<std::size_t> sources_,
|
TableParameters(std::vector<std::size_t> sources_,
|
||||||
@@ -90,6 +101,22 @@ struct TableParameters : public BaseParameters
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
TableParameters(std::vector<std::size_t> sources_,
|
||||||
|
std::vector<std::size_t> destinations_,
|
||||||
|
const AnnotationsType annotations_,
|
||||||
|
double fallback_speed_,
|
||||||
|
FallbackCoordinateType fallback_coordinate_type_,
|
||||||
|
double scale_factor_,
|
||||||
|
Args... args_)
|
||||||
|
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
||||||
|
destinations{std::move(destinations_)}, fallback_speed{fallback_speed_},
|
||||||
|
fallback_coordinate_type{fallback_coordinate_type_}, annotations{annotations_},
|
||||||
|
scale_factor{scale_factor_}
|
||||||
|
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool IsValid() const
|
bool IsValid() const
|
||||||
{
|
{
|
||||||
if (!BaseParameters::IsValid())
|
if (!BaseParameters::IsValid())
|
||||||
@@ -101,14 +128,7 @@ struct TableParameters : public BaseParameters
|
|||||||
|
|
||||||
// 1/ The user is able to specify duplicates in srcs and dsts, in that case it's their fault
|
// 1/ The user is able to specify duplicates in srcs and dsts, in that case it's their fault
|
||||||
|
|
||||||
// 2/ len(srcs) and len(dsts) smaller or equal to len(locations)
|
// 2/ 0 <= index < len(locations)
|
||||||
if (sources.size() > coordinates.size())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (destinations.size() > coordinates.size())
|
|
||||||
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))
|
if (std::any_of(begin(sources), end(sources), not_in_range))
|
||||||
@@ -117,6 +137,12 @@ struct TableParameters : public BaseParameters
|
|||||||
if (std::any_of(begin(destinations), end(destinations), not_in_range))
|
if (std::any_of(begin(destinations), end(destinations), not_in_range))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (fallback_speed <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (scale_factor <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ template <> class AlgorithmDataFacade<MLD>
|
|||||||
|
|
||||||
virtual EdgeWeight GetNodeDuration(const NodeID node) const = 0; // TODO: to be removed
|
virtual EdgeWeight GetNodeDuration(const NodeID node) const = 0; // TODO: to be removed
|
||||||
|
|
||||||
|
virtual EdgeDistance GetNodeDistance(const NodeID node) const = 0;
|
||||||
|
|
||||||
virtual bool IsForwardEdge(EdgeID edge) const = 0;
|
virtual bool IsForwardEdge(EdgeID edge) const = 0;
|
||||||
|
|
||||||
virtual bool IsBackwardEdge(EdgeID edge) const = 0;
|
virtual bool IsBackwardEdge(EdgeID edge) const = 0;
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
extractor::Datasources *m_datasources;
|
extractor::Datasources *m_datasources;
|
||||||
|
|
||||||
std::uint32_t m_check_sum;
|
std::uint32_t m_check_sum;
|
||||||
|
StringView m_data_timestamp;
|
||||||
util::vector_view<util::Coordinate> m_coordinate_list;
|
util::vector_view<util::Coordinate> m_coordinate_list;
|
||||||
extractor::PackedOSMIDsView m_osmnodeid_list;
|
extractor::PackedOSMIDsView m_osmnodeid_list;
|
||||||
util::vector_view<std::uint32_t> m_lane_description_offsets;
|
util::vector_view<std::uint32_t> m_lane_description_offsets;
|
||||||
@@ -183,6 +184,8 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
|
|
||||||
m_check_sum = *index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum");
|
m_check_sum = *index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum");
|
||||||
|
|
||||||
|
m_data_timestamp = make_timestamp_view(index, "/common/timestamp");
|
||||||
|
|
||||||
std::tie(m_coordinate_list, m_osmnodeid_list) =
|
std::tie(m_coordinate_list, m_osmnodeid_list) =
|
||||||
make_nbn_data_view(index, "/common/nbn_data");
|
make_nbn_data_view(index, "/common/nbn_data");
|
||||||
|
|
||||||
@@ -312,12 +315,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
std::vector<PhantomNodeWithDistance>
|
std::vector<PhantomNodeWithDistance>
|
||||||
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
|
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
|
||||||
const float max_distance,
|
const float max_distance,
|
||||||
const Approach approach) const override final
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const override final
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(m_geospatial_query.get());
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
|
||||||
return m_geospatial_query->NearestPhantomNodesInRange(
|
return m_geospatial_query->NearestPhantomNodesInRange(
|
||||||
input_coordinate, max_distance, approach);
|
input_coordinate, max_distance, approach, use_all_edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PhantomNodeWithDistance>
|
std::vector<PhantomNodeWithDistance>
|
||||||
@@ -325,12 +329,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
const float max_distance,
|
const float max_distance,
|
||||||
const int bearing,
|
const int bearing,
|
||||||
const int bearing_range,
|
const int bearing_range,
|
||||||
const Approach approach) const override final
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const override final
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(m_geospatial_query.get());
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
|
||||||
return m_geospatial_query->NearestPhantomNodesInRange(
|
return m_geospatial_query->NearestPhantomNodesInRange(
|
||||||
input_coordinate, max_distance, bearing, bearing_range, approach);
|
input_coordinate, max_distance, bearing, bearing_range, approach, use_all_edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PhantomNodeWithDistance>
|
std::vector<PhantomNodeWithDistance>
|
||||||
@@ -384,23 +389,25 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode>
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||||
const Approach approach) const override final
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const override final
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(m_geospatial_query.get());
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
|
||||||
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
|
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
input_coordinate, approach);
|
input_coordinate, approach, use_all_edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode>
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||||
const double max_distance,
|
const double max_distance,
|
||||||
const Approach approach) const override final
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const override final
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(m_geospatial_query.get());
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
|
||||||
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
|
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
input_coordinate, max_distance, approach);
|
input_coordinate, max_distance, approach, use_all_edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode>
|
||||||
@@ -408,28 +415,35 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
const double max_distance,
|
const double max_distance,
|
||||||
const int bearing,
|
const int bearing,
|
||||||
const int bearing_range,
|
const int bearing_range,
|
||||||
const Approach approach) const override final
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const override final
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(m_geospatial_query.get());
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
|
||||||
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
|
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
input_coordinate, max_distance, bearing, bearing_range, approach);
|
input_coordinate, max_distance, bearing, bearing_range, approach, use_all_edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode>
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||||
const int bearing,
|
const int bearing,
|
||||||
const int bearing_range,
|
const int bearing_range,
|
||||||
const Approach approach) const override final
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const override final
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(m_geospatial_query.get());
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
|
||||||
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
|
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
input_coordinate, bearing, bearing_range, approach);
|
input_coordinate, bearing, bearing_range, approach, use_all_edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t GetCheckSum() const override final { return m_check_sum; }
|
std::uint32_t GetCheckSum() const override final { return m_check_sum; }
|
||||||
|
|
||||||
|
std::string GetTimestamp() const override final
|
||||||
|
{
|
||||||
|
return std::string(m_data_timestamp.begin(), m_data_timestamp.end());
|
||||||
|
}
|
||||||
|
|
||||||
GeometryID GetGeometryIndex(const NodeID id) const override final
|
GeometryID GetGeometryIndex(const NodeID id) const override final
|
||||||
{
|
{
|
||||||
return edge_based_node_data.GetGeometryID(id);
|
return edge_based_node_data.GetGeometryID(id);
|
||||||
@@ -697,6 +711,11 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
|
|||||||
return query_graph.GetNodeDuration(node);
|
return query_graph.GetNodeDuration(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EdgeDistance GetNodeDistance(const NodeID node) const override final
|
||||||
|
{
|
||||||
|
return query_graph.GetNodeDistance(node);
|
||||||
|
}
|
||||||
|
|
||||||
bool IsForwardEdge(const NodeID node) const override final
|
bool IsForwardEdge(const NodeID node) const override final
|
||||||
{
|
{
|
||||||
return query_graph.IsForwardEdge(node);
|
return query_graph.IsForwardEdge(node);
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ class BaseDataFacade
|
|||||||
|
|
||||||
virtual std::uint32_t GetCheckSum() const = 0;
|
virtual std::uint32_t GetCheckSum() const = 0;
|
||||||
|
|
||||||
|
virtual std::string GetTimestamp() const = 0;
|
||||||
|
|
||||||
// node and edge information access
|
// node and edge information access
|
||||||
virtual util::Coordinate GetCoordinateOfNode(const NodeID id) const = 0;
|
virtual util::Coordinate GetCoordinateOfNode(const NodeID id) const = 0;
|
||||||
|
|
||||||
@@ -126,11 +128,13 @@ class BaseDataFacade
|
|||||||
const float max_distance,
|
const float max_distance,
|
||||||
const int bearing,
|
const int bearing,
|
||||||
const int bearing_range,
|
const int bearing_range,
|
||||||
const Approach approach) const = 0;
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const = 0;
|
||||||
virtual std::vector<PhantomNodeWithDistance>
|
virtual std::vector<PhantomNodeWithDistance>
|
||||||
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
|
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
|
||||||
const float max_distance,
|
const float max_distance,
|
||||||
const Approach approach) const = 0;
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const = 0;
|
||||||
|
|
||||||
virtual std::vector<PhantomNodeWithDistance>
|
virtual std::vector<PhantomNodeWithDistance>
|
||||||
NearestPhantomNodes(const util::Coordinate input_coordinate,
|
NearestPhantomNodes(const util::Coordinate input_coordinate,
|
||||||
@@ -157,22 +161,26 @@ class BaseDataFacade
|
|||||||
|
|
||||||
virtual std::pair<PhantomNode, PhantomNode>
|
virtual std::pair<PhantomNode, PhantomNode>
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||||
const Approach approach) const = 0;
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const = 0;
|
||||||
virtual std::pair<PhantomNode, PhantomNode>
|
virtual std::pair<PhantomNode, PhantomNode>
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||||
const double max_distance,
|
const double max_distance,
|
||||||
const Approach approach) const = 0;
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const = 0;
|
||||||
virtual std::pair<PhantomNode, PhantomNode>
|
virtual std::pair<PhantomNode, PhantomNode>
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||||
const double max_distance,
|
const double max_distance,
|
||||||
const int bearing,
|
const int bearing,
|
||||||
const int bearing_range,
|
const int bearing_range,
|
||||||
const Approach approach) const = 0;
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const = 0;
|
||||||
virtual std::pair<PhantomNode, PhantomNode>
|
virtual std::pair<PhantomNode, PhantomNode>
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||||
const int bearing,
|
const int bearing,
|
||||||
const int bearing_range,
|
const int bearing_range,
|
||||||
const Approach approach) const = 0;
|
const Approach approach,
|
||||||
|
const bool use_all_edges = false) const = 0;
|
||||||
|
|
||||||
virtual bool HasLaneData(const EdgeID id) const = 0;
|
virtual bool HasLaneData(const EdgeID id) const = 0;
|
||||||
virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0;
|
virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <boost/iostreams/device/mapped_file.hpp>
|
#include <boost/iostreams/device/mapped_file.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
@@ -24,8 +25,7 @@ namespace datafacade
|
|||||||
class MMapMemoryAllocator : public ContiguousBlockAllocator
|
class MMapMemoryAllocator : public ContiguousBlockAllocator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit MMapMemoryAllocator(const storage::StorageConfig &config,
|
explicit MMapMemoryAllocator(const storage::StorageConfig &config);
|
||||||
const boost::filesystem::path &memory_file);
|
|
||||||
~MMapMemoryAllocator() override final;
|
~MMapMemoryAllocator() override final;
|
||||||
|
|
||||||
// interface to give access to the datafacades
|
// interface to give access to the datafacades
|
||||||
@@ -33,8 +33,8 @@ class MMapMemoryAllocator : public ContiguousBlockAllocator
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
storage::SharedDataIndex index;
|
storage::SharedDataIndex index;
|
||||||
util::vector_view<char> mapped_memory;
|
std::vector<boost::iostreams::mapped_file> mapped_memory_files;
|
||||||
boost::iostreams::mapped_file mapped_memory_file;
|
std::string rtree_filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace datafacade
|
} // namespace datafacade
|
||||||
|
|||||||
@@ -32,9 +32,8 @@ class ExternalProvider final : public DataFacadeProvider<AlgorithmT, FacadeT>
|
|||||||
public:
|
public:
|
||||||
using Facade = typename DataFacadeProvider<AlgorithmT, FacadeT>::Facade;
|
using Facade = typename DataFacadeProvider<AlgorithmT, FacadeT>::Facade;
|
||||||
|
|
||||||
ExternalProvider(const storage::StorageConfig &config,
|
ExternalProvider(const storage::StorageConfig &config)
|
||||||
const boost::filesystem::path &memory_file)
|
: facade_factory(std::make_shared<datafacade::MMapMemoryAllocator>(config))
|
||||||
: facade_factory(std::make_shared<datafacade::MMapMemoryAllocator>(config, memory_file))
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,12 +63,16 @@ template <typename Algorithm> class Engine final : public EngineInterface
|
|||||||
<< "\" with algorithm " << routing_algorithms::name<Algorithm>();
|
<< "\" with algorithm " << routing_algorithms::name<Algorithm>();
|
||||||
facade_provider = std::make_unique<WatchingProvider<Algorithm>>(config.dataset_name);
|
facade_provider = std::make_unique<WatchingProvider<Algorithm>>(config.dataset_name);
|
||||||
}
|
}
|
||||||
else if (!config.memory_file.empty())
|
else if (!config.memory_file.empty() || config.use_mmap)
|
||||||
{
|
{
|
||||||
util::Log(logDEBUG) << "Using memory mapped filed at " << config.memory_file
|
if (!config.memory_file.empty())
|
||||||
<< " with algorithm " << routing_algorithms::name<Algorithm>();
|
{
|
||||||
facade_provider = std::make_unique<ExternalProvider<Algorithm>>(config.storage_config,
|
util::Log(logWARNING)
|
||||||
config.memory_file);
|
<< "The 'memory_file' option is DEPRECATED - using direct mmaping instead";
|
||||||
|
}
|
||||||
|
util::Log(logDEBUG) << "Using direct memory mapping with algorithm "
|
||||||
|
<< routing_algorithms::name<Algorithm>();
|
||||||
|
facade_provider = std::make_unique<ExternalProvider<Algorithm>>(config.storage_config);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ struct EngineConfig final
|
|||||||
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
|
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
|
||||||
bool use_shared_memory = true;
|
bool use_shared_memory = true;
|
||||||
boost::filesystem::path memory_file;
|
boost::filesystem::path memory_file;
|
||||||
|
bool use_mmap = true;
|
||||||
Algorithm algorithm = Algorithm::CH;
|
Algorithm algorithm = Algorithm::CH;
|
||||||
std::string verbosity;
|
std::string verbosity;
|
||||||
std::string dataset_name;
|
std::string dataset_name;
|
||||||
|
|||||||
@@ -53,13 +53,15 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
std::vector<PhantomNodeWithDistance>
|
std::vector<PhantomNodeWithDistance>
|
||||||
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
|
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
|
||||||
const double max_distance,
|
const double max_distance,
|
||||||
const Approach approach) const
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const
|
||||||
{
|
{
|
||||||
auto results = rtree.Nearest(
|
auto results = rtree.Nearest(
|
||||||
input_coordinate,
|
input_coordinate,
|
||||||
[this, approach, &input_coordinate](const CandidateSegment &segment) {
|
[this, approach, &input_coordinate, use_all_edges](const CandidateSegment &segment) {
|
||||||
return boolPairAnd(boolPairAnd(HasValidEdge(segment), CheckSegmentExclude(segment)),
|
return boolPairAnd(
|
||||||
CheckApproach(input_coordinate, segment, approach));
|
boolPairAnd(HasValidEdge(segment, use_all_edges), CheckSegmentExclude(segment)),
|
||||||
|
CheckApproach(input_coordinate, segment, approach));
|
||||||
},
|
},
|
||||||
[this, max_distance, input_coordinate](const std::size_t,
|
[this, max_distance, input_coordinate](const std::size_t,
|
||||||
const CandidateSegment &segment) {
|
const CandidateSegment &segment) {
|
||||||
@@ -76,15 +78,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
const double max_distance,
|
const double max_distance,
|
||||||
const int bearing,
|
const int bearing,
|
||||||
const int bearing_range,
|
const int bearing_range,
|
||||||
const Approach approach) const
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const
|
||||||
{
|
{
|
||||||
auto results = rtree.Nearest(
|
auto results = rtree.Nearest(
|
||||||
input_coordinate,
|
input_coordinate,
|
||||||
[this, approach, &input_coordinate, bearing, bearing_range](
|
[this, approach, &input_coordinate, bearing, bearing_range, use_all_edges](
|
||||||
const CandidateSegment &segment) {
|
const CandidateSegment &segment) {
|
||||||
auto use_direction =
|
auto use_direction =
|
||||||
boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
|
boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
|
||||||
boolPairAnd(HasValidEdge(segment), CheckSegmentExclude(segment)));
|
boolPairAnd(HasValidEdge(segment, use_all_edges),
|
||||||
|
CheckSegmentExclude(segment)));
|
||||||
use_direction =
|
use_direction =
|
||||||
boolPairAnd(use_direction, CheckApproach(input_coordinate, segment, approach));
|
boolPairAnd(use_direction, CheckApproach(input_coordinate, segment, approach));
|
||||||
return use_direction;
|
return use_direction;
|
||||||
@@ -201,18 +205,23 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode>
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||||
const double max_distance,
|
const double max_distance,
|
||||||
const Approach approach) const
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const
|
||||||
{
|
{
|
||||||
bool has_small_component = false;
|
bool has_small_component = false;
|
||||||
bool has_big_component = false;
|
bool has_big_component = false;
|
||||||
auto results = rtree.Nearest(
|
auto results = rtree.Nearest(
|
||||||
input_coordinate,
|
input_coordinate,
|
||||||
[this, approach, &input_coordinate, &has_big_component, &has_small_component](
|
[this,
|
||||||
const CandidateSegment &segment) {
|
approach,
|
||||||
|
&input_coordinate,
|
||||||
|
&has_big_component,
|
||||||
|
&has_small_component,
|
||||||
|
&use_all_edges](const CandidateSegment &segment) {
|
||||||
auto use_segment =
|
auto use_segment =
|
||||||
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
|
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
|
||||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||||
const auto valid_edges = HasValidEdge(segment);
|
const auto valid_edges = HasValidEdge(segment, use_all_edges);
|
||||||
const auto admissible_segments = CheckSegmentExclude(segment);
|
const auto admissible_segments = CheckSegmentExclude(segment);
|
||||||
use_directions = boolPairAnd(use_directions, admissible_segments);
|
use_directions = boolPairAnd(use_directions, admissible_segments);
|
||||||
use_directions = boolPairAnd(use_directions, valid_edges);
|
use_directions = boolPairAnd(use_directions, valid_edges);
|
||||||
@@ -247,19 +256,24 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
// a second phantom node is return that is the nearest coordinate in a big component.
|
// a second phantom node is return that is the nearest coordinate in a big component.
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode>
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||||
const Approach approach) const
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const
|
||||||
{
|
{
|
||||||
bool has_small_component = false;
|
bool has_small_component = false;
|
||||||
bool has_big_component = false;
|
bool has_big_component = false;
|
||||||
auto results = rtree.Nearest(
|
auto results = rtree.Nearest(
|
||||||
input_coordinate,
|
input_coordinate,
|
||||||
[this, approach, &input_coordinate, &has_big_component, &has_small_component](
|
[this,
|
||||||
const CandidateSegment &segment) {
|
approach,
|
||||||
|
&input_coordinate,
|
||||||
|
&has_big_component,
|
||||||
|
&has_small_component,
|
||||||
|
&use_all_edges](const CandidateSegment &segment) {
|
||||||
auto use_segment =
|
auto use_segment =
|
||||||
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
|
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
|
||||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||||
|
|
||||||
const auto valid_edges = HasValidEdge(segment);
|
const auto valid_edges = HasValidEdge(segment, use_all_edges);
|
||||||
const auto admissible_segments = CheckSegmentExclude(segment);
|
const auto admissible_segments = CheckSegmentExclude(segment);
|
||||||
use_directions = boolPairAnd(use_directions, admissible_segments);
|
use_directions = boolPairAnd(use_directions, admissible_segments);
|
||||||
use_directions = boolPairAnd(use_directions, valid_edges);
|
use_directions = boolPairAnd(use_directions, valid_edges);
|
||||||
@@ -294,7 +308,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
||||||
const int bearing,
|
const int bearing,
|
||||||
const int bearing_range,
|
const int bearing_range,
|
||||||
const Approach approach) const
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const
|
||||||
{
|
{
|
||||||
bool has_small_component = false;
|
bool has_small_component = false;
|
||||||
bool has_big_component = false;
|
bool has_big_component = false;
|
||||||
@@ -306,12 +321,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
bearing,
|
bearing,
|
||||||
bearing_range,
|
bearing_range,
|
||||||
&has_big_component,
|
&has_big_component,
|
||||||
&has_small_component](const CandidateSegment &segment) {
|
&has_small_component,
|
||||||
|
&use_all_edges](const CandidateSegment &segment) {
|
||||||
auto use_segment =
|
auto use_segment =
|
||||||
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
|
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
|
||||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||||
const auto admissible_segments = CheckSegmentExclude(segment);
|
const auto admissible_segments = CheckSegmentExclude(segment);
|
||||||
use_directions = boolPairAnd(use_directions, HasValidEdge(segment));
|
use_directions = boolPairAnd(use_directions, HasValidEdge(segment, use_all_edges));
|
||||||
|
|
||||||
if (use_segment)
|
if (use_segment)
|
||||||
{
|
{
|
||||||
@@ -352,7 +368,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
const double max_distance,
|
const double max_distance,
|
||||||
const int bearing,
|
const int bearing,
|
||||||
const int bearing_range,
|
const int bearing_range,
|
||||||
const Approach approach) const
|
const Approach approach,
|
||||||
|
const bool use_all_edges) const
|
||||||
{
|
{
|
||||||
bool has_small_component = false;
|
bool has_small_component = false;
|
||||||
bool has_big_component = false;
|
bool has_big_component = false;
|
||||||
@@ -364,12 +381,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
bearing,
|
bearing,
|
||||||
bearing_range,
|
bearing_range,
|
||||||
&has_big_component,
|
&has_big_component,
|
||||||
&has_small_component](const CandidateSegment &segment) {
|
&has_small_component,
|
||||||
|
&use_all_edges](const CandidateSegment &segment) {
|
||||||
auto use_segment =
|
auto use_segment =
|
||||||
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
|
(!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
|
||||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||||
const auto admissible_segments = CheckSegmentExclude(segment);
|
const auto admissible_segments = CheckSegmentExclude(segment);
|
||||||
use_directions = boolPairAnd(use_directions, HasValidEdge(segment));
|
use_directions = boolPairAnd(use_directions, HasValidEdge(segment, use_all_edges));
|
||||||
|
|
||||||
if (use_segment)
|
if (use_segment)
|
||||||
{
|
{
|
||||||
@@ -461,6 +479,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
EdgeDuration{0});
|
EdgeDuration{0});
|
||||||
|
|
||||||
EdgeDistance forward_distance_offset = 0;
|
EdgeDistance forward_distance_offset = 0;
|
||||||
|
// Sum up the distance from the start to the fwd_segment_position
|
||||||
for (auto current = forward_geometry.begin();
|
for (auto current = forward_geometry.begin();
|
||||||
current < forward_geometry.begin() + data.fwd_segment_position;
|
current < forward_geometry.begin() + data.fwd_segment_position;
|
||||||
++current)
|
++current)
|
||||||
@@ -490,8 +509,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
EdgeDuration{0});
|
EdgeDuration{0});
|
||||||
|
|
||||||
EdgeDistance reverse_distance_offset = 0;
|
EdgeDistance reverse_distance_offset = 0;
|
||||||
for (auto current = forward_geometry.begin();
|
// Sum up the distance from just after the fwd_segment_position to the end
|
||||||
current < forward_geometry.end() - data.fwd_segment_position - 2;
|
for (auto current = forward_geometry.begin() + data.fwd_segment_position + 1;
|
||||||
|
current != std::prev(forward_geometry.end());
|
||||||
++current)
|
++current)
|
||||||
{
|
{
|
||||||
reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance(
|
reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance(
|
||||||
@@ -628,7 +648,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
* which means that this edge is not currently traversible. If this is the case,
|
* which means that this edge is not currently traversible. If this is the case,
|
||||||
* then we shouldn't snap to this edge.
|
* then we shouldn't snap to this edge.
|
||||||
*/
|
*/
|
||||||
std::pair<bool, bool> HasValidEdge(const CandidateSegment &segment) const
|
std::pair<bool, bool> HasValidEdge(const CandidateSegment &segment,
|
||||||
|
const bool use_all_edges = false) const
|
||||||
{
|
{
|
||||||
|
|
||||||
bool forward_edge_valid = false;
|
bool forward_edge_valid = false;
|
||||||
@@ -652,6 +673,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
reverse_edge_valid = data.reverse_segment_id.enabled;
|
reverse_edge_valid = data.reverse_segment_id.enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forward_edge_valid = forward_edge_valid && (data.is_startpoint || use_all_edges);
|
||||||
|
reverse_edge_valid = reverse_edge_valid && (data.is_startpoint || use_all_edges);
|
||||||
|
|
||||||
return std::make_pair(forward_edge_valid, reverse_edge_valid);
|
return std::make_pair(forward_edge_valid, reverse_edge_valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -138,7 +138,8 @@ class BasePlugin
|
|||||||
std::vector<std::vector<PhantomNodeWithDistance>>
|
std::vector<std::vector<PhantomNodeWithDistance>>
|
||||||
GetPhantomNodesInRange(const datafacade::BaseDataFacade &facade,
|
GetPhantomNodesInRange(const datafacade::BaseDataFacade &facade,
|
||||||
const api::BaseParameters ¶meters,
|
const api::BaseParameters ¶meters,
|
||||||
const std::vector<double> radiuses) const
|
const std::vector<double> radiuses,
|
||||||
|
bool use_all_edges = false) const
|
||||||
{
|
{
|
||||||
std::vector<std::vector<PhantomNodeWithDistance>> phantom_nodes(
|
std::vector<std::vector<PhantomNodeWithDistance>> phantom_nodes(
|
||||||
parameters.coordinates.size());
|
parameters.coordinates.size());
|
||||||
@@ -171,12 +172,13 @@ class BasePlugin
|
|||||||
radiuses[i],
|
radiuses[i],
|
||||||
parameters.bearings[i]->bearing,
|
parameters.bearings[i]->bearing,
|
||||||
parameters.bearings[i]->range,
|
parameters.bearings[i]->range,
|
||||||
approach);
|
approach,
|
||||||
|
use_all_edges);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
phantom_nodes[i] = facade.NearestPhantomNodesInRange(
|
phantom_nodes[i] = facade.NearestPhantomNodesInRange(
|
||||||
parameters.coordinates[i], radiuses[i], approach);
|
parameters.coordinates[i], radiuses[i], approach, use_all_edges);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,6 +270,7 @@ class BasePlugin
|
|||||||
const bool use_bearings = !parameters.bearings.empty();
|
const bool use_bearings = !parameters.bearings.empty();
|
||||||
const bool use_radiuses = !parameters.radiuses.empty();
|
const bool use_radiuses = !parameters.radiuses.empty();
|
||||||
const bool use_approaches = !parameters.approaches.empty();
|
const bool use_approaches = !parameters.approaches.empty();
|
||||||
|
const bool use_all_edges = parameters.snapping == api::BaseParameters::SnappingType::Any;
|
||||||
|
|
||||||
BOOST_ASSERT(parameters.IsValid());
|
BOOST_ASSERT(parameters.IsValid());
|
||||||
for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
|
for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
|
||||||
@@ -294,7 +297,8 @@ class BasePlugin
|
|||||||
*parameters.radiuses[i],
|
*parameters.radiuses[i],
|
||||||
parameters.bearings[i]->bearing,
|
parameters.bearings[i]->bearing,
|
||||||
parameters.bearings[i]->range,
|
parameters.bearings[i]->range,
|
||||||
approach);
|
approach,
|
||||||
|
use_all_edges);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -303,7 +307,8 @@ class BasePlugin
|
|||||||
parameters.coordinates[i],
|
parameters.coordinates[i],
|
||||||
parameters.bearings[i]->bearing,
|
parameters.bearings[i]->bearing,
|
||||||
parameters.bearings[i]->range,
|
parameters.bearings[i]->range,
|
||||||
approach);
|
approach,
|
||||||
|
use_all_edges);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -312,13 +317,16 @@ class BasePlugin
|
|||||||
{
|
{
|
||||||
phantom_node_pairs[i] =
|
phantom_node_pairs[i] =
|
||||||
facade.NearestPhantomNodeWithAlternativeFromBigComponent(
|
facade.NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
parameters.coordinates[i], *parameters.radiuses[i], approach);
|
parameters.coordinates[i],
|
||||||
|
*parameters.radiuses[i],
|
||||||
|
approach,
|
||||||
|
use_all_edges);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
phantom_node_pairs[i] =
|
phantom_node_pairs[i] =
|
||||||
facade.NearestPhantomNodeWithAlternativeFromBigComponent(
|
facade.NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
parameters.coordinates[i], approach);
|
parameters.coordinates[i], approach, use_all_edges);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ class RoutingAlgorithmsInterface
|
|||||||
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
||||||
const std::vector<std::size_t> &source_indices,
|
const std::vector<std::size_t> &source_indices,
|
||||||
const std::vector<std::size_t> &target_indices,
|
const std::vector<std::size_t> &target_indices,
|
||||||
const bool calculate_distance,
|
const bool calculate_distance) const = 0;
|
||||||
const bool calculate_duration) const = 0;
|
|
||||||
|
|
||||||
virtual routing_algorithms::SubMatchingList
|
virtual routing_algorithms::SubMatchingList
|
||||||
MapMatching(const routing_algorithms::CandidateLists &candidates_list,
|
MapMatching(const routing_algorithms::CandidateLists &candidates_list,
|
||||||
@@ -88,8 +87,7 @@ template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgo
|
|||||||
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
||||||
const std::vector<std::size_t> &source_indices,
|
const std::vector<std::size_t> &source_indices,
|
||||||
const std::vector<std::size_t> &target_indices,
|
const std::vector<std::size_t> &target_indices,
|
||||||
const bool calculate_distance,
|
const bool calculate_distance) const final override;
|
||||||
const bool calculate_duration) const final override;
|
|
||||||
|
|
||||||
routing_algorithms::SubMatchingList
|
routing_algorithms::SubMatchingList
|
||||||
MapMatching(const routing_algorithms::CandidateLists &candidates_list,
|
MapMatching(const routing_algorithms::CandidateLists &candidates_list,
|
||||||
@@ -198,8 +196,7 @@ std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>>
|
|||||||
RoutingAlgorithms<Algorithm>::ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
RoutingAlgorithms<Algorithm>::ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
||||||
const std::vector<std::size_t> &_source_indices,
|
const std::vector<std::size_t> &_source_indices,
|
||||||
const std::vector<std::size_t> &_target_indices,
|
const std::vector<std::size_t> &_target_indices,
|
||||||
const bool calculate_distance,
|
const bool calculate_distance) const
|
||||||
const bool calculate_duration) const
|
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!phantom_nodes.empty());
|
BOOST_ASSERT(!phantom_nodes.empty());
|
||||||
|
|
||||||
@@ -222,8 +219,7 @@ RoutingAlgorithms<Algorithm>::ManyToManySearch(const std::vector<PhantomNode> &p
|
|||||||
phantom_nodes,
|
phantom_nodes,
|
||||||
std::move(source_indices),
|
std::move(source_indices),
|
||||||
std::move(target_indices),
|
std::move(target_indices),
|
||||||
calculate_distance,
|
calculate_distance);
|
||||||
calculate_duration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Algorithm>
|
template <typename Algorithm>
|
||||||
|
|||||||
@@ -25,15 +25,17 @@ struct NodeBucket
|
|||||||
unsigned from_clique_arc : 1;
|
unsigned from_clique_arc : 1;
|
||||||
EdgeWeight weight;
|
EdgeWeight weight;
|
||||||
EdgeDuration duration;
|
EdgeDuration duration;
|
||||||
|
EdgeDistance distance;
|
||||||
|
|
||||||
NodeBucket(NodeID middle_node,
|
NodeBucket(NodeID middle_node,
|
||||||
NodeID parent_node,
|
NodeID parent_node,
|
||||||
bool from_clique_arc,
|
bool from_clique_arc,
|
||||||
unsigned column_index,
|
unsigned column_index,
|
||||||
EdgeWeight weight,
|
EdgeWeight weight,
|
||||||
EdgeDuration duration)
|
EdgeDuration duration,
|
||||||
|
EdgeDistance distance)
|
||||||
: middle_node(middle_node), parent_node(parent_node), column_index(column_index),
|
: middle_node(middle_node), parent_node(parent_node), column_index(column_index),
|
||||||
from_clique_arc(from_clique_arc), weight(weight), duration(duration)
|
from_clique_arc(from_clique_arc), weight(weight), duration(duration), distance(distance)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,9 +43,10 @@ struct NodeBucket
|
|||||||
NodeID parent_node,
|
NodeID parent_node,
|
||||||
unsigned column_index,
|
unsigned column_index,
|
||||||
EdgeWeight weight,
|
EdgeWeight weight,
|
||||||
EdgeDuration duration)
|
EdgeDuration duration,
|
||||||
|
EdgeDistance distance)
|
||||||
: middle_node(middle_node), parent_node(parent_node), column_index(column_index),
|
: middle_node(middle_node), parent_node(parent_node), column_index(column_index),
|
||||||
from_clique_arc(false), weight(weight), duration(duration)
|
from_clique_arc(false), weight(weight), duration(duration), distance(distance)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,8 +97,7 @@ manyToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
const std::vector<PhantomNode> &phantom_nodes,
|
const std::vector<PhantomNode> &phantom_nodes,
|
||||||
const std::vector<std::size_t> &source_indices,
|
const std::vector<std::size_t> &source_indices,
|
||||||
const std::vector<std::size_t> &target_indices,
|
const std::vector<std::size_t> &target_indices,
|
||||||
const bool calculate_distance,
|
const bool calculate_distance);
|
||||||
const bool calculate_duration);
|
|
||||||
|
|
||||||
} // namespace routing_algorithms
|
} // namespace routing_algorithms
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
|
|||||||
@@ -85,13 +85,17 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
|||||||
{
|
{
|
||||||
heap.Insert(phantom_node.forward_segment_id.id,
|
heap.Insert(phantom_node.forward_segment_id.id,
|
||||||
-phantom_node.GetForwardWeightPlusOffset(),
|
-phantom_node.GetForwardWeightPlusOffset(),
|
||||||
{phantom_node.forward_segment_id.id, -phantom_node.GetForwardDuration()});
|
{phantom_node.forward_segment_id.id,
|
||||||
|
-phantom_node.GetForwardDuration(),
|
||||||
|
-phantom_node.GetForwardDistance()});
|
||||||
}
|
}
|
||||||
if (phantom_node.IsValidReverseSource())
|
if (phantom_node.IsValidReverseSource())
|
||||||
{
|
{
|
||||||
heap.Insert(phantom_node.reverse_segment_id.id,
|
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||||
-phantom_node.GetReverseWeightPlusOffset(),
|
-phantom_node.GetReverseWeightPlusOffset(),
|
||||||
{phantom_node.reverse_segment_id.id, -phantom_node.GetReverseDuration()});
|
{phantom_node.reverse_segment_id.id,
|
||||||
|
-phantom_node.GetReverseDuration(),
|
||||||
|
-phantom_node.GetReverseDistance()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,13 +106,17 @@ void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
|||||||
{
|
{
|
||||||
heap.Insert(phantom_node.forward_segment_id.id,
|
heap.Insert(phantom_node.forward_segment_id.id,
|
||||||
phantom_node.GetForwardWeightPlusOffset(),
|
phantom_node.GetForwardWeightPlusOffset(),
|
||||||
{phantom_node.forward_segment_id.id, phantom_node.GetForwardDuration()});
|
{phantom_node.forward_segment_id.id,
|
||||||
|
phantom_node.GetForwardDuration(),
|
||||||
|
phantom_node.GetForwardDistance()});
|
||||||
}
|
}
|
||||||
if (phantom_node.IsValidReverseTarget())
|
if (phantom_node.IsValidReverseTarget())
|
||||||
{
|
{
|
||||||
heap.Insert(phantom_node.reverse_segment_id.id,
|
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||||
phantom_node.GetReverseWeightPlusOffset(),
|
phantom_node.GetReverseWeightPlusOffset(),
|
||||||
{phantom_node.reverse_segment_id.id, phantom_node.GetReverseDuration()});
|
{phantom_node.reverse_segment_id.id,
|
||||||
|
phantom_node.GetReverseDuration(),
|
||||||
|
phantom_node.GetReverseDistance()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -186,9 +186,10 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <bool UseDuration>
|
template <bool UseDuration>
|
||||||
EdgeWeight getLoopWeight(const DataFacade<Algorithm> &facade, NodeID node)
|
std::tuple<EdgeWeight, EdgeDistance> getLoopWeight(const DataFacade<Algorithm> &facade, NodeID node)
|
||||||
{
|
{
|
||||||
EdgeWeight loop_weight = UseDuration ? MAXIMAL_EDGE_DURATION : INVALID_EDGE_WEIGHT;
|
EdgeWeight loop_weight = UseDuration ? MAXIMAL_EDGE_DURATION : INVALID_EDGE_WEIGHT;
|
||||||
|
EdgeDistance loop_distance = MAXIMAL_EDGE_DISTANCE;
|
||||||
for (auto edge : facade.GetAdjacentEdgeRange(node))
|
for (auto edge : facade.GetAdjacentEdgeRange(node))
|
||||||
{
|
{
|
||||||
const auto &data = facade.GetEdgeData(edge);
|
const auto &data = facade.GetEdgeData(edge);
|
||||||
@@ -198,11 +199,15 @@ EdgeWeight getLoopWeight(const DataFacade<Algorithm> &facade, NodeID node)
|
|||||||
if (to == node)
|
if (to == node)
|
||||||
{
|
{
|
||||||
const auto value = UseDuration ? data.duration : data.weight;
|
const auto value = UseDuration ? data.duration : data.weight;
|
||||||
loop_weight = std::min(loop_weight, value);
|
if (value < loop_weight)
|
||||||
|
{
|
||||||
|
loop_weight = value;
|
||||||
|
loop_distance = data.distance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return loop_weight;
|
return std::make_tuple(loop_weight, loop_distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -509,90 +509,6 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
return std::make_tuple(weight, std::move(unpacked_nodes), std::move(unpacked_edges));
|
return std::make_tuple(weight, std::move(unpacked_nodes), std::move(unpacked_edges));
|
||||||
}
|
}
|
||||||
|
|
||||||
// With (s, middle, t) we trace back the paths middle -> s and middle -> t.
|
|
||||||
// This gives us a packed path (node ids) from the base graph around s and t,
|
|
||||||
// and overlay node ids otherwise. We then have to unpack the overlay clique
|
|
||||||
// edges by recursively descending unpacking the path down to the base graph.
|
|
||||||
|
|
||||||
using UnpackedNodes = std::vector<NodeID>;
|
|
||||||
using UnpackedEdges = std::vector<EdgeID>;
|
|
||||||
using UnpackedPath = std::tuple<EdgeWeight, UnpackedNodes, UnpackedEdges>;
|
|
||||||
|
|
||||||
template <typename Algorithm, typename... Args>
|
|
||||||
UnpackedPath
|
|
||||||
unpackPathAndCalculateDistance(SearchEngineData<Algorithm> &engine_working_data,
|
|
||||||
const DataFacade<Algorithm> &facade,
|
|
||||||
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
|
||||||
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
|
||||||
const bool force_loop_forward,
|
|
||||||
const bool force_loop_reverse,
|
|
||||||
EdgeWeight weight_upper_bound,
|
|
||||||
PackedPath packed_path,
|
|
||||||
NodeID middle,
|
|
||||||
Args... args)
|
|
||||||
{
|
|
||||||
EdgeWeight weight = weight_upper_bound;
|
|
||||||
const auto &partition = facade.GetMultiLevelPartition();
|
|
||||||
const NodeID source_node = !packed_path.empty() ? std::get<0>(packed_path.front()) : middle;
|
|
||||||
|
|
||||||
// Unpack path
|
|
||||||
std::vector<NodeID> unpacked_nodes;
|
|
||||||
std::vector<EdgeID> unpacked_edges;
|
|
||||||
unpacked_nodes.reserve(packed_path.size());
|
|
||||||
unpacked_edges.reserve(packed_path.size());
|
|
||||||
|
|
||||||
unpacked_nodes.push_back(source_node);
|
|
||||||
|
|
||||||
for (auto const &packed_edge : packed_path)
|
|
||||||
{
|
|
||||||
NodeID source, target;
|
|
||||||
bool overlay_edge;
|
|
||||||
std::tie(source, target, overlay_edge) = packed_edge;
|
|
||||||
if (!overlay_edge)
|
|
||||||
{ // a base graph edge
|
|
||||||
unpacked_nodes.push_back(target);
|
|
||||||
unpacked_edges.push_back(facade.FindEdge(source, target));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // an overlay graph edge
|
|
||||||
LevelID level = getNodeQueryLevel(partition, source, args...);
|
|
||||||
CellID parent_cell_id = partition.GetCell(level, source);
|
|
||||||
BOOST_ASSERT(parent_cell_id == partition.GetCell(level, target));
|
|
||||||
|
|
||||||
LevelID sublevel = level - 1;
|
|
||||||
|
|
||||||
// Here heaps can be reused, let's go deeper!
|
|
||||||
forward_heap.Clear();
|
|
||||||
reverse_heap.Clear();
|
|
||||||
forward_heap.Insert(source, 0, {source});
|
|
||||||
reverse_heap.Insert(target, 0, {target});
|
|
||||||
|
|
||||||
// TODO: when structured bindings will be allowed change to
|
|
||||||
// auto [subpath_weight, subpath_source, subpath_target, subpath] = ...
|
|
||||||
EdgeWeight subpath_weight;
|
|
||||||
std::vector<NodeID> subpath_nodes;
|
|
||||||
std::vector<EdgeID> subpath_edges;
|
|
||||||
std::tie(subpath_weight, subpath_nodes, subpath_edges) = search(engine_working_data,
|
|
||||||
facade,
|
|
||||||
forward_heap,
|
|
||||||
reverse_heap,
|
|
||||||
force_loop_forward,
|
|
||||||
force_loop_reverse,
|
|
||||||
weight_upper_bound,
|
|
||||||
sublevel,
|
|
||||||
parent_cell_id);
|
|
||||||
BOOST_ASSERT(!subpath_edges.empty());
|
|
||||||
BOOST_ASSERT(subpath_nodes.size() > 1);
|
|
||||||
BOOST_ASSERT(subpath_nodes.front() == source);
|
|
||||||
BOOST_ASSERT(subpath_nodes.back() == target);
|
|
||||||
unpacked_nodes.insert(
|
|
||||||
unpacked_nodes.end(), std::next(subpath_nodes.begin()), subpath_nodes.end());
|
|
||||||
unpacked_edges.insert(unpacked_edges.end(), subpath_edges.begin(), subpath_edges.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return std::make_tuple(weight, std::move(unpacked_nodes), std::move(unpacked_edges));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alias to be compatible with the CH-based search
|
// Alias to be compatible with the CH-based search
|
||||||
template <typename Algorithm>
|
template <typename Algorithm>
|
||||||
inline void search(SearchEngineData<Algorithm> &engine_working_data,
|
inline void search(SearchEngineData<Algorithm> &engine_working_data,
|
||||||
|
|||||||
@@ -30,7 +30,11 @@ struct HeapData
|
|||||||
struct ManyToManyHeapData : HeapData
|
struct ManyToManyHeapData : HeapData
|
||||||
{
|
{
|
||||||
EdgeWeight duration;
|
EdgeWeight duration;
|
||||||
ManyToManyHeapData(NodeID p, EdgeWeight duration) : HeapData(p), duration(duration) {}
|
EdgeDistance distance;
|
||||||
|
ManyToManyHeapData(NodeID p, EdgeWeight duration, EdgeDistance distance)
|
||||||
|
: HeapData(p), duration(duration), distance(distance)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct SearchEngineData<routing_algorithms::ch::Algorithm>
|
template <> struct SearchEngineData<routing_algorithms::ch::Algorithm>
|
||||||
@@ -75,12 +79,16 @@ struct MultiLayerDijkstraHeapData
|
|||||||
struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData
|
struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData
|
||||||
{
|
{
|
||||||
EdgeWeight duration;
|
EdgeWeight duration;
|
||||||
ManyToManyMultiLayerDijkstraHeapData(NodeID p, EdgeWeight duration)
|
EdgeDistance distance;
|
||||||
: MultiLayerDijkstraHeapData(p), duration(duration)
|
ManyToManyMultiLayerDijkstraHeapData(NodeID p, EdgeWeight duration, EdgeDistance distance)
|
||||||
|
: MultiLayerDijkstraHeapData(p), duration(duration), distance(distance)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
ManyToManyMultiLayerDijkstraHeapData(NodeID p, bool from, EdgeWeight duration)
|
ManyToManyMultiLayerDijkstraHeapData(NodeID p,
|
||||||
: MultiLayerDijkstraHeapData(p, from), duration(duration)
|
bool from,
|
||||||
|
EdgeWeight duration,
|
||||||
|
EdgeDistance distance)
|
||||||
|
: MultiLayerDijkstraHeapData(p, from), duration(duration), distance(distance)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,20 +15,25 @@ struct EdgeBasedEdge
|
|||||||
public:
|
public:
|
||||||
struct EdgeData
|
struct EdgeData
|
||||||
{
|
{
|
||||||
EdgeData() : turn_id(0), weight(0), duration(0), forward(false), backward(false) {}
|
EdgeData()
|
||||||
|
: turn_id(0), weight(0), distance(0), duration(0), forward(false), backward(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
EdgeData(const NodeID turn_id,
|
EdgeData(const NodeID turn_id,
|
||||||
const EdgeWeight weight,
|
const EdgeWeight weight,
|
||||||
|
const EdgeDistance distance,
|
||||||
const EdgeWeight duration,
|
const EdgeWeight duration,
|
||||||
const bool forward,
|
const bool forward,
|
||||||
const bool backward)
|
const bool backward)
|
||||||
: turn_id(turn_id), weight(weight), duration(duration), forward(forward),
|
: turn_id(turn_id), weight(weight), distance(distance), duration(duration),
|
||||||
backward(backward)
|
forward(forward), backward(backward)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeID turn_id; // ID of the edge based node (node based edge)
|
NodeID turn_id; // ID of the edge based node (node based edge)
|
||||||
EdgeWeight weight;
|
EdgeWeight weight;
|
||||||
|
EdgeDistance distance;
|
||||||
EdgeWeight duration : 30;
|
EdgeWeight duration : 30;
|
||||||
std::uint32_t forward : 1;
|
std::uint32_t forward : 1;
|
||||||
std::uint32_t backward : 1;
|
std::uint32_t backward : 1;
|
||||||
@@ -43,6 +48,7 @@ struct EdgeBasedEdge
|
|||||||
const NodeID edge_id,
|
const NodeID edge_id,
|
||||||
const EdgeWeight weight,
|
const EdgeWeight weight,
|
||||||
const EdgeWeight duration,
|
const EdgeWeight duration,
|
||||||
|
const EdgeDistance distance,
|
||||||
const bool forward,
|
const bool forward,
|
||||||
const bool backward);
|
const bool backward);
|
||||||
EdgeBasedEdge(const NodeID source, const NodeID target, const EdgeBasedEdge::EdgeData &data);
|
EdgeBasedEdge(const NodeID source, const NodeID target, const EdgeBasedEdge::EdgeData &data);
|
||||||
@@ -53,7 +59,7 @@ struct EdgeBasedEdge
|
|||||||
NodeID target;
|
NodeID target;
|
||||||
EdgeData data;
|
EdgeData data;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(extractor::EdgeBasedEdge) == 20,
|
static_assert(sizeof(extractor::EdgeBasedEdge) == 24,
|
||||||
"Size of extractor::EdgeBasedEdge type is "
|
"Size of extractor::EdgeBasedEdge type is "
|
||||||
"bigger than expected. This will influence "
|
"bigger than expected. This will influence "
|
||||||
"memory consumption.");
|
"memory consumption.");
|
||||||
@@ -67,9 +73,10 @@ inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
|
|||||||
const NodeID turn_id,
|
const NodeID turn_id,
|
||||||
const EdgeWeight weight,
|
const EdgeWeight weight,
|
||||||
const EdgeWeight duration,
|
const EdgeWeight duration,
|
||||||
|
const EdgeDistance distance,
|
||||||
const bool forward,
|
const bool forward,
|
||||||
const bool backward)
|
const bool backward)
|
||||||
: source(source), target(target), data{turn_id, weight, duration, forward, backward}
|
: source(source), target(target), data{turn_id, weight, distance, duration, forward, backward}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,9 +89,9 @@ class EdgeBasedGraphFactory
|
|||||||
// The following get access functions destroy the content in the factory
|
// The following get access functions destroy the content in the factory
|
||||||
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
|
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
|
||||||
void GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSegment> &nodes);
|
void GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSegment> &nodes);
|
||||||
void GetStartPointMarkers(std::vector<bool> &node_is_startpoint);
|
|
||||||
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
|
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
|
||||||
void GetEdgeBasedNodeDurations(std::vector<EdgeWeight> &output_node_durations);
|
void GetEdgeBasedNodeDurations(std::vector<EdgeWeight> &output_node_durations);
|
||||||
|
void GetEdgeBasedNodeDistances(std::vector<EdgeDistance> &output_node_distances);
|
||||||
std::uint32_t GetConnectivityChecksum() const;
|
std::uint32_t GetConnectivityChecksum() const;
|
||||||
|
|
||||||
std::uint64_t GetNumberOfEdgeBasedNodes() const;
|
std::uint64_t GetNumberOfEdgeBasedNodes() const;
|
||||||
@@ -111,14 +111,11 @@ class EdgeBasedGraphFactory
|
|||||||
std::vector<ConditionalTurnPenalty>
|
std::vector<ConditionalTurnPenalty>
|
||||||
IndexConditionals(std::vector<Conditional> &&conditionals) const;
|
IndexConditionals(std::vector<Conditional> &&conditionals) const;
|
||||||
|
|
||||||
//! maps index from m_edge_based_node_list to ture/false if the node is an entry point to the
|
|
||||||
//! graph
|
|
||||||
std::vector<bool> m_edge_based_node_is_startpoint;
|
|
||||||
|
|
||||||
//! node weights that indicate the length of the segment (node based) represented by the
|
//! node weights that indicate the length of the segment (node based) represented by the
|
||||||
//! edge-based node
|
//! edge-based node
|
||||||
std::vector<EdgeWeight> m_edge_based_node_weights;
|
std::vector<EdgeWeight> m_edge_based_node_weights;
|
||||||
std::vector<EdgeDuration> m_edge_based_node_durations;
|
std::vector<EdgeDuration> m_edge_based_node_durations;
|
||||||
|
std::vector<EdgeDistance> m_edge_based_node_distances;
|
||||||
|
|
||||||
//! list of edge based nodes (compressed segments)
|
//! list of edge based nodes (compressed segments)
|
||||||
std::vector<EdgeBasedNodeSegment> m_edge_based_node_segments;
|
std::vector<EdgeBasedNodeSegment> m_edge_based_node_segments;
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ struct EdgeBasedNodeSegment
|
|||||||
EdgeBasedNodeSegment()
|
EdgeBasedNodeSegment()
|
||||||
: forward_segment_id{SPECIAL_SEGMENTID, false},
|
: forward_segment_id{SPECIAL_SEGMENTID, false},
|
||||||
reverse_segment_id{SPECIAL_SEGMENTID, false}, u(SPECIAL_NODEID), v(SPECIAL_NODEID),
|
reverse_segment_id{SPECIAL_SEGMENTID, false}, u(SPECIAL_NODEID), v(SPECIAL_NODEID),
|
||||||
fwd_segment_position(std::numeric_limits<unsigned short>::max())
|
fwd_segment_position(std::numeric_limits<unsigned short>::max() >>
|
||||||
|
1), // >> 1 because we've only got 15 bits
|
||||||
|
is_startpoint(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,9 +32,10 @@ struct EdgeBasedNodeSegment
|
|||||||
const SegmentID reverse_segment_id_,
|
const SegmentID reverse_segment_id_,
|
||||||
NodeID u,
|
NodeID u,
|
||||||
NodeID v,
|
NodeID v,
|
||||||
unsigned short fwd_segment_position)
|
unsigned short fwd_segment_position,
|
||||||
|
bool is_startpoint_)
|
||||||
: forward_segment_id(forward_segment_id_), reverse_segment_id(reverse_segment_id_), u(u),
|
: forward_segment_id(forward_segment_id_), reverse_segment_id(reverse_segment_id_), u(u),
|
||||||
v(v), fwd_segment_position(fwd_segment_position)
|
v(v), fwd_segment_position(fwd_segment_position), is_startpoint(is_startpoint_)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(forward_segment_id.enabled || reverse_segment_id.enabled);
|
BOOST_ASSERT(forward_segment_id.enabled || reverse_segment_id.enabled);
|
||||||
}
|
}
|
||||||
@@ -41,7 +44,8 @@ struct EdgeBasedNodeSegment
|
|||||||
SegmentID reverse_segment_id; // edge-based graph node ID in reverse direction (v->u if exists)
|
SegmentID reverse_segment_id; // edge-based graph node ID in reverse direction (v->u if exists)
|
||||||
NodeID u; // node-based graph node ID of the start node
|
NodeID u; // node-based graph node ID of the start node
|
||||||
NodeID v; // node-based graph node ID of the target node
|
NodeID v; // node-based graph node ID of the target node
|
||||||
unsigned short fwd_segment_position; // segment id in a compressed geometry
|
unsigned short fwd_segment_position : 15; // segment id in a compressed geometry
|
||||||
|
bool is_startpoint : 1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,9 +85,9 @@ class Extractor
|
|||||||
// output data
|
// output data
|
||||||
EdgeBasedNodeDataContainer &edge_based_nodes_container,
|
EdgeBasedNodeDataContainer &edge_based_nodes_container,
|
||||||
std::vector<EdgeBasedNodeSegment> &edge_based_node_segments,
|
std::vector<EdgeBasedNodeSegment> &edge_based_node_segments,
|
||||||
std::vector<bool> &node_is_startpoint,
|
|
||||||
std::vector<EdgeWeight> &edge_based_node_weights,
|
std::vector<EdgeWeight> &edge_based_node_weights,
|
||||||
std::vector<EdgeDuration> &edge_based_node_durations,
|
std::vector<EdgeDuration> &edge_based_node_durations,
|
||||||
|
std::vector<EdgeDistance> &edge_based_node_distances,
|
||||||
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
||||||
std::uint32_t &connectivity_checksum);
|
std::uint32_t &connectivity_checksum);
|
||||||
|
|
||||||
@@ -96,7 +96,6 @@ class Extractor
|
|||||||
const std::vector<EdgeBasedNodeSegment> &input_node_segments,
|
const std::vector<EdgeBasedNodeSegment> &input_node_segments,
|
||||||
EdgeBasedNodeDataContainer &nodes_container) const;
|
EdgeBasedNodeDataContainer &nodes_container) const;
|
||||||
void BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_segments,
|
void BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_segments,
|
||||||
std::vector<bool> node_is_startpoint,
|
|
||||||
const std::vector<util::Coordinate> &coordinates);
|
const std::vector<util::Coordinate> &coordinates);
|
||||||
std::shared_ptr<RestrictionMap> LoadRestrictionMap();
|
std::shared_ptr<RestrictionMap> LoadRestrictionMap();
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ struct ExtractorConfig final : storage::IOConfig
|
|||||||
".osrm.geometry",
|
".osrm.geometry",
|
||||||
".osrm.nbg_nodes",
|
".osrm.nbg_nodes",
|
||||||
".osrm.ebg_nodes",
|
".osrm.ebg_nodes",
|
||||||
|
".osrm.timestamp",
|
||||||
".osrm.edges",
|
".osrm.edges",
|
||||||
".osrm.ebg",
|
".osrm.ebg",
|
||||||
".osrm.ramIndex",
|
".osrm.ramIndex",
|
||||||
@@ -82,6 +83,7 @@ struct ExtractorConfig final : storage::IOConfig
|
|||||||
boost::filesystem::path input_path;
|
boost::filesystem::path input_path;
|
||||||
boost::filesystem::path profile_path;
|
boost::filesystem::path profile_path;
|
||||||
std::vector<boost::filesystem::path> location_dependent_data_paths;
|
std::vector<boost::filesystem::path> location_dependent_data_paths;
|
||||||
|
std::string data_version;
|
||||||
|
|
||||||
unsigned requested_num_threads;
|
unsigned requested_num_threads;
|
||||||
unsigned small_component_size;
|
unsigned small_component_size;
|
||||||
|
|||||||
@@ -308,6 +308,26 @@ inline void writeTurnLaneData(const boost::filesystem::path &path,
|
|||||||
storage::serialization::write(writer, "/common/turn_lanes/data", turn_lane_data);
|
storage::serialization::write(writer, "/common/turn_lanes/data", turn_lane_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reads .osrm.timestamp
|
||||||
|
template <typename TimestampDataT>
|
||||||
|
inline void readTimestamp(const boost::filesystem::path &path, TimestampDataT ×tamp)
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
|
|
||||||
|
storage::serialization::read(reader, "/common/timestamp", timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// writes .osrm.timestamp
|
||||||
|
template <typename TimestampDataT>
|
||||||
|
inline void writeTimestamp(const boost::filesystem::path &path, const TimestampDataT ×tamp)
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
|
storage::tar::FileWriter writer{path, fingerprint};
|
||||||
|
|
||||||
|
storage::serialization::write(writer, "/common/timestamp", timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
// reads .osrm.maneuver_overrides
|
// reads .osrm.maneuver_overrides
|
||||||
template <typename StorageManeuverOverrideT, typename NodeSequencesT>
|
template <typename StorageManeuverOverrideT, typename NodeSequencesT>
|
||||||
inline void readManeuverOverrides(const boost::filesystem::path &path,
|
inline void readManeuverOverrides(const boost::filesystem::path &path,
|
||||||
@@ -453,8 +473,8 @@ void writeNames(const boost::filesystem::path &path, const NameTableT &table)
|
|||||||
serialization::write(writer, "/common/names", table);
|
serialization::write(writer, "/common/names", table);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeWeigtsVectorT>
|
template <typename NodeWeightsVectorT>
|
||||||
void readEdgeBasedNodeWeights(const boost::filesystem::path &path, NodeWeigtsVectorT &weights)
|
void readEdgeBasedNodeWeights(const boost::filesystem::path &path, NodeWeightsVectorT &weights)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
storage::tar::FileReader reader{path, fingerprint};
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
@@ -462,9 +482,33 @@ void readEdgeBasedNodeWeights(const boost::filesystem::path &path, NodeWeigtsVec
|
|||||||
storage::serialization::read(reader, "/extractor/edge_based_node_weights", weights);
|
storage::serialization::read(reader, "/extractor/edge_based_node_weights", weights);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeWeigtsVectorT, typename NodeDurationsVectorT>
|
template <typename NodeDistancesVectorT>
|
||||||
|
void readEdgeBasedNodeDistances(const boost::filesystem::path &path,
|
||||||
|
NodeDistancesVectorT &distances)
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
|
|
||||||
|
storage::serialization::read(reader, "/extractor/edge_based_node_distances", distances);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename NodeWeightsVectorT, typename NodeDurationsVectorT, typename NodeDistancesVectorT>
|
||||||
|
void writeEdgeBasedNodeWeightsDurationsDistances(const boost::filesystem::path &path,
|
||||||
|
const NodeWeightsVectorT &weights,
|
||||||
|
const NodeDurationsVectorT &durations,
|
||||||
|
const NodeDistancesVectorT &distances)
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
|
storage::tar::FileWriter writer{path, fingerprint};
|
||||||
|
|
||||||
|
storage::serialization::write(writer, "/extractor/edge_based_node_weights", weights);
|
||||||
|
storage::serialization::write(writer, "/extractor/edge_based_node_durations", durations);
|
||||||
|
storage::serialization::write(writer, "/extractor/edge_based_node_distances", distances);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename NodeWeightsVectorT, typename NodeDurationsVectorT>
|
||||||
void readEdgeBasedNodeWeightsDurations(const boost::filesystem::path &path,
|
void readEdgeBasedNodeWeightsDurations(const boost::filesystem::path &path,
|
||||||
NodeWeigtsVectorT &weights,
|
NodeWeightsVectorT &weights,
|
||||||
NodeDurationsVectorT &durations)
|
NodeDurationsVectorT &durations)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
@@ -474,9 +518,9 @@ void readEdgeBasedNodeWeightsDurations(const boost::filesystem::path &path,
|
|||||||
storage::serialization::read(reader, "/extractor/edge_based_node_durations", durations);
|
storage::serialization::read(reader, "/extractor/edge_based_node_durations", durations);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeWeigtsVectorT, typename NodeDurationsVectorT>
|
template <typename NodeWeightsVectorT, typename NodeDurationsVectorT>
|
||||||
void writeEdgeBasedNodeWeightsDurations(const boost::filesystem::path &path,
|
void writeEdgeBasedNodeWeightsDurations(const boost::filesystem::path &path,
|
||||||
const NodeWeigtsVectorT &weights,
|
const NodeWeightsVectorT &weights,
|
||||||
const NodeDurationsVectorT &durations)
|
const NodeDurationsVectorT &durations)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ struct InternalExtractorEdge
|
|||||||
WeightData weight_data,
|
WeightData weight_data,
|
||||||
DurationData duration_data,
|
DurationData duration_data,
|
||||||
util::Coordinate source_coordinate)
|
util::Coordinate source_coordinate)
|
||||||
: result(source, target, 0, 0, {}, -1, {}), weight_data(std::move(weight_data)),
|
: result(source, target, 0, 0, 0, {}, -1, {}), weight_data(std::move(weight_data)),
|
||||||
duration_data(std::move(duration_data)), source_coordinate(std::move(source_coordinate))
|
duration_data(std::move(duration_data)), source_coordinate(std::move(source_coordinate))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ struct NodeBasedEdge
|
|||||||
NodeID target,
|
NodeID target,
|
||||||
EdgeWeight weight,
|
EdgeWeight weight,
|
||||||
EdgeDuration duration,
|
EdgeDuration duration,
|
||||||
|
EdgeDistance distance,
|
||||||
GeometryID geometry_id,
|
GeometryID geometry_id,
|
||||||
AnnotationID annotation_data,
|
AnnotationID annotation_data,
|
||||||
NodeBasedEdgeClassification flags);
|
NodeBasedEdgeClassification flags);
|
||||||
@@ -107,6 +108,7 @@ struct NodeBasedEdge
|
|||||||
NodeID target; // 32 4
|
NodeID target; // 32 4
|
||||||
EdgeWeight weight; // 32 4
|
EdgeWeight weight; // 32 4
|
||||||
EdgeDuration duration; // 32 4
|
EdgeDuration duration; // 32 4
|
||||||
|
EdgeDistance distance; // 32 4
|
||||||
GeometryID geometry_id; // 32 4
|
GeometryID geometry_id; // 32 4
|
||||||
AnnotationID annotation_data; // 32 4
|
AnnotationID annotation_data; // 32 4
|
||||||
NodeBasedEdgeClassification flags; // 32 4
|
NodeBasedEdgeClassification flags; // 32 4
|
||||||
@@ -120,6 +122,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
|||||||
OSMNodeID target,
|
OSMNodeID target,
|
||||||
EdgeWeight weight,
|
EdgeWeight weight,
|
||||||
EdgeDuration duration,
|
EdgeDuration duration,
|
||||||
|
EdgeDistance distance,
|
||||||
GeometryID geometry_id,
|
GeometryID geometry_id,
|
||||||
AnnotationID annotation_data,
|
AnnotationID annotation_data,
|
||||||
NodeBasedEdgeClassification flags);
|
NodeBasedEdgeClassification flags);
|
||||||
@@ -137,7 +140,8 @@ inline NodeBasedEdgeClassification::NodeBasedEdgeClassification()
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline NodeBasedEdge::NodeBasedEdge()
|
inline NodeBasedEdge::NodeBasedEdge()
|
||||||
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), weight(0), duration(0), annotation_data(-1)
|
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), weight(0), duration(0), distance(0),
|
||||||
|
annotation_data(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,11 +149,12 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
|
|||||||
NodeID target,
|
NodeID target,
|
||||||
EdgeWeight weight,
|
EdgeWeight weight,
|
||||||
EdgeDuration duration,
|
EdgeDuration duration,
|
||||||
|
EdgeDistance distance,
|
||||||
GeometryID geometry_id,
|
GeometryID geometry_id,
|
||||||
AnnotationID annotation_data,
|
AnnotationID annotation_data,
|
||||||
NodeBasedEdgeClassification flags)
|
NodeBasedEdgeClassification flags)
|
||||||
: source(source), target(target), weight(weight), duration(duration), geometry_id(geometry_id),
|
: source(source), target(target), weight(weight), duration(duration), distance(distance),
|
||||||
annotation_data(annotation_data), flags(flags)
|
geometry_id(geometry_id), annotation_data(annotation_data), flags(flags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,11 +180,18 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
|
|||||||
OSMNodeID target,
|
OSMNodeID target,
|
||||||
EdgeWeight weight,
|
EdgeWeight weight,
|
||||||
EdgeDuration duration,
|
EdgeDuration duration,
|
||||||
|
EdgeDistance distance,
|
||||||
GeometryID geometry_id,
|
GeometryID geometry_id,
|
||||||
AnnotationID annotation_data,
|
AnnotationID annotation_data,
|
||||||
NodeBasedEdgeClassification flags)
|
NodeBasedEdgeClassification flags)
|
||||||
: NodeBasedEdge(
|
: NodeBasedEdge(SPECIAL_NODEID,
|
||||||
SPECIAL_NODEID, SPECIAL_NODEID, weight, duration, geometry_id, annotation_data, flags),
|
SPECIAL_NODEID,
|
||||||
|
weight,
|
||||||
|
duration,
|
||||||
|
distance,
|
||||||
|
geometry_id,
|
||||||
|
annotation_data,
|
||||||
|
flags),
|
||||||
osm_source_id(std::move(source)), osm_target_id(std::move(target))
|
osm_source_id(std::move(source)), osm_target_id(std::move(target))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -189,7 +201,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert(sizeof(extractor::NodeBasedEdge) == 28,
|
static_assert(sizeof(extractor::NodeBasedEdge) == 32,
|
||||||
"Size of extractor::NodeBasedEdge type is "
|
"Size of extractor::NodeBasedEdge type is "
|
||||||
"bigger than expected. This will influence "
|
"bigger than expected. This will influence "
|
||||||
"memory consumption.");
|
"memory consumption.");
|
||||||
|
|||||||
@@ -142,6 +142,10 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
|
|||||||
if (shared_memory.IsEmpty())
|
if (shared_memory.IsEmpty())
|
||||||
return engine_config_ptr();
|
return engine_config_ptr();
|
||||||
|
|
||||||
|
auto mmap_memory = params->Get(Nan::New("mmap_memory").ToLocalChecked());
|
||||||
|
if (mmap_memory.IsEmpty())
|
||||||
|
return engine_config_ptr();
|
||||||
|
|
||||||
if (!memory_file->IsUndefined())
|
if (!memory_file->IsUndefined())
|
||||||
{
|
{
|
||||||
if (path->IsUndefined())
|
if (path->IsUndefined())
|
||||||
@@ -190,6 +194,18 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
|
|||||||
return engine_config_ptr();
|
return engine_config_ptr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!mmap_memory->IsUndefined())
|
||||||
|
{
|
||||||
|
if (mmap_memory->IsBoolean())
|
||||||
|
{
|
||||||
|
engine_config->use_mmap = Nan::To<bool>(mmap_memory).FromJust();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Nan::ThrowError("mmap_memory option must be a boolean");
|
||||||
|
return engine_config_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (path->IsUndefined() && !engine_config->use_shared_memory)
|
if (path->IsUndefined() && !engine_config->use_shared_memory)
|
||||||
{
|
{
|
||||||
@@ -928,6 +944,101 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (obj->Has(Nan::New("waypoints").ToLocalChecked()))
|
||||||
|
{
|
||||||
|
v8::Local<v8::Value> waypoints = obj->Get(Nan::New("waypoints").ToLocalChecked());
|
||||||
|
if (waypoints.IsEmpty())
|
||||||
|
return route_parameters_ptr();
|
||||||
|
|
||||||
|
// must be array
|
||||||
|
if (!waypoints->IsArray())
|
||||||
|
{
|
||||||
|
Nan::ThrowError(
|
||||||
|
"Waypoints must be an array of integers corresponding to the input coordinates.");
|
||||||
|
return route_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto waypoints_array = v8::Local<v8::Array>::Cast(waypoints);
|
||||||
|
// must have at least two elements
|
||||||
|
if (waypoints_array->Length() < 2)
|
||||||
|
{
|
||||||
|
Nan::ThrowError("At least two waypoints must be provided");
|
||||||
|
return route_parameters_ptr();
|
||||||
|
}
|
||||||
|
auto coords_size = params->coordinates.size();
|
||||||
|
auto waypoints_array_size = waypoints_array->Length();
|
||||||
|
|
||||||
|
const auto first_index = Nan::To<std::uint32_t>(waypoints_array->Get(0)).FromJust();
|
||||||
|
const auto last_index =
|
||||||
|
Nan::To<std::uint32_t>(waypoints_array->Get(waypoints_array_size - 1)).FromJust();
|
||||||
|
if (first_index != 0 || last_index != coords_size - 1)
|
||||||
|
{
|
||||||
|
Nan::ThrowError("First and last waypoints values must correspond to first and last "
|
||||||
|
"coordinate indices");
|
||||||
|
return route_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < waypoints_array_size; ++i)
|
||||||
|
{
|
||||||
|
v8::Local<v8::Value> waypoint_value = waypoints_array->Get(i);
|
||||||
|
// all elements must be numbers
|
||||||
|
if (!waypoint_value->IsNumber())
|
||||||
|
{
|
||||||
|
Nan::ThrowError("Waypoint values must be an array of integers");
|
||||||
|
return route_parameters_ptr();
|
||||||
|
}
|
||||||
|
// check that the waypoint index corresponds with an inpute coordinate
|
||||||
|
const auto index = Nan::To<std::uint32_t>(waypoint_value).FromJust();
|
||||||
|
if (index >= coords_size)
|
||||||
|
{
|
||||||
|
Nan::ThrowError("Waypoints must correspond with the index of an input coordinate");
|
||||||
|
return route_parameters_ptr();
|
||||||
|
}
|
||||||
|
params->waypoints.emplace_back(static_cast<unsigned>(waypoint_value->NumberValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!params->waypoints.empty())
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < params->waypoints.size() - 1; i++)
|
||||||
|
{
|
||||||
|
if (params->waypoints[i] >= params->waypoints[i + 1])
|
||||||
|
{
|
||||||
|
Nan::ThrowError("Waypoints must be supplied in increasing order");
|
||||||
|
return route_parameters_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->Has(Nan::New("snapping").ToLocalChecked()))
|
||||||
|
{
|
||||||
|
v8::Local<v8::Value> snapping = obj->Get(Nan::New("snapping").ToLocalChecked());
|
||||||
|
if (snapping.IsEmpty())
|
||||||
|
return route_parameters_ptr();
|
||||||
|
|
||||||
|
if (!snapping->IsString())
|
||||||
|
{
|
||||||
|
Nan::ThrowError("Snapping must be a string: [default, any]");
|
||||||
|
return route_parameters_ptr();
|
||||||
|
}
|
||||||
|
const Nan::Utf8String snapping_utf8str(snapping);
|
||||||
|
std::string snapping_str{*snapping_utf8str, *snapping_utf8str + snapping_utf8str.length()};
|
||||||
|
|
||||||
|
if (snapping_str == "default")
|
||||||
|
{
|
||||||
|
params->snapping = osrm::RouteParameters::SnappingType::Default;
|
||||||
|
}
|
||||||
|
else if (snapping_str == "any")
|
||||||
|
{
|
||||||
|
params->snapping = osrm::RouteParameters::SnappingType::Any;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Nan::ThrowError("'snapping' param must be one of [default, any]");
|
||||||
|
return route_parameters_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool parsedSuccessfully = parseCommonParameters(obj, params);
|
bool parsedSuccessfully = parseCommonParameters(obj, params);
|
||||||
if (!parsedSuccessfully)
|
if (!parsedSuccessfully)
|
||||||
{
|
{
|
||||||
@@ -1167,6 +1278,70 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (obj->Has(Nan::New("fallback_speed").ToLocalChecked()))
|
||||||
|
{
|
||||||
|
auto fallback_speed = obj->Get(Nan::New("fallback_speed").ToLocalChecked());
|
||||||
|
|
||||||
|
if (!fallback_speed->IsNumber())
|
||||||
|
{
|
||||||
|
Nan::ThrowError("fallback_speed must be a number");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
else if (fallback_speed->NumberValue() <= 0)
|
||||||
|
{
|
||||||
|
Nan::ThrowError("fallback_speed must be > 0");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
params->fallback_speed = static_cast<double>(fallback_speed->NumberValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->Has(Nan::New("fallback_coordinate").ToLocalChecked()))
|
||||||
|
{
|
||||||
|
auto fallback_coordinate = obj->Get(Nan::New("fallback_coordinate").ToLocalChecked());
|
||||||
|
|
||||||
|
if (!fallback_coordinate->IsString())
|
||||||
|
{
|
||||||
|
Nan::ThrowError("fallback_coordinate must be a string: [input, snapped]");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string fallback_coordinate_str = *v8::String::Utf8Value(fallback_coordinate);
|
||||||
|
|
||||||
|
if (fallback_coordinate_str == "snapped")
|
||||||
|
{
|
||||||
|
params->fallback_coordinate_type =
|
||||||
|
osrm::TableParameters::FallbackCoordinateType::Snapped;
|
||||||
|
}
|
||||||
|
else if (fallback_coordinate_str == "input")
|
||||||
|
{
|
||||||
|
params->fallback_coordinate_type = osrm::TableParameters::FallbackCoordinateType::Input;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Nan::ThrowError("'fallback_coordinate' param must be one of [input, snapped]");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->Has(Nan::New("scale_factor").ToLocalChecked()))
|
||||||
|
{
|
||||||
|
auto scale_factor = obj->Get(Nan::New("scale_factor").ToLocalChecked());
|
||||||
|
|
||||||
|
if (!scale_factor->IsNumber())
|
||||||
|
{
|
||||||
|
Nan::ThrowError("scale_factor must be a number");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
else if (scale_factor->NumberValue() <= 0)
|
||||||
|
{
|
||||||
|
Nan::ThrowError("scale_factor must be > 0");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
params->scale_factor = static_cast<double>(scale_factor->NumberValue());
|
||||||
|
}
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,28 +75,35 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
|||||||
|
|
||||||
// Implementation of the cell view. We need a template parameter here
|
// Implementation of the cell view. We need a template parameter here
|
||||||
// because we need to derive a read-only and read-write view from this.
|
// because we need to derive a read-only and read-write view from this.
|
||||||
template <typename WeightValueT, typename DurationValueT> class CellImpl
|
template <typename WeightValueT, typename DurationValueT, typename DistanceValueT>
|
||||||
|
class CellImpl
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
using WeightPtrT = WeightValueT *;
|
using WeightPtrT = WeightValueT *;
|
||||||
using DurationPtrT = DurationValueT *;
|
using DurationPtrT = DurationValueT *;
|
||||||
|
using DistancePtrT = DistanceValueT *;
|
||||||
BoundarySize num_source_nodes;
|
BoundarySize num_source_nodes;
|
||||||
BoundarySize num_destination_nodes;
|
BoundarySize num_destination_nodes;
|
||||||
|
|
||||||
WeightPtrT const weights;
|
WeightPtrT const weights;
|
||||||
DurationPtrT const durations;
|
DurationPtrT const durations;
|
||||||
|
DistancePtrT const distances;
|
||||||
const NodeID *const source_boundary;
|
const NodeID *const source_boundary;
|
||||||
const NodeID *const destination_boundary;
|
const NodeID *const destination_boundary;
|
||||||
|
|
||||||
using RowIterator = WeightPtrT;
|
using RowIterator = WeightPtrT;
|
||||||
// Possibly replace with
|
// Possibly replace with
|
||||||
// http://www.boost.org/doc/libs/1_55_0/libs/range/doc/html/range/reference/adaptors/reference/strided.html
|
// http://www.boost.org/doc/libs/1_55_0/libs/range/doc/html/range/reference/adaptors/reference/strided.html
|
||||||
class ColumnIterator : public boost::iterator_facade<ColumnIterator,
|
|
||||||
WeightValueT,
|
template <typename ValuePtrT>
|
||||||
|
class ColumnIterator : public boost::iterator_facade<ColumnIterator<ValuePtrT>,
|
||||||
|
decltype(*std::declval<ValuePtrT>()),
|
||||||
boost::random_access_traversal_tag>
|
boost::random_access_traversal_tag>
|
||||||
{
|
{
|
||||||
typedef boost::iterator_facade<ColumnIterator,
|
|
||||||
WeightValueT,
|
using ValueT = decltype(*std::declval<ValuePtrT>());
|
||||||
|
typedef boost::iterator_facade<ColumnIterator<ValueT>,
|
||||||
|
ValueT,
|
||||||
boost::random_access_traversal_tag>
|
boost::random_access_traversal_tag>
|
||||||
base_t;
|
base_t;
|
||||||
|
|
||||||
@@ -108,7 +115,7 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
|||||||
|
|
||||||
explicit ColumnIterator() : current(nullptr), stride(1) {}
|
explicit ColumnIterator() : current(nullptr), stride(1) {}
|
||||||
|
|
||||||
explicit ColumnIterator(WeightPtrT begin, std::size_t row_length)
|
explicit ColumnIterator(ValuePtrT begin, std::size_t row_length)
|
||||||
: current(begin), stride(row_length)
|
: current(begin), stride(row_length)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(begin != nullptr);
|
BOOST_ASSERT(begin != nullptr);
|
||||||
@@ -126,7 +133,7 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
friend class ::boost::iterator_core_access;
|
friend class ::boost::iterator_core_access;
|
||||||
WeightPtrT current;
|
ValuePtrT current;
|
||||||
const std::size_t stride;
|
const std::size_t stride;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -147,12 +154,13 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
|||||||
auto iter =
|
auto iter =
|
||||||
std::find(destination_boundary, destination_boundary + num_destination_nodes, node);
|
std::find(destination_boundary, destination_boundary + num_destination_nodes, node);
|
||||||
if (iter == destination_boundary + num_destination_nodes)
|
if (iter == destination_boundary + num_destination_nodes)
|
||||||
return boost::make_iterator_range(ColumnIterator{}, ColumnIterator{});
|
return boost::make_iterator_range(ColumnIterator<ValuePtr>{},
|
||||||
|
ColumnIterator<ValuePtr>{});
|
||||||
|
|
||||||
auto column = std::distance(destination_boundary, iter);
|
auto column = std::distance(destination_boundary, iter);
|
||||||
auto begin = ColumnIterator{ptr + column, num_destination_nodes};
|
auto begin = ColumnIterator<ValuePtr>{ptr + column, num_destination_nodes};
|
||||||
auto end = ColumnIterator{ptr + column + num_source_nodes * num_destination_nodes,
|
auto end = ColumnIterator<ValuePtr>{
|
||||||
num_destination_nodes};
|
ptr + column + num_source_nodes * num_destination_nodes, num_destination_nodes};
|
||||||
return boost::make_iterator_range(begin, end);
|
return boost::make_iterator_range(begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,6 +173,10 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
|||||||
|
|
||||||
auto GetInDuration(NodeID node) const { return GetInRange(durations, node); }
|
auto GetInDuration(NodeID node) const { return GetInRange(durations, node); }
|
||||||
|
|
||||||
|
auto GetInDistance(NodeID node) const { return GetInRange(distances, node); }
|
||||||
|
|
||||||
|
auto GetOutDistance(NodeID node) const { return GetOutRange(distances, node); }
|
||||||
|
|
||||||
auto GetSourceNodes() const
|
auto GetSourceNodes() const
|
||||||
{
|
{
|
||||||
return boost::make_iterator_range(source_boundary, source_boundary + num_source_nodes);
|
return boost::make_iterator_range(source_boundary, source_boundary + num_source_nodes);
|
||||||
@@ -179,17 +191,20 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
|||||||
CellImpl(const CellData &data,
|
CellImpl(const CellData &data,
|
||||||
WeightPtrT const all_weights,
|
WeightPtrT const all_weights,
|
||||||
DurationPtrT const all_durations,
|
DurationPtrT const all_durations,
|
||||||
|
DistancePtrT const all_distances,
|
||||||
const NodeID *const all_sources,
|
const NodeID *const all_sources,
|
||||||
const NodeID *const all_destinations)
|
const NodeID *const all_destinations)
|
||||||
: num_source_nodes{data.num_source_nodes},
|
: num_source_nodes{data.num_source_nodes},
|
||||||
num_destination_nodes{data.num_destination_nodes},
|
num_destination_nodes{data.num_destination_nodes},
|
||||||
weights{all_weights + data.value_offset},
|
weights{all_weights + data.value_offset},
|
||||||
durations{all_durations + data.value_offset},
|
durations{all_durations + data.value_offset},
|
||||||
|
distances{all_distances + data.value_offset},
|
||||||
source_boundary{all_sources + data.source_boundary_offset},
|
source_boundary{all_sources + data.source_boundary_offset},
|
||||||
destination_boundary{all_destinations + data.destination_boundary_offset}
|
destination_boundary{all_destinations + data.destination_boundary_offset}
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(all_weights != nullptr);
|
BOOST_ASSERT(all_weights != nullptr);
|
||||||
BOOST_ASSERT(all_durations != nullptr);
|
BOOST_ASSERT(all_durations != nullptr);
|
||||||
|
BOOST_ASSERT(all_distances != nullptr);
|
||||||
BOOST_ASSERT(num_source_nodes == 0 || all_sources != nullptr);
|
BOOST_ASSERT(num_source_nodes == 0 || all_sources != nullptr);
|
||||||
BOOST_ASSERT(num_destination_nodes == 0 || all_destinations != nullptr);
|
BOOST_ASSERT(num_destination_nodes == 0 || all_destinations != nullptr);
|
||||||
}
|
}
|
||||||
@@ -201,7 +216,8 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
|||||||
const NodeID *const all_destinations)
|
const NodeID *const all_destinations)
|
||||||
: num_source_nodes{data.num_source_nodes},
|
: num_source_nodes{data.num_source_nodes},
|
||||||
num_destination_nodes{data.num_destination_nodes}, weights{nullptr},
|
num_destination_nodes{data.num_destination_nodes}, weights{nullptr},
|
||||||
durations{nullptr}, source_boundary{all_sources + data.source_boundary_offset},
|
durations{nullptr}, distances{nullptr},
|
||||||
|
source_boundary{all_sources + data.source_boundary_offset},
|
||||||
destination_boundary{all_destinations + data.destination_boundary_offset}
|
destination_boundary{all_destinations + data.destination_boundary_offset}
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(num_source_nodes == 0 || all_sources != nullptr);
|
BOOST_ASSERT(num_source_nodes == 0 || all_sources != nullptr);
|
||||||
@@ -212,8 +228,8 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
|||||||
std::size_t LevelIDToIndex(LevelID level) const { return level - 1; }
|
std::size_t LevelIDToIndex(LevelID level) const { return level - 1; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Cell = CellImpl<EdgeWeight, EdgeDuration>;
|
using Cell = CellImpl<EdgeWeight, EdgeDuration, EdgeDistance>;
|
||||||
using ConstCell = CellImpl<const EdgeWeight, const EdgeDuration>;
|
using ConstCell = CellImpl<const EdgeWeight, const EdgeDuration, const EdgeDistance>;
|
||||||
|
|
||||||
CellStorageImpl() {}
|
CellStorageImpl() {}
|
||||||
|
|
||||||
@@ -361,6 +377,7 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
|||||||
|
|
||||||
metric.weights.resize(total_size + 1, INVALID_EDGE_WEIGHT);
|
metric.weights.resize(total_size + 1, INVALID_EDGE_WEIGHT);
|
||||||
metric.durations.resize(total_size + 1, MAXIMAL_EDGE_DURATION);
|
metric.durations.resize(total_size + 1, MAXIMAL_EDGE_DURATION);
|
||||||
|
metric.distances.resize(total_size + 1, INVALID_EDGE_DISTANCE);
|
||||||
|
|
||||||
return metric;
|
return metric;
|
||||||
}
|
}
|
||||||
@@ -388,6 +405,7 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
|||||||
return ConstCell{cells[cell_index],
|
return ConstCell{cells[cell_index],
|
||||||
metric.weights.data(),
|
metric.weights.data(),
|
||||||
metric.durations.data(),
|
metric.durations.data(),
|
||||||
|
metric.distances.data(),
|
||||||
source_boundary.empty() ? nullptr : source_boundary.data(),
|
source_boundary.empty() ? nullptr : source_boundary.data(),
|
||||||
destination_boundary.empty() ? nullptr : destination_boundary.data()};
|
destination_boundary.empty() ? nullptr : destination_boundary.data()};
|
||||||
}
|
}
|
||||||
@@ -415,6 +433,7 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
|||||||
return Cell{cells[cell_index],
|
return Cell{cells[cell_index],
|
||||||
metric.weights.data(),
|
metric.weights.data(),
|
||||||
metric.durations.data(),
|
metric.durations.data(),
|
||||||
|
metric.distances.data(),
|
||||||
source_boundary.data(),
|
source_boundary.data(),
|
||||||
destination_boundary.data()};
|
destination_boundary.data()};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
|
|||||||
edge.data.turn_id,
|
edge.data.turn_id,
|
||||||
std::max(edge.data.weight, 1),
|
std::max(edge.data.weight, 1),
|
||||||
edge.data.duration,
|
edge.data.duration,
|
||||||
|
edge.data.distance,
|
||||||
edge.data.forward,
|
edge.data.forward,
|
||||||
edge.data.backward);
|
edge.data.backward);
|
||||||
|
|
||||||
@@ -51,6 +52,7 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
|
|||||||
edge.data.turn_id,
|
edge.data.turn_id,
|
||||||
std::max(edge.data.weight, 1),
|
std::max(edge.data.weight, 1),
|
||||||
edge.data.duration,
|
edge.data.duration,
|
||||||
|
edge.data.distance,
|
||||||
edge.data.backward,
|
edge.data.backward,
|
||||||
edge.data.forward);
|
edge.data.forward);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,6 +162,13 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
|||||||
(-approach_type %
|
(-approach_type %
|
||||||
';')[ph::bind(&engine::api::BaseParameters::approaches, qi::_r1) = qi::_1];
|
';')[ph::bind(&engine::api::BaseParameters::approaches, qi::_r1) = qi::_1];
|
||||||
|
|
||||||
|
snapping_type.add("default", engine::api::BaseParameters::SnappingType::Default)(
|
||||||
|
"any", engine::api::BaseParameters::SnappingType::Any);
|
||||||
|
|
||||||
|
snapping_rule =
|
||||||
|
qi::lit("snapping=") >
|
||||||
|
snapping_type[ph::bind(&engine::api::BaseParameters::snapping, qi::_r1) = qi::_1];
|
||||||
|
|
||||||
exclude_rule = qi::lit("exclude=") >
|
exclude_rule = qi::lit("exclude=") >
|
||||||
(qi::as_string[+qi::char_("a-zA-Z0-9")] %
|
(qi::as_string[+qi::char_("a-zA-Z0-9")] %
|
||||||
',')[ph::bind(&engine::api::BaseParameters::exclude, qi::_r1) = qi::_1];
|
',')[ph::bind(&engine::api::BaseParameters::exclude, qi::_r1) = qi::_1];
|
||||||
@@ -171,13 +178,16 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
|||||||
| bearings_rule(qi::_r1) //
|
| bearings_rule(qi::_r1) //
|
||||||
| generate_hints_rule(qi::_r1) //
|
| generate_hints_rule(qi::_r1) //
|
||||||
| approach_rule(qi::_r1) //
|
| approach_rule(qi::_r1) //
|
||||||
| exclude_rule(qi::_r1);
|
| exclude_rule(qi::_r1) //
|
||||||
|
| snapping_rule(qi::_r1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
qi::rule<Iterator, Signature> base_rule;
|
qi::rule<Iterator, Signature> base_rule;
|
||||||
qi::rule<Iterator, Signature> query_rule;
|
qi::rule<Iterator, Signature> query_rule;
|
||||||
|
|
||||||
|
qi::real_parser<double, json_policy> double_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
qi::rule<Iterator, Signature> bearings_rule;
|
qi::rule<Iterator, Signature> bearings_rule;
|
||||||
qi::rule<Iterator, Signature> radiuses_rule;
|
qi::rule<Iterator, Signature> radiuses_rule;
|
||||||
@@ -195,9 +205,10 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
|||||||
qi::rule<Iterator, unsigned char()> base64_char;
|
qi::rule<Iterator, unsigned char()> base64_char;
|
||||||
qi::rule<Iterator, std::string()> polyline_chars;
|
qi::rule<Iterator, std::string()> polyline_chars;
|
||||||
qi::rule<Iterator, double()> unlimited_rule;
|
qi::rule<Iterator, double()> unlimited_rule;
|
||||||
qi::real_parser<double, json_policy> double_;
|
qi::rule<Iterator, Signature> snapping_rule;
|
||||||
|
|
||||||
qi::symbols<char, engine::Approach> approach_type;
|
qi::symbols<char, engine::Approach> approach_type;
|
||||||
|
qi::symbols<char, engine::api::BaseParameters::SnappingType> snapping_type;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,17 +42,12 @@ struct MatchParametersGrammar final : public RouteParametersGrammar<Iterator, Si
|
|||||||
(qi::uint_ %
|
(qi::uint_ %
|
||||||
';')[ph::bind(&engine::api::MatchParameters::timestamps, qi::_r1) = qi::_1];
|
';')[ph::bind(&engine::api::MatchParameters::timestamps, qi::_r1) = qi::_1];
|
||||||
|
|
||||||
waypoints_rule =
|
|
||||||
qi::lit("waypoints=") >
|
|
||||||
(size_t_ % ';')[ph::bind(&engine::api::MatchParameters::waypoints, qi::_r1) = qi::_1];
|
|
||||||
|
|
||||||
gaps_type.add("split", engine::api::MatchParameters::GapsType::Split)(
|
gaps_type.add("split", engine::api::MatchParameters::GapsType::Split)(
|
||||||
"ignore", engine::api::MatchParameters::GapsType::Ignore);
|
"ignore", engine::api::MatchParameters::GapsType::Ignore);
|
||||||
|
|
||||||
root_rule =
|
root_rule =
|
||||||
BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") >
|
BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") >
|
||||||
-('?' > (timestamps_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1) |
|
-('?' > (timestamps_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1) |
|
||||||
waypoints_rule(qi::_r1) |
|
|
||||||
(qi::lit("gaps=") >
|
(qi::lit("gaps=") >
|
||||||
gaps_type[ph::bind(&engine::api::MatchParameters::gaps, qi::_r1) = qi::_1]) |
|
gaps_type[ph::bind(&engine::api::MatchParameters::gaps, qi::_r1) = qi::_1]) |
|
||||||
(qi::lit("tidy=") >
|
(qi::lit("tidy=") >
|
||||||
@@ -63,7 +58,6 @@ struct MatchParametersGrammar final : public RouteParametersGrammar<Iterator, Si
|
|||||||
private:
|
private:
|
||||||
qi::rule<Iterator, Signature> root_rule;
|
qi::rule<Iterator, Signature> root_rule;
|
||||||
qi::rule<Iterator, Signature> timestamps_rule;
|
qi::rule<Iterator, Signature> timestamps_rule;
|
||||||
qi::rule<Iterator, Signature> waypoints_rule;
|
|
||||||
qi::rule<Iterator, std::size_t()> size_t_;
|
qi::rule<Iterator, std::size_t()> size_t_;
|
||||||
|
|
||||||
qi::symbols<char, engine::api::MatchParameters::GapsType> gaps_type;
|
qi::symbols<char, engine::api::MatchParameters::GapsType> gaps_type;
|
||||||
|
|||||||
@@ -48,6 +48,14 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
|||||||
|
|
||||||
RouteParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_)
|
RouteParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_)
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_HAS_LONG_LONG
|
||||||
|
if (std::is_same<std::size_t, unsigned long long>::value)
|
||||||
|
size_t_ = qi::ulong_long;
|
||||||
|
else
|
||||||
|
size_t_ = qi::ulong_;
|
||||||
|
#else
|
||||||
|
size_t_ = qi::ulong_;
|
||||||
|
#endif
|
||||||
using AnnotationsType = engine::api::RouteParameters::AnnotationsType;
|
using AnnotationsType = engine::api::RouteParameters::AnnotationsType;
|
||||||
|
|
||||||
const auto add_annotation = [](engine::api::RouteParameters &route_parameters,
|
const auto add_annotation = [](engine::api::RouteParameters &route_parameters,
|
||||||
@@ -70,8 +78,12 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
|||||||
"distance", AnnotationsType::Distance)("weight", AnnotationsType::Weight)(
|
"distance", AnnotationsType::Distance)("weight", AnnotationsType::Weight)(
|
||||||
"datasources", AnnotationsType::Datasources)("speed", AnnotationsType::Speed);
|
"datasources", AnnotationsType::Datasources)("speed", AnnotationsType::Speed);
|
||||||
|
|
||||||
|
waypoints_rule =
|
||||||
|
qi::lit("waypoints=") >
|
||||||
|
(size_t_ % ';')[ph::bind(&engine::api::RouteParameters::waypoints, qi::_r1) = qi::_1];
|
||||||
|
|
||||||
base_rule =
|
base_rule =
|
||||||
BaseGrammar::base_rule(qi::_r1) |
|
BaseGrammar::base_rule(qi::_r1) | waypoints_rule(qi::_r1) |
|
||||||
(qi::lit("steps=") >
|
(qi::lit("steps=") >
|
||||||
qi::bool_[ph::bind(&engine::api::RouteParameters::steps, qi::_r1) = qi::_1]) |
|
qi::bool_[ph::bind(&engine::api::RouteParameters::steps, qi::_r1) = qi::_1]) |
|
||||||
(qi::lit("geometries=") >
|
(qi::lit("geometries=") >
|
||||||
@@ -94,6 +106,8 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
|||||||
private:
|
private:
|
||||||
qi::rule<Iterator, Signature> root_rule;
|
qi::rule<Iterator, Signature> root_rule;
|
||||||
qi::rule<Iterator, Signature> route_rule;
|
qi::rule<Iterator, Signature> route_rule;
|
||||||
|
qi::rule<Iterator, Signature> waypoints_rule;
|
||||||
|
qi::rule<Iterator, std::size_t()> size_t_;
|
||||||
|
|
||||||
qi::symbols<char, engine::api::RouteParameters::GeometriesType> geometries_type;
|
qi::symbols<char, engine::api::RouteParameters::GeometriesType> geometries_type;
|
||||||
qi::symbols<char, engine::api::RouteParameters::OverviewType> overview_type;
|
qi::symbols<char, engine::api::RouteParameters::OverviewType> overview_type;
|
||||||
|
|||||||
@@ -48,10 +48,28 @@ struct TableParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
|||||||
(qi::lit("all") |
|
(qi::lit("all") |
|
||||||
(size_t_ % ';')[ph::bind(&engine::api::TableParameters::sources, qi::_r1) = qi::_1]);
|
(size_t_ % ';')[ph::bind(&engine::api::TableParameters::sources, qi::_r1) = qi::_1]);
|
||||||
|
|
||||||
|
fallback_speed_rule =
|
||||||
|
qi::lit("fallback_speed=") >
|
||||||
|
(double_)[ph::bind(&engine::api::TableParameters::fallback_speed, qi::_r1) = qi::_1];
|
||||||
|
|
||||||
|
fallback_coordinate_type.add("input",
|
||||||
|
engine::api::TableParameters::FallbackCoordinateType::Input)(
|
||||||
|
"snapped", engine::api::TableParameters::FallbackCoordinateType::Snapped);
|
||||||
|
|
||||||
|
scale_factor_rule =
|
||||||
|
qi::lit("scale_factor=") >
|
||||||
|
(double_)[ph::bind(&engine::api::TableParameters::scale_factor, qi::_r1) = qi::_1];
|
||||||
|
|
||||||
table_rule = destinations_rule(qi::_r1) | sources_rule(qi::_r1);
|
table_rule = destinations_rule(qi::_r1) | sources_rule(qi::_r1);
|
||||||
|
|
||||||
root_rule = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") >
|
root_rule = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") >
|
||||||
-('?' > (table_rule(qi::_r1) | base_rule(qi::_r1)) % '&');
|
-('?' > (table_rule(qi::_r1) | base_rule(qi::_r1) | scale_factor_rule(qi::_r1) |
|
||||||
|
fallback_speed_rule(qi::_r1) |
|
||||||
|
(qi::lit("fallback_coordinate=") >
|
||||||
|
fallback_coordinate_type
|
||||||
|
[ph::bind(&engine::api::TableParameters::fallback_coordinate_type,
|
||||||
|
qi::_r1) = qi::_1])) %
|
||||||
|
'&');
|
||||||
}
|
}
|
||||||
|
|
||||||
TableParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_)
|
TableParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_)
|
||||||
@@ -73,13 +91,20 @@ struct TableParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
|||||||
qi::rule<Iterator, Signature> base_rule;
|
qi::rule<Iterator, Signature> base_rule;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using json_policy = no_trailing_dot_policy<double, 'j', 's', 'o', 'n'>;
|
||||||
|
|
||||||
qi::rule<Iterator, Signature> root_rule;
|
qi::rule<Iterator, Signature> root_rule;
|
||||||
qi::rule<Iterator, Signature> table_rule;
|
qi::rule<Iterator, Signature> table_rule;
|
||||||
qi::rule<Iterator, Signature> sources_rule;
|
qi::rule<Iterator, Signature> sources_rule;
|
||||||
qi::rule<Iterator, Signature> destinations_rule;
|
qi::rule<Iterator, Signature> destinations_rule;
|
||||||
|
qi::rule<Iterator, Signature> fallback_speed_rule;
|
||||||
|
qi::rule<Iterator, Signature> scale_factor_rule;
|
||||||
qi::rule<Iterator, std::size_t()> size_t_;
|
qi::rule<Iterator, std::size_t()> size_t_;
|
||||||
qi::symbols<char, engine::api::TableParameters::AnnotationsType> annotations;
|
qi::symbols<char, engine::api::TableParameters::AnnotationsType> annotations;
|
||||||
qi::rule<Iterator, engine::api::TableParameters::AnnotationsType()> annotations_list;
|
qi::rule<Iterator, engine::api::TableParameters::AnnotationsType()> annotations_list;
|
||||||
|
qi::symbols<char, engine::api::TableParameters::FallbackCoordinateType>
|
||||||
|
fallback_coordinate_type;
|
||||||
|
qi::real_parser<double, json_policy> double_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,15 @@ struct Block
|
|||||||
{
|
{
|
||||||
std::uint64_t num_entries;
|
std::uint64_t num_entries;
|
||||||
std::uint64_t byte_size;
|
std::uint64_t byte_size;
|
||||||
|
std::uint64_t offset;
|
||||||
|
|
||||||
Block() : num_entries(0), byte_size(0) {}
|
Block() : num_entries(0), byte_size(0), offset(0) {}
|
||||||
|
Block(std::uint64_t num_entries, std::uint64_t byte_size, std::uint64_t offset)
|
||||||
|
: num_entries(num_entries), byte_size(byte_size), offset(offset)
|
||||||
|
{
|
||||||
|
}
|
||||||
Block(std::uint64_t num_entries, std::uint64_t byte_size)
|
Block(std::uint64_t num_entries, std::uint64_t byte_size)
|
||||||
: num_entries(num_entries), byte_size(byte_size)
|
: num_entries(num_entries), byte_size(byte_size), offset(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -29,7 +34,7 @@ using NamedBlock = std::tuple<std::string, Block>;
|
|||||||
template <typename T> Block make_block(uint64_t num_entries)
|
template <typename T> Block make_block(uint64_t num_entries)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(T) % alignof(T) == 0, "aligned T* can't be used as an array pointer");
|
static_assert(sizeof(T) % alignof(T) == 0, "aligned T* can't be used as an array pointer");
|
||||||
return Block{num_entries, sizeof(T) * num_entries};
|
return Block{num_entries, sizeof(T) * num_entries, 0};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "storage/shared_datatype.hpp"
|
#include "storage/shared_datatype.hpp"
|
||||||
#include "storage/tar.hpp"
|
#include "storage/tar.hpp"
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
#include <boost/function_output_iterator.hpp>
|
#include <boost/function_output_iterator.hpp>
|
||||||
#include <boost/iterator/function_input_iterator.hpp>
|
#include <boost/iterator/function_input_iterator.hpp>
|
||||||
|
|
||||||
@@ -30,22 +31,37 @@ namespace serialization
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template <typename T, typename BlockT = unsigned char>
|
template <typename T, typename BlockT = unsigned char>
|
||||||
inline BlockT packBits(const T &data, std::size_t index, std::size_t count)
|
inline BlockT packBits(const T &data, std::size_t base_index, const std::size_t count)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<typename T::value_type, bool>::value, "value_type is not bool");
|
static_assert(std::is_same<typename T::value_type, bool>::value, "value_type is not bool");
|
||||||
|
static_assert(std::is_unsigned<BlockT>::value, "BlockT must be unsigned type");
|
||||||
|
static_assert(std::is_integral<BlockT>::value, "BlockT must be an integral type");
|
||||||
|
static_assert(CHAR_BIT == 8, "Non-8-bit bytes not supported, sorry!");
|
||||||
|
BOOST_ASSERT(sizeof(BlockT) * CHAR_BIT >= count);
|
||||||
|
|
||||||
|
// Note: if this packing is changed, be sure to update vector_view<bool>
|
||||||
|
// as well, so that on-disk and in-memory layouts match.
|
||||||
BlockT value = 0;
|
BlockT value = 0;
|
||||||
for (std::size_t bit = 0; bit < count; ++bit, ++index)
|
for (std::size_t bit = 0; bit < count; ++bit)
|
||||||
value = (value << 1) | data[index];
|
{
|
||||||
|
value |= (data[base_index + bit] ? BlockT{1} : BlockT{0}) << bit;
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename BlockT = unsigned char>
|
template <typename T, typename BlockT = unsigned char>
|
||||||
inline void unpackBits(T &data, std::size_t index, std::size_t count, BlockT value)
|
inline void
|
||||||
|
unpackBits(T &data, const std::size_t base_index, const std::size_t count, const BlockT value)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<typename T::value_type, bool>::value, "value_type is not bool");
|
static_assert(std::is_same<typename T::value_type, bool>::value, "value_type is not bool");
|
||||||
const BlockT mask = BlockT{1} << (count - 1);
|
static_assert(std::is_unsigned<BlockT>::value, "BlockT must be unsigned type");
|
||||||
for (std::size_t bit = 0; bit < count; value <<= 1, ++bit, ++index)
|
static_assert(std::is_integral<BlockT>::value, "BlockT must be an integral type");
|
||||||
data[index] = value & mask;
|
static_assert(CHAR_BIT == 8, "Non-8-bit bytes not supported, sorry!");
|
||||||
|
BOOST_ASSERT(sizeof(BlockT) * CHAR_BIT >= count);
|
||||||
|
for (std::size_t bit = 0; bit < count; ++bit)
|
||||||
|
{
|
||||||
|
data[base_index + bit] = value & (BlockT{1} << bit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VectorT>
|
template <typename VectorT>
|
||||||
@@ -55,15 +71,16 @@ void readBoolVector(tar::FileReader &reader, const std::string &name, VectorT &d
|
|||||||
data.resize(count);
|
data.resize(count);
|
||||||
std::uint64_t index = 0;
|
std::uint64_t index = 0;
|
||||||
|
|
||||||
constexpr std::uint64_t WORD_BITS = CHAR_BIT * sizeof(std::uint64_t);
|
using BlockType = std::uint64_t;
|
||||||
|
constexpr std::uint64_t BLOCK_BITS = CHAR_BIT * sizeof(BlockType);
|
||||||
|
|
||||||
const auto decode = [&](const std::uint64_t block) {
|
const auto decode = [&](const BlockType block) {
|
||||||
auto read_size = std::min<std::size_t>(count - index, WORD_BITS);
|
auto read_size = std::min<std::size_t>(count - index, BLOCK_BITS);
|
||||||
unpackBits<VectorT, std::uint64_t>(data, index, read_size, block);
|
unpackBits<VectorT, BlockType>(data, index, read_size, block);
|
||||||
index += WORD_BITS;
|
index += BLOCK_BITS;
|
||||||
};
|
};
|
||||||
|
|
||||||
reader.ReadStreaming<std::uint64_t>(name, boost::make_function_output_iterator(decode));
|
reader.ReadStreaming<BlockType>(name, boost::make_function_output_iterator(decode));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VectorT>
|
template <typename VectorT>
|
||||||
@@ -73,19 +90,20 @@ void writeBoolVector(tar::FileWriter &writer, const std::string &name, const Vec
|
|||||||
writer.WriteElementCount64(name, count);
|
writer.WriteElementCount64(name, count);
|
||||||
std::uint64_t index = 0;
|
std::uint64_t index = 0;
|
||||||
|
|
||||||
constexpr std::uint64_t WORD_BITS = CHAR_BIT * sizeof(std::uint64_t);
|
using BlockType = std::uint64_t;
|
||||||
|
constexpr std::uint64_t BLOCK_BITS = CHAR_BIT * sizeof(BlockType);
|
||||||
|
|
||||||
// FIXME on old boost version the function_input_iterator does not work with lambdas
|
// FIXME on old boost version the function_input_iterator does not work with lambdas
|
||||||
// so we need to wrap it in a function here.
|
// so we need to wrap it in a function here.
|
||||||
const std::function<std::uint64_t()> encode_function = [&]() -> std::uint64_t {
|
const std::function<BlockType()> encode_function = [&]() -> BlockType {
|
||||||
auto write_size = std::min<std::size_t>(count - index, WORD_BITS);
|
auto write_size = std::min<std::size_t>(count - index, BLOCK_BITS);
|
||||||
auto packed = packBits<VectorT, std::uint64_t>(data, index, write_size);
|
auto packed = packBits<VectorT, BlockType>(data, index, write_size);
|
||||||
index += WORD_BITS;
|
index += BLOCK_BITS;
|
||||||
return packed;
|
return packed;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::uint64_t number_of_blocks = (count + WORD_BITS - 1) / WORD_BITS;
|
std::uint64_t number_of_blocks = (count + BLOCK_BITS - 1) / BLOCK_BITS;
|
||||||
writer.WriteStreaming<std::uint64_t>(
|
writer.WriteStreaming<BlockType>(
|
||||||
name,
|
name,
|
||||||
boost::make_function_input_iterator(encode_function, boost::infinite()),
|
boost::make_function_input_iterator(encode_function, boost::infinite()),
|
||||||
number_of_blocks);
|
number_of_blocks);
|
||||||
@@ -266,9 +284,9 @@ template <typename K, typename V> void write(io::BufferWriter &writer, const std
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void read(io::BufferReader &reader, DataLayout &layout) { read(reader, layout.blocks); }
|
inline void read(io::BufferReader &reader, BaseDataLayout &layout) { read(reader, layout.blocks); }
|
||||||
|
|
||||||
inline void write(io::BufferWriter &writer, const DataLayout &layout)
|
inline void write(io::BufferWriter &writer, const BaseDataLayout &layout)
|
||||||
{
|
{
|
||||||
write(writer, layout.blocks);
|
write(writer, layout.blocks);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <boost/function_output_iterator.hpp>
|
#include <boost/function_output_iterator.hpp>
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
@@ -19,8 +20,8 @@ class SharedDataIndex
|
|||||||
public:
|
public:
|
||||||
struct AllocatedRegion
|
struct AllocatedRegion
|
||||||
{
|
{
|
||||||
char *memory_ptr;
|
void *memory_ptr;
|
||||||
DataLayout layout;
|
std::unique_ptr<BaseDataLayout> layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
SharedDataIndex() = default;
|
SharedDataIndex() = default;
|
||||||
@@ -29,10 +30,10 @@ class SharedDataIndex
|
|||||||
// Build mapping from block name to region
|
// Build mapping from block name to region
|
||||||
for (auto index : util::irange<std::uint32_t>(0, regions.size()))
|
for (auto index : util::irange<std::uint32_t>(0, regions.size()))
|
||||||
{
|
{
|
||||||
regions[index].layout.List("",
|
regions[index].layout->List("",
|
||||||
boost::make_function_output_iterator([&](const auto &name) {
|
boost::make_function_output_iterator([&](const auto &name) {
|
||||||
block_to_region[name] = index;
|
block_to_region[name] = index;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,32 +41,44 @@ class SharedDataIndex
|
|||||||
{
|
{
|
||||||
for (const auto ®ion : regions)
|
for (const auto ®ion : regions)
|
||||||
{
|
{
|
||||||
region.layout.List(name_prefix, out);
|
region.layout->List(name_prefix, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> auto GetBlockPtr(const std::string &name) const
|
template <typename T> auto GetBlockPtr(const std::string &name) const
|
||||||
{
|
{
|
||||||
|
#if !defined(__GNUC__) || (__GNUC__ > 4)
|
||||||
|
// is_tivially_copyable only exists in GCC >=5
|
||||||
|
static_assert(std::is_trivially_copyable<T>::value,
|
||||||
|
"Block-based data must be a trivially copyable type");
|
||||||
|
static_assert(sizeof(T) % alignof(T) == 0, "aligned T* can't be used as an array pointer");
|
||||||
|
#endif
|
||||||
const auto ®ion = GetBlockRegion(name);
|
const auto ®ion = GetBlockRegion(name);
|
||||||
return region.layout.GetBlockPtr<T>(region.memory_ptr, name);
|
return reinterpret_cast<T *>(region.layout->GetBlockPtr(region.memory_ptr, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> auto GetBlockPtr(const std::string &name)
|
template <typename T> auto GetBlockPtr(const std::string &name)
|
||||||
{
|
{
|
||||||
|
#if !defined(__GNUC__) || (__GNUC__ > 4)
|
||||||
|
// is_tivially_copyable only exists in GCC >=5
|
||||||
|
static_assert(std::is_trivially_copyable<T>::value,
|
||||||
|
"Block-based data must be a trivially copyable type");
|
||||||
|
static_assert(sizeof(T) % alignof(T) == 0, "aligned T* can't be used as an array pointer");
|
||||||
|
#endif
|
||||||
const auto ®ion = GetBlockRegion(name);
|
const auto ®ion = GetBlockRegion(name);
|
||||||
return region.layout.GetBlockPtr<T>(region.memory_ptr, name);
|
return reinterpret_cast<T *>(region.layout->GetBlockPtr(region.memory_ptr, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t GetBlockEntries(const std::string &name) const
|
std::size_t GetBlockEntries(const std::string &name) const
|
||||||
{
|
{
|
||||||
const auto ®ion = GetBlockRegion(name);
|
const auto ®ion = GetBlockRegion(name);
|
||||||
return region.layout.GetBlockEntries(name);
|
return region.layout->GetBlockEntries(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t GetBlockSize(const std::string &name) const
|
std::size_t GetBlockSize(const std::string &name) const
|
||||||
{
|
{
|
||||||
const auto ®ion = GetBlockRegion(name);
|
const auto ®ion = GetBlockRegion(name);
|
||||||
return region.layout.GetBlockSize(name);
|
return region.layout->GetBlockSize(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ namespace osrm
|
|||||||
namespace storage
|
namespace storage
|
||||||
{
|
{
|
||||||
|
|
||||||
class DataLayout;
|
class BaseDataLayout;
|
||||||
namespace serialization
|
namespace serialization
|
||||||
{
|
{
|
||||||
inline void read(io::BufferReader &reader, DataLayout &layout);
|
inline void read(io::BufferReader &reader, BaseDataLayout &layout);
|
||||||
|
|
||||||
inline void write(io::BufferWriter &writer, const DataLayout &layout);
|
inline void write(io::BufferWriter &writer, const BaseDataLayout &layout);
|
||||||
} // namespace serialization
|
} // namespace serialization
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
@@ -54,44 +54,28 @@ inline std::string trimName(const std::string &name_prefix, const std::string &n
|
|||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
class DataLayout
|
class BaseDataLayout
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DataLayout() : blocks{} {}
|
virtual ~BaseDataLayout() = default;
|
||||||
|
|
||||||
inline void SetBlock(const std::string &name, Block block) { blocks[name] = std::move(block); }
|
inline void SetBlock(const std::string &name, Block block) { blocks[name] = std::move(block); }
|
||||||
|
|
||||||
inline uint64_t GetBlockEntries(const std::string &name) const
|
inline std::uint64_t GetBlockEntries(const std::string &name) const
|
||||||
{
|
{
|
||||||
return GetBlock(name).num_entries;
|
return GetBlock(name).num_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint64_t GetBlockSize(const std::string &name) const { return GetBlock(name).byte_size; }
|
inline std::uint64_t GetBlockSize(const std::string &name) const
|
||||||
|
{
|
||||||
|
return GetBlock(name).byte_size;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool HasBlock(const std::string &name) const
|
inline bool HasBlock(const std::string &name) const
|
||||||
{
|
{
|
||||||
return blocks.find(name) != blocks.end();
|
return blocks.find(name) != blocks.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint64_t GetSizeOfLayout() const
|
|
||||||
{
|
|
||||||
uint64_t result = 0;
|
|
||||||
for (const auto &name_and_block : blocks)
|
|
||||||
{
|
|
||||||
result += GetBlockSize(name_and_block.first) + BLOCK_ALIGNMENT;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> inline T *GetBlockPtr(char *shared_memory, const std::string &name) const
|
|
||||||
{
|
|
||||||
static_assert(BLOCK_ALIGNMENT % std::alignment_of<T>::value == 0,
|
|
||||||
"Datatype does not fit alignment constraints.");
|
|
||||||
|
|
||||||
char *ptr = (char *)GetAlignedBlockPtr(shared_memory, name);
|
|
||||||
return (T *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Depending on the name prefix this function either lists all blocks with the same prefix
|
// Depending on the name prefix this function either lists all blocks with the same prefix
|
||||||
// or all entries in the sub-directory.
|
// or all entries in the sub-directory.
|
||||||
// '/ch/edge' -> '/ch/edge_filter/0/blocks', '/ch/edge_filter/1/blocks'
|
// '/ch/edge' -> '/ch/edge_filter/0/blocks', '/ch/edge_filter/1/blocks'
|
||||||
@@ -115,10 +99,10 @@ class DataLayout
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
virtual inline void *GetBlockPtr(void *base_ptr, const std::string &name) const = 0;
|
||||||
friend void serialization::read(io::BufferReader &reader, DataLayout &layout);
|
virtual inline std::uint64_t GetSizeOfLayout() const = 0;
|
||||||
friend void serialization::write(io::BufferWriter &writer, const DataLayout &layout);
|
|
||||||
|
|
||||||
|
protected:
|
||||||
const Block &GetBlock(const std::string &name) const
|
const Block &GetBlock(const std::string &name) const
|
||||||
{
|
{
|
||||||
auto iter = blocks.find(name);
|
auto iter = blocks.find(name);
|
||||||
@@ -130,10 +114,42 @@ class DataLayout
|
|||||||
return iter->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend void serialization::read(io::BufferReader &reader, BaseDataLayout &layout);
|
||||||
|
friend void serialization::write(io::BufferWriter &writer, const BaseDataLayout &layout);
|
||||||
|
|
||||||
|
std::map<std::string, Block> blocks;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ContiguousDataLayout final : public BaseDataLayout
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline std::uint64_t GetSizeOfLayout() const override final
|
||||||
|
{
|
||||||
|
std::uint64_t result = 0;
|
||||||
|
for (const auto &name_and_block : blocks)
|
||||||
|
{
|
||||||
|
result += GetBlockSize(name_and_block.first) + BLOCK_ALIGNMENT;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void *GetBlockPtr(void *base_ptr, const std::string &name) const override final
|
||||||
|
{
|
||||||
|
// TODO: re-enable this alignment checking somehow
|
||||||
|
// static_assert(BLOCK_ALIGNMENT % std::alignment_of<T>::value == 0,
|
||||||
|
// "Datatype does not fit alignment constraints.");
|
||||||
|
|
||||||
|
return GetAlignedBlockPtr(base_ptr, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend void serialization::read(io::BufferReader &reader, BaseDataLayout &layout);
|
||||||
|
friend void serialization::write(io::BufferWriter &writer, const BaseDataLayout &layout);
|
||||||
|
|
||||||
// Fit aligned storage in buffer to 64 bytes to conform with AVX 512 types
|
// Fit aligned storage in buffer to 64 bytes to conform with AVX 512 types
|
||||||
inline void *align(void *&ptr) const noexcept
|
inline void *align(void *&ptr) const noexcept
|
||||||
{
|
{
|
||||||
const auto intptr = reinterpret_cast<uintptr_t>(ptr);
|
const auto intptr = reinterpret_cast<std::uintptr_t>(ptr);
|
||||||
const auto aligned = (intptr - 1u + BLOCK_ALIGNMENT) & -BLOCK_ALIGNMENT;
|
const auto aligned = (intptr - 1u + BLOCK_ALIGNMENT) & -BLOCK_ALIGNMENT;
|
||||||
return ptr = reinterpret_cast<void *>(aligned);
|
return ptr = reinterpret_cast<void *>(aligned);
|
||||||
}
|
}
|
||||||
@@ -157,7 +173,27 @@ class DataLayout
|
|||||||
}
|
}
|
||||||
|
|
||||||
static constexpr std::size_t BLOCK_ALIGNMENT = 64;
|
static constexpr std::size_t BLOCK_ALIGNMENT = 64;
|
||||||
std::map<std::string, Block> blocks;
|
};
|
||||||
|
|
||||||
|
class TarDataLayout final : public BaseDataLayout
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline std::uint64_t GetSizeOfLayout() const override final
|
||||||
|
{
|
||||||
|
std::uint64_t result = 0;
|
||||||
|
for (const auto &name_and_block : blocks)
|
||||||
|
{
|
||||||
|
result += GetBlockSize(name_and_block.first);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void *GetBlockPtr(void *base_ptr, const std::string &name) const override final
|
||||||
|
{
|
||||||
|
auto offset = GetBlock(name).offset;
|
||||||
|
const auto offset_address = reinterpret_cast<std::uintptr_t>(base_ptr) + offset;
|
||||||
|
return reinterpret_cast<void *>(offset_address);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SharedRegion
|
struct SharedRegion
|
||||||
|
|||||||
@@ -35,22 +35,28 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
namespace storage
|
namespace storage
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void populateLayoutFromFile(const boost::filesystem::path &path, storage::BaseDataLayout &layout);
|
||||||
|
|
||||||
class Storage
|
class Storage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Storage(StorageConfig config);
|
Storage(StorageConfig config);
|
||||||
|
|
||||||
int Run(int max_wait, const std::string &name, bool only_metric);
|
int Run(int max_wait, const std::string &name, bool only_metric);
|
||||||
|
|
||||||
void PopulateStaticLayout(DataLayout &layout);
|
|
||||||
void PopulateUpdatableLayout(DataLayout &layout);
|
|
||||||
void PopulateStaticData(const SharedDataIndex &index);
|
void PopulateStaticData(const SharedDataIndex &index);
|
||||||
void PopulateUpdatableData(const SharedDataIndex &index);
|
void PopulateUpdatableData(const SharedDataIndex &index);
|
||||||
|
void PopulateLayout(storage::BaseDataLayout &layout,
|
||||||
|
const std::vector<std::pair<bool, boost::filesystem::path>> &files);
|
||||||
|
std::string PopulateLayoutWithRTree(storage::BaseDataLayout &layout);
|
||||||
|
std::vector<std::pair<bool, boost::filesystem::path>> GetUpdatableFiles();
|
||||||
|
std::vector<std::pair<bool, boost::filesystem::path>> GetStaticFiles();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StorageConfig config;
|
StorageConfig config;
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ struct StorageConfig final : IOConfig
|
|||||||
".osrm.turn_duration_penalties",
|
".osrm.turn_duration_penalties",
|
||||||
".osrm.datasource_names",
|
".osrm.datasource_names",
|
||||||
".osrm.names",
|
".osrm.names",
|
||||||
|
".osrm.timestamp",
|
||||||
".osrm.properties",
|
".osrm.properties",
|
||||||
".osrm.icd",
|
".osrm.icd",
|
||||||
".osrm.maneuver_overrides"},
|
".osrm.maneuver_overrides"},
|
||||||
|
|||||||
@@ -272,6 +272,11 @@ inline auto make_partition_view(const SharedDataIndex &index, const std::string
|
|||||||
level_data_ptr, std::move(partition), std::move(cell_to_children)};
|
level_data_ptr, std::move(partition), std::move(cell_to_children)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline auto make_timestamp_view(const SharedDataIndex &index, const std::string &name)
|
||||||
|
{
|
||||||
|
return util::StringView(index.GetBlockPtr<char>(name), index.GetBlockEntries(name));
|
||||||
|
}
|
||||||
|
|
||||||
inline auto make_cell_storage_view(const SharedDataIndex &index, const std::string &name)
|
inline auto make_cell_storage_view(const SharedDataIndex &index, const std::string &name)
|
||||||
{
|
{
|
||||||
auto source_boundary = make_vector_view<NodeID>(index, name + "/source_boundary");
|
auto source_boundary = make_vector_view<NodeID>(index, name + "/source_boundary");
|
||||||
@@ -294,11 +299,14 @@ inline auto make_filtered_cell_metric_view(const SharedDataIndex &index,
|
|||||||
auto prefix = name + "/exclude/" + std::to_string(exclude_index);
|
auto prefix = name + "/exclude/" + std::to_string(exclude_index);
|
||||||
auto weights_block_id = prefix + "/weights";
|
auto weights_block_id = prefix + "/weights";
|
||||||
auto durations_block_id = prefix + "/durations";
|
auto durations_block_id = prefix + "/durations";
|
||||||
|
auto distances_block_id = prefix + "/distances";
|
||||||
|
|
||||||
auto weights = make_vector_view<EdgeWeight>(index, weights_block_id);
|
auto weights = make_vector_view<EdgeWeight>(index, weights_block_id);
|
||||||
auto durations = make_vector_view<EdgeDuration>(index, durations_block_id);
|
auto durations = make_vector_view<EdgeDuration>(index, durations_block_id);
|
||||||
|
auto distances = make_vector_view<EdgeDistance>(index, distances_block_id);
|
||||||
|
|
||||||
return customizer::CellMetricView{std::move(weights), std::move(durations)};
|
return customizer::CellMetricView{
|
||||||
|
std::move(weights), std::move(durations), std::move(distances)};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto make_cell_metric_view(const SharedDataIndex &index, const std::string &name)
|
inline auto make_cell_metric_view(const SharedDataIndex &index, const std::string &name)
|
||||||
@@ -311,12 +319,14 @@ inline auto make_cell_metric_view(const SharedDataIndex &index, const std::strin
|
|||||||
{
|
{
|
||||||
auto weights_block_id = prefix + "/weights";
|
auto weights_block_id = prefix + "/weights";
|
||||||
auto durations_block_id = prefix + "/durations";
|
auto durations_block_id = prefix + "/durations";
|
||||||
|
auto distances_block_id = prefix + "/distances";
|
||||||
|
|
||||||
auto weights = make_vector_view<EdgeWeight>(index, weights_block_id);
|
auto weights = make_vector_view<EdgeWeight>(index, weights_block_id);
|
||||||
auto durations = make_vector_view<EdgeDuration>(index, durations_block_id);
|
auto durations = make_vector_view<EdgeDuration>(index, durations_block_id);
|
||||||
|
auto distances = make_vector_view<EdgeDistance>(index, distances_block_id);
|
||||||
|
|
||||||
cell_metric_excludes.push_back(
|
cell_metric_excludes.push_back(customizer::CellMetricView{
|
||||||
customizer::CellMetricView{std::move(weights), std::move(durations)});
|
std::move(weights), std::move(durations), std::move(distances)});
|
||||||
}
|
}
|
||||||
|
|
||||||
return cell_metric_excludes;
|
return cell_metric_excludes;
|
||||||
@@ -332,6 +342,7 @@ inline auto make_multi_level_graph_view(const SharedDataIndex &index, const std:
|
|||||||
index, name + "/node_to_edge_offset");
|
index, name + "/node_to_edge_offset");
|
||||||
auto node_weights = make_vector_view<EdgeWeight>(index, name + "/node_weights");
|
auto node_weights = make_vector_view<EdgeWeight>(index, name + "/node_weights");
|
||||||
auto node_durations = make_vector_view<EdgeDuration>(index, name + "/node_durations");
|
auto node_durations = make_vector_view<EdgeDuration>(index, name + "/node_durations");
|
||||||
|
auto node_distances = make_vector_view<EdgeDistance>(index, name + "/node_distances");
|
||||||
auto is_forward_edge = make_vector_view<bool>(index, name + "/is_forward_edge");
|
auto is_forward_edge = make_vector_view<bool>(index, name + "/is_forward_edge");
|
||||||
auto is_backward_edge = make_vector_view<bool>(index, name + "/is_backward_edge");
|
auto is_backward_edge = make_vector_view<bool>(index, name + "/is_backward_edge");
|
||||||
|
|
||||||
@@ -340,6 +351,7 @@ inline auto make_multi_level_graph_view(const SharedDataIndex &index, const std:
|
|||||||
std::move(node_to_offset),
|
std::move(node_to_offset),
|
||||||
std::move(node_weights),
|
std::move(node_weights),
|
||||||
std::move(node_durations),
|
std::move(node_durations),
|
||||||
|
std::move(node_distances),
|
||||||
std::move(is_forward_edge),
|
std::move(is_forward_edge),
|
||||||
std::move(is_backward_edge));
|
std::move(is_backward_edge));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,17 @@ class Updater
|
|||||||
std::vector<EdgeWeight> &node_weights,
|
std::vector<EdgeWeight> &node_weights,
|
||||||
std::uint32_t &connectivity_checksum) const;
|
std::uint32_t &connectivity_checksum) const;
|
||||||
|
|
||||||
EdgeID
|
EdgeID LoadAndUpdateEdgeExpandedGraph(
|
||||||
LoadAndUpdateEdgeExpandedGraph(std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list,
|
std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list,
|
||||||
std::vector<EdgeWeight> &node_weights,
|
std::vector<EdgeWeight> &node_weights,
|
||||||
std::vector<EdgeDuration> &node_durations, // TODO: to be deleted
|
std::vector<EdgeDuration> &node_durations, // TODO: remove when optional
|
||||||
std::uint32_t &connectivity_checksum) const;
|
std::uint32_t &connectivity_checksum) const;
|
||||||
|
EdgeID LoadAndUpdateEdgeExpandedGraph(
|
||||||
|
std::vector<extractor::EdgeBasedEdge> &edge_based_edge_list,
|
||||||
|
std::vector<EdgeWeight> &node_weights,
|
||||||
|
std::vector<EdgeDuration> &node_durations, // TODO: remove when optional
|
||||||
|
std::vector<EdgeDistance> &node_distances, // TODO: remove when optional
|
||||||
|
std::uint32_t &connectivity_checksum) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UpdaterConfig config;
|
UpdaterConfig config;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#ifndef OSRM_UTIL_DEBUG_HPP_
|
#ifndef OSRM_UTIL_DEBUG_HPP_
|
||||||
#define OSRM_UTIL_DEBUG_HPP_
|
#define OSRM_UTIL_DEBUG_HPP_
|
||||||
|
|
||||||
|
#include "extractor/edge_based_edge.hpp"
|
||||||
#include "extractor/node_data_container.hpp"
|
#include "extractor/node_data_container.hpp"
|
||||||
#include "extractor/query_node.hpp"
|
#include "extractor/query_node.hpp"
|
||||||
#include "guidance/intersection.hpp"
|
#include "guidance/intersection.hpp"
|
||||||
|
#include "guidance/turn_instruction.hpp"
|
||||||
#include "guidance/turn_lane_data.hpp"
|
#include "guidance/turn_lane_data.hpp"
|
||||||
#include "engine/guidance/route_step.hpp"
|
#include "engine/guidance/route_step.hpp"
|
||||||
#include "util/node_based_graph.hpp"
|
#include "util/node_based_graph.hpp"
|
||||||
@@ -186,6 +188,23 @@ inline std::ostream &operator<<(std::ostream &out, const LaneDataVector &turn_la
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace extractor
|
||||||
|
{
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, const EdgeBasedEdge &edge)
|
||||||
|
{
|
||||||
|
out << " EdgeBasedEdge {";
|
||||||
|
out << " source " << edge.source << ", target: " << edge.target;
|
||||||
|
out << " EdgeBasedEdgeData data {";
|
||||||
|
out << " turn_id: " << edge.data.turn_id << ", weight: " << edge.data.weight;
|
||||||
|
out << " distance: " << edge.data.distance << ", duration: " << edge.data.duration;
|
||||||
|
out << " forward: " << (edge.data.forward == 0 ? "false" : "true")
|
||||||
|
<< ", backward: " << (edge.data.backward == 0 ? "false" : "true");
|
||||||
|
out << " }";
|
||||||
|
out << "}";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /*OSRM_ENGINE_GUIDANCE_DEBUG_HPP_*/
|
#endif /*OSRM_ENGINE_GUIDANCE_DEBUG_HPP_*/
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ THE SOFTWARE.
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#include "msinttypes/stdint.h"
|
#include "rapidjson/msinttypes/stdint.h"
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#else
|
#else
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|||||||
+17
-16
@@ -15,14 +15,14 @@ namespace util
|
|||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template <typename T, typename RegionT>
|
template <typename T, typename MmapContainerT>
|
||||||
util::vector_view<T> mmapFile(const boost::filesystem::path &file, RegionT ®ion)
|
util::vector_view<T> mmapFile(const boost::filesystem::path &file, MmapContainerT &mmap_container)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
region.open(file);
|
mmap_container.open(file);
|
||||||
std::size_t num_objects = region.size() / sizeof(T);
|
std::size_t num_objects = mmap_container.size() / sizeof(T);
|
||||||
auto data_ptr = region.data();
|
auto data_ptr = mmap_container.data();
|
||||||
BOOST_ASSERT(reinterpret_cast<uintptr_t>(data_ptr) % alignof(T) == 0);
|
BOOST_ASSERT(reinterpret_cast<uintptr_t>(data_ptr) % alignof(T) == 0);
|
||||||
return util::vector_view<T>(reinterpret_cast<T *>(data_ptr), num_objects);
|
return util::vector_view<T>(reinterpret_cast<T *>(data_ptr), num_objects);
|
||||||
}
|
}
|
||||||
@@ -34,9 +34,10 @@ util::vector_view<T> mmapFile(const boost::filesystem::path &file, RegionT ®i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename RegionT>
|
template <typename T, typename MmapContainerT>
|
||||||
util::vector_view<T>
|
util::vector_view<T> mmapFile(const boost::filesystem::path &file,
|
||||||
mmapFile(const boost::filesystem::path &file, RegionT ®ion, const std::size_t size)
|
MmapContainerT &mmap_container,
|
||||||
|
const std::size_t size)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -45,10 +46,10 @@ mmapFile(const boost::filesystem::path &file, RegionT ®ion, const std::size_t
|
|||||||
params.path = file.string();
|
params.path = file.string();
|
||||||
params.flags = boost::iostreams::mapped_file::readwrite;
|
params.flags = boost::iostreams::mapped_file::readwrite;
|
||||||
params.new_file_size = size;
|
params.new_file_size = size;
|
||||||
region.open(params);
|
mmap_container.open(params);
|
||||||
|
|
||||||
std::size_t num_objects = size / sizeof(T);
|
std::size_t num_objects = size / sizeof(T);
|
||||||
auto data_ptr = region.data();
|
auto data_ptr = mmap_container.data();
|
||||||
BOOST_ASSERT(reinterpret_cast<uintptr_t>(data_ptr) % alignof(T) == 0);
|
BOOST_ASSERT(reinterpret_cast<uintptr_t>(data_ptr) % alignof(T) == 0);
|
||||||
return util::vector_view<T>(reinterpret_cast<T *>(data_ptr), num_objects);
|
return util::vector_view<T>(reinterpret_cast<T *>(data_ptr), num_objects);
|
||||||
}
|
}
|
||||||
@@ -63,24 +64,24 @@ mmapFile(const boost::filesystem::path &file, RegionT ®ion, const std::size_t
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
util::vector_view<const T> mmapFile(const boost::filesystem::path &file,
|
util::vector_view<const T> mmapFile(const boost::filesystem::path &file,
|
||||||
boost::iostreams::mapped_file_source ®ion)
|
boost::iostreams::mapped_file_source &mmap_container)
|
||||||
{
|
{
|
||||||
return detail::mmapFile<const T>(file, region);
|
return detail::mmapFile<const T>(file, mmap_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
util::vector_view<T> mmapFile(const boost::filesystem::path &file,
|
util::vector_view<T> mmapFile(const boost::filesystem::path &file,
|
||||||
boost::iostreams::mapped_file ®ion)
|
boost::iostreams::mapped_file &mmap_container)
|
||||||
{
|
{
|
||||||
return detail::mmapFile<T>(file, region);
|
return detail::mmapFile<T>(file, mmap_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
util::vector_view<T> mmapFile(const boost::filesystem::path &file,
|
util::vector_view<T> mmapFile(const boost::filesystem::path &file,
|
||||||
boost::iostreams::mapped_file ®ion,
|
boost::iostreams::mapped_file &mmap_container,
|
||||||
std::size_t size)
|
std::size_t size)
|
||||||
{
|
{
|
||||||
return detail::mmapFile<T>(file, region, size);
|
return detail::mmapFile<T>(file, mmap_container, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <tbb/parallel_sort.h>
|
#include <tbb/parallel_sort.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -20,24 +21,27 @@ namespace util
|
|||||||
struct NodeBasedEdgeData
|
struct NodeBasedEdgeData
|
||||||
{
|
{
|
||||||
NodeBasedEdgeData()
|
NodeBasedEdgeData()
|
||||||
: weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_WEIGHT), geometry_id({0, false}),
|
: weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_WEIGHT),
|
||||||
reversed(false), annotation_data(-1)
|
distance(INVALID_EDGE_DISTANCE), geometry_id({0, false}), reversed(false),
|
||||||
|
annotation_data(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeBasedEdgeData(EdgeWeight weight,
|
NodeBasedEdgeData(EdgeWeight weight,
|
||||||
EdgeWeight duration,
|
EdgeWeight duration,
|
||||||
|
EdgeDistance distance,
|
||||||
GeometryID geometry_id,
|
GeometryID geometry_id,
|
||||||
bool reversed,
|
bool reversed,
|
||||||
extractor::NodeBasedEdgeClassification flags,
|
extractor::NodeBasedEdgeClassification flags,
|
||||||
AnnotationID annotation_data)
|
AnnotationID annotation_data)
|
||||||
: weight(weight), duration(duration), geometry_id(geometry_id), reversed(reversed),
|
: weight(weight), duration(duration), distance(distance), geometry_id(geometry_id),
|
||||||
flags(flags), annotation_data(annotation_data)
|
reversed(reversed), flags(flags), annotation_data(annotation_data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeWeight weight;
|
EdgeWeight weight;
|
||||||
EdgeWeight duration;
|
EdgeWeight duration;
|
||||||
|
EdgeDistance distance;
|
||||||
GeometryID geometry_id;
|
GeometryID geometry_id;
|
||||||
bool reversed : 1;
|
bool reversed : 1;
|
||||||
extractor::NodeBasedEdgeClassification flags;
|
extractor::NodeBasedEdgeClassification flags;
|
||||||
@@ -80,11 +84,13 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
|||||||
const extractor::NodeBasedEdge &input_edge) {
|
const extractor::NodeBasedEdge &input_edge) {
|
||||||
output_edge.data.weight = input_edge.weight;
|
output_edge.data.weight = input_edge.weight;
|
||||||
output_edge.data.duration = input_edge.duration;
|
output_edge.data.duration = input_edge.duration;
|
||||||
|
output_edge.data.distance = input_edge.distance;
|
||||||
output_edge.data.flags = input_edge.flags;
|
output_edge.data.flags = input_edge.flags;
|
||||||
output_edge.data.annotation_data = input_edge.annotation_data;
|
output_edge.data.annotation_data = input_edge.annotation_data;
|
||||||
|
|
||||||
BOOST_ASSERT(output_edge.data.weight > 0);
|
BOOST_ASSERT(output_edge.data.weight > 0);
|
||||||
BOOST_ASSERT(output_edge.data.duration > 0);
|
BOOST_ASSERT(output_edge.data.duration > 0);
|
||||||
|
BOOST_ASSERT(output_edge.data.distance >= 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ using EdgeDistance = float;
|
|||||||
using SegmentWeight = std::uint32_t;
|
using SegmentWeight = std::uint32_t;
|
||||||
using SegmentDuration = std::uint32_t;
|
using SegmentDuration = std::uint32_t;
|
||||||
using TurnPenalty = std::int16_t; // turn penalty in 100ms units
|
using TurnPenalty = std::int16_t; // turn penalty in 100ms units
|
||||||
|
using DataTimestamp = std::string;
|
||||||
|
|
||||||
static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max();
|
static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max();
|
||||||
|
|
||||||
@@ -113,8 +114,10 @@ static const SegmentWeight MAX_SEGMENT_WEIGHT = INVALID_SEGMENT_WEIGHT - 1;
|
|||||||
static const SegmentDuration MAX_SEGMENT_DURATION = INVALID_SEGMENT_DURATION - 1;
|
static const SegmentDuration MAX_SEGMENT_DURATION = INVALID_SEGMENT_DURATION - 1;
|
||||||
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<EdgeWeight>::max();
|
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<EdgeWeight>::max();
|
||||||
static const EdgeDuration MAXIMAL_EDGE_DURATION = std::numeric_limits<EdgeDuration>::max();
|
static const EdgeDuration MAXIMAL_EDGE_DURATION = std::numeric_limits<EdgeDuration>::max();
|
||||||
|
static const EdgeDistance MAXIMAL_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
|
||||||
static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>::max();
|
static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>::max();
|
||||||
static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
|
static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
|
||||||
|
static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits<double>::max();
|
||||||
|
|
||||||
// FIXME the bitfields we use require a reduced maximal duration, this should be kept consistent
|
// FIXME the bitfields we use require a reduced maximal duration, this should be kept consistent
|
||||||
// within the code base. For now we have to ensure that we don't case 30 bit to -1 and break any
|
// within the code base. For now we have to ensure that we don't case 30 bit to -1 and break any
|
||||||
|
|||||||
@@ -195,7 +195,10 @@ template <> class vector_view<bool>
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
||||||
const std::size_t bucket = index / WORD_BITS;
|
const std::size_t bucket = index / WORD_BITS;
|
||||||
|
// Note: ordering of bits here should match packBits in storage/serialization.hpp
|
||||||
|
// so that directly mmap-ing data is possible
|
||||||
const auto offset = index % WORD_BITS;
|
const auto offset = index % WORD_BITS;
|
||||||
|
BOOST_ASSERT(WORD_BITS > offset);
|
||||||
return m_ptr[bucket] & (static_cast<Word>(1) << offset);
|
return m_ptr[bucket] & (static_cast<Word>(1) << offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,11 +227,23 @@ template <> class vector_view<bool>
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(index < m_size);
|
BOOST_ASSERT(index < m_size);
|
||||||
const auto bucket = index / WORD_BITS;
|
const auto bucket = index / WORD_BITS;
|
||||||
|
// Note: ordering of bits here should match packBits in storage/serialization.hpp
|
||||||
|
// so that directly mmap-ing data is possible
|
||||||
const auto offset = index % WORD_BITS;
|
const auto offset = index % WORD_BITS;
|
||||||
|
BOOST_ASSERT(WORD_BITS > offset);
|
||||||
return reference{m_ptr + bucket, static_cast<Word>(1) << offset};
|
return reference{m_ptr + bucket, static_cast<Word>(1) << offset};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> friend void swap(vector_view<T> &, vector_view<T> &) noexcept;
|
template <typename T> friend void swap(vector_view<T> &, vector_view<T> &) noexcept;
|
||||||
|
|
||||||
|
friend std::ostream &operator<<(std::ostream &os, const vector_view<bool> &rhs)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < rhs.size(); ++i)
|
||||||
|
{
|
||||||
|
os << (i > 0 ? " " : "") << rhs.at(i);
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Both vector_view<T> and the vector_view<bool> specializations share this impl.
|
// Both vector_view<T> and the vector_view<bool> specializations share this impl.
|
||||||
|
|||||||
Generated
+6732
-2897
File diff suppressed because it is too large
Load Diff
+7
-7
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "osrm",
|
"name": "osrm",
|
||||||
"version": "5.18.0-latest.1",
|
"version": "5.22.0-customsnapping.2",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"nan": "^2.6.2",
|
"nan": "^2.11.1",
|
||||||
"node-cmake": "^2.3.2",
|
"node-cmake": "^2.3.2",
|
||||||
"node-pre-gyp": "^0.6.36",
|
"node-pre-gyp": "^0.12.0",
|
||||||
"rimraf": "^2.5.4"
|
"rimraf": "^2.5.4"
|
||||||
},
|
},
|
||||||
"browserify": {
|
"browserify": {
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "node ./node_modules/eslint/bin/eslint.js -c ./.eslintrc features/step_definitions/ features/support/",
|
"lint": "node ./node_modules/eslint/bin/eslint.js -c ./.eslintrc features/step_definitions/ features/support/",
|
||||||
"test": "npm run lint && node ./node_modules/cucumber/bin/cucumber.js features/ -p verify && node ./node_modules/cucumber/bin/cucumber.js features/ -p mld",
|
"test": "npm run lint && node ./node_modules/cucumber/bin/cucumber.js features/ -p verify && node ./node_modules/cucumber/bin/cucumber.js features/ -p verify -m mmap && node ./node_modules/cucumber/bin/cucumber.js features/ -p mld && node ./node_modules/cucumber/bin/cucumber.js features/ -p mld -m mmap",
|
||||||
"clean": "rm -rf test/cache",
|
"clean": "rm -rf test/cache",
|
||||||
"docs": "./scripts/build_api_docs.sh",
|
"docs": "./scripts/build_api_docs.sh",
|
||||||
"install": "node-pre-gyp install --fallback-to-build=false || ./scripts/node_install.sh",
|
"install": "node-pre-gyp install --fallback-to-build=false || ./scripts/node_install.sh",
|
||||||
@@ -47,14 +47,14 @@
|
|||||||
"csv-stringify": "^3.0.0",
|
"csv-stringify": "^3.0.0",
|
||||||
"cucumber": "^1.2.1",
|
"cucumber": "^1.2.1",
|
||||||
"d3-queue": "^2.0.3",
|
"d3-queue": "^2.0.3",
|
||||||
"docbox": "^1.0.6",
|
"docbox": "^1.0.11",
|
||||||
"documentation": "^4.0.0-rc.1",
|
"documentation": "^4.0.0-rc.1",
|
||||||
"eslint": "^2.4.0",
|
"eslint": "^5.10.0",
|
||||||
"faucet": "^0.0.1",
|
"faucet": "^0.0.1",
|
||||||
"jsonpath": "^1.0.0",
|
"jsonpath": "^1.0.0",
|
||||||
"node-timeout": "0.0.4",
|
"node-timeout": "0.0.4",
|
||||||
"polyline": "^0.2.0",
|
"polyline": "^0.2.0",
|
||||||
"request": "^2.69.0",
|
"request": "^2.88.0",
|
||||||
"tape": "^4.7.0",
|
"tape": "^4.7.0",
|
||||||
"turf": "^3.0.14",
|
"turf": "^3.0.14",
|
||||||
"xmlbuilder": "^4.2.1"
|
"xmlbuilder": "^4.2.1"
|
||||||
|
|||||||
+4
-17
@@ -7,6 +7,7 @@ Sequence = require('lib/sequence')
|
|||||||
Handlers = require("lib/way_handlers")
|
Handlers = require("lib/way_handlers")
|
||||||
find_access_tag = require("lib/access").find_access_tag
|
find_access_tag = require("lib/access").find_access_tag
|
||||||
limit = require("lib/maxspeed").limit
|
limit = require("lib/maxspeed").limit
|
||||||
|
Measure = require("lib/measure")
|
||||||
|
|
||||||
function setup()
|
function setup()
|
||||||
local default_speed = 15
|
local default_speed = 15
|
||||||
@@ -206,20 +207,6 @@ function setup()
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local function parse_maxspeed(source)
|
|
||||||
if not source then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
local n = tonumber(source:match("%d*"))
|
|
||||||
if not n then
|
|
||||||
n = 0
|
|
||||||
end
|
|
||||||
if string.match(source, "mph") or string.match(source, "mp/h") then
|
|
||||||
n = (n*1609)/1000
|
|
||||||
end
|
|
||||||
return n
|
|
||||||
end
|
|
||||||
|
|
||||||
function process_node(profile, node, result)
|
function process_node(profile, node, result)
|
||||||
-- parse access and barrier tags
|
-- parse access and barrier tags
|
||||||
local highway = node:get_value_by_key("highway")
|
local highway = node:get_value_by_key("highway")
|
||||||
@@ -276,9 +263,9 @@ function handle_bicycle_tags(profile,way,result,data)
|
|||||||
|
|
||||||
-- other tags
|
-- other tags
|
||||||
data.junction = way:get_value_by_key("junction")
|
data.junction = way:get_value_by_key("junction")
|
||||||
data.maxspeed = parse_maxspeed(way:get_value_by_key ( "maxspeed") )
|
data.maxspeed = Measure.get_max_speed(way:get_value_by_key ("maxspeed")) or 0
|
||||||
data.maxspeed_forward = parse_maxspeed(way:get_value_by_key( "maxspeed:forward"))
|
data.maxspeed_forward = Measure.get_max_speed(way:get_value_by_key("maxspeed:forward")) or 0
|
||||||
data.maxspeed_backward = parse_maxspeed(way:get_value_by_key( "maxspeed:backward"))
|
data.maxspeed_backward = Measure.get_max_speed(way:get_value_by_key("maxspeed:backward")) or 0
|
||||||
data.barrier = way:get_value_by_key("barrier")
|
data.barrier = way:get_value_by_key("barrier")
|
||||||
data.oneway = way:get_value_by_key("oneway")
|
data.oneway = way:get_value_by_key("oneway")
|
||||||
data.oneway_bicycle = way:get_value_by_key("oneway:bicycle")
|
data.oneway_bicycle = way:get_value_by_key("oneway:bicycle")
|
||||||
|
|||||||
@@ -269,6 +269,7 @@ function setup()
|
|||||||
["at:rural"] = 100,
|
["at:rural"] = 100,
|
||||||
["at:trunk"] = 100,
|
["at:trunk"] = 100,
|
||||||
["be:motorway"] = 120,
|
["be:motorway"] = 120,
|
||||||
|
["be-vlg:rural"] = 70,
|
||||||
["by:urban"] = 60,
|
["by:urban"] = 60,
|
||||||
["by:motorway"] = 110,
|
["by:motorway"] = 110,
|
||||||
["ch:rural"] = 80,
|
["ch:rural"] = 80,
|
||||||
|
|||||||
@@ -6,6 +6,18 @@ Measure = {}
|
|||||||
local inch_to_meters = 0.0254
|
local inch_to_meters = 0.0254
|
||||||
local feet_to_inches = 12
|
local feet_to_inches = 12
|
||||||
local pound_to_kilograms = 0.45359237
|
local pound_to_kilograms = 0.45359237
|
||||||
|
local miles_to_kilometers = 1.609
|
||||||
|
|
||||||
|
-- Parse speed value as kilometers by hours.
|
||||||
|
function Measure.parse_value_speed(source)
|
||||||
|
local n = tonumber(source:match("%d*"))
|
||||||
|
if n then
|
||||||
|
if string.match(source, "mph") or string.match(source, "mp/h") then
|
||||||
|
n = n * miles_to_kilometers
|
||||||
|
end
|
||||||
|
return n
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- Parse string as a height in meters.
|
--- Parse string as a height in meters.
|
||||||
--- according to http://wiki.openstreetmap.org/wiki/Key:maxheight
|
--- according to http://wiki.openstreetmap.org/wiki/Key:maxheight
|
||||||
@@ -42,6 +54,13 @@ function Measure.parse_value_kilograms(value)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get maxspeed of specified way in kilometers by hours.
|
||||||
|
function Measure.get_max_speed(raw_value)
|
||||||
|
if raw_value then
|
||||||
|
return Measure.parse_value_speed(raw_value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- default maxheight value defined in https://wiki.openstreetmap.org/wiki/Key:maxheight#Non-numerical_values
|
-- default maxheight value defined in https://wiki.openstreetmap.org/wiki/Key:maxheight#Non-numerical_values
|
||||||
local default_maxheight = 4.5
|
local default_maxheight = 4.5
|
||||||
-- Available Non numerical values equal to 4.5; below_default and no_indications are not considered
|
-- Available Non numerical values equal to 4.5; below_default and no_indications are not considered
|
||||||
|
|||||||
@@ -432,7 +432,7 @@ end
|
|||||||
|
|
||||||
-- maxspeed and advisory maxspeed
|
-- maxspeed and advisory maxspeed
|
||||||
function WayHandlers.maxspeed(profile,way,result,data)
|
function WayHandlers.maxspeed(profile,way,result,data)
|
||||||
local keys = Sequence { 'maxspeed:advisory', 'maxspeed' }
|
local keys = Sequence { 'maxspeed:advisory', 'maxspeed', 'source:maxspeed', 'maxspeed:type' }
|
||||||
local forward, backward = Tags.get_forward_backward_by_set(way,data,keys)
|
local forward, backward = Tags.get_forward_backward_by_set(way,data,keys)
|
||||||
forward = WayHandlers.parse_maxspeed(forward,profile)
|
forward = WayHandlers.parse_maxspeed(forward,profile)
|
||||||
backward = WayHandlers.parse_maxspeed(backward,profile)
|
backward = WayHandlers.parse_maxspeed(backward,profile)
|
||||||
@@ -450,12 +450,9 @@ function WayHandlers.parse_maxspeed(source,profile)
|
|||||||
if not source then
|
if not source then
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
local n = tonumber(source:match("%d*"))
|
|
||||||
if n then
|
local n = Measure.get_max_speed(source)
|
||||||
if string.match(source, "mph") or string.match(source, "mp/h") then
|
if not n then
|
||||||
n = (n*1609)/1000
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- parse maxspeed like FR:urban
|
-- parse maxspeed like FR:urban
|
||||||
source = string.lower(source)
|
source = string.lower(source)
|
||||||
n = profile.maxspeed_table[source]
|
n = profile.maxspeed_table[source]
|
||||||
|
|||||||
+6
-2
@@ -6,8 +6,12 @@ var fs = require('fs');
|
|||||||
var name = process.argv[2];
|
var name = process.argv[2];
|
||||||
var cmd = process.argv.slice(3).join(' ');
|
var cmd = process.argv.slice(3).join(' ');
|
||||||
var start = Date.now();
|
var start = Date.now();
|
||||||
exec(cmd, (err) => {
|
exec(cmd, (err, stdout, stderr) => {
|
||||||
if (err) return console.log(err);
|
if (err) {
|
||||||
|
console.log(stdout);
|
||||||
|
console.log(stderr);
|
||||||
|
return process.exit(err.code);
|
||||||
|
}
|
||||||
var stop = +new Date();
|
var stop = +new Date();
|
||||||
var time = (stop - start) / 1000.;
|
var time = (stop - start) / 1000.;
|
||||||
fs.appendFileSync('/tmp/osrm.timings', `${name}\t${time}`, 'utf-8');
|
fs.appendFileSync('/tmp/osrm.timings', `${name}\t${time}`, 'utf-8');
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ void ContractNode(ContractorThreadData *data,
|
|||||||
target,
|
target,
|
||||||
path_weight,
|
path_weight,
|
||||||
in_data.duration + out_data.duration,
|
in_data.duration + out_data.duration,
|
||||||
|
in_data.distance + out_data.distance,
|
||||||
out_data.originalEdges + in_data.originalEdges,
|
out_data.originalEdges + in_data.originalEdges,
|
||||||
node,
|
node,
|
||||||
SHORTCUT_ARC,
|
SHORTCUT_ARC,
|
||||||
@@ -225,6 +226,7 @@ void ContractNode(ContractorThreadData *data,
|
|||||||
source,
|
source,
|
||||||
path_weight,
|
path_weight,
|
||||||
in_data.duration + out_data.duration,
|
in_data.duration + out_data.duration,
|
||||||
|
in_data.distance + out_data.distance,
|
||||||
out_data.originalEdges + in_data.originalEdges,
|
out_data.originalEdges + in_data.originalEdges,
|
||||||
node,
|
node,
|
||||||
SHORTCUT_ARC,
|
SHORTCUT_ARC,
|
||||||
@@ -280,6 +282,7 @@ void ContractNode(ContractorThreadData *data,
|
|||||||
target,
|
target,
|
||||||
path_weight,
|
path_weight,
|
||||||
in_data.duration + out_data.duration,
|
in_data.duration + out_data.duration,
|
||||||
|
in_data.distance + out_data.distance,
|
||||||
out_data.originalEdges + in_data.originalEdges,
|
out_data.originalEdges + in_data.originalEdges,
|
||||||
node,
|
node,
|
||||||
SHORTCUT_ARC,
|
SHORTCUT_ARC,
|
||||||
@@ -290,6 +293,7 @@ void ContractNode(ContractorThreadData *data,
|
|||||||
source,
|
source,
|
||||||
path_weight,
|
path_weight,
|
||||||
in_data.duration + out_data.duration,
|
in_data.duration + out_data.duration,
|
||||||
|
in_data.distance + out_data.distance,
|
||||||
out_data.originalEdges + in_data.originalEdges,
|
out_data.originalEdges + in_data.originalEdges,
|
||||||
node,
|
node,
|
||||||
SHORTCUT_ARC,
|
SHORTCUT_ARC,
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ auto LoadAndUpdateEdgeExpandedGraph(const CustomizationConfig &config,
|
|||||||
const partitioner::MultiLevelPartition &mlp,
|
const partitioner::MultiLevelPartition &mlp,
|
||||||
std::vector<EdgeWeight> &node_weights,
|
std::vector<EdgeWeight> &node_weights,
|
||||||
std::vector<EdgeDuration> &node_durations,
|
std::vector<EdgeDuration> &node_durations,
|
||||||
|
std::vector<EdgeDistance> &node_distances,
|
||||||
std::uint32_t &connectivity_checksum)
|
std::uint32_t &connectivity_checksum)
|
||||||
{
|
{
|
||||||
updater::Updater updater(config.updater_config);
|
updater::Updater updater(config.updater_config);
|
||||||
@@ -84,6 +85,8 @@ auto LoadAndUpdateEdgeExpandedGraph(const CustomizationConfig &config,
|
|||||||
EdgeID num_nodes = updater.LoadAndUpdateEdgeExpandedGraph(
|
EdgeID num_nodes = updater.LoadAndUpdateEdgeExpandedGraph(
|
||||||
edge_based_edge_list, node_weights, node_durations, connectivity_checksum);
|
edge_based_edge_list, node_weights, node_durations, connectivity_checksum);
|
||||||
|
|
||||||
|
extractor::files::readEdgeBasedNodeDistances(config.GetPath(".osrm.enw"), node_distances);
|
||||||
|
|
||||||
auto directed = partitioner::splitBidirectionalEdges(edge_based_edge_list);
|
auto directed = partitioner::splitBidirectionalEdges(edge_based_edge_list);
|
||||||
|
|
||||||
auto tidied = partitioner::prepareEdgesForUsageInGraph<
|
auto tidied = partitioner::prepareEdgesForUsageInGraph<
|
||||||
@@ -124,10 +127,11 @@ int Customizer::Run(const CustomizationConfig &config)
|
|||||||
partitioner::files::readPartition(config.GetPath(".osrm.partition"), mlp);
|
partitioner::files::readPartition(config.GetPath(".osrm.partition"), mlp);
|
||||||
|
|
||||||
std::vector<EdgeWeight> node_weights;
|
std::vector<EdgeWeight> node_weights;
|
||||||
std::vector<EdgeDuration> node_durations; // TODO: to be removed later
|
std::vector<EdgeDuration> node_durations; // TODO: remove when durations are optional
|
||||||
|
std::vector<EdgeDistance> node_distances; // TODO: remove when distances are optional
|
||||||
std::uint32_t connectivity_checksum = 0;
|
std::uint32_t connectivity_checksum = 0;
|
||||||
auto graph = LoadAndUpdateEdgeExpandedGraph(
|
auto graph = LoadAndUpdateEdgeExpandedGraph(
|
||||||
config, mlp, node_weights, node_durations, connectivity_checksum);
|
config, mlp, node_weights, node_durations, node_distances, connectivity_checksum);
|
||||||
BOOST_ASSERT(graph.GetNumberOfNodes() == node_weights.size());
|
BOOST_ASSERT(graph.GetNumberOfNodes() == node_weights.size());
|
||||||
std::for_each(node_weights.begin(), node_weights.end(), [](auto &w) { w &= 0x7fffffff; });
|
std::for_each(node_weights.begin(), node_weights.end(), [](auto &w) { w &= 0x7fffffff; });
|
||||||
util::Log() << "Loaded edge based graph: " << graph.GetNumberOfEdges() << " edges, "
|
util::Log() << "Loaded edge based graph: " << graph.GetNumberOfEdges() << " edges, "
|
||||||
@@ -166,8 +170,10 @@ int Customizer::Run(const CustomizationConfig &config)
|
|||||||
util::Log() << "MLD customization writing took " << TIMER_SEC(writing_mld_data) << " seconds";
|
util::Log() << "MLD customization writing took " << TIMER_SEC(writing_mld_data) << " seconds";
|
||||||
|
|
||||||
TIMER_START(writing_graph);
|
TIMER_START(writing_graph);
|
||||||
MultiLevelEdgeBasedGraph shaved_graph{
|
MultiLevelEdgeBasedGraph shaved_graph{std::move(graph),
|
||||||
std::move(graph), std::move(node_weights), std::move(node_durations)};
|
std::move(node_weights),
|
||||||
|
std::move(node_durations),
|
||||||
|
std::move(node_distances)};
|
||||||
customizer::files::writeGraph(
|
customizer::files::writeGraph(
|
||||||
config.GetPath(".osrm.mldgr"), shaved_graph, connectivity_checksum);
|
config.GetPath(".osrm.mldgr"), shaved_graph, connectivity_checksum);
|
||||||
TIMER_STOP(writing_graph);
|
TIMER_STOP(writing_graph);
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ std::string waypointTypeToString(const guidance::WaypointType waypoint_type)
|
|||||||
return waypoint_type_names[static_cast<std::size_t>(waypoint_type)];
|
return waypoint_type_names[static_cast<std::size_t>(waypoint_type)];
|
||||||
}
|
}
|
||||||
|
|
||||||
util::json::Array coordinateToLonLat(const util::Coordinate coordinate)
|
util::json::Array coordinateToLonLat(const util::Coordinate &coordinate)
|
||||||
{
|
{
|
||||||
util::json::Array array;
|
util::json::Array array;
|
||||||
array.values.push_back(static_cast<double>(util::toFloating(coordinate.lon)));
|
array.values.push_back(static_cast<double>(util::toFloating(coordinate.lon)));
|
||||||
@@ -240,17 +240,22 @@ util::json::Object makeRoute(const guidance::Route &route,
|
|||||||
return json_route;
|
return json_route;
|
||||||
}
|
}
|
||||||
|
|
||||||
util::json::Object makeWaypoint(const util::Coordinate location, std::string name)
|
util::json::Object
|
||||||
|
makeWaypoint(const util::Coordinate &location, const double &distance, std::string name)
|
||||||
{
|
{
|
||||||
util::json::Object waypoint;
|
util::json::Object waypoint;
|
||||||
waypoint.values["location"] = detail::coordinateToLonLat(location);
|
waypoint.values["location"] = detail::coordinateToLonLat(location);
|
||||||
waypoint.values["name"] = std::move(name);
|
waypoint.values["name"] = std::move(name);
|
||||||
|
waypoint.values["distance"] = distance;
|
||||||
return waypoint;
|
return waypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
util::json::Object makeWaypoint(const util::Coordinate location, std::string name, const Hint &hint)
|
util::json::Object makeWaypoint(const util::Coordinate &location,
|
||||||
|
const double &distance,
|
||||||
|
std::string name,
|
||||||
|
const Hint &hint)
|
||||||
{
|
{
|
||||||
auto waypoint = makeWaypoint(location, name);
|
auto waypoint = makeWaypoint(location, distance, name);
|
||||||
waypoint.values["hint"] = hint.ToBase64();
|
waypoint.values["hint"] = hint.ToBase64();
|
||||||
return waypoint;
|
return waypoint;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "engine/datafacade/mmap_memory_allocator.hpp"
|
#include "engine/datafacade/mmap_memory_allocator.hpp"
|
||||||
|
|
||||||
|
#include "storage/block.hpp"
|
||||||
#include "storage/io.hpp"
|
#include "storage/io.hpp"
|
||||||
#include "storage/serialization.hpp"
|
#include "storage/serialization.hpp"
|
||||||
#include "storage/storage.hpp"
|
#include "storage/storage.hpp"
|
||||||
@@ -7,7 +8,7 @@
|
|||||||
#include "util/log.hpp"
|
#include "util/log.hpp"
|
||||||
#include "util/mmap_file.hpp"
|
#include "util/mmap_file.hpp"
|
||||||
|
|
||||||
#include "boost/assert.hpp"
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
@@ -16,46 +17,50 @@ namespace engine
|
|||||||
namespace datafacade
|
namespace datafacade
|
||||||
{
|
{
|
||||||
|
|
||||||
MMapMemoryAllocator::MMapMemoryAllocator(const storage::StorageConfig &config,
|
MMapMemoryAllocator::MMapMemoryAllocator(const storage::StorageConfig &config)
|
||||||
const boost::filesystem::path &memory_file)
|
|
||||||
{
|
{
|
||||||
storage::Storage storage(config);
|
storage::Storage storage(config);
|
||||||
|
std::vector<storage::SharedDataIndex::AllocatedRegion> allocated_regions;
|
||||||
|
|
||||||
if (!boost::filesystem::exists(memory_file))
|
|
||||||
{
|
{
|
||||||
storage::DataLayout initial_layout;
|
std::unique_ptr<storage::BaseDataLayout> fake_layout =
|
||||||
storage.PopulateStaticLayout(initial_layout);
|
std::make_unique<storage::TarDataLayout>();
|
||||||
storage.PopulateUpdatableLayout(initial_layout);
|
|
||||||
|
|
||||||
auto data_size = initial_layout.GetSizeOfLayout();
|
// Convert the boost::filesystem::path object into a plain string
|
||||||
|
// that's stored as a member of this allocator object
|
||||||
|
rtree_filename = storage.PopulateLayoutWithRTree(*fake_layout);
|
||||||
|
|
||||||
storage::io::BufferWriter writer;
|
// Now, we add one more AllocatedRegion, with it's start address as the start
|
||||||
storage::serialization::write(writer, initial_layout);
|
// of the rtree_filename string we've saved. In the fake_layout, we've
|
||||||
auto encoded_layout = writer.GetBuffer();
|
// stated that the data is at offset 0, which is where the string starts
|
||||||
|
// at it's own memory address.
|
||||||
auto total_size = data_size + encoded_layout.size();
|
// The syntax &(rtree_filename[0]) gets the memory address of the first char.
|
||||||
|
// We can't use the convenient `.data()` or `.c_str()` methods, because
|
||||||
mapped_memory = util::mmapFile<char>(memory_file, mapped_memory_file, total_size);
|
// prior to C++17 (which we're not using), those return a `const char *`,
|
||||||
|
// which isn't compatible with the `char *` that AllocatedRegion expects
|
||||||
std::copy(encoded_layout.begin(), encoded_layout.end(), mapped_memory.data());
|
// for it's memory_ptr
|
||||||
|
allocated_regions.push_back({&(rtree_filename[0]), std::move(fake_layout)});
|
||||||
index = storage::SharedDataIndex(
|
|
||||||
{{mapped_memory.data() + encoded_layout.size(), std::move(initial_layout)}});
|
|
||||||
|
|
||||||
storage.PopulateStaticData(index);
|
|
||||||
storage.PopulateUpdatableData(index);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
auto files = storage.GetStaticFiles();
|
||||||
|
auto updatable_files = storage.GetUpdatableFiles();
|
||||||
|
files.insert(files.end(), updatable_files.begin(), updatable_files.end());
|
||||||
|
|
||||||
|
for (const auto &file : files)
|
||||||
{
|
{
|
||||||
mapped_memory = util::mmapFile<char>(memory_file, mapped_memory_file);
|
if (boost::filesystem::exists(file.second))
|
||||||
|
{
|
||||||
storage::DataLayout layout;
|
std::unique_ptr<storage::BaseDataLayout> layout =
|
||||||
storage::io::BufferReader reader(mapped_memory.data(), mapped_memory.size());
|
std::make_unique<storage::TarDataLayout>();
|
||||||
storage::serialization::read(reader, layout);
|
boost::iostreams::mapped_file mapped_memory_file;
|
||||||
auto layout_size = reader.GetPosition();
|
util::mmapFile<char>(file.second, mapped_memory_file);
|
||||||
|
mapped_memory_files.push_back(std::move(mapped_memory_file));
|
||||||
index = storage::SharedDataIndex({{mapped_memory.data() + layout_size, std::move(layout)}});
|
storage::populateLayoutFromFile(file.second, *layout);
|
||||||
|
allocated_regions.push_back({mapped_memory_file.data(), std::move(layout)});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
index = storage::SharedDataIndex{std::move(allocated_regions)};
|
||||||
}
|
}
|
||||||
|
|
||||||
MMapMemoryAllocator::~MMapMemoryAllocator() {}
|
MMapMemoryAllocator::~MMapMemoryAllocator() {}
|
||||||
|
|||||||
@@ -15,14 +15,20 @@ ProcessMemoryAllocator::ProcessMemoryAllocator(const storage::StorageConfig &con
|
|||||||
storage::Storage storage(config);
|
storage::Storage storage(config);
|
||||||
|
|
||||||
// Calculate the layout/size of the memory block
|
// Calculate the layout/size of the memory block
|
||||||
storage::DataLayout layout;
|
auto static_files = storage.GetStaticFiles();
|
||||||
storage.PopulateStaticLayout(layout);
|
auto updatable_files = storage.GetUpdatableFiles();
|
||||||
storage.PopulateUpdatableLayout(layout);
|
std::unique_ptr<storage::BaseDataLayout> layout =
|
||||||
|
std::make_unique<storage::ContiguousDataLayout>();
|
||||||
|
storage.PopulateLayoutWithRTree(*layout);
|
||||||
|
storage.PopulateLayout(*layout, static_files);
|
||||||
|
storage.PopulateLayout(*layout, updatable_files);
|
||||||
|
|
||||||
// Allocate the memory block, then load data from files into it
|
// Allocate the memory block, then load data from files into it
|
||||||
internal_memory = std::make_unique<char[]>(layout.GetSizeOfLayout());
|
internal_memory = std::make_unique<char[]>(layout->GetSizeOfLayout());
|
||||||
|
|
||||||
index = storage::SharedDataIndex({{internal_memory.get(), std::move(layout)}});
|
std::vector<storage::SharedDataIndex::AllocatedRegion> regions;
|
||||||
|
regions.push_back({internal_memory.get(), std::move(layout)});
|
||||||
|
index = {std::move(regions)};
|
||||||
|
|
||||||
storage.PopulateStaticData(index);
|
storage.PopulateStaticData(index);
|
||||||
storage.PopulateUpdatableData(index);
|
storage.PopulateUpdatableData(index);
|
||||||
|
|||||||
@@ -25,8 +25,9 @@ SharedMemoryAllocator::SharedMemoryAllocator(
|
|||||||
auto mem = storage::makeSharedMemory(shm_key);
|
auto mem = storage::makeSharedMemory(shm_key);
|
||||||
|
|
||||||
storage::io::BufferReader reader(reinterpret_cast<char *>(mem->Ptr()), mem->Size());
|
storage::io::BufferReader reader(reinterpret_cast<char *>(mem->Ptr()), mem->Size());
|
||||||
storage::DataLayout layout;
|
std::unique_ptr<storage::BaseDataLayout> layout =
|
||||||
storage::serialization::read(reader, layout);
|
std::make_unique<storage::ContiguousDataLayout>();
|
||||||
|
storage::serialization::read(reader, *layout);
|
||||||
auto layout_size = reader.GetPosition();
|
auto layout_size = reader.GetPosition();
|
||||||
|
|
||||||
regions.push_back({reinterpret_cast<char *>(mem->Ptr()) + layout_size, std::move(layout)});
|
regions.push_back({reinterpret_cast<char *>(mem->Ptr()) + layout_size, std::move(layout)});
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ bool EngineConfig::IsValid() const
|
|||||||
unlimited_or_more_than(max_results_nearest, 0) &&
|
unlimited_or_more_than(max_results_nearest, 0) &&
|
||||||
max_alternatives >= 0;
|
max_alternatives >= 0;
|
||||||
|
|
||||||
return ((use_shared_memory && all_path_are_empty) || storage_config.IsValid()) && limits_valid;
|
return ((use_shared_memory && all_path_are_empty) || (use_mmap && storage_config.IsValid()) ||
|
||||||
|
storage_config.IsValid()) &&
|
||||||
|
limits_valid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user