Compare commits

..

12 Commits

Author SHA1 Message Date
Daniel Patterson 951af0c245 Prepare 5.22.0 release. 2019-01-30 15:35:51 -08:00
Daniel Patterson bbf338aa7c Merge branch 'master' into 5.22 2019-01-30 15:35:20 -08:00
Lev Dragunov 8b45ff7a18 Store metadata about original OSM data, and return it in the API response, if available. 2019-01-30 15:31:56 -08:00
Daniel Patterson 4c665b24d9 Add optional builds for lts and node version aliases. This will give us a heads up when new Node (#5347)
versions break bindings, and might automagically get us support for new versions if it "just works".
2019-01-30 12:17:04 -08:00
Daniel Patterson 67809998f9 Prepare 5.22.0-rc.2 2019-01-24 17:01:23 -08:00
Daniel Patterson 8992134d4c Fix regression in profile. 2019-01-24 17:00:55 -08:00
Daniel Patterson 51dd414b83 Prepare release candidate. 2019-01-24 16:35:10 -08:00
Daniel Patterson 381d492a8f Add waypoints parameter to viaroute API (#5345)
* Add silent waypoints to viaroute API.
2019-01-24 16:19:59 -08:00
Daniel Patterson e250c83c21 Add BUILD_CONCURRENCY argument so that we can limit concurrency on Docker Hub (and thus reduce peak memory need for build) 2019-01-17 16:16:44 -08:00
Andrii Dmytrenko e2e326d15e Fix cpack config by pointing to a correct LICENSE file 2019-01-17 09:45:11 -08:00
Daniel Patterson 4abca85474 Downgrade to debian:stretch-slim to ensure stable environment for building. 2019-01-11 16:46:28 -08:00
Daniel Patterson 2c78d862a3 Reset master for next release. 2018-12-18 16:25:51 -07:00
48 changed files with 757 additions and 907 deletions
+135 -2
View File
@@ -13,7 +13,6 @@ 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*)?$/
@@ -37,6 +36,10 @@ env:
- ENABLE_NODE_BINDINGS=On - ENABLE_NODE_BINDINGS=On
- NODE="10" - NODE="10"
stages:
- core
- optional
matrix: matrix:
fast_finish: true fast_finish: true
@@ -44,12 +47,14 @@ matrix:
include: include:
# Debug Builds # Debug Builds
- os: linux - stage: core
os: linux
compiler: "format-taginfo-docs" compiler: "format-taginfo-docs"
env: NODE=10 env: NODE=10
sudo: false sudo: false
before_install: before_install:
install: install:
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
- source $NVM_DIR/nvm.sh - source $NVM_DIR/nvm.sh
- nvm install $NODE - nvm install $NODE
- nvm use $NODE - nvm use $NODE
@@ -276,7 +281,135 @@ matrix:
after_success: after_success:
- ./scripts/travis/publish.sh - ./scripts/travis/publish.sh
- os: osx
stage: optional
osx_image: xcode9.2
compiler: "mason-osx-release-node-latest"
# we use the xcode provides clang and don't install our own
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="node"
after_success:
- ./scripts/travis/publish.sh
- os: linux
sudo: false
compiler: "node-latest-mason-linux-release"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-4.9-dev']
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="node"
install:
- pushd ${OSRM_BUILD_DIR}
- |
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
-DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
-DENABLE_GLIBC_WORKAROUND=ON
- make --jobs=${JOBS}
- popd
script:
- npm run nodejs-tests
after_success:
- ./scripts/travis/publish.sh
- os: linux
sudo: false
compiler: "node-latest-mason-linux-debug"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-4.9-dev']
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="node"
install:
- pushd ${OSRM_BUILD_DIR}
- |
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
-DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
-DENABLE_GLIBC_WORKAROUND=ON
- make --jobs=${JOBS}
- popd
script:
- npm run nodejs-tests
after_success:
- ./scripts/travis/publish.sh
- os: osx
osx_image: xcode9.2
compiler: "mason-osx-release-node-lts"
# we use the xcode provides clang and don't install our own
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="--lts"
after_success:
- ./scripts/travis/publish.sh
- os: linux
sudo: false
compiler: "node-lts-mason-linux-release"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-4.9-dev']
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="--lts"
install:
- pushd ${OSRM_BUILD_DIR}
- |
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
-DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
-DENABLE_GLIBC_WORKAROUND=ON
- make --jobs=${JOBS}
- popd
script:
- npm run nodejs-tests
after_success:
- ./scripts/travis/publish.sh
- os: linux
sudo: false
compiler: "node-lts-mason-linux-debug"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-4.9-dev']
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="--lts"
install:
- pushd ${OSRM_BUILD_DIR}
- |
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
-DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
-DENABLE_GLIBC_WORKAROUND=ON
- make --jobs=${JOBS}
- popd
script:
- npm run nodejs-tests
after_success:
- ./scripts/travis/publish.sh
allow_failures:
- compiler: "mason-osx-release-node-latest"
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="node"
- compiler: "node-latest-mason-linux-release"
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="node"
- compiler: "node-latest-mason-linux-debug"
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="node"
- compiler: "mason-osx-release-node-lts"
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="--lts"
- compiler: "node-lts-mason-linux-release"
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="--lts"
- compiler: "node-lts-mason-linux-debug"
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="--lts"
before_install: before_install:
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
- source $NVM_DIR/nvm.sh - source $NVM_DIR/nvm.sh
- nvm install $NODE - nvm install $NODE
- nvm use $NODE - nvm use $NODE
+8
View File
@@ -1,3 +1,11 @@
# 5.22.0
- Changes from 5.21.0
- Build:
- ADDED: optionally build Node `lts` and `latest` bindings [#5347](https://github.com/Project-OSRM/osrm-backend/pull/5347)
- Features:
- ADDED: new waypoints parameter to the `route` plugin, enabling silent waypoints [#5345](https://github.com/Project-OSRM/osrm-backend/pull/5345)
- ADDED: data timestamp information in the response (saved in new file `.osrm.timestamp`). [#5115](https://github.com/Project-OSRM/osrm-backend/issues/5115)
# 5.21.0 # 5.21.0
- Changes from 5.20.0 - Changes from 5.20.0
- Features: - Features:
+1 -1
View File
@@ -11,7 +11,7 @@ SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY "FALSE")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md") SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Open Source Routing Machine (OSRM) is a high-performance routing engine. It combines sophisticated routing algorithms with the open and free data of the OpenStreetMap.") SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Open Source Routing Machine (OSRM) is a high-performance routing engine. It combines sophisticated routing algorithms with the open and free data of the OpenStreetMap.")
SET(CPACK_PACKAGE_CONTACT "Project OSRM <info@project-osrm.org>") SET(CPACK_PACKAGE_CONTACT "Project OSRM <info@project-osrm.org>")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENCE.TXT") SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.TXT")
SET(CPACK_STRIP_FILES "TRUE") SET(CPACK_STRIP_FILES "TRUE")
file(GLOB_RECURSE ProfileGlob ${CMAKE_SOURCE_DIR}/profiles/*) file(GLOB_RECURSE ProfileGlob ${CMAKE_SOURCE_DIR}/profiles/*)
+15 -10
View File
@@ -1,14 +1,14 @@
FROM debian:buster-slim as builder FROM debian:stretch-slim as builder
ARG DOCKER_TAG ARG DOCKER_TAG
ARG BUILD_CONCURRENCY
RUN mkdir -p /src && mkdir -p /opt RUN mkdir -p /src && mkdir -p /opt
COPY . /src COPY . /src
WORKDIR /src WORKDIR /src
RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \ RUN NPROC=${BUILD_CONCURRENCY:-$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1)} && \
apt-get update && \ apt-get update && \
apt-get -y --no-install-recommends install cmake make git gcc g++ libbz2-dev libstxxl-dev libstxxl1v5 libxml2-dev \ apt-get -y --no-install-recommends install cmake make git gcc g++ libbz2-dev libxml2-dev \
libzip-dev libboost1.67-all-dev lua5.2 liblua5.2-dev libtbb-dev -o APT::Install-Suggests=0 -o APT::Install-Recommends=0 && \ libzip-dev libboost1.62-all-dev lua5.2 liblua5.2-dev libtbb-dev -o APT::Install-Suggests=0 -o APT::Install-Recommends=0 && \
NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
echo "Building OSRM ${DOCKER_TAG}" && \ echo "Building OSRM ${DOCKER_TAG}" && \
git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \ git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \
echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \ echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \
@@ -30,15 +30,20 @@ RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
# 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 debian:buster-slim as runstage FROM debian:stretch-slim as runstage
RUN mkdir -p /src && mkdir -p /opt RUN mkdir -p /src && mkdir -p /opt
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends libboost-program-options1.67.0 libboost-regex1.67.0 \ apt-get install -y --no-install-recommends libboost-program-options1.62.0 libboost-regex1.62.0 \
libboost-date-time1.67.0 libboost-chrono1.67.0 libboost-filesystem1.67.0 \ libboost-date-time1.62.0 libboost-chrono1.62.0 libboost-filesystem1.62.0 \
libboost-iostreams1.67.0 libboost-thread1.67.0 expat liblua5.2-0 libtbb2 &&\ libboost-iostreams1.62.0 libboost-thread1.62.0 expat liblua5.2-0 libtbb2 &&\
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*
COPY --from=builder /usr/local /usr/local COPY --from=builder /usr/local /usr/local
COPY --from=builder /opt /opt COPY --from=builder /opt /opt
RUN /usr/local/bin/osrm-extract --help && \
/usr/local/bin/osrm-routed --help && \
/usr/local/bin/osrm-contract --help && \
/usr/local/bin/osrm-partition --help && \
/usr/local/bin/osrm-customize --help
WORKDIR /opt WORKDIR /opt
EXPOSE 5000 EXPOSE 5000
+1 -1
View File
@@ -6,4 +6,4 @@
# ensure that "COPY . /src" is referring to the repo root, not the directory # ensure that "COPY . /src" is referring to the repo root, not the directory
# that contains the Dockerfile. # that contains the Dockerfile.
# This script gets executed with a pwd of wherever the Dockerfile is. # This script gets executed with a pwd of wherever the Dockerfile is.
docker build --build-arg DOCKER_TAG=${DOCKER_TAG} -t $IMAGE_NAME -f Dockerfile .. docker build --build-arg BUILD_CONCURRENCY=${CONCURRENCY:-1} --build-arg DOCKER_TAG=${DOCKER_TAG} -t $IMAGE_NAME -f Dockerfile ..
+9 -1
View File
@@ -70,6 +70,8 @@ curl 'http://router.project-osrm.org/route/v1/driving/polyline(ofp_Ik_vpAilAyu@t
### Responses ### Responses
#### Code
Every response object has a `code` property containing one of the strings below or a service dependent code: Every response object has a `code` property containing one of the strings below or a service dependent code:
| Type | Description | | Type | Description |
@@ -87,12 +89,17 @@ Every response object has a `code` property containing one of the strings below
- `message` is a **optional** human-readable error message. All other status types are service dependent. - `message` is a **optional** human-readable error message. All other status types are service dependent.
- In case of an error the HTTP status code will be `400`. Otherwise the HTTP status code will be `200` and `code` will be `Ok`. - In case of an error the HTTP status code will be `400`. Otherwise the HTTP status code will be `200` and `code` will be `Ok`.
#### Data version
Every response object has a `data_version` propetry containing timestamp from the original OpenStreetMap file. This field is optional. It can be ommited if data_version parametr was not set on osrm-extract stage or OSM file has not `osmosis_replication_timestamp` section.
#### Example response #### Example response
```json ```json
{ {
"code": "Ok", "code": "Ok",
"message": "Everything worked" "message": "Everything worked",
"data_version": "2017-11-17T21:43:02Z"
} }
``` ```
@@ -195,6 +202,7 @@ In addition to the [general options](#general-options) the following options are
|geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) | |geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) |
|overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.| |overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.|
|continue\_straight |`default` (default), `true`, `false` |Forces the route to keep going straight at waypoints constraining uturns there even if it would be faster. Default value depends on the profile. | |continue\_straight |`default` (default), `true`, `false` |Forces the route to keep going straight at waypoints constraining uturns there even if it would be faster. Default value depends on the profile. |
|waypoints | `{index};{index};{index}...` |Treats input coordinates indicated by given indices as waypoints in returned Match object. Default is to treat all input coordinates as waypoints. |
\* Please note that even if alternative routes are requested, a result cannot be guaranteed. \* Please note that even if alternative routes are requested, a result cannot be guaranteed.
+2
View File
@@ -57,6 +57,7 @@ Returns the fastest route between two or more coordinates while visiting the way
- `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`) - `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
- `options.continue_straight` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile. - `options.continue_straight` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile.
- `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`. - `options.approaches` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
- `options.waypoints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Indices to coordinates to treat as waypoints. If not supplied, all coordinates are waypoints. Must include first and last coordinate index.
`null`/`true`/`false` `null`/`true`/`false`
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** - `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
@@ -210,6 +211,7 @@ if they can not be matched successfully.
- `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy. Can be `null` for default value `5` meters or `double >= 0`. - `options.radiuses` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy. Can be `null` for default value `5` meters or `double >= 0`.
- `options.gaps` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Allows the input track splitting based on huge timestamp gaps between points. Either `split` or `ignore` (optional, default `split`). - `options.gaps` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** Allows the input track splitting based on huge timestamp gaps between points. Either `split` or `ignore` (optional, default `split`).
- `options.tidy` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Allows the input track modification to obtain better matching quality for noisy tracks (optional, default `false`). - `options.tidy` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Allows the input track modification to obtain better matching quality for noisy tracks (optional, default `false`).
- `options.waypoints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Indices to coordinates to treat as waypoints. If not supplied, all coordinates are waypoints. Must include first and last coordinate index.
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** - `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)**
**Examples** **Examples**
-25
View File
@@ -35,28 +35,3 @@ 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 |
+4
View File
@@ -75,6 +75,10 @@ module.exports = function () {
got.message = json.message || ''; got.message = json.message || '';
} }
if (headers.has('data_version')) {
got.data_version = json.data_version || '';
}
if (headers.has('#')) { if (headers.has('#')) {
// comment column // comment column
got['#'] = row['#']; got['#'] = row['#'];
+20 -3
View File
@@ -17,9 +17,26 @@ Feature: Basic Routing
| ab | | ab |
When I route I should get When I route I should get
| from | to | route | | from | to | route | data_version |
| a | b | ab,ab | | a | b | ab,ab | |
| b | a | ab,ab | | b | a | ab,ab | |
Scenario: Data_version test
Given the node map
"""
a b
"""
And the extract extra arguments "--data_version cucumber_data_version"
And the ways
| nodes |
| ab |
When I route I should get
| from | to | route | data_version |
| a | b | ab,ab | cucumber_data_version |
| b | a | ab,ab | cucumber_data_version |
Scenario: Routing in between two nodes of way Scenario: Routing in between two nodes of way
Given the node map Given the node map
-168
View File
@@ -1,168 +0,0 @@
@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 |
+47
View File
@@ -18,6 +18,53 @@ Feature: Via points
| waypoints | route | | waypoints | route |
| a,b,c | abc,abc,abc,abc | | a,b,c | abc,abc,abc,abc |
Scenario: Simple via point with waypoints collapsing
Given the node map
"""
a
b 1c d
2
e
"""
And the ways
| nodes |
| ace |
| bcd |
Given the query options
| waypoints | 0;2 |
When I route I should get
| waypoints | route | turns |
| b,1,e | bcd,ace,ace | depart,turn right,arrive |
| b,2,e | bcd,ace,ace | depart,turn right,arrive |
Scenario: Simple via point with waypoints collapsing
Given the node map
"""
a 2 b
c d
1 3
"""
And the ways
| nodes |
| ab |
| bd |
| cd |
| ac |
Given the query options
| waypoints | 0;2 |
When I route I should get
| waypoints | route | turns |
| 1,2,3 | cd,ac,ab,bd,cd | depart,new name right,new name right,new name right,arrive |
Scenario: Simple via point with core factor Scenario: Simple via point with core factor
Given the contract extra arguments "--core 0.8" Given the contract extra arguments "--core 0.8"
Given the node map Given the node map
+5 -25
View File
@@ -63,13 +63,6 @@ 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;
@@ -80,34 +73,21 @@ 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()) &&
@@ -123,8 +103,8 @@ struct BaseParameters
}); });
} }
}; };
} // namespace api }
} // namespace engine }
} // namespace osrm }
#endif // ROUTE_PARAMETERS_HPP #endif // ROUTE_PARAMETERS_HPP
+4 -9
View File
@@ -63,7 +63,7 @@ struct MatchParameters : public RouteParameters
RouteParameters::GeometriesType::Polyline, RouteParameters::GeometriesType::Polyline,
RouteParameters::OverviewType::Simplified, RouteParameters::OverviewType::Simplified,
{}), {}),
gaps(GapsType::Split), tidy(false), waypoints() gaps(GapsType::Split), tidy(false)
{ {
} }
@@ -79,24 +79,19 @@ struct MatchParameters : public RouteParameters
bool tidy_, bool tidy_,
std::vector<std::size_t> waypoints_, std::vector<std::size_t> waypoints_,
Args... args_) Args... args_)
: RouteParameters{std::forward<Args>(args_)...}, timestamps{std::move(timestamps_)}, : RouteParameters{std::forward<Args>(args_)..., waypoints_},
gaps(gaps_), tidy(tidy_), waypoints{std::move(waypoints_)} timestamps{std::move(timestamps_)}, gaps(gaps_), tidy(tidy_)
{ {
} }
std::vector<unsigned> timestamps; std::vector<unsigned> timestamps;
GapsType gaps; GapsType gaps;
bool tidy; bool tidy;
std::vector<std::size_t> waypoints;
bool IsValid() const bool IsValid() const
{ {
const auto valid_waypoints =
std::all_of(waypoints.begin(), waypoints.end(), [this](const auto &w) {
return w < coordinates.size();
});
return RouteParameters::IsValid() && return RouteParameters::IsValid() &&
(timestamps.empty() || timestamps.size() == coordinates.size()) && valid_waypoints; (timestamps.empty() || timestamps.size() == coordinates.size());
} }
}; };
} }
+11 -4
View File
@@ -44,8 +44,11 @@ class RouteAPI : public BaseAPI
{ {
} }
void MakeResponse(const InternalManyRoutesResult &raw_routes, void
util::json::Object &response) const MakeResponse(const InternalManyRoutesResult &raw_routes,
const std::vector<PhantomNodes>
&all_start_end_points, // all used coordinates, ignoring waypoints= parameter
util::json::Object &response) const
{ {
BOOST_ASSERT(!raw_routes.routes.empty()); BOOST_ASSERT(!raw_routes.routes.empty());
@@ -62,10 +65,14 @@ class RouteAPI : public BaseAPI
route.target_traversed_in_reverse)); route.target_traversed_in_reverse));
} }
response.values["waypoints"] = response.values["waypoints"] = BaseAPI::MakeWaypoints(all_start_end_points);
BaseAPI::MakeWaypoints(raw_routes.routes[0].segment_end_coordinates);
response.values["routes"] = std::move(jsRoutes); response.values["routes"] = std::move(jsRoutes);
response.values["code"] = "Ok"; response.values["code"] = "Ok";
auto data_timestamp = facade.GetTimestamp();
if (!data_timestamp.empty())
{
response.values["data_version"] = data_timestamp;
}
} }
protected: protected:
+51 -7
View File
@@ -98,7 +98,8 @@ struct RouteParameters : public BaseParameters
annotations_type{AnnotationsType::None}, annotations_type{AnnotationsType::None},
geometries{geometries_}, geometries{geometries_},
overview{overview_}, overview{overview_},
continue_straight{continue_straight_} continue_straight{continue_straight_},
waypoints()
{ {
} }
@@ -114,7 +115,9 @@ struct RouteParameters : public BaseParameters
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_}, : BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_}, number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None}, annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_} geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_},
waypoints()
{ {
} }
@@ -131,7 +134,43 @@ struct RouteParameters : public BaseParameters
number_of_alternatives{alternatives_ ? 1u : 0u}, number_of_alternatives{alternatives_ ? 1u : 0u},
annotations{annotations_ == AnnotationsType::None ? false : true}, annotations{annotations_ == AnnotationsType::None ? false : true},
annotations_type{annotations_}, geometries{geometries_}, overview{overview_}, annotations_type{annotations_}, geometries{geometries_}, overview{overview_},
continue_straight{continue_straight_} continue_straight{continue_straight_}, waypoints()
{
}
// RouteParameters constructor adding the `waypoints` parameter
template <typename... Args>
RouteParameters(const bool steps_,
const bool alternatives_,
const bool annotations_,
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
std::vector<std::size_t> waypoints_,
const Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_},
waypoints{waypoints_}
{
}
// RouteParameters constructor adding the `waypoints` parameter
template <typename... Args>
RouteParameters(const bool steps_,
const bool alternatives_,
const AnnotationsType annotations_,
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
std::vector<std::size_t> waypoints_,
Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u},
annotations{annotations_ == AnnotationsType::None ? false : true},
annotations_type{annotations_}, geometries{geometries_}, overview{overview_},
continue_straight{continue_straight_}, waypoints{waypoints_}
{ {
} }
@@ -144,12 +183,17 @@ struct RouteParameters : public BaseParameters
GeometriesType geometries = GeometriesType::Polyline; GeometriesType geometries = GeometriesType::Polyline;
OverviewType overview = OverviewType::Simplified; OverviewType overview = OverviewType::Simplified;
boost::optional<bool> continue_straight; boost::optional<bool> continue_straight;
std::vector<std::size_t> waypoints;
bool IsValid() const bool IsValid() const
{ {
const auto coordinates_ok = coordinates.size() >= 2; const auto coordinates_ok = coordinates.size() >= 2;
const auto base_params_ok = BaseParameters::IsValid(); const auto base_params_ok = BaseParameters::IsValid();
return coordinates_ok && base_params_ok; const auto valid_waypoints =
std::all_of(waypoints.begin(), waypoints.end(), [this](const auto &w) {
return w < coordinates.size();
});
return coordinates_ok && base_params_ok && valid_waypoints;
} }
}; };
@@ -173,8 +217,8 @@ inline RouteParameters::AnnotationsType operator|=(RouteParameters::AnnotationsT
{ {
return lhs = lhs | rhs; return lhs = lhs | rhs;
} }
} } // ns api
} } // ns engine
} } // ns osrm
#endif #endif
+5 -3
View File
@@ -78,6 +78,7 @@ struct TableParameters : public BaseParameters
}; };
AnnotationsType annotations = AnnotationsType::Duration; AnnotationsType annotations = AnnotationsType::Duration;
double scale_factor = 1; double scale_factor = 1;
TableParameters() = default; TableParameters() = default;
@@ -112,6 +113,7 @@ struct TableParameters : public BaseParameters
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_} scale_factor{scale_factor_}
{ {
} }
@@ -164,8 +166,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
@@ -137,6 +137,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
extractor::Datasources *m_datasources; extractor::Datasources *m_datasources;
std::uint32_t m_check_sum; std::uint32_t m_check_sum;
StringView m_data_timestamp;
util::vector_view<util::Coordinate> m_coordinate_list; util::vector_view<util::Coordinate> m_coordinate_list;
extractor::PackedOSMIDsView m_osmnodeid_list; extractor::PackedOSMIDsView m_osmnodeid_list;
util::vector_view<std::uint32_t> m_lane_description_offsets; util::vector_view<std::uint32_t> m_lane_description_offsets;
@@ -183,6 +184,8 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
m_check_sum = *index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum"); m_check_sum = *index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum");
m_data_timestamp = make_timestamp_view(index, "/common/timestamp");
std::tie(m_coordinate_list, m_osmnodeid_list) = std::tie(m_coordinate_list, m_osmnodeid_list) =
make_nbn_data_view(index, "/common/nbn_data"); make_nbn_data_view(index, "/common/nbn_data");
@@ -384,88 +387,59 @@ 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> NearestPhantomNodeWithAlternativeFromBigComponent( std::pair<PhantomNode, PhantomNode>
const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const Approach approach, const Approach approach) const override final
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, input_coordinate, approach);
approach,
use_all_edges,
minimum_stoppage_penalty,
maximum_stoppage_penalty);
} }
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( 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 Approach approach) const override final
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, input_coordinate, max_distance, approach);
max_distance,
approach,
use_all_edges,
minimum_stoppage_penalty,
maximum_stoppage_penalty);
} }
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( std::pair<PhantomNode, PhantomNode>
const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach, const Approach approach) const override final
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, input_coordinate, max_distance, bearing, bearing_range, approach);
max_distance,
bearing,
bearing_range,
approach,
use_all_edges,
minimum_stoppage_penalty,
maximum_stoppage_penalty);
} }
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( std::pair<PhantomNode, PhantomNode>
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 Approach approach) const override final
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, input_coordinate, bearing, bearing_range, approach);
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; }
std::string GetTimestamp() const override final
{
return std::string(m_data_timestamp.begin(), m_data_timestamp.end());
}
GeometryID GetGeometryIndex(const NodeID id) const override final GeometryID GetGeometryIndex(const NodeID id) const override final
{ {
return edge_based_node_data.GetGeometryID(id); return edge_based_node_data.GetGeometryID(id);
+20 -30
View File
@@ -74,6 +74,8 @@ class BaseDataFacade
virtual std::uint32_t GetCheckSum() const = 0; virtual std::uint32_t GetCheckSum() const = 0;
virtual std::string GetTimestamp() const = 0;
// node and edge information access // node and edge information access
virtual util::Coordinate GetCoordinateOfNode(const NodeID id) const = 0; virtual util::Coordinate GetCoordinateOfNode(const NodeID id) const = 0;
@@ -157,36 +159,24 @@ 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> NearestPhantomNodeWithAlternativeFromBigComponent( virtual std::pair<PhantomNode, PhantomNode>
const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const Approach approach, const Approach approach) const = 0;
const bool use_all_edges, virtual std::pair<PhantomNode, PhantomNode>
const double minimum_stoppage_penalty, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double maximum_stoppage_penalty) const = 0; const double max_distance,
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( const Approach approach) const = 0;
const util::Coordinate input_coordinate, virtual std::pair<PhantomNode, PhantomNode>
const double max_distance, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const Approach approach, const double max_distance,
const bool use_all_edges, const int bearing,
const double minimum_stoppage_penalty, const int bearing_range,
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 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 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;
+45 -116
View File
@@ -205,25 +205,18 @@ 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 Approach approach) const
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, [this, approach, &input_coordinate, &has_big_component, &has_small_component](
approach, const CandidateSegment &segment) {
&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, use_all_edges); const auto valid_edges = HasValidEdge(segment);
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);
@@ -250,39 +243,27 @@ 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( return std::make_pair(MakePhantomNode(input_coordinate, results.front()).phantom_node,
MakePhantomNode( MakePhantomNode(input_coordinate, results.back()).phantom_node);
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 Approach approach) const
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, [this, approach, &input_coordinate, &has_big_component, &has_small_component](
approach, const CandidateSegment &segment) {
&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, use_all_edges); const auto valid_edges = HasValidEdge(segment);
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);
@@ -307,13 +288,8 @@ 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( return std::make_pair(MakePhantomNode(input_coordinate, results.front()).phantom_node,
MakePhantomNode( MakePhantomNode(input_coordinate, results.back()).phantom_node);
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
@@ -322,10 +298,7 @@ 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 Approach approach) const
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;
@@ -337,13 +310,12 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bearing, bearing,
bearing_range, bearing_range,
&has_big_component, &has_big_component,
&has_small_component, &has_small_component](const CandidateSegment &segment) {
&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_all_edges)); use_directions = boolPairAnd(use_directions, HasValidEdge(segment));
if (use_segment) if (use_segment)
{ {
@@ -373,13 +345,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
} }
BOOST_ASSERT(results.size() > 0); BOOST_ASSERT(results.size() > 0);
return std::make_pair( return std::make_pair(MakePhantomNode(input_coordinate, results.front()).phantom_node,
MakePhantomNode( MakePhantomNode(input_coordinate, results.back()).phantom_node);
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
@@ -389,10 +356,7 @@ 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 Approach approach) const
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;
@@ -404,13 +368,12 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bearing, bearing,
bearing_range, bearing_range,
&has_big_component, &has_big_component,
&has_small_component, &has_small_component](const CandidateSegment &segment) {
&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_all_edges)); use_directions = boolPairAnd(use_directions, HasValidEdge(segment));
if (use_segment) if (use_segment)
{ {
@@ -442,13 +405,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
} }
BOOST_ASSERT(results.size() > 0); BOOST_ASSERT(results.size() > 0);
return std::make_pair( return std::make_pair(MakePhantomNode(input_coordinate, results.front()).phantom_node,
MakePhantomNode( MakePhantomNode(input_coordinate, results.back()).phantom_node);
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:
@@ -466,11 +424,8 @@ 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 EdgeData &data) const
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;
@@ -509,21 +464,16 @@ 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});
// For measuring distance from begin up to end EdgeDistance forward_distance_offset = 0;
const auto appx_distance = [this](decltype(forward_geometry.begin()) begin, // Sum up the distance from the start to the fwd_segment_position
decltype(forward_geometry.begin()) end) { for (auto current = forward_geometry.begin();
EdgeDistance dist = 0; current < forward_geometry.begin() + data.fwd_segment_position;
for (; begin != end; ++begin) ++current)
{ {
dist += util::coordinate_calculation::fccApproximateDistance( forward_distance_offset += util::coordinate_calculation::fccApproximateDistance(
datafacade.GetCoordinateOfNode(*begin), datafacade.GetCoordinateOfNode(*current),
datafacade.GetCoordinateOfNode(*std::next(begin))); datafacade.GetCoordinateOfNode(*std::next(current)));
} }
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()));
@@ -544,9 +494,16 @@ 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 = EdgeDistance reverse_distance_offset = 0;
appx_distance(forward_geometry.begin() + data.fwd_segment_position + 1, // Sum up the distance from just after the fwd_segment_position to the end
std::prev(forward_geometry.end())); for (auto current = forward_geometry.begin() + data.fwd_segment_position + 1;
current != 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];
@@ -556,43 +513,16 @@ 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
@@ -623,7 +553,6 @@ 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,
@@ -774,7 +703,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const CoordinateList &coordinates; const CoordinateList &coordinates;
DataFacadeT &datafacade; DataFacadeT &datafacade;
}; };
} // namespace engine }
} // namespace osrm }
#endif #endif
+2 -5
View File
@@ -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
// captured by the phantom node. So we need to add the target duration here. // caputed 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,9 +182,6 @@ 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)
{ {
+4 -4
View File
@@ -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) == sizeof(PhantomNode) + 4, "Hint is bigger than expected"); static_assert(sizeof(Hint) == 80 + 4, "Hint is bigger than expected");
constexpr std::size_t ENCODED_HINT_SIZE = 120; constexpr std::size_t ENCODED_HINT_SIZE = 112;
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
+22 -28
View File
@@ -44,15 +44,14 @@ namespace engine
struct PhantomNode struct PhantomNode
{ {
PhantomNode() PhantomNode()
: forward_segment_id{SPECIAL_SEGMENTID, false}, reverse_segment_id{SPECIAL_SEGMENTID, : forward_segment_id{SPECIAL_SEGMENTID, false},
false}, reverse_segment_id{SPECIAL_SEGMENTID, false}, forward_weight(INVALID_EDGE_WEIGHT),
forward_weight(INVALID_EDGE_WEIGHT), reverse_weight(INVALID_EDGE_WEIGHT), reverse_weight(INVALID_EDGE_WEIGHT), forward_weight_offset(0), reverse_weight_offset(0),
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), speed_approximation(0), forward_duration_offset(0), reverse_duration_offset(0), fwd_segment_position(0),
fwd_segment_position(0), is_valid_forward_source{false}, is_valid_forward_target{false}, 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)
{ {
@@ -70,13 +69,13 @@ struct PhantomNode
return reverse_weight_offset + reverse_weight; return reverse_weight_offset + reverse_weight;
} }
EdgeDuration GetForwardDuration() const EdgeWeight 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;
} }
EdgeDuration GetReverseDuration() const EdgeWeight 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;
@@ -110,9 +109,8 @@ struct PhantomNode
bool IsValid(const unsigned number_of_nodes) const bool IsValid(const unsigned number_of_nodes) const
{ {
return location.IsValid() && return location.IsValid() && ((forward_segment_id.id < number_of_nodes) ||
((forward_segment_id.id < number_of_nodes) || (reverse_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) ||
@@ -165,11 +163,10 @@ struct PhantomNode
EdgeDistance reverse_distance, EdgeDistance reverse_distance,
EdgeDistance forward_distance_offset, EdgeDistance forward_distance_offset,
EdgeDistance reverse_distance_offset, EdgeDistance reverse_distance_offset,
EdgeDuration forward_duration, EdgeWeight forward_duration,
EdgeDuration reverse_duration, EdgeWeight reverse_duration,
EdgeDuration forward_duration_offset, EdgeWeight forward_duration_offset,
EdgeDuration reverse_duration_offset, EdgeWeight 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,
@@ -185,9 +182,8 @@ 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},
speed_approximation{speed_approximation}, component{component.id, component.is_tiny}, component{component.id, component.is_tiny}, location{location},
location{location}, input_location{input_location}, input_location{input_location}, fwd_segment_position{other.fwd_segment_position},
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},
@@ -205,12 +201,10 @@ 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
EdgeDuration forward_duration; EdgeWeight forward_duration;
EdgeDuration reverse_duration; EdgeWeight reverse_duration;
EdgeDuration forward_duration_offset; // TODO: try to remove -> requires path unpacking changes EdgeWeight forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
EdgeDuration reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes EdgeWeight 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
@@ -225,7 +219,7 @@ struct PhantomNode
unsigned short bearing : 12; unsigned short bearing : 12;
}; };
static_assert(sizeof(PhantomNode) == 84, "PhantomNode has more padding then expected"); static_assert(sizeof(PhantomNode) == 80, "PhantomNode has more padding then expected");
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>; using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
@@ -240,7 +234,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
+4 -20
View File
@@ -270,7 +270,6 @@ 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()))
@@ -297,10 +296,7 @@ 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
{ {
@@ -309,10 +305,7 @@ 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
@@ -321,22 +314,13 @@ class BasePlugin
{ {
phantom_node_pairs[i] = phantom_node_pairs[i] =
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i], parameters.coordinates[i], *parameters.radiuses[i], approach);
*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], parameters.coordinates[i], approach);
approach,
use_all_edges,
parameters.min_stoppage_penalty,
parameters.max_stoppage_penalty);
} }
} }
+2
View File
@@ -55,6 +55,7 @@ struct ExtractorConfig final : storage::IOConfig
".osrm.geometry", ".osrm.geometry",
".osrm.nbg_nodes", ".osrm.nbg_nodes",
".osrm.ebg_nodes", ".osrm.ebg_nodes",
".osrm.timestamp",
".osrm.edges", ".osrm.edges",
".osrm.ebg", ".osrm.ebg",
".osrm.ramIndex", ".osrm.ramIndex",
@@ -82,6 +83,7 @@ struct ExtractorConfig final : storage::IOConfig
boost::filesystem::path input_path; boost::filesystem::path input_path;
boost::filesystem::path profile_path; boost::filesystem::path profile_path;
std::vector<boost::filesystem::path> location_dependent_data_paths; std::vector<boost::filesystem::path> location_dependent_data_paths;
std::string data_version;
unsigned requested_num_threads; unsigned requested_num_threads;
unsigned small_component_size; unsigned small_component_size;
+20
View File
@@ -308,6 +308,26 @@ inline void writeTurnLaneData(const boost::filesystem::path &path,
storage::serialization::write(writer, "/common/turn_lanes/data", turn_lane_data); storage::serialization::write(writer, "/common/turn_lanes/data", turn_lane_data);
} }
// reads .osrm.timestamp
template <typename TimestampDataT>
inline void readTimestamp(const boost::filesystem::path &path, TimestampDataT &timestamp)
{
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
storage::tar::FileReader reader{path, fingerprint};
storage::serialization::read(reader, "/common/timestamp", timestamp);
}
// writes .osrm.timestamp
template <typename TimestampDataT>
inline void writeTimestamp(const boost::filesystem::path &path, const TimestampDataT &timestamp)
{
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
storage::tar::FileWriter writer{path, fingerprint};
storage::serialization::write(writer, "/common/timestamp", timestamp);
}
// reads .osrm.maneuver_overrides // reads .osrm.maneuver_overrides
template <typename StorageManeuverOverrideT, typename NodeSequencesT> template <typename StorageManeuverOverrideT, typename NodeSequencesT>
inline void readManeuverOverrides(const boost::filesystem::path &path, inline void readManeuverOverrides(const boost::filesystem::path &path,
-81
View File
@@ -1,81 +0,0 @@
#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
+66 -74
View File
@@ -692,80 +692,6 @@ 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;
} }
@@ -1018,6 +944,72 @@ argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
} }
} }
if (obj->Has(Nan::New("waypoints").ToLocalChecked()))
{
v8::Local<v8::Value> waypoints = obj->Get(Nan::New("waypoints").ToLocalChecked());
if (waypoints.IsEmpty())
return route_parameters_ptr();
// must be array
if (!waypoints->IsArray())
{
Nan::ThrowError(
"Waypoints must be an array of integers corresponding to the input coordinates.");
return route_parameters_ptr();
}
auto waypoints_array = v8::Local<v8::Array>::Cast(waypoints);
// must have at least two elements
if (waypoints_array->Length() < 2)
{
Nan::ThrowError("At least two waypoints must be provided");
return route_parameters_ptr();
}
auto coords_size = params->coordinates.size();
auto waypoints_array_size = waypoints_array->Length();
const auto first_index = Nan::To<std::uint32_t>(waypoints_array->Get(0)).FromJust();
const auto last_index =
Nan::To<std::uint32_t>(waypoints_array->Get(waypoints_array_size - 1)).FromJust();
if (first_index != 0 || last_index != coords_size - 1)
{
Nan::ThrowError("First and last waypoints values must correspond to first and last "
"coordinate indices");
return route_parameters_ptr();
}
for (uint32_t i = 0; i < waypoints_array_size; ++i)
{
v8::Local<v8::Value> waypoint_value = waypoints_array->Get(i);
// all elements must be numbers
if (!waypoint_value->IsNumber())
{
Nan::ThrowError("Waypoint values must be an array of integers");
return route_parameters_ptr();
}
// check that the waypoint index corresponds with an inpute coordinate
const auto index = Nan::To<std::uint32_t>(waypoint_value).FromJust();
if (index >= coords_size)
{
Nan::ThrowError("Waypoints must correspond with the index of an input coordinate");
return route_parameters_ptr();
}
params->waypoints.emplace_back(static_cast<unsigned>(waypoint_value->NumberValue()));
}
if (!params->waypoints.empty())
{
for (std::size_t i = 0; i < params->waypoints.size() - 1; i++)
{
if (params->waypoints[i] >= params->waypoints[i + 1])
{
Nan::ThrowError("Waypoints must be supplied in increasing order");
return route_parameters_ptr();
}
}
}
}
bool parsedSuccessfully = parseCommonParameters(obj, params); bool parsedSuccessfully = parseCommonParameters(obj, params);
if (!parsedSuccessfully) if (!parsedSuccessfully)
{ {
+5 -27
View File
@@ -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,16 +135,6 @@ 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 &params, 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];
@@ -172,13 +162,6 @@ 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];
@@ -188,9 +171,7 @@ 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:
@@ -207,7 +188,6 @@ 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;
@@ -217,13 +197,11 @@ 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
@@ -42,17 +42,12 @@ struct MatchParametersGrammar final : public RouteParametersGrammar<Iterator, Si
(qi::uint_ % (qi::uint_ %
';')[ph::bind(&engine::api::MatchParameters::timestamps, qi::_r1) = qi::_1]; ';')[ph::bind(&engine::api::MatchParameters::timestamps, qi::_r1) = qi::_1];
waypoints_rule =
qi::lit("waypoints=") >
(size_t_ % ';')[ph::bind(&engine::api::MatchParameters::waypoints, qi::_r1) = qi::_1];
gaps_type.add("split", engine::api::MatchParameters::GapsType::Split)( gaps_type.add("split", engine::api::MatchParameters::GapsType::Split)(
"ignore", engine::api::MatchParameters::GapsType::Ignore); "ignore", engine::api::MatchParameters::GapsType::Ignore);
root_rule = root_rule =
BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") > BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") >
-('?' > (timestamps_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1) | -('?' > (timestamps_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1) |
waypoints_rule(qi::_r1) |
(qi::lit("gaps=") > (qi::lit("gaps=") >
gaps_type[ph::bind(&engine::api::MatchParameters::gaps, qi::_r1) = qi::_1]) | gaps_type[ph::bind(&engine::api::MatchParameters::gaps, qi::_r1) = qi::_1]) |
(qi::lit("tidy=") > (qi::lit("tidy=") >
@@ -63,7 +58,6 @@ struct MatchParametersGrammar final : public RouteParametersGrammar<Iterator, Si
private: private:
qi::rule<Iterator, Signature> root_rule; qi::rule<Iterator, Signature> root_rule;
qi::rule<Iterator, Signature> timestamps_rule; qi::rule<Iterator, Signature> timestamps_rule;
qi::rule<Iterator, Signature> waypoints_rule;
qi::rule<Iterator, std::size_t()> size_t_; qi::rule<Iterator, std::size_t()> size_t_;
qi::symbols<char, engine::api::MatchParameters::GapsType> gaps_type; qi::symbols<char, engine::api::MatchParameters::GapsType> gaps_type;
@@ -48,6 +48,14 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
RouteParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_) RouteParametersGrammar(qi::rule<Iterator, Signature> &root_rule_) : BaseGrammar(root_rule_)
{ {
#ifdef BOOST_HAS_LONG_LONG
if (std::is_same<std::size_t, unsigned long long>::value)
size_t_ = qi::ulong_long;
else
size_t_ = qi::ulong_;
#else
size_t_ = qi::ulong_;
#endif
using AnnotationsType = engine::api::RouteParameters::AnnotationsType; using AnnotationsType = engine::api::RouteParameters::AnnotationsType;
const auto add_annotation = [](engine::api::RouteParameters &route_parameters, const auto add_annotation = [](engine::api::RouteParameters &route_parameters,
@@ -70,8 +78,12 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
"distance", AnnotationsType::Distance)("weight", AnnotationsType::Weight)( "distance", AnnotationsType::Distance)("weight", AnnotationsType::Weight)(
"datasources", AnnotationsType::Datasources)("speed", AnnotationsType::Speed); "datasources", AnnotationsType::Datasources)("speed", AnnotationsType::Speed);
waypoints_rule =
qi::lit("waypoints=") >
(size_t_ % ';')[ph::bind(&engine::api::RouteParameters::waypoints, qi::_r1) = qi::_1];
base_rule = base_rule =
BaseGrammar::base_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1) | waypoints_rule(qi::_r1) |
(qi::lit("steps=") > (qi::lit("steps=") >
qi::bool_[ph::bind(&engine::api::RouteParameters::steps, qi::_r1) = qi::_1]) | qi::bool_[ph::bind(&engine::api::RouteParameters::steps, qi::_r1) = qi::_1]) |
(qi::lit("geometries=") > (qi::lit("geometries=") >
@@ -94,6 +106,8 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
private: private:
qi::rule<Iterator, Signature> root_rule; qi::rule<Iterator, Signature> root_rule;
qi::rule<Iterator, Signature> route_rule; qi::rule<Iterator, Signature> route_rule;
qi::rule<Iterator, Signature> waypoints_rule;
qi::rule<Iterator, std::size_t()> size_t_;
qi::symbols<char, engine::api::RouteParameters::GeometriesType> geometries_type; qi::symbols<char, engine::api::RouteParameters::GeometriesType> geometries_type;
qi::symbols<char, engine::api::RouteParameters::OverviewType> overview_type; qi::symbols<char, engine::api::RouteParameters::OverviewType> overview_type;
@@ -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 &)>
@@ -106,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
+1
View File
@@ -58,6 +58,7 @@ struct StorageConfig final : IOConfig
".osrm.turn_duration_penalties", ".osrm.turn_duration_penalties",
".osrm.datasource_names", ".osrm.datasource_names",
".osrm.names", ".osrm.names",
".osrm.timestamp",
".osrm.properties", ".osrm.properties",
".osrm.icd", ".osrm.icd",
".osrm.maneuver_overrides"}, ".osrm.maneuver_overrides"},
+5
View File
@@ -272,6 +272,11 @@ inline auto make_partition_view(const SharedDataIndex &index, const std::string
level_data_ptr, std::move(partition), std::move(cell_to_children)}; level_data_ptr, std::move(partition), std::move(cell_to_children)};
} }
inline auto make_timestamp_view(const SharedDataIndex &index, const std::string &name)
{
return util::StringView(index.GetBlockPtr<char>(name), index.GetBlockEntries(name));
}
inline auto make_cell_storage_view(const SharedDataIndex &index, const std::string &name) inline auto make_cell_storage_view(const SharedDataIndex &index, const std::string &name)
{ {
auto source_boundary = make_vector_view<NodeID>(index, name + "/source_boundary"); auto source_boundary = make_vector_view<NodeID>(index, name + "/source_boundary");
+2 -2
View File
@@ -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(!std::isnan(value)); assert(!isnan(value));
assert(!std::isinf(value)); assert(!isinf(value));
if (value == 0) if (value == 0)
{ {
+3 -5
View File
@@ -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>;
@@ -79,6 +79,7 @@ using EdgeDistance = float;
using SegmentWeight = std::uint32_t; using SegmentWeight = std::uint32_t;
using SegmentDuration = std::uint32_t; using SegmentDuration = std::uint32_t;
using TurnPenalty = std::int16_t; // turn penalty in 100ms units using TurnPenalty = std::int16_t; // turn penalty in 100ms units
using DataTimestamp = std::string;
static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max(); static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max();
@@ -116,10 +117,7 @@ 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(); static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits<double>::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
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "osrm", "name": "osrm",
"version": "5.21.0-customsnapping.5", "version": "5.22.0",
"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": {
+3
View File
@@ -120,6 +120,9 @@ 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 {
+5 -85
View File
@@ -86,10 +86,8 @@ 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, always_calculate_distance); snapped_phantoms, params.sources, params.destinations, request_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()))
@@ -99,61 +97,8 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
std::vector<api::TableAPI::TableCellRef> estimated_pairs; 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 != INVALID_FALLBACK_SPEED || params.scale_factor != 1 || 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++)
{ {
@@ -161,22 +106,6 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
{ {
const auto &table_index = row * num_destinations + column; const auto &table_index = row * num_destinations + column;
BOOST_ASSERT(table_index < result_tables_pair.first.size()); 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 && if (params.fallback_speed != INVALID_FALLBACK_SPEED && params.fallback_speed > 0 &&
result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION) result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
{ {
@@ -203,7 +132,6 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
estimated_pairs.emplace_back(row, column); 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 && if (params.scale_factor > 0 && params.scale_factor != 1 &&
result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION && result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION &&
result_tables_pair.first[table_index] != 0) result_tables_pair.first[table_index] != 0)
@@ -225,19 +153,11 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
} }
} }
// 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, estimated_pairs, result); table_api.MakeResponse(result_tables_pair, snapped_phantoms, estimated_pairs, result);
return Status::Ok; return Status::Ok;
} }
} // namespace plugins }
} // namespace engine }
} // namespace osrm }
+31 -1
View File
@@ -73,6 +73,16 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
return Error("InvalidValue", "Invalid coordinate value.", json_result); return Error("InvalidValue", "Invalid coordinate value.", json_result);
} }
// Error: first and last points should be waypoints
if (!route_parameters.waypoints.empty() &&
(route_parameters.waypoints[0] != 0 ||
route_parameters.waypoints.back() != (route_parameters.coordinates.size() - 1)))
{
return Error("InvalidValue",
"First and last coordinates must be specified as waypoints.",
json_result);
}
if (!CheckAlgorithms(route_parameters, algorithms, json_result)) if (!CheckAlgorithms(route_parameters, algorithms, json_result))
return Status::Error; return Status::Error;
@@ -132,7 +142,27 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
if (routes.routes[0].is_valid()) if (routes.routes[0].is_valid())
{ {
route_api.MakeResponse(routes, json_result); auto collapse_legs = !route_parameters.waypoints.empty();
if (collapse_legs)
{
std::vector<bool> waypoint_legs(route_parameters.coordinates.size(), false);
std::for_each(route_parameters.waypoints.begin(),
route_parameters.waypoints.end(),
[&](const std::size_t waypoint_index) {
BOOST_ASSERT(waypoint_index < waypoint_legs.size());
waypoint_legs[waypoint_index] = true;
});
// First and last coordinates should always be waypoints
// This gets validated earlier, but double-checking here, jic
BOOST_ASSERT(waypoint_legs.front());
BOOST_ASSERT(waypoint_legs.back());
for (std::size_t i = 0; i < routes.routes.size(); i++)
{
routes.routes[i] = CollapseInternalRouteResult(routes.routes[i], waypoint_legs);
}
}
route_api.MakeResponse(routes, start_end_nodes, json_result);
} }
else else
{ {
+9
View File
@@ -51,6 +51,7 @@
#include <osmium/handler/node_locations_for_ways.hpp> #include <osmium/handler/node_locations_for_ways.hpp>
#include <osmium/index/map/flex_mem.hpp> #include <osmium/index/map/flex_mem.hpp>
#include <osmium/io/any_input.hpp> #include <osmium/io/any_input.hpp>
#include <osmium/osm/timestamp.hpp>
#include <osmium/thread/pool.hpp> #include <osmium/thread/pool.hpp>
#include <osmium/visitor.hpp> #include <osmium/visitor.hpp>
@@ -425,6 +426,14 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
// write .timestamp data file // write .timestamp data file
std::string timestamp = header.get("osmosis_replication_timestamp"); std::string timestamp = header.get("osmosis_replication_timestamp");
if (config.data_version == "osmosis")
{
files::writeTimestamp(config.GetPath(".osrm.timestamp").string(), timestamp);
}
else
{
files::writeTimestamp(config.GetPath(".osrm.timestamp").string(), config.data_version);
}
if (timestamp.empty()) if (timestamp.empty())
{ {
timestamp = "n/a"; timestamp = "n/a";
+12
View File
@@ -302,6 +302,7 @@ std::vector<std::pair<bool, boost::filesystem::path>> Storage::GetStaticFiles()
{REQUIRED, config.GetPath(".osrm.ebg_nodes")}, {REQUIRED, config.GetPath(".osrm.ebg_nodes")},
{REQUIRED, config.GetPath(".osrm.tls")}, {REQUIRED, config.GetPath(".osrm.tls")},
{REQUIRED, config.GetPath(".osrm.tld")}, {REQUIRED, config.GetPath(".osrm.tld")},
{REQUIRED, config.GetPath(".osrm.timestamp")},
{REQUIRED, config.GetPath(".osrm.maneuver_overrides")}, {REQUIRED, config.GetPath(".osrm.maneuver_overrides")},
{REQUIRED, config.GetPath(".osrm.edges")}, {REQUIRED, config.GetPath(".osrm.edges")},
{REQUIRED, config.GetPath(".osrm.names")}, {REQUIRED, config.GetPath(".osrm.names")},
@@ -401,6 +402,17 @@ void Storage::PopulateStaticData(const SharedDataIndex &index)
extractor::files::readNames(config.GetPath(".osrm.names"), name_table); extractor::files::readNames(config.GetPath(".osrm.names"), name_table);
} }
// Timestamp mark
{
auto timestamp_ref = make_timestamp_view(index, "/common/timestamp");
std::string ts;
extractor::files::readTimestamp(config.GetPath(".osrm.timestamp"), ts);
if (!ts.empty())
{
memcpy(const_cast<char *>(timestamp_ref.data()), ts.data(), ts.size());
}
}
// Turn lane data // Turn lane data
{ {
auto turn_lane_data = make_lane_data_view(index, "/common/turn_lanes"); auto turn_lane_data = make_lane_data_view(index, "/common/turn_lanes");
+4
View File
@@ -43,6 +43,10 @@ return_code parseArguments(int argc,
boost::program_options::value<boost::filesystem::path>(&extractor_config.profile_path) boost::program_options::value<boost::filesystem::path>(&extractor_config.profile_path)
->default_value("profiles/car.lua"), ->default_value("profiles/car.lua"),
"Path to LUA routing profile")( "Path to LUA routing profile")(
"data_version,d",
boost::program_options::value<std::string>(&extractor_config.data_version)
->default_value(""),
"Data version. Leave blank to avoid. osmosis - to get timestamp from file")(
"threads,t", "threads,t",
boost::program_options::value<unsigned int>(&extractor_config.requested_num_threads) boost::program_options::value<unsigned int>(&extractor_config.requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()), ->default_value(tbb::task_scheduler_init::default_num_threads()),
+24
View File
@@ -319,6 +319,30 @@ test('match: throws on invalid waypoints values, waypoints must correspond with
'Waypoints must correspond with the index of an input coordinate'); 'Waypoints must correspond with the index of an input coordinate');
}); });
test('match: throws on invalid waypoints values, waypoints must be an array', function (assert) {
assert.plan(1);
var osrm = new OSRM(data_path);
var options = {
steps: true,
coordinates: three_test_coordinates,
waypoints: "string"
};
assert.throws(function () { osrm.match(options, function (err, response) { console.log(err); }); },
'Waypoints must be an array of integers corresponding to the input coordinates.');
});
test('match: throws on invalid waypoints values, waypoints must be an array of integers', function (assert) {
assert.plan(1);
var osrm = new OSRM(data_path);
var options = {
steps: true,
coordinates: three_test_coordinates,
waypoints: [0,1,"string"]
};
assert.throws(function () { osrm.match(options, function (err, response) { console.log(err); }); },
'Waypoint values must be an array of integers');
});
test('match: error on split trace', function(assert) { test('match: error on split trace', function(assert) {
assert.plan(1); assert.plan(1);
var osrm = new OSRM(data_path); var osrm = new OSRM(data_path);
+76 -12
View File
@@ -606,23 +606,87 @@ test('route: route in Monaco without motorways', function(assert) {
}); });
}); });
test('route: throws on invalid snapping values', function (assert) {
test('route: throws on invalid waypoints values needs at least two', function (assert) {
assert.plan(1);
var osrm = new OSRM(monaco_path);
var options = {
steps: true,
coordinates: three_test_coordinates,
waypoints: [0]
};
assert.throws(function () { osrm.route(options, function (err, response) { }); },
'At least two waypoints must be provided');
});
test('route: throws on invalid waypoints values, needs first and last coordinate indices', function (assert) {
assert.plan(1);
var osrm = new OSRM(monaco_path);
var options = {
steps: true,
coordinates: three_test_coordinates,
waypoints: [1, 2]
};
assert.throws(function () { osrm.route(options, function (err, response) { console.log(err); }); },
'First and last waypoints values must correspond to first and last coordinate indices');
});
test('route: throws on invalid waypoints values, order matters', function (assert) {
assert.plan(1);
var osrm = new OSRM(monaco_path);
var options = {
steps: true,
coordinates: three_test_coordinates,
waypoints: [2, 0]
};
assert.throws(function () { osrm.route(options, function (err, response) { console.log(err); }); },
'First and last waypoints values must correspond to first and last coordinate indices');
});
test('route: throws on invalid waypoints values, waypoints must correspond with a coordinate index', function (assert) {
assert.plan(1);
var osrm = new OSRM(monaco_path);
var options = {
steps: true,
coordinates: three_test_coordinates,
waypoints: [0, 3, 2]
};
assert.throws(function () { osrm.route(options, function (err, response) { console.log(err); }); },
'Waypoints must correspond with the index of an input coordinate');
});
test('route: throws on invalid waypoints values, waypoints must be an array', function (assert) {
assert.plan(1);
var osrm = new OSRM(monaco_path);
var options = {
steps: true,
coordinates: three_test_coordinates,
waypoints: "string"
};
assert.throws(function () { osrm.route(options, function (err, response) { console.log(err); }); },
'Waypoints must be an array of integers corresponding to the input coordinates.');
});
test('route: throws on invalid waypoints values, waypoints must be an array of integers', function (assert) {
assert.plan(1);
var osrm = new OSRM(monaco_path);
var options = {
steps: true,
coordinates: three_test_coordinates,
waypoints: [0,1,"string"]
};
assert.throws(function () { osrm.route(options, function (err, response) { console.log(err); }); },
'Waypoint values must be an array of integers');
});
test('route: throws on invalid waypoints values, waypoints must be an array of integers in increasing order', function (assert) {
assert.plan(1); assert.plan(1);
var osrm = new OSRM(monaco_path); var osrm = new OSRM(monaco_path);
var options = { var options = {
steps: true, steps: true,
coordinates: three_test_coordinates.concat(three_test_coordinates), coordinates: three_test_coordinates.concat(three_test_coordinates),
snapping: "zing" waypoints: [0,2,1,5]
}; };
assert.throws(function () { osrm.route(options, function (err, response) { console.error(`response: ${response}`); console.error(`error: ${err}`); }); }, 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\]/); /Waypoints must be supplied in increasing order/);
});
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
});
}); });
-43
View File
@@ -48,21 +48,6 @@ 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);
@@ -318,33 +303,5 @@ tables.forEach(function(annotation) {
assert.throws(()=>osrm.table(options, (err, res) => {}), /scale_factor must be > 0/, "should throw on invalid scale_factor value"); 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");
});
}); });
+19 -30
View File
@@ -282,48 +282,36 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
return {}; return {};
} }
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( std::pair<PhantomNode, PhantomNode>
const util::Coordinate /*input_coordinate*/, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/,
const Approach /*approach*/, const Approach /*approach*/) const override
const bool /* use_all_edges */,
const double /* min_stoppage_penalty */,
const double /* max_stoppage_penalty */) const override
{ {
return {}; return {};
} }
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( 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 Approach /*approach*/) const override
const bool /* use_all_edges */,
const double /* min_stoppage_penalty */,
const double /* max_stoppage_penalty */) const override
{ {
return {}; return {};
} }
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( std::pair<PhantomNode, PhantomNode>
const util::Coordinate /*input_coordinate*/, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/,
const double /*max_distance*/, const double /*max_distance*/,
const int /*bearing*/, const int /*bearing*/,
const int /*bearing_range*/, const int /*bearing_range*/,
const Approach /*approach*/, const Approach /*approach*/) const override
const bool /* use_all_edges */,
const double /* min_stoppage_penalty */,
const double /* max_stoppage_penalty */) const override
{ {
return {}; return {};
} }
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( std::pair<PhantomNode, PhantomNode>
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 Approach /*approach*/) const override
const bool /* use_all_edges */,
const double /* min_stoppage_penalty */,
const double /* max_stoppage_penalty */) const override
{ {
return {}; return {};
} }
@@ -353,6 +341,7 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
StringView GetDestinationsForID(const NameID /*id*/) const override { return StringView{}; } StringView GetDestinationsForID(const NameID /*id*/) const override { return StringView{}; }
StringView GetExitsForID(const NameID /*id*/) const override { return StringView{}; } StringView GetExitsForID(const NameID /*id*/) const override { return StringView{}; }
bool GetContinueStraightDefault() const override { return false; } bool GetContinueStraightDefault() const override { return false; }
std::string GetTimestamp() const override { return ""; }
double GetMapMatchingMaxSpeed() const override { return 0; } double GetMapMatchingMaxSpeed() const override { return 0; }
const char *GetWeightName() const override { return ""; } const char *GetWeightName() const override { return ""; }
unsigned GetWeightPrecision() const override { return 0; } unsigned GetWeightPrecision() const override { return 0; }
+5 -17
View File
@@ -10,7 +10,6 @@
#include "extractor/turn_lane_types.hpp" #include "extractor/turn_lane_types.hpp"
#include "guidance/turn_bearing.hpp" #include "guidance/turn_bearing.hpp"
#include "guidance/turn_instruction.hpp" #include "guidance/turn_instruction.hpp"
#include "guidance/turn_instruction.hpp"
#include "engine/algorithm.hpp" #include "engine/algorithm.hpp"
#include "engine/datafacade/algorithm_datafacade.hpp" #include "engine/datafacade/algorithm_datafacade.hpp"
@@ -54,6 +53,7 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
{ {
return 0; return 0;
} }
std::string GetTimestamp() const override { return ""; }
NodeForwardRange GetUncompressedForwardGeometry(const EdgeID /* id */) const override NodeForwardRange GetUncompressedForwardGeometry(const EdgeID /* id */) const override
{ {
static NodeID data[] = {0, 1, 2, 3}; static NodeID data[] = {0, 1, 2, 3};
@@ -169,10 +169,7 @@ 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 engine::Approach /*approach*/) const override
const bool /* use_all_edges */,
const double /* min_stoppage_penalty */,
const double /* max_stoppage_penalty */) const override
{ {
return {}; return {};
} }
@@ -181,10 +178,7 @@ 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 engine::Approach /*approach*/) const override
const bool /* use_all_edges */,
const double /* min_stoppage_penalty */,
const double /* max_stoppage_penalty */) const override
{ {
return {}; return {};
} }
@@ -195,10 +189,7 @@ 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 engine::Approach /*approach*/) const override
const bool /* use_all_edges */,
const double /* min_stoppage_penalty */,
const double /* max_stoppage_penalty */) const override
{ {
return {}; return {};
} }
@@ -208,10 +199,7 @@ 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 engine::Approach /*approach*/) const override
const bool /* use_all_edges */,
const double /* min_stoppage_penalty */,
const double /* max_stoppage_penalty */) const override
{ {
return {}; return {};
} }