Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 210908dbe6 | |||
| 6b9006f6e7 | |||
| ca55521c87 | |||
| 67e99c9809 | |||
| 05647adcc6 | |||
| 6c37b71046 | |||
| cb2a46b8d9 | |||
| 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 |
@@ -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
|
||||||
|
|||||||
+59
-64
@@ -13,11 +13,12 @@ notifications:
|
|||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
- 5.21
|
||||||
# enable building tags
|
# enable building tags
|
||||||
- /^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 +35,7 @@ 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"
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
@@ -45,7 +46,7 @@ matrix:
|
|||||||
# Debug Builds
|
# Debug Builds
|
||||||
- os: linux
|
- 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:
|
||||||
@@ -53,8 +54,7 @@ matrix:
|
|||||||
- 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 +156,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 +180,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,6 +228,54 @@ 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
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- source $NVM_DIR/nvm.sh
|
- source $NVM_DIR/nvm.sh
|
||||||
- nvm install $NODE
|
- nvm install $NODE
|
||||||
@@ -294,15 +294,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@1.11.1
|
|
||||||
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 +376,4 @@ script:
|
|||||||
fi
|
fi
|
||||||
- |
|
- |
|
||||||
- popd
|
- popd
|
||||||
- yarn test
|
- npm test
|
||||||
|
|||||||
+25
-1
@@ -1,13 +1,37 @@
|
|||||||
# UNRELEASED
|
# 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:
|
- Changes from 5.19.0:
|
||||||
- Table:
|
- 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)
|
- 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)
|
- 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:
|
- Features:
|
||||||
- ADDED: direct mmapping of datafiles is now supported via the `--mmap` switch. [#5242](https://github.com/Project-OSRM/osrm-backend/pull/5242)
|
- 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)
|
- 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:
|
- Windows:
|
||||||
- FIXED: Windows builds again. [#5249](https://github.com/Project-OSRM/osrm-backend/pull/5249)
|
- 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
|
# 5.19.0
|
||||||
- Changes from 5.18.0:
|
- Changes from 5.18.0:
|
||||||
|
|||||||
@@ -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/)
|
||||||
|
|
||||||
|
|||||||
+12
-13
@@ -1,15 +1,13 @@
|
|||||||
FROM alpine:3.6 as buildstage
|
FROM debian:buster-slim as builder
|
||||||
|
|
||||||
ARG DOCKER_TAG
|
ARG DOCKER_TAG
|
||||||
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=$(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 libstxxl-dev libstxxl1v5 libxml2-dev \
|
||||||
apk upgrade && \
|
libzip-dev libboost1.67-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) && \
|
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 && \
|
||||||
@@ -26,20 +24,21 @@ 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:buster-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.67.0 libboost-regex1.67.0 \
|
||||||
apk add boost-filesystem boost-program_options boost-regex boost-iostreams boost-thread libgomp lua5.2 expat libtbb@testing
|
libboost-date-time1.67.0 libboost-chrono1.67.0 libboost-filesystem1.67.0 \
|
||||||
COPY --from=buildstage /usr/local /usr/local
|
libboost-iostreams1.67.0 libboost-thread1.67.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
|
||||||
WORKDIR /opt
|
WORKDIR /opt
|
||||||
|
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
|
|||||||
+10
-3
@@ -119,7 +119,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
|
||||||
@@ -236,9 +235,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_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.|
|
|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;
|
||||||
@@ -284,6 +284,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:
|
||||||
|
|
||||||
@@ -384,6 +385,10 @@ All other properties might be undefined.
|
|||||||
2361.73,
|
2361.73,
|
||||||
0
|
0
|
||||||
]
|
]
|
||||||
|
],
|
||||||
|
"fallback_speed_cells": [
|
||||||
|
[ 0, 1 ],
|
||||||
|
[ 1, 0 ]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -552,6 +557,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:
|
||||||
|
|
||||||
@@ -906,6 +912,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.
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ tables. Optionally returns distance table.
|
|||||||
- `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_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.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**
|
||||||
@@ -156,6 +157,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
|
||||||
|
|
||||||
|
|||||||
@@ -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 |
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -115,7 +115,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 +151,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();
|
||||||
}*/
|
}*/
|
||||||
|
|||||||
@@ -596,7 +596,6 @@ Feature: Basic Distance Matrix
|
|||||||
| e | 198.8 | 298.9 | 499 | 710.3 | 0 | 1592.8 |
|
| e | 198.8 | 298.9 | 499 | 710.3 | 0 | 1592.8 |
|
||||||
| f | 596.4 | 696.5 | 896.6 | 1107.9 | 397.6 | 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)
|
Scenario: Testbot - Filling in noroutes with estimates (defaults to input coordinate location)
|
||||||
Given a grid size of 300 meters
|
Given a grid size of 300 meters
|
||||||
Given the extract extra arguments "--small-component-size 4"
|
Given the extract extra arguments "--small-component-size 4"
|
||||||
@@ -617,10 +616,21 @@ Feature: Basic Distance Matrix
|
|||||||
| | a | b | f | 1 |
|
| | a | b | f | 1 |
|
||||||
| a | 0 | 300.2 | 900.7 | 1501.1 |
|
| a | 0 | 300.2 | 900.7 | 1501.1 |
|
||||||
| b | 300.2 | 0 | 600.5 | 1200.9 |
|
| b | 300.2 | 0 | 600.5 | 1200.9 |
|
||||||
| f | 900.7 | 600.5 | 0 | 302.2 |
|
| f | 900.7 | 600.5 | 0 | 300.2 |
|
||||||
| 1 | 1501.1 | 1200.9 | 300.2 | 0 |
|
| 1 | 1501.1 | 1200.9 | 300.2 | 0 |
|
||||||
|
|
||||||
Scenario: Testbot - Filling in noroutes with estimates - use input coordinate
|
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 a grid size of 300 meters
|
||||||
Given the extract extra arguments "--small-component-size 4"
|
Given the extract extra arguments "--small-component-size 4"
|
||||||
Given the query options
|
Given the query options
|
||||||
@@ -641,9 +651,21 @@ Feature: Basic Distance Matrix
|
|||||||
| | a | b | f | 1 |
|
| | a | b | f | 1 |
|
||||||
| a | 0 | 300.2 | 900.7 | 1501.1 |
|
| a | 0 | 300.2 | 900.7 | 1501.1 |
|
||||||
| b | 300.2 | 0 | 600.5 | 1200.9 |
|
| b | 300.2 | 0 | 600.5 | 1200.9 |
|
||||||
| f | 900.7 | 600.5 | 0 | 302.2 |
|
| f | 900.7 | 600.5 | 0 | 300.2 |
|
||||||
| 1 | 1501.1 | 1200.9 | 300.2 | 0 |
|
| 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
|
Scenario: Testbot - Filling in noroutes with estimates - use snapped coordinate
|
||||||
Given a grid size of 300 meters
|
Given a grid size of 300 meters
|
||||||
Given the extract extra arguments "--small-component-size 4"
|
Given the extract extra arguments "--small-component-size 4"
|
||||||
@@ -665,5 +687,39 @@ Feature: Basic Distance Matrix
|
|||||||
| | a | b | f | 1 |
|
| | a | b | f | 1 |
|
||||||
| a | 0 | 300.2 | 900.7 | 1200.9 |
|
| a | 0 | 300.2 | 900.7 | 1200.9 |
|
||||||
| b | 300.2 | 0 | 600.5 | 900.7 |
|
| b | 300.2 | 0 | 600.5 | 900.7 |
|
||||||
| f | 900.7 | 600.5 | 0 | 302.2 |
|
| f | 900.7 | 600.5 | 0 | 300.2 |
|
||||||
| 1 | 1200.9 | 900.7 | 300.2 | 0 |
|
| 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 |
|
||||||
@@ -534,6 +534,35 @@ Feature: Basic Duration Matrix
|
|||||||
| f | 18 | 12 | 0 | 30 |
|
| f | 18 | 12 | 0 | 30 |
|
||||||
| 1 | 30 | 24 | 30 | 0 |
|
| 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
|
Scenario: Testbot - Filling in noroutes with estimates - use input coordinate
|
||||||
Given a grid size of 300 meters
|
Given a grid size of 300 meters
|
||||||
Given the extract extra arguments "--small-component-size 4"
|
Given the extract extra arguments "--small-component-size 4"
|
||||||
@@ -558,6 +587,36 @@ Feature: Basic Duration Matrix
|
|||||||
| f | 18 | 12 | 0 | 30 |
|
| f | 18 | 12 | 0 | 30 |
|
||||||
| 1 | 30 | 24 | 30 | 0 |
|
| 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
|
Scenario: Testbot - Filling in noroutes with estimates - use snapped coordinate
|
||||||
Given a grid size of 300 meters
|
Given a grid size of 300 meters
|
||||||
Given the extract extra arguments "--small-component-size 4"
|
Given the extract extra arguments "--small-component-size 4"
|
||||||
@@ -580,4 +639,139 @@ Feature: Basic Duration Matrix
|
|||||||
| a | 0 | 30 | 18 | 24 |
|
| a | 0 | 30 | 18 | 24 |
|
||||||
| b | 30 | 0 | 12 | 18 |
|
| b | 30 | 0 | 12 | 18 |
|
||||||
| f | 18 | 12 | 0 | 30 |
|
| f | 18 | 12 | 0 | 30 |
|
||||||
| 1 | 24 | 18 | 30 | 0 |
|
| 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 |
|
||||||
|
|||||||
@@ -111,9 +111,9 @@ Feature: Multi level routing
|
|||||||
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 | 2383.7 | 1566.9 | 1366.8 |
|
| a | 0 | 2383.7 | 1566.9 | 1366.8 |
|
||||||
| f | 2339.9 | 0 | 1198.1 | 1522.1 |
|
| f | 2383.7 | 0 | 1293.3 | 1617.3 |
|
||||||
| l | 1618.3 | 1293.3 | 0 | 800.5 |
|
| l | 1566.9 | 1293.3 | 0 | 800.5 |
|
||||||
| o | 1418.2 | 1617.3 | 800.5 | 0 |
|
| 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 |
|
||||||
@@ -122,21 +122,21 @@ Feature: Multi level routing
|
|||||||
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 | 2339.9 |
|
| f | 2383.7 |
|
||||||
| l | 1618.3 |
|
| l | 1566.9 |
|
||||||
| o | 1418.2 |
|
| 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 | 2383.7 | 1566.9 | 1366.8 |
|
| a | 0 | 2383.7 | 1566.9 | 1366.8 |
|
||||||
| f | 2339.9 | 0 | 1198.1 | 1522.1 |
|
| 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 | 1366.8 |
|
| a | 0 | 1366.8 |
|
||||||
| f | 2339.9 | 1522.1 |
|
| f | 2383.7 | 1617.3 |
|
||||||
| l | 1618.3 | 800.5 |
|
| l | 1566.9 | 800.5 |
|
||||||
| o | 1418.2 | 0 |
|
| 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
|
||||||
|
|||||||
@@ -182,4 +182,4 @@ Feature: Snap start/end point to the nearest way
|
|||||||
| x | m | xe,xe |
|
| x | m | xe,xe |
|
||||||
| x | n | xf,xf |
|
| x | n | xf,xf |
|
||||||
| x | o | xg,xg |
|
| x | o | xg,xg |
|
||||||
| x | p | xh,xh |
|
| x | p | xh,xh |
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
@routing @maxspeed @testbot
|
||||||
|
Feature: Testbot - Acceleration profiles
|
||||||
|
|
||||||
|
Background: Use specific speeds
|
||||||
|
Given the profile "testbot"
|
||||||
|
|
||||||
|
Scenario: Testbot - No stoppage penalties
|
||||||
|
Given a grid size of 10 meters
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a 1 2 3 4 5 b
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | maxspeed:forward | maxspeed:backward |
|
||||||
|
| ab | trunk | 60 | 45 |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | route | time | distance |
|
||||||
|
| a | b | ab,ab | 3.6s | 59.9m |
|
||||||
|
| a | 1 | ab,ab | 0.6s | 10m |
|
||||||
|
| a | 2 | ab,ab | 1.2s | 20m |
|
||||||
|
| a | 3 | ab,ab | 1.8s | 30m |
|
||||||
|
| a | 4 | ab,ab | 2.4s | 40m |
|
||||||
|
| a | 5 | ab,ab | 3s | 50m |
|
||||||
|
| 5 | b | ab,ab | 0.6s | 9.9m |
|
||||||
|
| 4 | b | ab,ab | 1.2s | 19.9m |
|
||||||
|
| 3 | b | ab,ab | 1.8s | 29.9m |
|
||||||
|
| 2 | b | ab,ab | 2.4s | 39.9m |
|
||||||
|
| 1 | b | ab,ab | 3s | 49.9m |
|
||||||
|
| 1 | 2 | ab,ab | 0.6s | 10m |
|
||||||
|
| 1 | 3 | ab,ab | 1.2s | 20m |
|
||||||
|
| 1 | 4 | ab,ab | 1.8s | 30m |
|
||||||
|
| 1 | 5 | ab,ab | 2.4s | 40m |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | 1 | 2 | 3 | 4 | 5 | b |
|
||||||
|
| a | 0 | 0.6 | 1.2 | 1.8 | 2.4 | 3 | 3.6 |
|
||||||
|
| 1 | 0.8 | 0 | 0.6 | 1.2 | 1.8 | 2.4 | 3 |
|
||||||
|
| 2 | 1.6 | 0.8 | 0 | 0.6 | 1.2 | 1.8 | 2.4 |
|
||||||
|
| 3 | 2.4 | 1.6 | 0.8 | 0 | 0.6 | 1.2 | 1.8 |
|
||||||
|
| 4 | 3.2 | 2.4 | 1.6 | 0.8 | 0 | 0.6 | 1.2 |
|
||||||
|
| 5 | 4 | 3.2 | 2.4 | 1.6 | 0.8 | 0 | 0.6 |
|
||||||
|
| b | 4.8 | 4 | 3.2 | 2.4 | 1.6 | 0.8 | 0 |
|
||||||
|
|
||||||
|
Scenario: Testbot - No stoppage points, tiny grid size
|
||||||
|
Given a grid size of 1 meters
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a 1 2 3 4 5 6 7 8 9 b
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | maxspeed:forward | maxspeed:backward |
|
||||||
|
| ab | trunk | 60 | 45 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | b |
|
||||||
|
| a | 0 | 0 | 0.1 | 0.1 | 0.2 | 0.3 | 0.3 | 0.4 | 0.4 | 0.5 | 0.6 |
|
||||||
|
| 1 | 0 | 0 | 0.1 | 0.1 | 0.2 | 0.3 | 0.3 | 0.4 | 0.4 | 0.5 | 0.6 |
|
||||||
|
| 2 | 0.1 | 0.1 | 0 | 0 | 0.1 | 0.2 | 0.2 | 0.3 | 0.3 | 0.4 | 0.5 |
|
||||||
|
| 3 | 0.2 | 0.2 | 0 | 0 | 0.1 | 0.2 | 0.2 | 0.3 | 0.3 | 0.4 | 0.5 |
|
||||||
|
| 4 | 0.3 | 0.3 | 0.2 | 0.1 | 0 | 0.1 | 0.1 | 0.2 | 0.2 | 0.3 | 0.4 |
|
||||||
|
| 5 | 0.4 | 0.4 | 0.3 | 0.2 | 0.1 | 0 | 0 | 0.1 | 0.1 | 0.2 | 0.3 |
|
||||||
|
| 6 | 0.4 | 0.4 | 0.3 | 0.2 | 0.1 | 0 | 0 | 0.1 | 0.1 | 0.2 | 0.3 |
|
||||||
|
| 7 | 0.5 | 0.5 | 0.4 | 0.3 | 0.2 | 0.1 | 0.1 | 0 | 0 | 0.1 | 0.2 |
|
||||||
|
| 8 | 0.6 | 0.6 | 0.5 | 0.4 | 0.3 | 0.2 | 0.2 | 0 | 0 | 0.1 | 0.2 |
|
||||||
|
| 9 | 0.7 | 0.7 | 0.6 | 0.5 | 0.4 | 0.3 | 0.3 | 0.2 | 0.1 | 0 | 0.1 |
|
||||||
|
| b | 0.8 | 0.8 | 0.7 | 0.6 | 0.5 | 0.4 | 0.4 | 0.3 | 0.2 | 0.1 | 0 |
|
||||||
|
|
||||||
|
Scenario: Testbot - No stoppage points, tiny grid size
|
||||||
|
Given a grid size of 1 meters
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a 1 2 3 4 5 6 7 8 9 b
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | maxspeed:forward | maxspeed:backward |
|
||||||
|
| ab | trunk | 60 | 45 |
|
||||||
|
|
||||||
|
And the query options
|
||||||
|
| stoppage_penalty | 1.85,15 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | b |
|
||||||
|
| a | 0 | 1.4 | 2 | 2.5 | 2.9 | 3.2 | 3.6 | 3.8 | 4.1 | 4.4 | 4.6 |
|
||||||
|
| 1 | 1.4 | 0 | 1.4 | 2 | 2.5 | 2.9 | 3.2 | 3.6 | 3.8 | 4.1 | 4.4 |
|
||||||
|
| 2 | 2 | 1.4 | 0 | 1.4 | 2 | 2.5 | 2.9 | 3.2 | 3.6 | 3.8 | 4.1 |
|
||||||
|
| 3 | 2.5 | 2 | 1.4 | 0 | 1.4 | 2 | 2.5 | 2.9 | 3.2 | 3.6 | 3.8 |
|
||||||
|
| 4 | 2.9 | 2.5 | 2 | 1.4 | 0 | 1.4 | 2 | 2.5 | 2.9 | 3.2 | 3.6 |
|
||||||
|
| 5 | 3.2 | 2.9 | 2.5 | 2 | 1.4 | 0 | 1.4 | 2 | 2.5 | 2.9 | 3.2 |
|
||||||
|
| 6 | 3.6 | 3.2 | 2.9 | 2.5 | 2 | 1.4 | 0 | 1.4 | 2 | 2.5 | 2.9 |
|
||||||
|
| 7 | 3.8 | 3.6 | 3.2 | 2.9 | 2.5 | 2 | 1.4 | 0 | 1.4 | 2 | 2.5 |
|
||||||
|
| 8 | 4.1 | 3.8 | 3.6 | 3.2 | 2.9 | 2.5 | 2 | 1.4 | 0 | 1.4 | 2 |
|
||||||
|
| 9 | 4.4 | 4.1 | 3.8 | 3.6 | 3.2 | 2.9 | 2.5 | 2 | 1.4 | 0 | 1.4 |
|
||||||
|
| b | 4.6 | 4.4 | 4.1 | 3.8 | 3.6 | 3.2 | 2.9 | 2.5 | 2 | 1.4 | 0 |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Testbot - Use stoppage penalty at waypoints
|
||||||
|
Given a grid size of 10 meters
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a 1 2 3 4 5 b
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | maxspeed:forward | maxspeed:backward |
|
||||||
|
| ab | trunk | 60 | 45 |
|
||||||
|
|
||||||
|
And the query options
|
||||||
|
| stoppage_penalty | 1.85,15 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | 1 | 2 | 3 | 4 | 5 | b |
|
||||||
|
| a | 0 | 4.6 | 6.5 | 8 | 9.3 | 10.4 | 11.3 |
|
||||||
|
| 1 | 4.6 | 0 | 4.6 | 6.5 | 8 | 9.3 | 10.3 |
|
||||||
|
| 2 | 6.5 | 4.6 | 0 | 4.6 | 6.5 | 8 | 9.2 |
|
||||||
|
| 3 | 8 | 6.5 | 4.6 | 0 | 4.6 | 6.5 | 8 |
|
||||||
|
| 4 | 9.3 | 8 | 6.5 | 4.6 | 0 | 4.6 | 6.5 |
|
||||||
|
| 5 | 10.4 | 9.3 | 8 | 6.5 | 4.6 | 0 | 4.6 |
|
||||||
|
| b | 11.3 | 10.3 | 9.2 | 8 | 6.5 | 4.6 | 0 |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Long distance grid with no penalty
|
||||||
|
Given a grid size of 1000 meters
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a 1 2 3 4 5 b
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | maxspeed:forward | maxspeed:backward |
|
||||||
|
| ab | trunk | 60 | 45 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | 1 | 2 | 3 | 4 | 5 | b |
|
||||||
|
| a | 0 | 59.9 | 119.9 | 179.9 | 239.9 | 299.9 | 359.9 |
|
||||||
|
| 1 | 79.9 | 0 | 60 | 120 | 180 | 240 | 300 |
|
||||||
|
| 2 | 159.9 | 80 | 0 | 60 | 120 | 180 | 240 |
|
||||||
|
| 3 | 239.9 | 160 | 80 | 0 | 60 | 120 | 180 |
|
||||||
|
| 4 | 319.9 | 240 | 160 | 80 | 0 | 60 | 120 |
|
||||||
|
| 5 | 399.9 | 320 | 240 | 160 | 80 | 0 | 60 |
|
||||||
|
| b | 479.9 | 400 | 320 | 240 | 160 | 80 | 0 |
|
||||||
|
|
||||||
|
Scenario: Long distance grid
|
||||||
|
Given a grid size of 1000 meters
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a 1 2 3 4 5 b
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | maxspeed:forward | maxspeed:backward |
|
||||||
|
| ab | trunk | 60 | 45 |
|
||||||
|
|
||||||
|
And the query options
|
||||||
|
| stoppage_penalty | 1.85,15 |
|
||||||
|
|
||||||
|
When I request a travel time matrix I should get
|
||||||
|
| | a | 1 | 2 | 3 | 4 | 5 | b |
|
||||||
|
| a | 0 | 68.9 | 128.9 | 188.9 | 248.9 | 308.9 | 368.9 |
|
||||||
|
| 1 | 86.6 | 0 | 69 | 129 | 189 | 249 | 309 |
|
||||||
|
| 2 | 166.6 | 86.7 | 0 | 69 | 129 | 189 | 249 |
|
||||||
|
| 3 | 246.6 | 166.7 | 86.7 | 0 | 69 | 129 | 189 |
|
||||||
|
| 4 | 326.6 | 246.7 | 166.7 | 86.7 | 0 | 69 | 129 |
|
||||||
|
| 5 | 406.6 | 326.7 | 246.7 | 166.7 | 86.7 | 0 | 69 |
|
||||||
|
| b | 486.6 | 406.7 | 326.7 | 246.7 | 166.7 | 86.7 | 0 |
|
||||||
@@ -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,21 +80,34 @@ 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;
|
||||||
|
double min_stoppage_penalty = INVALID_MINIMUM_STOPPAGE_PENALTY;
|
||||||
|
double max_stoppage_penalty = INVALID_MAXIMUM_STOPPAGE_PENALTY;
|
||||||
|
|
||||||
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,
|
||||||
|
double min_stoppage_penalty_ = INVALID_MINIMUM_STOPPAGE_PENALTY,
|
||||||
|
double max_stoppage_penalty_ = INVALID_MAXIMUM_STOPPAGE_PENALTY)
|
||||||
: 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_), min_stoppage_penalty(min_stoppage_penalty_),
|
||||||
|
max_stoppage_penalty(max_stoppage_penalty_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME add validation for invalid bearing values
|
// FIXME add validation for invalid bearing values
|
||||||
bool IsValid() const
|
bool IsValid() const
|
||||||
{
|
{
|
||||||
|
if (min_stoppage_penalty <= 0 || max_stoppage_penalty <= 0 ||
|
||||||
|
min_stoppage_penalty > max_stoppage_penalty)
|
||||||
|
return false;
|
||||||
|
|
||||||
return (hints.empty() || hints.size() == coordinates.size()) &&
|
return (hints.empty() || hints.size() == coordinates.size()) &&
|
||||||
(bearings.empty() || bearings.size() == coordinates.size()) &&
|
(bearings.empty() || bearings.size() == coordinates.size()) &&
|
||||||
(radiuses.empty() || radiuses.size() == coordinates.size()) &&
|
(radiuses.empty() || radiuses.size() == coordinates.size()) &&
|
||||||
@@ -103,8 +123,8 @@ struct BaseParameters
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
} // namespace api
|
||||||
}
|
} // namespace engine
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif // ROUTE_PARAMETERS_HPP
|
#endif // ROUTE_PARAMETERS_HPP
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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,7 +59,7 @@ 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 = 0;
|
double fallback_speed = INVALID_FALLBACK_SPEED;
|
||||||
|
|
||||||
enum class FallbackCoordinateType
|
enum class FallbackCoordinateType
|
||||||
{
|
{
|
||||||
@@ -78,6 +78,7 @@ 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>
|
||||||
@@ -105,10 +106,12 @@ struct TableParameters : public BaseParameters
|
|||||||
const AnnotationsType annotations_,
|
const AnnotationsType annotations_,
|
||||||
double fallback_speed_,
|
double fallback_speed_,
|
||||||
FallbackCoordinateType fallback_coordinate_type_,
|
FallbackCoordinateType fallback_coordinate_type_,
|
||||||
|
double scale_factor_,
|
||||||
Args... args_)
|
Args... args_)
|
||||||
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
||||||
destinations{std::move(destinations_)}, fallback_speed{fallback_speed_},
|
destinations{std::move(destinations_)}, fallback_speed{fallback_speed_},
|
||||||
fallback_coordinate_type{fallback_coordinate_type_}, annotations{annotations_}
|
fallback_coordinate_type{fallback_coordinate_type_}, annotations{annotations_},
|
||||||
|
scale_factor{scale_factor_}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,14 +126,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))
|
||||||
@@ -139,7 +135,10 @@ 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)
|
if (fallback_speed <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (scale_factor <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -165,8 +164,8 @@ inline TableParameters::AnnotationsType &operator|=(TableParameters::Annotations
|
|||||||
{
|
{
|
||||||
return lhs = lhs | rhs;
|
return lhs = lhs | rhs;
|
||||||
}
|
}
|
||||||
}
|
} // namespace api
|
||||||
}
|
} // namespace engine
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif // ENGINE_API_TABLE_PARAMETERS_HPP
|
#endif // ENGINE_API_TABLE_PARAMETERS_HPP
|
||||||
|
|||||||
@@ -312,12 +312,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 +326,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>
|
||||||
@@ -382,50 +384,84 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
input_coordinate, max_results, max_distance, bearing, bearing_range, approach);
|
input_coordinate, max_results, max_distance, bearing, bearing_range, approach);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
const util::Coordinate input_coordinate,
|
||||||
const Approach approach) const override final
|
const Approach approach,
|
||||||
|
const bool use_all_edges,
|
||||||
|
const double minimum_stoppage_penalty,
|
||||||
|
const double maximum_stoppage_penalty) 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,
|
||||||
|
minimum_stoppage_penalty,
|
||||||
|
maximum_stoppage_penalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
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 double minimum_stoppage_penalty,
|
||||||
|
const double maximum_stoppage_penalty) 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,
|
||||||
|
minimum_stoppage_penalty,
|
||||||
|
maximum_stoppage_penalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
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 override final
|
const Approach approach,
|
||||||
|
const bool use_all_edges,
|
||||||
|
const double minimum_stoppage_penalty,
|
||||||
|
const double maximum_stoppage_penalty) 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,
|
||||||
|
minimum_stoppage_penalty,
|
||||||
|
maximum_stoppage_penalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
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 double minimum_stoppage_penalty,
|
||||||
|
const double maximum_stoppage_penalty) 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,
|
||||||
|
minimum_stoppage_penalty,
|
||||||
|
maximum_stoppage_penalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t GetCheckSum() const override final { return m_check_sum; }
|
std::uint32_t GetCheckSum() const override final { return m_check_sum; }
|
||||||
|
|||||||
@@ -126,11 +126,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,
|
||||||
@@ -155,24 +157,36 @@ class BaseDataFacade
|
|||||||
const double max_distance,
|
const double max_distance,
|
||||||
const Approach approach) const = 0;
|
const Approach approach) const = 0;
|
||||||
|
|
||||||
virtual std::pair<PhantomNode, PhantomNode>
|
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
const util::Coordinate input_coordinate,
|
||||||
const Approach approach) const = 0;
|
const Approach approach,
|
||||||
virtual std::pair<PhantomNode, PhantomNode>
|
const bool use_all_edges,
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
const double minimum_stoppage_penalty,
|
||||||
const double max_distance,
|
const double maximum_stoppage_penalty) const = 0;
|
||||||
const Approach approach) const = 0;
|
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
virtual std::pair<PhantomNode, PhantomNode>
|
const util::Coordinate input_coordinate,
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
const double max_distance,
|
||||||
const double max_distance,
|
const Approach approach,
|
||||||
const int bearing,
|
const bool use_all_edges,
|
||||||
const int bearing_range,
|
const double minimum_stoppage_penalty,
|
||||||
const Approach approach) const = 0;
|
const double maximum_stoppage_penalty) const = 0;
|
||||||
virtual std::pair<PhantomNode, PhantomNode>
|
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
|
const util::Coordinate input_coordinate,
|
||||||
const int bearing,
|
const double max_distance,
|
||||||
const int bearing_range,
|
const int bearing,
|
||||||
const Approach approach) const = 0;
|
const int bearing_range,
|
||||||
|
const Approach approach,
|
||||||
|
const bool use_all_edges,
|
||||||
|
const double minimum_stoppage_penalty,
|
||||||
|
const double maximum_stoppage_penalty) const = 0;
|
||||||
|
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
|
const util::Coordinate input_coordinate,
|
||||||
|
const int bearing,
|
||||||
|
const int bearing_range,
|
||||||
|
const Approach approach,
|
||||||
|
const bool use_all_edges,
|
||||||
|
const double minimum_stoppage_penalty,
|
||||||
|
const double maximum_stoppage_penalty) 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;
|
||||||
|
|||||||
@@ -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,25 @@ 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 double min_stoppage_penalty,
|
||||||
|
const double max_stoppage_penalty) 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);
|
||||||
@@ -239,27 +250,39 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(results.size() == 1 || results.size() == 2);
|
BOOST_ASSERT(results.size() == 1 || results.size() == 2);
|
||||||
return std::make_pair(MakePhantomNode(input_coordinate, results.front()).phantom_node,
|
return std::make_pair(
|
||||||
MakePhantomNode(input_coordinate, results.back()).phantom_node);
|
MakePhantomNode(
|
||||||
|
input_coordinate, results.front(), min_stoppage_penalty, max_stoppage_penalty)
|
||||||
|
.phantom_node,
|
||||||
|
MakePhantomNode(
|
||||||
|
input_coordinate, results.back(), min_stoppage_penalty, max_stoppage_penalty)
|
||||||
|
.phantom_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the nearest phantom node. If this phantom node is not from a big component
|
// Returns the nearest phantom node. If this phantom node is not from a big component
|
||||||
// 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 double min_stoppage_penalty,
|
||||||
|
const double max_stoppage_penalty) 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);
|
||||||
@@ -284,8 +307,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(results.size() == 1 || results.size() == 2);
|
BOOST_ASSERT(results.size() == 1 || results.size() == 2);
|
||||||
return std::make_pair(MakePhantomNode(input_coordinate, results.front()).phantom_node,
|
return std::make_pair(
|
||||||
MakePhantomNode(input_coordinate, results.back()).phantom_node);
|
MakePhantomNode(
|
||||||
|
input_coordinate, results.front(), min_stoppage_penalty, max_stoppage_penalty)
|
||||||
|
.phantom_node,
|
||||||
|
MakePhantomNode(
|
||||||
|
input_coordinate, results.back(), min_stoppage_penalty, max_stoppage_penalty)
|
||||||
|
.phantom_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the nearest phantom node. If this phantom node is not from a big component
|
// Returns the nearest phantom node. If this phantom node is not from a big component
|
||||||
@@ -294,7 +322,10 @@ 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 double min_stoppage_penalty,
|
||||||
|
const double max_stoppage_penalty) const
|
||||||
{
|
{
|
||||||
bool has_small_component = false;
|
bool has_small_component = false;
|
||||||
bool has_big_component = false;
|
bool has_big_component = false;
|
||||||
@@ -306,12 +337,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)
|
||||||
{
|
{
|
||||||
@@ -341,8 +373,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(results.size() > 0);
|
BOOST_ASSERT(results.size() > 0);
|
||||||
return std::make_pair(MakePhantomNode(input_coordinate, results.front()).phantom_node,
|
return std::make_pair(
|
||||||
MakePhantomNode(input_coordinate, results.back()).phantom_node);
|
MakePhantomNode(
|
||||||
|
input_coordinate, results.front(), min_stoppage_penalty, max_stoppage_penalty)
|
||||||
|
.phantom_node,
|
||||||
|
MakePhantomNode(
|
||||||
|
input_coordinate, results.back(), min_stoppage_penalty, max_stoppage_penalty)
|
||||||
|
.phantom_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the nearest phantom node. If this phantom node is not from a big component
|
// Returns the nearest phantom node. If this phantom node is not from a big component
|
||||||
@@ -352,7 +389,10 @@ 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 double min_stoppage_penalty,
|
||||||
|
const double max_stoppage_penalty) const
|
||||||
{
|
{
|
||||||
bool has_small_component = false;
|
bool has_small_component = false;
|
||||||
bool has_big_component = false;
|
bool has_big_component = false;
|
||||||
@@ -364,12 +404,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)
|
||||||
{
|
{
|
||||||
@@ -401,8 +442,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(results.size() > 0);
|
BOOST_ASSERT(results.size() > 0);
|
||||||
return std::make_pair(MakePhantomNode(input_coordinate, results.front()).phantom_node,
|
return std::make_pair(
|
||||||
MakePhantomNode(input_coordinate, results.back()).phantom_node);
|
MakePhantomNode(
|
||||||
|
input_coordinate, results.front(), min_stoppage_penalty, max_stoppage_penalty)
|
||||||
|
.phantom_node,
|
||||||
|
MakePhantomNode(
|
||||||
|
input_coordinate, results.back(), min_stoppage_penalty, max_stoppage_penalty)
|
||||||
|
.phantom_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -420,8 +466,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
return distance_and_phantoms;
|
return distance_and_phantoms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove stoppage penalty as its not needed here anymore
|
||||||
PhantomNodeWithDistance MakePhantomNode(const util::Coordinate input_coordinate,
|
PhantomNodeWithDistance MakePhantomNode(const util::Coordinate input_coordinate,
|
||||||
const EdgeData &data) const
|
const EdgeData &data,
|
||||||
|
const double min_stoppage_penalty = 0,
|
||||||
|
const double max_stoppage_penalty = 0) const
|
||||||
{
|
{
|
||||||
util::Coordinate point_on_segment;
|
util::Coordinate point_on_segment;
|
||||||
double ratio;
|
double ratio;
|
||||||
@@ -460,15 +509,21 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
forward_durations.begin() + data.fwd_segment_position,
|
forward_durations.begin() + data.fwd_segment_position,
|
||||||
EdgeDuration{0});
|
EdgeDuration{0});
|
||||||
|
|
||||||
EdgeDistance forward_distance_offset = 0;
|
// For measuring distance from begin up to end
|
||||||
for (auto current = forward_geometry.begin();
|
const auto appx_distance = [this](decltype(forward_geometry.begin()) begin,
|
||||||
current < forward_geometry.begin() + data.fwd_segment_position;
|
decltype(forward_geometry.begin()) end) {
|
||||||
++current)
|
EdgeDistance dist = 0;
|
||||||
{
|
for (; begin != end; ++begin)
|
||||||
forward_distance_offset += util::coordinate_calculation::fccApproximateDistance(
|
{
|
||||||
datafacade.GetCoordinateOfNode(*current),
|
dist += util::coordinate_calculation::fccApproximateDistance(
|
||||||
datafacade.GetCoordinateOfNode(*std::next(current)));
|
datafacade.GetCoordinateOfNode(*begin),
|
||||||
}
|
datafacade.GetCoordinateOfNode(*std::next(begin)));
|
||||||
|
}
|
||||||
|
return dist;
|
||||||
|
};
|
||||||
|
|
||||||
|
EdgeDistance forward_distance_offset = appx_distance(
|
||||||
|
forward_geometry.begin(), forward_geometry.begin() + data.fwd_segment_position);
|
||||||
|
|
||||||
BOOST_ASSERT(data.fwd_segment_position <
|
BOOST_ASSERT(data.fwd_segment_position <
|
||||||
std::distance(forward_durations.begin(), forward_durations.end()));
|
std::distance(forward_durations.begin(), forward_durations.end()));
|
||||||
@@ -489,15 +544,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
reverse_durations.end() - data.fwd_segment_position - 1,
|
reverse_durations.end() - data.fwd_segment_position - 1,
|
||||||
EdgeDuration{0});
|
EdgeDuration{0});
|
||||||
|
|
||||||
EdgeDistance reverse_distance_offset = 0;
|
EdgeDistance reverse_distance_offset =
|
||||||
for (auto current = forward_geometry.begin();
|
appx_distance(forward_geometry.begin() + data.fwd_segment_position + 1,
|
||||||
current < forward_geometry.end() - data.fwd_segment_position - 2;
|
std::prev(forward_geometry.end()));
|
||||||
++current)
|
|
||||||
{
|
|
||||||
reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance(
|
|
||||||
datafacade.GetCoordinateOfNode(*current),
|
|
||||||
datafacade.GetCoordinateOfNode(*std::next(current)));
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgeWeight reverse_weight =
|
EdgeWeight reverse_weight =
|
||||||
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1];
|
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1];
|
||||||
@@ -507,16 +556,43 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
point_on_segment,
|
point_on_segment,
|
||||||
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1)));
|
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1)));
|
||||||
|
|
||||||
|
// We may end up adding a stoppage penalty
|
||||||
|
double forward_speed = 0;
|
||||||
|
double reverse_speed = 0;
|
||||||
|
auto total_distance = 0;
|
||||||
|
auto penalty_range = max_stoppage_penalty - min_stoppage_penalty;
|
||||||
ratio = std::min(1.0, std::max(0.0, ratio));
|
ratio = std::min(1.0, std::max(0.0, ratio));
|
||||||
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
|
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
|
||||||
{
|
{
|
||||||
forward_weight = static_cast<EdgeWeight>(forward_weight * ratio);
|
forward_weight = static_cast<EdgeWeight>(forward_weight * ratio);
|
||||||
forward_duration = static_cast<EdgeDuration>(forward_duration * ratio);
|
forward_duration = static_cast<EdgeDuration>(forward_duration * ratio);
|
||||||
|
// Stoppage penalty based on speed
|
||||||
|
if (data.forward_segment_id.enabled && penalty_range > 0)
|
||||||
|
{
|
||||||
|
total_distance =
|
||||||
|
appx_distance(forward_geometry.begin(), std::prev(forward_geometry.end()));
|
||||||
|
const auto total_duration = std::accumulate(
|
||||||
|
forward_durations.begin(), forward_durations.end(), EdgeDuration{0});
|
||||||
|
forward_speed = total_distance / (total_duration * 0.1);
|
||||||
|
reverse_speed = forward_speed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
|
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
|
||||||
{
|
{
|
||||||
reverse_weight -= static_cast<EdgeWeight>(reverse_weight * ratio);
|
reverse_weight -= static_cast<EdgeWeight>(reverse_weight * ratio);
|
||||||
reverse_duration -= static_cast<EdgeDuration>(reverse_duration * ratio);
|
reverse_duration -= static_cast<EdgeDuration>(reverse_duration * ratio);
|
||||||
|
// Stoppage penalty based on speed
|
||||||
|
if (data.reverse_segment_id.enabled && penalty_range > 0)
|
||||||
|
{
|
||||||
|
if (total_distance == 0)
|
||||||
|
total_distance =
|
||||||
|
appx_distance(forward_geometry.begin(), std::prev(forward_geometry.end()));
|
||||||
|
const auto total_duration = std::accumulate(
|
||||||
|
reverse_durations.begin(), reverse_durations.end(), EdgeDuration{0});
|
||||||
|
reverse_speed = total_distance / (total_duration * 0.1);
|
||||||
|
if (forward_speed == 0)
|
||||||
|
forward_speed = reverse_speed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check phantom node segments validity
|
// check phantom node segments validity
|
||||||
@@ -547,6 +623,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
reverse_duration,
|
reverse_duration,
|
||||||
forward_duration_offset,
|
forward_duration_offset,
|
||||||
reverse_duration_offset,
|
reverse_duration_offset,
|
||||||
|
static_cast<float>((forward_speed + reverse_speed) / 2.0),
|
||||||
is_forward_valid_source,
|
is_forward_valid_source,
|
||||||
is_forward_valid_target,
|
is_forward_valid_target,
|
||||||
is_reverse_valid_source,
|
is_reverse_valid_source,
|
||||||
@@ -628,7 +705,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 +730,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,7 +774,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
const CoordinateList &coordinates;
|
const CoordinateList &coordinates;
|
||||||
DataFacadeT &datafacade;
|
DataFacadeT &datafacade;
|
||||||
};
|
};
|
||||||
}
|
} // namespace engine
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
|
|||||||
[](const NamedSegment &segment) { return segment.name_id; });
|
[](const NamedSegment &segment) { return segment.name_id; });
|
||||||
return summary;
|
return summary;
|
||||||
}
|
}
|
||||||
}
|
} // namespace detail
|
||||||
|
|
||||||
inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
||||||
const std::vector<PathData> &route_data,
|
const std::vector<PathData> &route_data,
|
||||||
@@ -166,7 +166,7 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
|||||||
// `forward_duration`: duration of (d,t)
|
// `forward_duration`: duration of (d,t)
|
||||||
// `forward_offset`: duration of (c, d)
|
// `forward_offset`: duration of (c, d)
|
||||||
// path_data will have entries for (s,b), (b, c), (c, d) but (d, t) is only
|
// path_data will have entries for (s,b), (b, c), (c, d) but (d, t) is only
|
||||||
// caputed by the phantom node. So we need to add the target duration here.
|
// captured by the phantom node. So we need to add the target duration here.
|
||||||
// On local segments, the target duration is already part of the duration, however.
|
// On local segments, the target duration is already part of the duration, however.
|
||||||
|
|
||||||
duration = duration + target_duration;
|
duration = duration + target_duration;
|
||||||
@@ -182,6 +182,9 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
|||||||
duration = std::max(0, duration);
|
duration = std::max(0, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add start and stop penalties to the duration to simulate accel/deceleration
|
||||||
|
//
|
||||||
|
|
||||||
std::string summary;
|
std::string summary;
|
||||||
if (needs_summary)
|
if (needs_summary)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -63,11 +63,11 @@ struct Hint
|
|||||||
friend std::ostream &operator<<(std::ostream &, const Hint &);
|
friend std::ostream &operator<<(std::ostream &, const Hint &);
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(Hint) == 80 + 4, "Hint is bigger than expected");
|
static_assert(sizeof(Hint) == sizeof(PhantomNode) + 4, "Hint is bigger than expected");
|
||||||
constexpr std::size_t ENCODED_HINT_SIZE = 112;
|
constexpr std::size_t ENCODED_HINT_SIZE = 120;
|
||||||
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
|
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
|
||||||
"ENCODED_HINT_SIZE does not match size of Hint");
|
"ENCODED_HINT_SIZE does not match size of Hint");
|
||||||
}
|
} // namespace engine
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,14 +44,15 @@ namespace engine
|
|||||||
struct PhantomNode
|
struct PhantomNode
|
||||||
{
|
{
|
||||||
PhantomNode()
|
PhantomNode()
|
||||||
: forward_segment_id{SPECIAL_SEGMENTID, false},
|
: forward_segment_id{SPECIAL_SEGMENTID, false}, reverse_segment_id{SPECIAL_SEGMENTID,
|
||||||
reverse_segment_id{SPECIAL_SEGMENTID, false}, forward_weight(INVALID_EDGE_WEIGHT),
|
false},
|
||||||
reverse_weight(INVALID_EDGE_WEIGHT), forward_weight_offset(0), reverse_weight_offset(0),
|
forward_weight(INVALID_EDGE_WEIGHT), reverse_weight(INVALID_EDGE_WEIGHT),
|
||||||
|
forward_weight_offset(0), reverse_weight_offset(0),
|
||||||
forward_distance(INVALID_EDGE_DISTANCE), reverse_distance(INVALID_EDGE_DISTANCE),
|
forward_distance(INVALID_EDGE_DISTANCE), reverse_distance(INVALID_EDGE_DISTANCE),
|
||||||
forward_distance_offset(0), reverse_distance_offset(0),
|
forward_distance_offset(0), reverse_distance_offset(0),
|
||||||
forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION),
|
forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION),
|
||||||
forward_duration_offset(0), reverse_duration_offset(0), fwd_segment_position(0),
|
forward_duration_offset(0), reverse_duration_offset(0), speed_approximation(0),
|
||||||
is_valid_forward_source{false}, is_valid_forward_target{false},
|
fwd_segment_position(0), is_valid_forward_source{false}, is_valid_forward_target{false},
|
||||||
is_valid_reverse_source{false}, is_valid_reverse_target{false}, bearing(0)
|
is_valid_reverse_source{false}, is_valid_reverse_target{false}, bearing(0)
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -69,13 +70,13 @@ struct PhantomNode
|
|||||||
return reverse_weight_offset + reverse_weight;
|
return reverse_weight_offset + reverse_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeWeight GetForwardDuration() const
|
EdgeDuration GetForwardDuration() const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(forward_segment_id.enabled);
|
BOOST_ASSERT(forward_segment_id.enabled);
|
||||||
return forward_duration + forward_duration_offset;
|
return forward_duration + forward_duration_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeWeight GetReverseDuration() const
|
EdgeDuration GetReverseDuration() const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(reverse_segment_id.enabled);
|
BOOST_ASSERT(reverse_segment_id.enabled);
|
||||||
return reverse_duration + reverse_duration_offset;
|
return reverse_duration + reverse_duration_offset;
|
||||||
@@ -109,8 +110,9 @@ struct PhantomNode
|
|||||||
|
|
||||||
bool IsValid(const unsigned number_of_nodes) const
|
bool IsValid(const unsigned number_of_nodes) const
|
||||||
{
|
{
|
||||||
return location.IsValid() && ((forward_segment_id.id < number_of_nodes) ||
|
return location.IsValid() &&
|
||||||
(reverse_segment_id.id < number_of_nodes)) &&
|
((forward_segment_id.id < number_of_nodes) ||
|
||||||
|
(reverse_segment_id.id < number_of_nodes)) &&
|
||||||
((forward_weight != INVALID_EDGE_WEIGHT) ||
|
((forward_weight != INVALID_EDGE_WEIGHT) ||
|
||||||
(reverse_weight != INVALID_EDGE_WEIGHT)) &&
|
(reverse_weight != INVALID_EDGE_WEIGHT)) &&
|
||||||
((forward_duration != MAXIMAL_EDGE_DURATION) ||
|
((forward_duration != MAXIMAL_EDGE_DURATION) ||
|
||||||
@@ -163,10 +165,11 @@ struct PhantomNode
|
|||||||
EdgeDistance reverse_distance,
|
EdgeDistance reverse_distance,
|
||||||
EdgeDistance forward_distance_offset,
|
EdgeDistance forward_distance_offset,
|
||||||
EdgeDistance reverse_distance_offset,
|
EdgeDistance reverse_distance_offset,
|
||||||
EdgeWeight forward_duration,
|
EdgeDuration forward_duration,
|
||||||
EdgeWeight reverse_duration,
|
EdgeDuration reverse_duration,
|
||||||
EdgeWeight forward_duration_offset,
|
EdgeDuration forward_duration_offset,
|
||||||
EdgeWeight reverse_duration_offset,
|
EdgeDuration reverse_duration_offset,
|
||||||
|
EdgeDistance speed_approximation,
|
||||||
bool is_valid_forward_source,
|
bool is_valid_forward_source,
|
||||||
bool is_valid_forward_target,
|
bool is_valid_forward_target,
|
||||||
bool is_valid_reverse_source,
|
bool is_valid_reverse_source,
|
||||||
@@ -182,8 +185,9 @@ struct PhantomNode
|
|||||||
reverse_distance_offset{reverse_distance_offset}, forward_duration{forward_duration},
|
reverse_distance_offset{reverse_distance_offset}, forward_duration{forward_duration},
|
||||||
reverse_duration{reverse_duration}, forward_duration_offset{forward_duration_offset},
|
reverse_duration{reverse_duration}, forward_duration_offset{forward_duration_offset},
|
||||||
reverse_duration_offset{reverse_duration_offset},
|
reverse_duration_offset{reverse_duration_offset},
|
||||||
component{component.id, component.is_tiny}, location{location},
|
speed_approximation{speed_approximation}, component{component.id, component.is_tiny},
|
||||||
input_location{input_location}, fwd_segment_position{other.fwd_segment_position},
|
location{location}, input_location{input_location},
|
||||||
|
fwd_segment_position{other.fwd_segment_position},
|
||||||
is_valid_forward_source{is_valid_forward_source},
|
is_valid_forward_source{is_valid_forward_source},
|
||||||
is_valid_forward_target{is_valid_forward_target},
|
is_valid_forward_target{is_valid_forward_target},
|
||||||
is_valid_reverse_source{is_valid_reverse_source},
|
is_valid_reverse_source{is_valid_reverse_source},
|
||||||
@@ -201,10 +205,12 @@ struct PhantomNode
|
|||||||
EdgeDistance reverse_distance;
|
EdgeDistance reverse_distance;
|
||||||
EdgeDistance forward_distance_offset; // TODO: try to remove -> requires path unpacking changes
|
EdgeDistance forward_distance_offset; // TODO: try to remove -> requires path unpacking changes
|
||||||
EdgeDistance reverse_distance_offset; // TODO: try to remove -> requires path unpacking changes
|
EdgeDistance reverse_distance_offset; // TODO: try to remove -> requires path unpacking changes
|
||||||
EdgeWeight forward_duration;
|
EdgeDuration forward_duration;
|
||||||
EdgeWeight reverse_duration;
|
EdgeDuration reverse_duration;
|
||||||
EdgeWeight forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
|
EdgeDuration forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
|
||||||
EdgeWeight reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes
|
EdgeDuration reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes
|
||||||
|
EdgeDistance speed_approximation; // m/s
|
||||||
|
|
||||||
ComponentID component;
|
ComponentID component;
|
||||||
|
|
||||||
util::Coordinate location; // this is the coordinate of x
|
util::Coordinate location; // this is the coordinate of x
|
||||||
@@ -219,7 +225,7 @@ struct PhantomNode
|
|||||||
unsigned short bearing : 12;
|
unsigned short bearing : 12;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(PhantomNode) == 80, "PhantomNode has more padding then expected");
|
static_assert(sizeof(PhantomNode) == 84, "PhantomNode has more padding then expected");
|
||||||
|
|
||||||
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
|
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
|
||||||
|
|
||||||
@@ -234,7 +240,7 @@ struct PhantomNodes
|
|||||||
PhantomNode source_phantom;
|
PhantomNode source_phantom;
|
||||||
PhantomNode target_phantom;
|
PhantomNode target_phantom;
|
||||||
};
|
};
|
||||||
}
|
} // namespace engine
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif // PHANTOM_NODES_H
|
#endif // PHANTOM_NODES_H
|
||||||
|
|||||||
@@ -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,10 @@ 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,
|
||||||
|
parameters.min_stoppage_penalty,
|
||||||
|
parameters.max_stoppage_penalty);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -303,7 +309,10 @@ 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,
|
||||||
|
parameters.min_stoppage_penalty,
|
||||||
|
parameters.max_stoppage_penalty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -312,13 +321,22 @@ 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,
|
||||||
|
parameters.min_stoppage_penalty,
|
||||||
|
parameters.max_stoppage_penalty);
|
||||||
}
|
}
|
||||||
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,
|
||||||
|
parameters.min_stoppage_penalty,
|
||||||
|
parameters.max_stoppage_penalty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ 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);
|
void GetEdgeBasedNodeDistances(std::vector<EdgeDistance> &output_node_distances);
|
||||||
@@ -112,10 +111,6 @@ 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;
|
||||||
|
|||||||
@@ -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,7 +85,6 @@ 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,
|
std::vector<EdgeDistance> &edge_based_node_distances,
|
||||||
@@ -97,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();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#include "util/typedefs.h"
|
||||||
|
|
||||||
|
namespace osrm
|
||||||
|
{
|
||||||
|
namespace extractor
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
constexpr int 5_MINUTE_BUCKETS_PER_WEEK = 2016;
|
||||||
|
constexpr int 1_HOUR_BUCKETS_PER_WEEK = 168;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a simple piecewise linear function
|
||||||
|
* (https://en.wikipedia.org/wiki/Piecewise_linear_function)
|
||||||
|
* in the form of a regularly spaced set of buckets.
|
||||||
|
* Assumes that the spacing between buckets is equal.
|
||||||
|
*/
|
||||||
|
template <typename DataType, int BUCKETCOUNT> struct PiecewiseLinearFunction
|
||||||
|
{
|
||||||
|
std::array<DataType, BUCKETCOUNT> sample;
|
||||||
|
|
||||||
|
inline DataType getAt(float position)
|
||||||
|
{
|
||||||
|
// Range check
|
||||||
|
assert(position >= 0);
|
||||||
|
assert(position < BUCKETCOUNT - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
PiecewiseLinearFunction<DataType, BUCKETCOUNT>
|
||||||
|
merge(PiecewiseLinearFunction<DataType, BUCKETCOUNT> &other, float offset)
|
||||||
|
{
|
||||||
|
PiecewiseLinearFunction result;
|
||||||
|
|
||||||
|
for (int i = 0; i < BUCKETCOUNT; i++)
|
||||||
|
{
|
||||||
|
for (int j = offset; j < BUCKETCOUNT + offset; j++)
|
||||||
|
{
|
||||||
|
|
||||||
|
result.sample[i] = sample[i] + other.sample[j % BUCKETCOUNT];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents variances in the default `.duration` of an edge
|
||||||
|
* over the space of a week.
|
||||||
|
*/
|
||||||
|
struct WeeklySpeedProfile
|
||||||
|
{
|
||||||
|
using Multiplier = std::uint8_t;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PiecewiseLinearFunction<Multiplier, 1_HOUR_BUCKETS_PER_WEEK> fn;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SpeedProfile() : min(0), max(0) { multipliers.fill(0); }
|
||||||
|
SpeedProfile(const std::array<Multiplier, BUCKETS> &other)
|
||||||
|
{
|
||||||
|
fn.samples = other;
|
||||||
|
min = std::min(samples);
|
||||||
|
max = std::max(samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EdgeDuration adjust(const EdgeDuration &original, const int bucket) const
|
||||||
|
{
|
||||||
|
// Treat Multiplier as an 8-bit fixed-point value.
|
||||||
|
EdgeDuration new_value = (original * multipliers[bucket]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EdgeDuration min(const EdgeDuration original) const {}
|
||||||
|
|
||||||
|
inline EdgeDuration max(const EdgeDuration original) const {}
|
||||||
|
|
||||||
|
duration = m * e1 + m2 * e2
|
||||||
|
};
|
||||||
|
} // namespace extractor
|
||||||
|
} // namespace osrm
|
||||||
@@ -692,6 +692,80 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (obj->Has(Nan::New("snapping").ToLocalChecked()))
|
||||||
|
{
|
||||||
|
v8::Local<v8::Value> snapping = obj->Get(Nan::New("snapping").ToLocalChecked());
|
||||||
|
if (snapping.IsEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!snapping->IsString())
|
||||||
|
{
|
||||||
|
Nan::ThrowError("Snapping must be a string: [default, any]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
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 false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->Has(Nan::New("stoppage_penalty").ToLocalChecked()))
|
||||||
|
{
|
||||||
|
v8::Local<v8::Value> stoppage_penalty =
|
||||||
|
obj->Get(Nan::New("stoppage_penalty").ToLocalChecked());
|
||||||
|
if (stoppage_penalty.IsEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stoppage_penalty->IsArray())
|
||||||
|
{
|
||||||
|
Nan::ThrowError("Stoppage penalty must be an array of 2 numbers [min,max]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto stoppage_penalty_array = v8::Local<v8::Array>::Cast(stoppage_penalty);
|
||||||
|
|
||||||
|
if (stoppage_penalty_array->Length() != 2)
|
||||||
|
{
|
||||||
|
Nan::ThrowError("Stoppage penalty must be an array of 2 numbers [min,max]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stoppage_penalty_array->Get(0)->IsNumber() ||
|
||||||
|
!stoppage_penalty_array->Get(1)->IsNumber())
|
||||||
|
{
|
||||||
|
Nan::ThrowError("Stoppage penalty must be an array of 2 numbers [min,max]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto min = static_cast<short>(stoppage_penalty_array->Get(0)->NumberValue());
|
||||||
|
const auto max = static_cast<short>(stoppage_penalty_array->Get(1)->NumberValue());
|
||||||
|
|
||||||
|
if (min < 0 || max < 0)
|
||||||
|
{
|
||||||
|
Nan::ThrowError("Stoppage penalty min/max can't be less than zero");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (max < min)
|
||||||
|
{
|
||||||
|
Nan::ThrowError("Stoppage penalty max must be larger than min");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
params->max_stoppage_penalty = max;
|
||||||
|
params->min_stoppage_penalty = min;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1192,7 +1266,7 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
|||||||
Nan::ThrowError("fallback_speed must be a number");
|
Nan::ThrowError("fallback_speed must be a number");
|
||||||
return table_parameters_ptr();
|
return table_parameters_ptr();
|
||||||
}
|
}
|
||||||
else if (fallback_speed->NumberValue() < 0)
|
else if (fallback_speed->NumberValue() <= 0)
|
||||||
{
|
{
|
||||||
Nan::ThrowError("fallback_speed must be > 0");
|
Nan::ThrowError("fallback_speed must be > 0");
|
||||||
return table_parameters_ptr();
|
return table_parameters_ptr();
|
||||||
@@ -1229,6 +1303,24 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace
|
|||||||
{
|
{
|
||||||
namespace ph = boost::phoenix;
|
namespace ph = boost::phoenix;
|
||||||
namespace qi = boost::spirit::qi;
|
namespace qi = boost::spirit::qi;
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
template <typename T, char... Fmt> struct no_trailing_dot_policy : qi::real_policies<T>
|
template <typename T, char... Fmt> struct no_trailing_dot_policy : qi::real_policies<T>
|
||||||
{
|
{
|
||||||
@@ -135,6 +135,16 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
|||||||
},
|
},
|
||||||
qi::_1)];
|
qi::_1)];
|
||||||
|
|
||||||
|
stoppage_rule = qi::lit("stoppage_penalty=") >
|
||||||
|
(qi::double_ > ',' > qi::double_)[ph::bind(
|
||||||
|
[](engine::api::BaseParameters ¶ms, double min, double max) {
|
||||||
|
params.min_stoppage_penalty = min;
|
||||||
|
params.max_stoppage_penalty = max;
|
||||||
|
},
|
||||||
|
qi::_r1,
|
||||||
|
qi::_1,
|
||||||
|
qi::_2)];
|
||||||
|
|
||||||
query_rule =
|
query_rule =
|
||||||
((location_rule % ';') | polyline_rule |
|
((location_rule % ';') | polyline_rule |
|
||||||
polyline6_rule)[ph::bind(&engine::api::BaseParameters::coordinates, qi::_r1) = qi::_1];
|
polyline6_rule)[ph::bind(&engine::api::BaseParameters::coordinates, qi::_r1) = qi::_1];
|
||||||
@@ -162,6 +172,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,7 +188,9 @@ 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) //
|
||||||
|
| stoppage_rule(qi::_r1); //
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -188,6 +207,7 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
|||||||
qi::rule<Iterator, Signature> generate_hints_rule;
|
qi::rule<Iterator, Signature> generate_hints_rule;
|
||||||
qi::rule<Iterator, Signature> approach_rule;
|
qi::rule<Iterator, Signature> approach_rule;
|
||||||
qi::rule<Iterator, Signature> exclude_rule;
|
qi::rule<Iterator, Signature> exclude_rule;
|
||||||
|
qi::rule<Iterator, Signature> stoppage_rule;
|
||||||
|
|
||||||
qi::rule<Iterator, osrm::engine::Bearing()> bearing_rule;
|
qi::rule<Iterator, osrm::engine::Bearing()> bearing_rule;
|
||||||
qi::rule<Iterator, osrm::util::Coordinate()> location_rule;
|
qi::rule<Iterator, osrm::util::Coordinate()> location_rule;
|
||||||
@@ -197,11 +217,13 @@ 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::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;
|
||||||
};
|
};
|
||||||
}
|
} // namespace api
|
||||||
}
|
} // namespace server
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace
|
|||||||
{
|
{
|
||||||
namespace ph = boost::phoenix;
|
namespace ph = boost::phoenix;
|
||||||
namespace qi = boost::spirit::qi;
|
namespace qi = boost::spirit::qi;
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
template <typename Iterator = std::string::iterator,
|
template <typename Iterator = std::string::iterator,
|
||||||
typename Signature = void(engine::api::TableParameters &)>
|
typename Signature = void(engine::api::TableParameters &)>
|
||||||
@@ -56,16 +56,20 @@ struct TableParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
|||||||
engine::api::TableParameters::FallbackCoordinateType::Input)(
|
engine::api::TableParameters::FallbackCoordinateType::Input)(
|
||||||
"snapped", engine::api::TableParameters::FallbackCoordinateType::Snapped);
|
"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 =
|
root_rule = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") >
|
||||||
BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") >
|
-('?' > (table_rule(qi::_r1) | base_rule(qi::_r1) | scale_factor_rule(qi::_r1) |
|
||||||
-('?' > (table_rule(qi::_r1) | base_rule(qi::_r1) | fallback_speed_rule(qi::_r1) |
|
fallback_speed_rule(qi::_r1) |
|
||||||
(qi::lit("fallback_coordinate=") >
|
(qi::lit("fallback_coordinate=") >
|
||||||
fallback_coordinate_type
|
fallback_coordinate_type
|
||||||
[ph::bind(&engine::api::TableParameters::fallback_coordinate_type,
|
[ph::bind(&engine::api::TableParameters::fallback_coordinate_type,
|
||||||
qi::_r1) = qi::_1])) %
|
qi::_r1) = qi::_1])) %
|
||||||
'&');
|
'&');
|
||||||
}
|
}
|
||||||
|
|
||||||
TableParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_)
|
TableParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_)
|
||||||
@@ -94,6 +98,7 @@ struct TableParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
|||||||
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> 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;
|
||||||
@@ -101,8 +106,8 @@ struct TableParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
|||||||
fallback_coordinate_type;
|
fallback_coordinate_type;
|
||||||
qi::real_parser<double, json_policy> double_;
|
qi::real_parser<double, json_policy> double_;
|
||||||
};
|
};
|
||||||
}
|
} // namespace api
|
||||||
}
|
} // namespace server
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -488,8 +488,8 @@ inline void Prettify(char *buffer, int length, int k)
|
|||||||
inline void dtoa_milo(double value, char *buffer)
|
inline void dtoa_milo(double value, char *buffer)
|
||||||
{
|
{
|
||||||
// Not handling NaN and inf
|
// Not handling NaN and inf
|
||||||
assert(!isnan(value));
|
assert(!std::isnan(value));
|
||||||
assert(!isinf(value));
|
assert(!std::isinf(value));
|
||||||
|
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ struct osm_way_id
|
|||||||
struct duplicated_node
|
struct duplicated_node
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
}
|
} // namespace tag
|
||||||
using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>;
|
using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>;
|
||||||
static_assert(std::is_pod<OSMNodeID>(), "OSMNodeID is not a valid alias");
|
static_assert(std::is_pod<OSMNodeID>(), "OSMNodeID is not a valid alias");
|
||||||
using OSMWayID = osrm::Alias<std::uint64_t, tag::osm_way_id>;
|
using OSMWayID = osrm::Alias<std::uint64_t, tag::osm_way_id>;
|
||||||
@@ -116,6 +116,10 @@ static const EdgeDuration MAXIMAL_EDGE_DURATION = std::numeric_limits<EdgeDurati
|
|||||||
static const EdgeDistance MAXIMAL_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::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<EdgeDistance>::max();
|
||||||
|
constexpr EdgeDuration INVALID_MINIMUM_STOPPAGE_PENALTY = std::numeric_limits<EdgeDuration>::max();
|
||||||
|
constexpr EdgeDuration INVALID_MAXIMUM_STOPPAGE_PENALTY = std::numeric_limits<EdgeDuration>::max();
|
||||||
|
constexpr float MAXIMAL_ACCEL_DECEL_PENALIZABLE_SPEED_INVERSE = 40.f; // seconds/metre
|
||||||
|
|
||||||
// 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
|
||||||
|
|||||||
Generated
+6732
-2897
File diff suppressed because it is too large
Load Diff
+6
-6
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "osrm",
|
"name": "osrm",
|
||||||
"version": "5.20.0-latest.1",
|
"version": "5.21.0-customsnapping.5",
|
||||||
"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": {
|
||||||
@@ -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")
|
||||||
|
|||||||
+1
-3
@@ -120,9 +120,6 @@ function setup()
|
|||||||
|
|
||||||
-- classes to support for exclude flags
|
-- classes to support for exclude flags
|
||||||
excludable = Sequence {
|
excludable = Sequence {
|
||||||
Set {'toll'},
|
|
||||||
Set {'motorway'},
|
|
||||||
Set {'ferry'}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
avoid = Set {
|
avoid = Set {
|
||||||
@@ -269,6 +266,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]
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,7 +213,8 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto candidates_lists = GetPhantomNodesInRange(facade, tidied.parameters, search_radiuses);
|
auto candidates_lists =
|
||||||
|
GetPhantomNodesInRange(facade, tidied.parameters, search_radiuses, true);
|
||||||
|
|
||||||
filterCandidates(tidied.parameters.coordinates, candidates_lists);
|
filterCandidates(tidied.parameters.coordinates, candidates_lists);
|
||||||
if (std::all_of(candidates_lists.begin(),
|
if (std::all_of(candidates_lists.begin(),
|
||||||
|
|||||||
@@ -86,8 +86,10 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
bool request_distance = params.annotations & api::TableParameters::AnnotationsType::Distance;
|
bool request_distance = params.annotations & api::TableParameters::AnnotationsType::Distance;
|
||||||
bool request_duration = params.annotations & api::TableParameters::AnnotationsType::Duration;
|
bool request_duration = params.annotations & api::TableParameters::AnnotationsType::Duration;
|
||||||
|
|
||||||
|
constexpr bool always_calculate_distance = true;
|
||||||
|
|
||||||
auto result_tables_pair = algorithms.ManyToManySearch(
|
auto result_tables_pair = algorithms.ManyToManySearch(
|
||||||
snapped_phantoms, params.sources, params.destinations, request_distance);
|
snapped_phantoms, params.sources, params.destinations, always_calculate_distance);
|
||||||
|
|
||||||
if ((request_duration && result_tables_pair.first.empty()) ||
|
if ((request_duration && result_tables_pair.first.empty()) ||
|
||||||
(request_distance && result_tables_pair.second.empty()))
|
(request_distance && result_tables_pair.second.empty()))
|
||||||
@@ -95,15 +97,88 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
return Error("NoTable", "No table found", result);
|
return Error("NoTable", "No table found", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<api::TableAPI::TableCellRef> estimated_pairs;
|
||||||
|
|
||||||
|
// Adds some time to adjust for getting up to speed and slowing down to a stop
|
||||||
|
// Returns a new `duration`
|
||||||
|
auto adjust_for_startstop = [](const double &comfortable_acceleration,
|
||||||
|
const EdgeDuration &duration,
|
||||||
|
const EdgeDistance &distance) -> EdgeDuration {
|
||||||
|
|
||||||
|
// Assume linear acceleration from 0 to velocity
|
||||||
|
// auto comfortable_acceleration = 1.85; // m/s^2
|
||||||
|
|
||||||
|
// Very short paths can end up with 0 duration. That'll lead to a divide
|
||||||
|
// by zero, so instead, we'll assume the travel speed is 10m/s (36km/h).
|
||||||
|
// Typically, the distance is also short, so we're quibbling at tiny numbers
|
||||||
|
// here, but tiny numbers is what this adjustment lambda is all about,
|
||||||
|
// so we do try to be reasonable.
|
||||||
|
const auto average_speed =
|
||||||
|
duration == 0 ? 10 : distance /
|
||||||
|
(duration / 10.); // duration is in deciseconds, we need m/sec
|
||||||
|
|
||||||
|
// Using the equations of motion as a simple approximation, assuming constant acceleration
|
||||||
|
// https://en.wikipedia.org/wiki/Equations_of_motion#Constant_translational_acceleration_in_a_straight_line
|
||||||
|
const auto distance_to_full_speed =
|
||||||
|
(average_speed * average_speed) / (2 * comfortable_acceleration);
|
||||||
|
|
||||||
|
/*
|
||||||
|
std::cout << "Comfortable accel is " << comfortable_acceleration << std::endl;
|
||||||
|
std::cout << "Average speed is " << average_speed << " duration is " << duration
|
||||||
|
<< std::endl;
|
||||||
|
std::cout << "Distance is " << distance << " distance to full speed is "
|
||||||
|
<< distance_to_full_speed << std::endl;
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (distance_to_full_speed > distance / 2)
|
||||||
|
{
|
||||||
|
// std::cout << "Distance was too short, so only using half" << std::endl;
|
||||||
|
const auto time_to_halfway = std::sqrt(distance / comfortable_acceleration);
|
||||||
|
return (2 * time_to_halfway) * 10; // result is in deciseconds
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// std::cout << "Distance was long, using cruising speed" << std::endl;
|
||||||
|
const auto cruising_distance = distance - 2 * distance_to_full_speed;
|
||||||
|
const auto cruising_time = cruising_distance / average_speed;
|
||||||
|
const auto acceleration_time = average_speed / comfortable_acceleration;
|
||||||
|
|
||||||
|
// std::cout << "Cruising distance is " << cruising_distance << std::endl;
|
||||||
|
// std::cout << "Cruising time is " << cruising_time << std::endl;
|
||||||
|
// std::cout << "Acceleration time is " << acceleration_time << std::endl;
|
||||||
|
return (cruising_time + 2 * acceleration_time) * 10; // result is in deciseconds
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Scan table for null results - if any exist, replace with distance estimates
|
// Scan table for null results - if any exist, replace with distance estimates
|
||||||
if (params.fallback_speed > 0)
|
if (params.fallback_speed != INVALID_FALLBACK_SPEED || params.scale_factor != 1 ||
|
||||||
|
(params.min_stoppage_penalty != INVALID_MINIMUM_STOPPAGE_PENALTY &&
|
||||||
|
params.max_stoppage_penalty != INVALID_MAXIMUM_STOPPAGE_PENALTY))
|
||||||
{
|
{
|
||||||
for (std::size_t row = 0; row < num_sources; row++)
|
for (std::size_t row = 0; row < num_sources; row++)
|
||||||
{
|
{
|
||||||
for (std::size_t column = 0; column < num_destinations; column++)
|
for (std::size_t column = 0; column < num_destinations; column++)
|
||||||
{
|
{
|
||||||
const auto &table_index = row * num_sources + column;
|
const auto &table_index = row * num_destinations + column;
|
||||||
if (result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
|
BOOST_ASSERT(table_index < result_tables_pair.first.size());
|
||||||
|
// apply an accel/deceleration penalty to the duration
|
||||||
|
if (result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION && row != column)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
const auto &source =
|
||||||
|
snapped_phantoms[params.sources.empty() ? row : params.sources[row]];
|
||||||
|
const auto &destination =
|
||||||
|
snapped_phantoms[params.destinations.empty() ? column
|
||||||
|
: params.destinations[column]];
|
||||||
|
*/
|
||||||
|
result_tables_pair.first[table_index] =
|
||||||
|
adjust_for_startstop(params.min_stoppage_penalty,
|
||||||
|
result_tables_pair.first[table_index],
|
||||||
|
result_tables_pair.second[table_index]);
|
||||||
|
}
|
||||||
|
// Estimate null results based on fallback_speed (if valid) and distance
|
||||||
|
if (params.fallback_speed != INVALID_FALLBACK_SPEED && params.fallback_speed > 0 &&
|
||||||
|
result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
|
||||||
{
|
{
|
||||||
const auto &source =
|
const auto &source =
|
||||||
snapped_phantoms[params.sources.empty() ? row : params.sources[row]];
|
snapped_phantoms[params.sources.empty() ? row : params.sources[row]];
|
||||||
@@ -125,16 +200,44 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
{
|
{
|
||||||
result_tables_pair.second[table_index] = distance_estimate;
|
result_tables_pair.second[table_index] = distance_estimate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
estimated_pairs.emplace_back(row, column);
|
||||||
|
}
|
||||||
|
// Apply a scale factor to non-null result if requested
|
||||||
|
if (params.scale_factor > 0 && params.scale_factor != 1 &&
|
||||||
|
result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION &&
|
||||||
|
result_tables_pair.first[table_index] != 0)
|
||||||
|
{
|
||||||
|
EdgeDuration diff =
|
||||||
|
MAXIMAL_EDGE_DURATION / result_tables_pair.first[table_index];
|
||||||
|
|
||||||
|
if (params.scale_factor >= diff)
|
||||||
|
{
|
||||||
|
result_tables_pair.first[table_index] = MAXIMAL_EDGE_DURATION - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result_tables_pair.first[table_index] = std::lround(
|
||||||
|
result_tables_pair.first[table_index] * params.scale_factor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If distances weren't requested, delete them from the result so they don't
|
||||||
|
// get rendered.
|
||||||
|
if (!request_distance)
|
||||||
|
{
|
||||||
|
std::vector<EdgeDistance> empty;
|
||||||
|
result_tables_pair.second.swap(empty);
|
||||||
|
}
|
||||||
|
|
||||||
api::TableAPI table_api{facade, params};
|
api::TableAPI table_api{facade, params};
|
||||||
table_api.MakeResponse(result_tables_pair, snapped_phantoms, result);
|
table_api.MakeResponse(result_tables_pair, snapped_phantoms, estimated_pairs, result);
|
||||||
|
|
||||||
return Status::Ok;
|
return Status::Ok;
|
||||||
}
|
}
|
||||||
}
|
} // namespace plugins
|
||||||
}
|
} // namespace engine
|
||||||
}
|
} // namespace osrm
|
||||||
|
|||||||
@@ -294,6 +294,7 @@ struct SpeedLayer : public vtzero::layer_builder
|
|||||||
vtzero::index_value key_duration;
|
vtzero::index_value key_duration;
|
||||||
vtzero::index_value key_name;
|
vtzero::index_value key_name;
|
||||||
vtzero::index_value key_rate;
|
vtzero::index_value key_rate;
|
||||||
|
vtzero::index_value key_is_startpoint;
|
||||||
|
|
||||||
SpeedLayer(vtzero::tile_builder &tile)
|
SpeedLayer(vtzero::tile_builder &tile)
|
||||||
: layer_builder(tile, "speeds"), uint_index(*this), double_index(*this),
|
: layer_builder(tile, "speeds"), uint_index(*this), double_index(*this),
|
||||||
@@ -302,7 +303,8 @@ struct SpeedLayer : public vtzero::layer_builder
|
|||||||
key_datasource(add_key_without_dup_check("datasource")),
|
key_datasource(add_key_without_dup_check("datasource")),
|
||||||
key_weight(add_key_without_dup_check("weight")),
|
key_weight(add_key_without_dup_check("weight")),
|
||||||
key_duration(add_key_without_dup_check("duration")),
|
key_duration(add_key_without_dup_check("duration")),
|
||||||
key_name(add_key_without_dup_check("name")), key_rate(add_key_without_dup_check("rate"))
|
key_name(add_key_without_dup_check("name")), key_rate(add_key_without_dup_check("rate")),
|
||||||
|
key_is_startpoint(add_key_without_dup_check("is_startpoint"))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,6 +351,11 @@ class SpeedLayerFeatureBuilder : public vtzero::linestring_feature_builder
|
|||||||
|
|
||||||
void set_rate(double value) { add_property(m_layer.key_rate, m_layer.double_index(value)); }
|
void set_rate(double value) { add_property(m_layer.key_rate, m_layer.double_index(value)); }
|
||||||
|
|
||||||
|
void set_is_startpoint(bool value)
|
||||||
|
{
|
||||||
|
add_property(m_layer.key_is_startpoint, m_layer.bool_index(value));
|
||||||
|
}
|
||||||
|
|
||||||
}; // class SpeedLayerFeatureBuilder
|
}; // class SpeedLayerFeatureBuilder
|
||||||
|
|
||||||
struct TurnsLayer : public vtzero::layer_builder
|
struct TurnsLayer : public vtzero::layer_builder
|
||||||
@@ -485,6 +492,8 @@ void encodeVectorTile(const DataFacadeBase &facade,
|
|||||||
const auto reverse_datasource_idx = reverse_datasource_range(
|
const auto reverse_datasource_idx = reverse_datasource_range(
|
||||||
reverse_datasource_range.size() - edge.fwd_segment_position - 1);
|
reverse_datasource_range.size() - edge.fwd_segment_position - 1);
|
||||||
|
|
||||||
|
const auto is_startpoint = edge.is_startpoint;
|
||||||
|
|
||||||
const auto component_id = facade.GetComponentID(edge.forward_segment_id.id);
|
const auto component_id = facade.GetComponentID(edge.forward_segment_id.id);
|
||||||
const auto name_id = facade.GetNameIndex(edge.forward_segment_id.id);
|
const auto name_id = facade.GetNameIndex(edge.forward_segment_id.id);
|
||||||
auto name = facade.GetNameForID(name_id);
|
auto name = facade.GetNameForID(name_id);
|
||||||
@@ -516,6 +525,7 @@ void encodeVectorTile(const DataFacadeBase &facade,
|
|||||||
fbuilder.set_duration(forward_duration / 10.0);
|
fbuilder.set_duration(forward_duration / 10.0);
|
||||||
fbuilder.set_name(name);
|
fbuilder.set_name(name);
|
||||||
fbuilder.set_rate(forward_rate / 10.0);
|
fbuilder.set_rate(forward_rate / 10.0);
|
||||||
|
fbuilder.set_is_startpoint(is_startpoint);
|
||||||
|
|
||||||
fbuilder.commit();
|
fbuilder.commit();
|
||||||
}
|
}
|
||||||
@@ -549,6 +559,7 @@ void encodeVectorTile(const DataFacadeBase &facade,
|
|||||||
fbuilder.set_duration(reverse_duration / 10.0);
|
fbuilder.set_duration(reverse_duration / 10.0);
|
||||||
fbuilder.set_name(name);
|
fbuilder.set_name(name);
|
||||||
fbuilder.set_rate(reverse_rate / 10.0);
|
fbuilder.set_rate(reverse_rate / 10.0);
|
||||||
|
fbuilder.set_is_startpoint(is_startpoint);
|
||||||
|
|
||||||
fbuilder.commit();
|
fbuilder.commit();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,12 +95,6 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSe
|
|||||||
swap(nodes, m_edge_based_node_segments);
|
swap(nodes, m_edge_based_node_segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::GetStartPointMarkers(std::vector<bool> &node_is_startpoint)
|
|
||||||
{
|
|
||||||
using std::swap; // Koenig swap
|
|
||||||
swap(m_edge_based_node_is_startpoint, node_is_startpoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights)
|
void EdgeBasedGraphFactory::GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights)
|
||||||
{
|
{
|
||||||
using std::swap; // Koenig swap
|
using std::swap; // Koenig swap
|
||||||
@@ -229,10 +223,9 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N
|
|||||||
edge_id_to_segment_id(nbe_to_ebn_mapping[edge_id_2]),
|
edge_id_to_segment_id(nbe_to_ebn_mapping[edge_id_2]),
|
||||||
current_edge_source_coordinate_id,
|
current_edge_source_coordinate_id,
|
||||||
current_edge_target_coordinate_id,
|
current_edge_target_coordinate_id,
|
||||||
i);
|
i,
|
||||||
|
forward_data.flags.startpoint || reverse_data.flags.startpoint);
|
||||||
|
|
||||||
m_edge_based_node_is_startpoint.push_back(forward_data.flags.startpoint ||
|
|
||||||
reverse_data.flags.startpoint);
|
|
||||||
current_edge_source_coordinate_id = current_edge_target_coordinate_id;
|
current_edge_source_coordinate_id = current_edge_target_coordinate_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +420,6 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(m_edge_based_node_segments.size() == m_edge_based_node_is_startpoint.size());
|
|
||||||
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_weights.size());
|
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_weights.size());
|
||||||
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_durations.size());
|
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_durations.size());
|
||||||
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_distances.size());
|
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_distances.size());
|
||||||
|
|||||||
@@ -239,7 +239,6 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
|||||||
EdgeBasedNodeDataContainer edge_based_nodes_container;
|
EdgeBasedNodeDataContainer edge_based_nodes_container;
|
||||||
std::vector<EdgeBasedNodeSegment> edge_based_node_segments;
|
std::vector<EdgeBasedNodeSegment> edge_based_node_segments;
|
||||||
util::DeallocatingVector<EdgeBasedEdge> edge_based_edge_list;
|
util::DeallocatingVector<EdgeBasedEdge> edge_based_edge_list;
|
||||||
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;
|
std::vector<EdgeDistance> edge_based_node_distances;
|
||||||
@@ -320,7 +319,6 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
|||||||
scripting_environment,
|
scripting_environment,
|
||||||
edge_based_nodes_container,
|
edge_based_nodes_container,
|
||||||
edge_based_node_segments,
|
edge_based_node_segments,
|
||||||
node_is_startpoint,
|
|
||||||
edge_based_node_weights,
|
edge_based_node_weights,
|
||||||
edge_based_node_durations,
|
edge_based_node_durations,
|
||||||
edge_based_node_distances,
|
edge_based_node_distances,
|
||||||
@@ -362,7 +360,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
|
|||||||
|
|
||||||
util::Log() << "Building r-tree ...";
|
util::Log() << "Building r-tree ...";
|
||||||
TIMER_START(rtree);
|
TIMER_START(rtree);
|
||||||
BuildRTree(std::move(edge_based_node_segments), std::move(node_is_startpoint), coordinates);
|
BuildRTree(std::move(edge_based_node_segments), coordinates);
|
||||||
|
|
||||||
TIMER_STOP(rtree);
|
TIMER_STOP(rtree);
|
||||||
|
|
||||||
@@ -737,7 +735,6 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
|
|||||||
// 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,
|
std::vector<EdgeDistance> &edge_based_node_distances,
|
||||||
@@ -788,7 +785,6 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
|
|||||||
|
|
||||||
edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list);
|
edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list);
|
||||||
edge_based_graph_factory.GetEdgeBasedNodeSegments(edge_based_node_segments);
|
edge_based_graph_factory.GetEdgeBasedNodeSegments(edge_based_node_segments);
|
||||||
edge_based_graph_factory.GetStartPointMarkers(node_is_startpoint);
|
|
||||||
edge_based_graph_factory.GetEdgeBasedNodeWeights(edge_based_node_weights);
|
edge_based_graph_factory.GetEdgeBasedNodeWeights(edge_based_node_weights);
|
||||||
edge_based_graph_factory.GetEdgeBasedNodeDurations(edge_based_node_durations);
|
edge_based_graph_factory.GetEdgeBasedNodeDurations(edge_based_node_durations);
|
||||||
edge_based_graph_factory.GetEdgeBasedNodeDistances(edge_based_node_distances);
|
edge_based_graph_factory.GetEdgeBasedNodeDistances(edge_based_node_distances);
|
||||||
@@ -803,35 +799,24 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
|
|||||||
Saves tree into '.ramIndex' and leaves into '.fileIndex'.
|
Saves tree into '.ramIndex' and leaves into '.fileIndex'.
|
||||||
*/
|
*/
|
||||||
void Extractor::BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_segments,
|
void Extractor::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)
|
||||||
{
|
{
|
||||||
util::Log() << "Constructing r-tree of " << edge_based_node_segments.size()
|
util::Log() << "Constructing r-tree of " << edge_based_node_segments.size()
|
||||||
<< " segments build on-top of " << coordinates.size() << " coordinates";
|
<< " segments build on-top of " << coordinates.size() << " coordinates";
|
||||||
|
|
||||||
BOOST_ASSERT(node_is_startpoint.size() == edge_based_node_segments.size());
|
|
||||||
|
|
||||||
// Filter node based edges based on startpoint
|
// Filter node based edges based on startpoint
|
||||||
auto out_iter = edge_based_node_segments.begin();
|
auto start_point_count = std::accumulate(edge_based_node_segments.begin(),
|
||||||
auto in_iter = edge_based_node_segments.begin();
|
edge_based_node_segments.end(),
|
||||||
for (auto index : util::irange<std::size_t>(0UL, node_is_startpoint.size()))
|
0,
|
||||||
{
|
[](const size_t so_far, const auto &segment) {
|
||||||
BOOST_ASSERT(in_iter != edge_based_node_segments.end());
|
return so_far + (segment.is_startpoint ? 1 : 0);
|
||||||
if (node_is_startpoint[index])
|
});
|
||||||
{
|
if (start_point_count == 0)
|
||||||
*out_iter = *in_iter;
|
|
||||||
out_iter++;
|
|
||||||
}
|
|
||||||
in_iter++;
|
|
||||||
}
|
|
||||||
auto new_size = out_iter - edge_based_node_segments.begin();
|
|
||||||
if (new_size == 0)
|
|
||||||
{
|
{
|
||||||
throw util::exception("There are no snappable edges left after processing. Are you "
|
throw util::exception("There are no snappable edges left after processing. Are you "
|
||||||
"setting travel modes correctly in the profile? Cannot continue." +
|
"setting travel modes correctly in the profile? Cannot continue." +
|
||||||
SOURCE_REF);
|
SOURCE_REF);
|
||||||
}
|
}
|
||||||
edge_based_node_segments.resize(new_size);
|
|
||||||
|
|
||||||
TIMER_START(construction);
|
TIMER_START(construction);
|
||||||
util::StaticRTree<EdgeBasedNodeSegment> rtree(
|
util::StaticRTree<EdgeBasedNodeSegment> rtree(
|
||||||
|
|||||||
@@ -56,11 +56,16 @@ std::string getWrongOptionHelp(const engine::api::TableParameters ¶meters)
|
|||||||
help = "Number of coordinates needs to be at least two.";
|
help = "Number of coordinates needs to be at least two.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.fallback_speed < 0)
|
if (parameters.fallback_speed <= 0)
|
||||||
{
|
{
|
||||||
help = "fallback_speed must be > 0";
|
help = "fallback_speed must be > 0";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parameters.scale_factor <= 0)
|
||||||
|
{
|
||||||
|
help = "scale_factor must be > 0";
|
||||||
|
}
|
||||||
|
|
||||||
return help;
|
return help;
|
||||||
}
|
}
|
||||||
} // anon. ns
|
} // anon. ns
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ double perpendicularDistance(const Coordinate segment_source,
|
|||||||
web_mercator::fromWGS84(query_location));
|
web_mercator::fromWGS84(query_location));
|
||||||
nearest_location = web_mercator::toWGS84(projected_nearest);
|
nearest_location = web_mercator::toWGS84(projected_nearest);
|
||||||
|
|
||||||
const double approximate_distance = greatCircleDistance(query_location, nearest_location);
|
const double approximate_distance = fccApproximateDistance(query_location, nearest_location);
|
||||||
BOOST_ASSERT(0.0 <= approximate_distance);
|
BOOST_ASSERT(0.0 <= approximate_distance);
|
||||||
return approximate_distance;
|
return approximate_distance;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,6 +148,7 @@
|
|||||||
{"key": "maxspeed", "value": "AT:rural"},
|
{"key": "maxspeed", "value": "AT:rural"},
|
||||||
{"key": "maxspeed", "value": "AT:trunk"},
|
{"key": "maxspeed", "value": "AT:trunk"},
|
||||||
{"key": "maxspeed", "value": "BE:motorway"},
|
{"key": "maxspeed", "value": "BE:motorway"},
|
||||||
|
{"key": "maxspeed", "value": "BE-VLG:rural"},
|
||||||
{"key": "maxspeed", "value": "BY:urban"},
|
{"key": "maxspeed", "value": "BY:urban"},
|
||||||
{"key": "maxspeed", "value": "BY:motorway"},
|
{"key": "maxspeed", "value": "BY:motorway"},
|
||||||
{"key": "maxspeed", "value": "CH:rural"},
|
{"key": "maxspeed", "value": "CH:rural"},
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ exports.three_test_coordinates = [[7.41337, 43.72956],
|
|||||||
|
|
||||||
exports.two_test_coordinates = exports.three_test_coordinates.slice(0, 2)
|
exports.two_test_coordinates = exports.three_test_coordinates.slice(0, 2)
|
||||||
|
|
||||||
exports.test_tile = {'at': [17059, 11948, 15], 'size': 148750};
|
exports.test_tile = {'at': [17059, 11948, 15], 'size': 156624};
|
||||||
|
|
||||||
// Test files generated by the routing engine; check test/data
|
// Test files generated by the routing engine; check test/data
|
||||||
if (process.env.OSRM_DATA_PATH !== undefined) {
|
if (process.env.OSRM_DATA_PATH !== undefined) {
|
||||||
|
|||||||
@@ -606,3 +606,23 @@ test('route: route in Monaco without motorways', function(assert) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('route: throws on invalid snapping values', function (assert) {
|
||||||
|
assert.plan(1);
|
||||||
|
var osrm = new OSRM(monaco_path);
|
||||||
|
var options = {
|
||||||
|
steps: true,
|
||||||
|
coordinates: three_test_coordinates.concat(three_test_coordinates),
|
||||||
|
snapping: "zing"
|
||||||
|
};
|
||||||
|
assert.throws(function () { osrm.route(options, function (err, response) { console.error(`response: ${response}`); console.error(`error: ${err}`); }); },
|
||||||
|
/'snapping' param must be one of \[default, any\]/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('route: snapping parameter passed through OK', function(assert) {
|
||||||
|
assert.plan(2);
|
||||||
|
var osrm = new OSRM(monaco_path);
|
||||||
|
osrm.route({snapping: "any", coordinates: [[7.448205209414596,43.754001097311544],[7.447122039202185,43.75306156811368]]}, function(err, route) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.equal(Math.round(route.routes[0].distance * 10), 1314); // Round it to nearest 0.1m to eliminate floating point comparison error
|
||||||
|
});
|
||||||
|
});
|
||||||
+88
-2
@@ -48,6 +48,21 @@ test('table: test annotations paramater combination', function(assert) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('table: snapping parameter passed through OK', function(assert) {
|
||||||
|
assert.plan(2);
|
||||||
|
var osrm = new OSRM(data_path);
|
||||||
|
var options = {
|
||||||
|
coordinates: [[7.448205209414596,43.754001097311544],[7.447122039202185,43.75306156811368]],
|
||||||
|
annotations: ['duration', 'distance'],
|
||||||
|
snapping: 'any'
|
||||||
|
};
|
||||||
|
console.log(options);
|
||||||
|
osrm.table(options, function(err, result) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.equal(Math.round(result.distances[0][1] * 10), 1315); // Round it to nearest 0.1m to eliminate floating point comparison error
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('table: returns buffer', function(assert) {
|
test('table: returns buffer', function(assert) {
|
||||||
assert.plan(3);
|
assert.plan(3);
|
||||||
var osrm = new OSRM(data_path);
|
var osrm = new OSRM(data_path);
|
||||||
@@ -234,7 +249,7 @@ tables.forEach(function(annotation) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('table: ' + annotation + ' table in Monaco without motorways', function(assert) {
|
test('table: ' + annotation + ' table in Monaco without motorways', function(assert) {
|
||||||
assert.plan(1);
|
assert.plan(2);
|
||||||
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||||
var options = {
|
var options = {
|
||||||
coordinates: two_test_coordinates,
|
coordinates: two_test_coordinates,
|
||||||
@@ -243,11 +258,12 @@ tables.forEach(function(annotation) {
|
|||||||
};
|
};
|
||||||
osrm.table(options, function(err, response) {
|
osrm.table(options, function(err, response) {
|
||||||
assert.equal(response[annotation].length, 2);
|
assert.equal(response[annotation].length, 2);
|
||||||
|
assert.strictEqual(response.fallback_speed_cells, undefined);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('table: ' + annotation + ' table in Monaco with fallback speeds', function(assert) {
|
test('table: ' + annotation + ' table in Monaco with fallback speeds', function(assert) {
|
||||||
assert.plan(1);
|
assert.plan(2);
|
||||||
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||||
var options = {
|
var options = {
|
||||||
coordinates: two_test_coordinates,
|
coordinates: two_test_coordinates,
|
||||||
@@ -257,8 +273,78 @@ tables.forEach(function(annotation) {
|
|||||||
};
|
};
|
||||||
osrm.table(options, function(err, response) {
|
osrm.table(options, function(err, response) {
|
||||||
assert.equal(response[annotation].length, 2);
|
assert.equal(response[annotation].length, 2);
|
||||||
|
assert.equal(response['fallback_speed_cells'].length, 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('table: ' + annotation + ' table in Monaco with invalid fallback speeds and fallback coordinates', function(assert) {
|
||||||
|
assert.plan(4);
|
||||||
|
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||||
|
var options = {
|
||||||
|
coordinates: two_test_coordinates,
|
||||||
|
annotations: [annotation.slice(0,-1)],
|
||||||
|
fallback_speed: -1
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /fallback_speed must be > 0/, "should throw on invalid fallback_speeds");
|
||||||
|
|
||||||
|
options.fallback_speed = '10';
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /fallback_speed must be a number/, "should throw on invalid fallback_speeds");
|
||||||
|
|
||||||
|
options.fallback_speed = 10;
|
||||||
|
options.fallback_coordinate = 'bla';
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /fallback_coordinate' param must be one of \[input, snapped\]/, "should throw on invalid fallback_coordinate");
|
||||||
|
|
||||||
|
options.fallback_coordinate = 10;
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /fallback_coordinate must be a string: \[input, snapped\]/, "should throw on invalid fallback_coordinate");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
test('table: ' + annotation + ' table in Monaco with invalid scale factor', function(assert) {
|
||||||
|
assert.plan(3);
|
||||||
|
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||||
|
var options = {
|
||||||
|
coordinates: two_test_coordinates,
|
||||||
|
annotations: [annotation.slice(0,-1)],
|
||||||
|
scale_factor: -1
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /scale_factor must be > 0/, "should throw on invalid scale_factor value");
|
||||||
|
|
||||||
|
options.scale_factor = '-1';
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /scale_factor must be a number/, "should throw on invalid scale_factor value");
|
||||||
|
|
||||||
|
options.scale_factor = 0;
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /scale_factor must be > 0/, "should throw on invalid scale_factor value");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
test('table: ' + annotation + ' table in Monaco with stoppage_penalty values', function(assert) {
|
||||||
|
assert.plan(6);
|
||||||
|
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||||
|
var options = {
|
||||||
|
coordinates: two_test_coordinates,
|
||||||
|
annotations: [annotation.slice(0,-1)],
|
||||||
|
stoppage_penalty: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /Stoppage penalty must be an array of 2 numbers/, "should throw on empty array");
|
||||||
|
|
||||||
|
options.stoppage_penalty = ['a',1];
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /Stoppage penalty must be an array of 2 numbers/, "should throw on non-numeric value");
|
||||||
|
|
||||||
|
options.stoppage_penalty = [1,2,3];
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /Stoppage penalty must be an array of 2 numbers/, "should throw on too many values");
|
||||||
|
|
||||||
|
options.stoppage_penalty = [1];
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /Stoppage penalty must be an array of 2 numbers/, "should throw on not enough values");
|
||||||
|
|
||||||
|
options.stoppage_penalty = [2,1];
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /Stoppage penalty max must be larger than min/, "should throw on max < min");
|
||||||
|
|
||||||
|
options.stoppage_penalty = [-1,2];
|
||||||
|
assert.throws(()=>osrm.table(options, (err, res) => {}), /Stoppage penalty min\/max can't be less than zero/, "should throw on negative value");
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -229,7 +229,8 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
|
|||||||
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
|
const Approach /*approach*/,
|
||||||
|
const bool /*use_all_edges*/) const override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -237,7 +238,8 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
|
|||||||
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
|
const Approach /*approach*/,
|
||||||
|
const bool /*use_all_edges*/) const override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -280,36 +282,48 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/,
|
const util::Coordinate /*input_coordinate*/,
|
||||||
const Approach /*approach*/) const override
|
const Approach /*approach*/,
|
||||||
|
const bool /* use_all_edges */,
|
||||||
|
const double /* min_stoppage_penalty */,
|
||||||
|
const double /* max_stoppage_penalty */) const override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/,
|
const util::Coordinate /*input_coordinate*/,
|
||||||
const double /*max_distance*/,
|
const double /*max_distance*/,
|
||||||
const Approach /*approach*/) const override
|
const Approach /*approach*/,
|
||||||
|
const bool /* use_all_edges */,
|
||||||
|
const double /* min_stoppage_penalty */,
|
||||||
|
const double /* max_stoppage_penalty */) const override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/,
|
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 override
|
const Approach /*approach*/,
|
||||||
|
const bool /* use_all_edges */,
|
||||||
|
const double /* min_stoppage_penalty */,
|
||||||
|
const double /* max_stoppage_penalty */) const override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode>
|
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/,
|
const util::Coordinate /*input_coordinate*/,
|
||||||
const int /*bearing*/,
|
const int /*bearing*/,
|
||||||
const int /*bearing_range*/,
|
const int /*bearing_range*/,
|
||||||
const Approach /*approach*/) const override
|
const Approach /*approach*/,
|
||||||
|
const bool /* use_all_edges */,
|
||||||
|
const double /* min_stoppage_penalty */,
|
||||||
|
const double /* max_stoppage_penalty */) const override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include <boost/test/test_case_template.hpp>
|
#include <boost/test/test_case_template.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "coordinates.hpp"
|
#include "coordinates.hpp"
|
||||||
#include "equal_json.hpp"
|
#include "equal_json.hpp"
|
||||||
#include "fixture.hpp"
|
#include "fixture.hpp"
|
||||||
@@ -32,18 +34,28 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates_fixture)
|
|||||||
|
|
||||||
// unset snapping dependent hint
|
// unset snapping dependent hint
|
||||||
for (auto &itr : result.values["waypoints"].get<json::Array>().values)
|
for (auto &itr : result.values["waypoints"].get<json::Array>().values)
|
||||||
|
{
|
||||||
|
// Hint values aren't stable, so blank it out
|
||||||
itr.get<json::Object>().values["hint"] = "";
|
itr.get<json::Object>().values["hint"] = "";
|
||||||
|
|
||||||
|
// Round value to 6 decimal places for double comparison later
|
||||||
|
itr.get<json::Object>().values["distance"] =
|
||||||
|
round(itr.get<json::Object>().values["distance"].get<json::Number>().value * 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
const auto location = json::Array{{{7.437070}, {43.749248}}};
|
const auto location = json::Array{{{7.437070}, {43.749248}}};
|
||||||
|
|
||||||
json::Object reference{
|
json::Object reference{
|
||||||
{{"code", "Ok"},
|
{{"code", "Ok"},
|
||||||
{"waypoints",
|
{"waypoints",
|
||||||
json::Array{
|
json::Array{{json::Object{{{"name", "Boulevard du Larvotto"},
|
||||||
{json::Object{
|
{"location", location},
|
||||||
{{"name", "Boulevard du Larvotto"}, {"location", location}, {"hint", ""}}},
|
{"distance", round(0.137249 * 1000000)},
|
||||||
json::Object{
|
{"hint", ""}}},
|
||||||
{{"name", "Boulevard du Larvotto"}, {"location", location}, {"hint", ""}}}}}},
|
json::Object{{{"name", "Boulevard du Larvotto"},
|
||||||
|
{"location", location},
|
||||||
|
{"distance", round(0.137249 * 1000000)},
|
||||||
|
{"hint", ""}}}}}},
|
||||||
{"routes",
|
{"routes",
|
||||||
json::Array{{json::Object{
|
json::Array{{json::Object{
|
||||||
{{"distance", 0.},
|
{{"distance", 0.},
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ void validate_feature_layer(vtzero::layer layer)
|
|||||||
BOOST_CHECK_EQUAL(layer.version(), 2);
|
BOOST_CHECK_EQUAL(layer.version(), 2);
|
||||||
BOOST_CHECK_EQUAL(to_string(layer.name()), "speeds");
|
BOOST_CHECK_EQUAL(to_string(layer.name()), "speeds");
|
||||||
BOOST_CHECK_EQUAL(layer.extent(), osrm::util::vector_tile::EXTENT);
|
BOOST_CHECK_EQUAL(layer.extent(), osrm::util::vector_tile::EXTENT);
|
||||||
BOOST_CHECK_EQUAL(layer.key_table().size(), 7);
|
BOOST_CHECK_EQUAL(layer.key_table().size(), 8);
|
||||||
BOOST_CHECK(layer.num_features() > 2500);
|
BOOST_CHECK(layer.num_features() > 2500);
|
||||||
|
|
||||||
while (auto feature = layer.next_feature())
|
while (auto feature = layer.next_feature())
|
||||||
@@ -62,6 +62,9 @@ void validate_feature_layer(vtzero::layer layer)
|
|||||||
BOOST_CHECK(props.find("is_small") != props.end());
|
BOOST_CHECK(props.find("is_small") != props.end());
|
||||||
BOOST_CHECK(props["is_small"].type() == typeid(bool));
|
BOOST_CHECK(props["is_small"].type() == typeid(bool));
|
||||||
|
|
||||||
|
BOOST_CHECK(props.find("is_startpoint") != props.end());
|
||||||
|
BOOST_CHECK(props["is_startpoint"].type() == typeid(bool));
|
||||||
|
|
||||||
BOOST_CHECK(props.find("datasource") != props.end());
|
BOOST_CHECK(props.find("datasource") != props.end());
|
||||||
BOOST_CHECK(props["datasource"].type() == typeid(std::string));
|
BOOST_CHECK(props["datasource"].type() == typeid(std::string));
|
||||||
|
|
||||||
@@ -73,7 +76,7 @@ void validate_feature_layer(vtzero::layer layer)
|
|||||||
std::count_if(layer.value_table().begin(), layer.value_table().end(), [](auto v) {
|
std::count_if(layer.value_table().begin(), layer.value_table().end(), [](auto v) {
|
||||||
return v.type() == vtzero::property_value_type::uint_value;
|
return v.type() == vtzero::property_value_type::uint_value;
|
||||||
});
|
});
|
||||||
BOOST_CHECK_EQUAL(number_of_uint_values, 77);
|
BOOST_CHECK_EQUAL(number_of_uint_values, 78);
|
||||||
}
|
}
|
||||||
|
|
||||||
void validate_turn_layer(vtzero::layer layer)
|
void validate_turn_layer(vtzero::layer layer)
|
||||||
@@ -125,7 +128,7 @@ void validate_node_layer(vtzero::layer layer)
|
|||||||
BOOST_CHECK_EQUAL(to_string(layer.name()), "osmnodes");
|
BOOST_CHECK_EQUAL(to_string(layer.name()), "osmnodes");
|
||||||
BOOST_CHECK_EQUAL(layer.extent(), osrm::util::vector_tile::EXTENT);
|
BOOST_CHECK_EQUAL(layer.extent(), osrm::util::vector_tile::EXTENT);
|
||||||
BOOST_CHECK_EQUAL(layer.key_table().size(), 0);
|
BOOST_CHECK_EQUAL(layer.key_table().size(), 0);
|
||||||
BOOST_CHECK_EQUAL(layer.num_features(), 1791);
|
BOOST_CHECK_EQUAL(layer.num_features(), 1810);
|
||||||
|
|
||||||
while (auto feature = layer.next_feature())
|
while (auto feature = layer.next_feature())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -113,7 +113,8 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
|
|||||||
const float /*max_distance*/,
|
const float /*max_distance*/,
|
||||||
const int /*bearing*/,
|
const int /*bearing*/,
|
||||||
const int /*bearing_range*/,
|
const int /*bearing_range*/,
|
||||||
const engine::Approach /*approach*/) const override
|
const engine::Approach /*approach*/,
|
||||||
|
const bool /*use_all_edges*/) const override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -121,7 +122,8 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
|
|||||||
std::vector<engine::PhantomNodeWithDistance>
|
std::vector<engine::PhantomNodeWithDistance>
|
||||||
NearestPhantomNodesInRange(const util::Coordinate /*input_coordinate*/,
|
NearestPhantomNodesInRange(const util::Coordinate /*input_coordinate*/,
|
||||||
const float /*max_distance*/,
|
const float /*max_distance*/,
|
||||||
const engine::Approach /*approach*/) const override
|
const engine::Approach /*approach*/,
|
||||||
|
const bool /*use_all_edges*/) const override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -167,7 +169,10 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
|
|||||||
std::pair<engine::PhantomNode, engine::PhantomNode>
|
std::pair<engine::PhantomNode, engine::PhantomNode>
|
||||||
NearestPhantomNodeWithAlternativeFromBigComponent(
|
NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
const util::Coordinate /*input_coordinate*/,
|
const util::Coordinate /*input_coordinate*/,
|
||||||
const engine::Approach /*approach*/) const override
|
const engine::Approach /*approach*/,
|
||||||
|
const bool /* use_all_edges */,
|
||||||
|
const double /* min_stoppage_penalty */,
|
||||||
|
const double /* max_stoppage_penalty */) const override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -176,7 +181,10 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
|
|||||||
NearestPhantomNodeWithAlternativeFromBigComponent(
|
NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
const util::Coordinate /*input_coordinate*/,
|
const util::Coordinate /*input_coordinate*/,
|
||||||
const double /*max_distance*/,
|
const double /*max_distance*/,
|
||||||
const engine::Approach /*approach*/) const override
|
const engine::Approach /*approach*/,
|
||||||
|
const bool /* use_all_edges */,
|
||||||
|
const double /* min_stoppage_penalty */,
|
||||||
|
const double /* max_stoppage_penalty */) const override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -187,7 +195,10 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
|
|||||||
const double /*max_distance*/,
|
const double /*max_distance*/,
|
||||||
const int /*bearing*/,
|
const int /*bearing*/,
|
||||||
const int /*bearing_range*/,
|
const int /*bearing_range*/,
|
||||||
const engine::Approach /*approach*/) const override
|
const engine::Approach /*approach*/,
|
||||||
|
const bool /* use_all_edges */,
|
||||||
|
const double /* min_stoppage_penalty */,
|
||||||
|
const double /* max_stoppage_penalty */) const override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -197,7 +208,10 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
|
|||||||
const util::Coordinate /*input_coordinate*/,
|
const util::Coordinate /*input_coordinate*/,
|
||||||
const int /*bearing*/,
|
const int /*bearing*/,
|
||||||
const int /*bearing_range*/,
|
const int /*bearing_range*/,
|
||||||
const engine::Approach /*approach*/) const override
|
const engine::Approach /*approach*/,
|
||||||
|
const bool /* use_all_edges */,
|
||||||
|
const double /* min_stoppage_penalty */,
|
||||||
|
const double /* max_stoppage_penalty */) const override
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,23 @@ BOOST_AUTO_TEST_CASE(invalid_table_urls)
|
|||||||
49UL);
|
49UL);
|
||||||
BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?fallback_coordinate=asdf"),
|
BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?fallback_coordinate=asdf"),
|
||||||
28UL);
|
28UL);
|
||||||
|
BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?fallback_coordinate=10"), 28UL);
|
||||||
|
BOOST_CHECK_EQUAL(
|
||||||
|
testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&scale_factor=-1"), 28UL);
|
||||||
|
BOOST_CHECK_EQUAL(
|
||||||
|
testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&scale_factor=0"), 28UL);
|
||||||
|
BOOST_CHECK_EQUAL(
|
||||||
|
testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&fallback_speed=0"),
|
||||||
|
28UL);
|
||||||
|
BOOST_CHECK_EQUAL(
|
||||||
|
testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&fallback_speed=-1"),
|
||||||
|
28UL);
|
||||||
|
BOOST_CHECK_EQUAL(
|
||||||
|
testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&fallback_speed=0"),
|
||||||
|
28UL);
|
||||||
|
BOOST_CHECK_EQUAL(
|
||||||
|
testInvalidOptions<TableParameters>("1,2;3,4?annotations=durations&fallback_speed=-1"),
|
||||||
|
28UL);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(valid_route_hint)
|
BOOST_AUTO_TEST_CASE(valid_route_hint)
|
||||||
@@ -565,6 +582,44 @@ BOOST_AUTO_TEST_CASE(valid_table_urls)
|
|||||||
BOOST_CHECK_EQUAL(result_7->annotations & TableParameters::AnnotationsType::Distance, true);
|
BOOST_CHECK_EQUAL(result_7->annotations & TableParameters::AnnotationsType::Distance, true);
|
||||||
CHECK_EQUAL_RANGE(reference_7.sources, result_7->sources);
|
CHECK_EQUAL_RANGE(reference_7.sources, result_7->sources);
|
||||||
CHECK_EQUAL_RANGE(reference_7.destinations, result_7->destinations);
|
CHECK_EQUAL_RANGE(reference_7.destinations, result_7->destinations);
|
||||||
|
|
||||||
|
TableParameters reference_8{};
|
||||||
|
reference_8.coordinates = coords_1;
|
||||||
|
auto result_8 =
|
||||||
|
parseParameters<TableParameters>("1,2;3,4?annotations=distance&fallback_speed=2.5");
|
||||||
|
BOOST_CHECK(result_8);
|
||||||
|
BOOST_CHECK_EQUAL(result_8->annotations & TableParameters::AnnotationsType::Distance, true);
|
||||||
|
CHECK_EQUAL_RANGE(reference_8.sources, result_8->sources);
|
||||||
|
CHECK_EQUAL_RANGE(reference_8.destinations, result_8->destinations);
|
||||||
|
|
||||||
|
TableParameters reference_9{};
|
||||||
|
reference_9.coordinates = coords_1;
|
||||||
|
auto result_9 = parseParameters<TableParameters>(
|
||||||
|
"1,2;3,4?annotations=distance&fallback_speed=2.5&fallback_coordinate=input");
|
||||||
|
BOOST_CHECK(result_9);
|
||||||
|
BOOST_CHECK_EQUAL(result_9->annotations & TableParameters::AnnotationsType::Distance, true);
|
||||||
|
CHECK_EQUAL_RANGE(reference_9.sources, result_9->sources);
|
||||||
|
CHECK_EQUAL_RANGE(reference_9.destinations, result_9->destinations);
|
||||||
|
|
||||||
|
TableParameters reference_10{};
|
||||||
|
reference_10.coordinates = coords_1;
|
||||||
|
auto result_10 = parseParameters<TableParameters>(
|
||||||
|
"1,2;3,4?annotations=distance&fallback_speed=20&fallback_coordinate=snapped");
|
||||||
|
BOOST_CHECK(result_10);
|
||||||
|
BOOST_CHECK_EQUAL(result_10->annotations & TableParameters::AnnotationsType::Distance, true);
|
||||||
|
CHECK_EQUAL_RANGE(reference_10.sources, result_10->sources);
|
||||||
|
CHECK_EQUAL_RANGE(reference_10.destinations, result_10->destinations);
|
||||||
|
|
||||||
|
auto result_11 = parseParameters<TableParameters>("1,2;3,4?sources=all&destinations=all&"
|
||||||
|
"annotations=duration&fallback_speed=1&"
|
||||||
|
"fallback_coordinate=snapped&scale_factor=2");
|
||||||
|
BOOST_CHECK(result_11);
|
||||||
|
CHECK_EQUAL_RANGE(reference_1.sources, result_11->sources);
|
||||||
|
CHECK_EQUAL_RANGE(reference_1.destinations, result_11->destinations);
|
||||||
|
CHECK_EQUAL_RANGE(reference_1.bearings, result_11->bearings);
|
||||||
|
CHECK_EQUAL_RANGE(reference_1.radiuses, result_11->radiuses);
|
||||||
|
CHECK_EQUAL_RANGE(reference_1.approaches, result_11->approaches);
|
||||||
|
CHECK_EQUAL_RANGE(reference_1.coordinates, result_11->coordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(valid_match_urls)
|
BOOST_AUTO_TEST_CASE(valid_match_urls)
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ template <unsigned NUM_NODES, unsigned NUM_EDGES> struct RandomGraphFixture
|
|||||||
TestData data;
|
TestData data;
|
||||||
data.u = edge_udist(g);
|
data.u = edge_udist(g);
|
||||||
data.v = edge_udist(g);
|
data.v = edge_udist(g);
|
||||||
|
data.is_startpoint = true;
|
||||||
if (used_edges.find(std::pair<unsigned, unsigned>(
|
if (used_edges.find(std::pair<unsigned, unsigned>(
|
||||||
std::min(data.u, data.v), std::max(data.u, data.v))) == used_edges.end())
|
std::min(data.u, data.v), std::max(data.u, data.v))) == used_edges.end())
|
||||||
{
|
{
|
||||||
@@ -151,7 +152,7 @@ template <unsigned NUM_NODES, unsigned NUM_EDGES> struct RandomGraphFixture
|
|||||||
struct GraphFixture
|
struct GraphFixture
|
||||||
{
|
{
|
||||||
GraphFixture(const std::vector<std::pair<FloatLongitude, FloatLatitude>> &input_coords,
|
GraphFixture(const std::vector<std::pair<FloatLongitude, FloatLatitude>> &input_coords,
|
||||||
const std::vector<std::pair<unsigned, unsigned>> &input_edges)
|
const std::vector<std::tuple<unsigned, unsigned, bool>> &input_edges)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (unsigned i = 0; i < input_coords.size(); i++)
|
for (unsigned i = 0; i < input_coords.size(); i++)
|
||||||
@@ -162,15 +163,16 @@ struct GraphFixture
|
|||||||
for (const auto &pair : input_edges)
|
for (const auto &pair : input_edges)
|
||||||
{
|
{
|
||||||
TestData d;
|
TestData d;
|
||||||
d.u = pair.first;
|
d.u = std::get<0>(pair);
|
||||||
d.v = pair.second;
|
d.v = std::get<1>(pair);
|
||||||
// We set the forward nodes to the target node-based-node IDs, just
|
// We set the forward nodes to the target node-based-node IDs, just
|
||||||
// so we have something to test against. Because this isn't a real
|
// so we have something to test against. Because this isn't a real
|
||||||
// graph, the actual values aren't important, we just need something
|
// graph, the actual values aren't important, we just need something
|
||||||
// to examine during tests.
|
// to examine during tests.
|
||||||
d.forward_segment_id = {pair.second, true};
|
d.forward_segment_id = {std::get<1>(pair), true};
|
||||||
d.reverse_segment_id = {pair.first, true};
|
d.reverse_segment_id = {std::get<0>(pair), true};
|
||||||
d.fwd_segment_position = 0;
|
d.fwd_segment_position = 0;
|
||||||
|
d.is_startpoint = std::get<2>(pair);
|
||||||
edges.emplace_back(d);
|
edges.emplace_back(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,7 +301,7 @@ BOOST_FIXTURE_TEST_CASE(construct_multiple_levels_test, TestRandomGraphFixture_M
|
|||||||
BOOST_AUTO_TEST_CASE(regression_test)
|
BOOST_AUTO_TEST_CASE(regression_test)
|
||||||
{
|
{
|
||||||
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
||||||
using Edge = std::pair<unsigned, unsigned>;
|
using Edge = std::tuple<unsigned, unsigned, bool>;
|
||||||
GraphFixture fixture(
|
GraphFixture fixture(
|
||||||
{
|
{
|
||||||
Coord{FloatLongitude{0.0}, FloatLatitude{40.0}}, //
|
Coord{FloatLongitude{0.0}, FloatLatitude{40.0}}, //
|
||||||
@@ -313,7 +315,7 @@ BOOST_AUTO_TEST_CASE(regression_test)
|
|||||||
Coord{FloatLongitude{105.0}, FloatLatitude{5.0}}, //
|
Coord{FloatLongitude{105.0}, FloatLatitude{5.0}}, //
|
||||||
Coord{FloatLongitude{110.0}, FloatLatitude{0.0}}, //
|
Coord{FloatLongitude{110.0}, FloatLatitude{0.0}}, //
|
||||||
},
|
},
|
||||||
{Edge(0, 1), Edge(2, 3), Edge(4, 5), Edge(6, 7), Edge(8, 9)});
|
{Edge(0, 1, true), Edge(2, 3, true), Edge(4, 5, true), Edge(6, 7, true), Edge(8, 9, true)});
|
||||||
|
|
||||||
TemporaryFile tmp;
|
TemporaryFile tmp;
|
||||||
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
|
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
|
||||||
@@ -335,13 +337,13 @@ BOOST_AUTO_TEST_CASE(regression_test)
|
|||||||
BOOST_AUTO_TEST_CASE(radius_regression_test)
|
BOOST_AUTO_TEST_CASE(radius_regression_test)
|
||||||
{
|
{
|
||||||
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
||||||
using Edge = std::pair<unsigned, unsigned>;
|
using Edge = std::tuple<unsigned, unsigned, bool>;
|
||||||
GraphFixture fixture(
|
GraphFixture fixture(
|
||||||
{
|
{
|
||||||
Coord(FloatLongitude{0.0}, FloatLatitude{0.0}),
|
Coord(FloatLongitude{0.0}, FloatLatitude{0.0}),
|
||||||
Coord(FloatLongitude{10.0}, FloatLatitude{10.0}),
|
Coord(FloatLongitude{10.0}, FloatLatitude{10.0}),
|
||||||
},
|
},
|
||||||
{Edge(0, 1), Edge(1, 0)});
|
{Edge(0, 1, true), Edge(1, 0, true)});
|
||||||
|
|
||||||
TemporaryFile tmp;
|
TemporaryFile tmp;
|
||||||
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
|
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
|
||||||
@@ -352,22 +354,54 @@ BOOST_AUTO_TEST_CASE(radius_regression_test)
|
|||||||
Coordinate input(FloatLongitude{5.2}, FloatLatitude{5.0});
|
Coordinate input(FloatLongitude{5.2}, FloatLatitude{5.0});
|
||||||
|
|
||||||
{
|
{
|
||||||
auto results =
|
auto results = query.NearestPhantomNodesInRange(
|
||||||
query.NearestPhantomNodesInRange(input, 0.01, osrm::engine::Approach::UNRESTRICTED);
|
input, 0.01, osrm::engine::Approach::UNRESTRICTED, true);
|
||||||
BOOST_CHECK_EQUAL(results.size(), 0);
|
BOOST_CHECK_EQUAL(results.size(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(permissive_edge_snapping)
|
||||||
|
{
|
||||||
|
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
||||||
|
using Edge = std::tuple<unsigned, unsigned, bool>;
|
||||||
|
GraphFixture fixture(
|
||||||
|
{
|
||||||
|
Coord(FloatLongitude{0.0}, FloatLatitude{0.0}),
|
||||||
|
Coord(FloatLongitude{0.001}, FloatLatitude{0.001}),
|
||||||
|
},
|
||||||
|
{Edge(0, 1, true), Edge(1, 0, false)});
|
||||||
|
|
||||||
|
TemporaryFile tmp;
|
||||||
|
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
|
||||||
|
TestDataFacade mockfacade;
|
||||||
|
engine::GeospatialQuery<MiniStaticRTree, TestDataFacade> query(
|
||||||
|
rtree, fixture.coords, mockfacade);
|
||||||
|
|
||||||
|
Coordinate input(FloatLongitude{0.0005}, FloatLatitude{0.0005});
|
||||||
|
|
||||||
|
{
|
||||||
|
auto results = query.NearestPhantomNodesInRange(
|
||||||
|
input, 1000, osrm::engine::Approach::UNRESTRICTED, false);
|
||||||
|
BOOST_CHECK_EQUAL(results.size(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto results = query.NearestPhantomNodesInRange(
|
||||||
|
input, 1000, osrm::engine::Approach::UNRESTRICTED, true);
|
||||||
|
BOOST_CHECK_EQUAL(results.size(), 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(bearing_tests)
|
BOOST_AUTO_TEST_CASE(bearing_tests)
|
||||||
{
|
{
|
||||||
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
||||||
using Edge = std::pair<unsigned, unsigned>;
|
using Edge = std::tuple<unsigned, unsigned, bool>;
|
||||||
GraphFixture fixture(
|
GraphFixture fixture(
|
||||||
{
|
{
|
||||||
Coord(FloatLongitude{0.0}, FloatLatitude{0.0}),
|
Coord(FloatLongitude{0.0}, FloatLatitude{0.0}),
|
||||||
Coord(FloatLongitude{10.0}, FloatLatitude{10.0}),
|
Coord(FloatLongitude{10.0}, FloatLatitude{10.0}),
|
||||||
},
|
},
|
||||||
{Edge(0, 1), Edge(1, 0)});
|
{Edge(0, 1, true), Edge(1, 0, true)});
|
||||||
|
|
||||||
TemporaryFile tmp;
|
TemporaryFile tmp;
|
||||||
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
|
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
|
||||||
@@ -405,20 +439,20 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto results =
|
auto results = query.NearestPhantomNodesInRange(
|
||||||
query.NearestPhantomNodesInRange(input, 11000, osrm::engine::Approach::UNRESTRICTED);
|
input, 11000, osrm::engine::Approach::UNRESTRICTED, true);
|
||||||
BOOST_CHECK_EQUAL(results.size(), 2);
|
BOOST_CHECK_EQUAL(results.size(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto results = query.NearestPhantomNodesInRange(
|
auto results = query.NearestPhantomNodesInRange(
|
||||||
input, 11000, 270, 10, osrm::engine::Approach::UNRESTRICTED);
|
input, 11000, 270, 10, osrm::engine::Approach::UNRESTRICTED, true);
|
||||||
BOOST_CHECK_EQUAL(results.size(), 0);
|
BOOST_CHECK_EQUAL(results.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto results = query.NearestPhantomNodesInRange(
|
auto results = query.NearestPhantomNodesInRange(
|
||||||
input, 11000, 45, 10, osrm::engine::Approach::UNRESTRICTED);
|
input, 11000, 45, 10, osrm::engine::Approach::UNRESTRICTED, true);
|
||||||
BOOST_CHECK_EQUAL(results.size(), 2);
|
BOOST_CHECK_EQUAL(results.size(), 2);
|
||||||
|
|
||||||
BOOST_CHECK(results[0].phantom_node.forward_segment_id.enabled);
|
BOOST_CHECK(results[0].phantom_node.forward_segment_id.enabled);
|
||||||
@@ -434,7 +468,7 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
|
|||||||
BOOST_AUTO_TEST_CASE(bbox_search_tests)
|
BOOST_AUTO_TEST_CASE(bbox_search_tests)
|
||||||
{
|
{
|
||||||
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
||||||
using Edge = std::pair<unsigned, unsigned>;
|
using Edge = std::tuple<unsigned, unsigned, bool>;
|
||||||
|
|
||||||
GraphFixture fixture(
|
GraphFixture fixture(
|
||||||
{
|
{
|
||||||
@@ -444,7 +478,7 @@ BOOST_AUTO_TEST_CASE(bbox_search_tests)
|
|||||||
Coord(FloatLongitude{3.0}, FloatLatitude{3.0}),
|
Coord(FloatLongitude{3.0}, FloatLatitude{3.0}),
|
||||||
Coord(FloatLongitude{4.0}, FloatLatitude{4.0}),
|
Coord(FloatLongitude{4.0}, FloatLatitude{4.0}),
|
||||||
},
|
},
|
||||||
{Edge(0, 1), Edge(1, 2), Edge(2, 3), Edge(3, 4)});
|
{Edge(0, 1, true), Edge(1, 2, true), Edge(2, 3, true), Edge(3, 4, true)});
|
||||||
|
|
||||||
TemporaryFile tmp;
|
TemporaryFile tmp;
|
||||||
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
|
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
|
||||||
|
|||||||
Reference in New Issue
Block a user