Compare commits

..

22 Commits

Author SHA1 Message Date
Daniel Patterson 6c37b71046 Actually expose snapping in node bindings. 2019-02-03 12:09:24 -08:00
Daniel Patterson cb2a46b8d9 Merge changes from c1eda57c13 - add snapping=any|default parameter. 2019-02-03 10:40:26 -08:00
Daniel Patterson b1451a7421 Release 5.21.0 2018-12-18 16:17:34 -07:00
Daniel Patterson da1c251144 Prep 5.21.0-rc.1 2018-12-15 21:43:10 -07:00
Daniel Patterson 1eab7b41d1 Update CHANGELOG. 2018-12-15 21:07:06 -07:00
Daniel Patterson 1dca8ae76a Correct invalid tests - these captured the incorrect behaviour, the matrices should've been symmetrical (a->o == o->a for these cases) 2018-12-15 21:07:06 -07:00
Daniel Patterson 002e86863d Add test to ensure forward/reverse snapping distances are correct, and fix some tests that were incorrect due to the bug. 2018-12-15 21:07:06 -07:00
Daniel Patterson 1d82b01816 Count reverse offset from the back of the geometry, not the front. 2018-12-15 21:07:06 -07:00
Frédéric Rodrigo 714719c377 Lua maxspeed parsing refactoring (#5144)
* Lua maxspeed parsing refactoring
2018-12-14 21:58:07 -07:00
Huyen Chau Nguyen 77b4fbb69c Fix maxspeed to consider source:maxspeed tags (#5217)
* In Belgium the maximum speed in rural areas is 70 in the region Flanders
* parse maxspeed using source:maxspeed and maxspeed:type tags
* add changelog
* make maxspeed:advisory more important than maxspeed
* add test for source:maxspeed
2018-12-14 21:42:44 -07:00
Matt Riggott 11fde865f7 Document switch to Debian base images (#5281)
* Document switch to Debian base images
2018-12-14 21:36:09 -07:00
Salim KAYABASI 717406043a Remove unused Node binary publishing, and upgrade build environment.
Upgrades the build environment to Node 10, which let's us pull down some security fixes in package dependencies that were unfixed in Node 4.

Also removes Node 4 and 6 binary publishing which were almost never used (20 downloads out of 50,000).

Fixes https://github.com/Project-OSRM/osrm-backend/issues/5312
2018-12-14 21:34:48 -07:00
Daniel Patterson 1ef85c57cc Upgrade CI environment to Node 10, remove builds for < Node 8
Remove yarn, npm is fast now, and comes with node.
Synchronize package-lock.json and package.json
2018-12-14 14:56:21 -07:00
Daniel Patterson d0180517a8 Merge branch 'master' of github.com:Project-OSRM/osrm-backend 2018-12-14 11:54:00 -07:00
Daniel Patterson 520b7ebbb6 Remove 5.20 build trigger from master branch - should only exist on release branches. 2018-12-14 11:53:48 -07:00
Dinesh Weerapurage 2caba96076 using libboost 1.67 in both build and run stages (#5311)
* using libboost 1.67 in both build and run stages, added execution permision for /opt
2018-12-14 11:51:05 -07:00
Daniel Patterson 81bc2f41a6 When matching, ignore 'is_startpoint' propert, snap to any edge (#5297)
Includes all edges in the rtree, but adds an `is_startpoint` flag to each.  Most plugin behaviour remains unchanged (non-startpoint edges aren't used as snapping candidates), but for map matching, we allow snapping to any edge.  This fixes map-matching across previously non-is_startpoint edges, like ferries, private service roads, and a few others.
2018-12-13 17:10:32 -07:00
Daniel Patterson 06e010b4d0 Include information on estimates in table response (#5259)
* Revert "Remove estimated_cells value in the response."

This reverts commit 364e35af06.

* Update changelog.

* fix linting

* adjust fallback_speed check

* change [].includes to [].indexOf !== -1 for compatibility with node 4

* change param name

* more cuke tests

* fix formatting
2018-12-11 12:21:57 -05:00
Kajari Ghosh 92d3ce789b Fix scale_factor bug (#5303)
* check for scale_factor != 1

* changelog
2018-12-10 17:11:08 -05:00
Kajari Ghosh 01ca32c81c Fix fallback speed validity checks (#5300)
* fix fallback_speeds check to only accept values > 0

* add invalid_fallback_speed
2018-12-10 14:53:30 -05:00
Kajari Ghosh 2e17f3010a Add a multiplier to the matrix (#5298)
* add a multiplier to the matrix

* add rounding

* remove scale_factor restrictions

* clamp for overflow error

* update check to match error message

* enforce clamping on < 0 and increase test coverage

* add an invalid scale_factor value to node tests

* increase test coverage

* changelog
2018-12-10 13:41:44 -05:00
Kajari Ghosh c4238c4ed6 Backport-v5.20.0 (#5301)
* Prepare RC.1

* Bump version.

* remove destination/sources length <= coordinates length check (#5289)

* Add node 10 builds to travis (#5246)

* Add node 10 builds to travis

* Add changelog

* bump version to rc5

* Fix fallback_speed vector access (#5291)

* add failing cuke test

* correctly access durations vector

* changelog

* one more cuke test

* bump rc version

* 5.20.0

* remove line from changelog about commit that isn't actually in here

* update CHANGELOG and osrm version in package.json for v5.20.0

* bump to restart appveyor
2018-12-10 11:27:13 -05:00
52 changed files with 4172 additions and 10892 deletions
+4
View File
@@ -68,6 +68,10 @@ Thumbs.db
/*.local.bat /*.local.bat
/CMakeSettings.json /CMakeSettings.json
# Jetbrains related files #
###########################
.idea/
# stxxl related files # # stxxl related files #
####################### #######################
.stxxl .stxxl
+7 -69
View File
@@ -13,12 +13,12 @@ notifications:
branches: branches:
only: only:
- master - master
- "5.20.1" - 5.21
# enable building tags # enable building tags
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/ - /^v\d+\.\d+(\.\d+)?(-\S*)?$/
cache: cache:
yarn: true npm: true
ccache: true ccache: true
apt: true apt: true
directories: directories:
@@ -35,7 +35,7 @@ env:
- CMAKE_VERSION=3.7.2 - CMAKE_VERSION=3.7.2
- MASON="$(pwd)/scripts/mason.sh" - MASON="$(pwd)/scripts/mason.sh"
- ENABLE_NODE_BINDINGS=On - ENABLE_NODE_BINDINGS=On
- NODE="4" - NODE="10"
matrix: matrix:
fast_finish: true fast_finish: true
@@ -46,7 +46,7 @@ matrix:
# Debug Builds # Debug Builds
- os: linux - os: linux
compiler: "format-taginfo-docs" compiler: "format-taginfo-docs"
env: NODE=6 env: NODE=10
sudo: false sudo: false
before_install: before_install:
install: install:
@@ -54,8 +54,7 @@ matrix:
- nvm install $NODE - nvm install $NODE
- nvm use $NODE - nvm use $NODE
- npm --version - npm --version
- npm install --ignore-scripts - npm ci --ignore-scripts
- npm link --ignore-scripts
script: script:
- ./scripts/check_taginfo.py taginfo.json profiles/car.lua - ./scripts/check_taginfo.py taginfo.json profiles/car.lua
- ${MASON} install clang-format 3.8.1 - ${MASON} install clang-format 3.8.1
@@ -171,14 +170,6 @@ matrix:
after_success: after_success:
- ./scripts/travis/publish.sh - ./scripts/travis/publish.sh
- os: osx
osx_image: xcode9.2
compiler: "mason-osx-release-node-4"
# we use the xcode provides clang and don't install our own
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON ENABLE_LTO=ON NODE="4"
after_success:
- ./scripts/travis/publish.sh
# Shared Library # Shared Library
- os: linux - os: linux
compiler: "gcc-7-release-shared" compiler: "gcc-7-release-shared"
@@ -189,54 +180,6 @@ matrix:
env: CCOMPILER='gcc-7' CXXCOMPILER='g++-7' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON env: CCOMPILER='gcc-7' CXXCOMPILER='g++-7' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
# Node build jobs. These skip running the tests. # Node build jobs. These skip running the tests.
- os: linux
sudo: false
compiler: "node-4-mason-linux-release"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-4.9-dev']
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Release' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="4"
install:
- pushd ${OSRM_BUILD_DIR}
- |
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
-DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
-DENABLE_GLIBC_WORKAROUND=ON
- make --jobs=${JOBS}
- popd
script:
- npm run nodejs-tests
after_success:
- ./scripts/travis/publish.sh
- os: linux
sudo: false
compiler: "node-4-mason-linux-debug"
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['libstdc++-4.9-dev']
env: CLANG_VERSION='5.0.0' BUILD_TYPE='Debug' ENABLE_MASON=ON ENABLE_LTO=ON JOBS=3 NODE="4"
install:
- pushd ${OSRM_BUILD_DIR}
- |
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_MASON=${ENABLE_MASON:-OFF} \
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
-DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
-DENABLE_GLIBC_WORKAROUND=ON
- make --jobs=${JOBS}
- popd
script:
- npm run nodejs-tests
after_success:
- ./scripts/travis/publish.sh
- os: linux - os: linux
sudo: false sudo: false
compiler: "node-8-mason-linux-release" compiler: "node-8-mason-linux-release"
@@ -351,15 +294,10 @@ before_install:
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
sudo mdutil -i off / sudo mdutil -i off /
fi fi
- |
if [[ ! -f $(which yarn) ]]; then
npm install -g yarn@1.11.1
fi
- export PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)") - export PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)")
- export PUBLISH=$([[ "${TRAVIS_TAG:-}" == "v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") - export PUBLISH=$([[ "${TRAVIS_TAG:-}" == "v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off")
- echo "Using ${JOBS} jobs" - echo "Using ${JOBS} jobs"
- yarn install --ignore-scripts - npm ci --ignore-scripts
- yarn check --ignore-scripts --integrity
# Bootstrap cmake to be able to run mason # Bootstrap cmake to be able to run mason
- CMAKE_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}.tar.gz" - CMAKE_URL="https://mason-binaries.s3.amazonaws.com/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}.tar.gz"
- CMAKE_DIR="mason_packages/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}" - CMAKE_DIR="mason_packages/${TRAVIS_OS_NAME}-x86_64/cmake/${CMAKE_VERSION}"
@@ -438,4 +376,4 @@ script:
fi fi
- | - |
- popd - popd
- yarn test - npm test
+14 -1
View File
@@ -1,10 +1,21 @@
# 5.20.1 RC 2 # 5.21.0
- Changes from 5.20.0 - Changes from 5.20.0
- Features: - Features:
- ADDED: all waypoints in responses now contain a distance property between the original coordinate and the snapped location. [#5255](https://github.com/Project-OSRM/osrm-backend/pull/5255) - ADDED: all waypoints in responses now contain a distance property between the original coordinate and the snapped location. [#5255](https://github.com/Project-OSRM/osrm-backend/pull/5255)
- ADDED: if `fallback_speed` is used, a new structure `fallback_speed_cells` will describe which cells contain estimated values [#5259](https://github.com/Project-OSRM/osrm-backend/pull/5259)
- REMOVED: we no longer publish Node 4 or 6 binary modules (they are still buildable from source) [#5314](https://github.com/Project-OSRM/osrm-backend/pull/5314)
- Table: - Table:
- ADDED: new parameter `scale_factor` which will scale the cell `duration` values by this factor. [#5298](https://github.com/Project-OSRM/osrm-backend/pull/5298) - ADDED: new parameter `scale_factor` which will scale the cell `duration` values by this factor. [#5298](https://github.com/Project-OSRM/osrm-backend/pull/5298)
- FIXED: only trigger `scale_factor` code to scan matrix when necessary. [#5303](https://github.com/Project-OSRM/osrm-backend/pull/5303) - FIXED: only trigger `scale_factor` code to scan matrix when necessary. [#5303](https://github.com/Project-OSRM/osrm-backend/pull/5303)
- FIXED: fix bug in reverse offset calculation that sometimes lead to negative (and other incorrect) values in distance table results [#5315](https://github.com/Project-OSRM/osrm-backend/pull/5315)
- Docker:
- FIXED: use consistent boost version between build and runtime [#5311](https://github.com/Project-OSRM/osrm-backend/pull/5311)
- FIXED: don't override default permissions on /opt [#5311](https://github.com/Project-OSRM/osrm-backend/pull/5311)
- Matching:
- CHANGED: matching will now consider edges marked with is_startpoint=false, allowing matching over ferries and other previously non-matchable edge types. [#5297](https://github.com/Project-OSRM/osrm-backend/pull/5297)
- Profile:
- ADDED: Parse `source:maxspeed` and `maxspeed:type` tags to apply maxspeeds and add belgian flanders rural speed limit. [#5217](https://github.com/Project-OSRM/osrm-backend/pull/5217)
- CHANGED: Refactor maxspeed parsing to use common library. [#5144](https://github.com/Project-OSRM/osrm-backend/pull/5144)
# 5.20.0 # 5.20.0
- Changes from 5.19.0: - Changes from 5.19.0:
@@ -19,6 +30,8 @@
- ADDED: Now publishing Node 10.x LTS binary modules [#5246](https://github.com/Project-OSRM/osrm-backend/pull/5246) - ADDED: Now publishing Node 10.x LTS binary modules [#5246](https://github.com/Project-OSRM/osrm-backend/pull/5246)
- Windows: - Windows:
- FIXED: Windows builds again. [#5249](https://github.com/Project-OSRM/osrm-backend/pull/5249) - FIXED: Windows builds again. [#5249](https://github.com/Project-OSRM/osrm-backend/pull/5249)
- Docker:
- CHANGED: switch from Alpine Linux to Debian Buster base images [#5281](https://github.com/Project-OSRM/osrm-backend/pull/5281)
# 5.19.0 # 5.19.0
- Changes from 5.18.0: - Changes from 5.18.0:
+1 -1
View File
@@ -50,7 +50,7 @@ If you want to use the CH pipeline instead replace `osrm-partition` and `osrm-cu
### Using Docker ### Using Docker
We base our Docker images ([backend](https://hub.docker.com/r/osrm/osrm-backend/), [frontend](https://hub.docker.com/r/osrm/osrm-frontend/)) on Alpine Linux and make sure they are as lightweight as possible. We base our Docker images ([backend](https://hub.docker.com/r/osrm/osrm-backend/), [frontend](https://hub.docker.com/r/osrm/osrm-frontend/)) on Debian and make sure they are as lightweight as possible.
Download OpenStreetMap extracts for example from [Geofabrik](http://download.geofabrik.de/) Download OpenStreetMap extracts for example from [Geofabrik](http://download.geofabrik.de/)
+4 -6
View File
@@ -7,7 +7,7 @@ WORKDIR /src
RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \ RUN NPROC=$(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 libstxxl-dev libstxxl1v5 libxml2-dev \
libzip-dev libboost-all-dev lua5.2 liblua5.2-dev libtbb-dev -o APT::Install-Suggests=0 -o APT::Install-Recommends=0 && \ libzip-dev libboost1.67-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) && \ 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 && \
@@ -24,7 +24,6 @@ RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
make -j${NPROC} install && \ make -j${NPROC} install && \
cd ../profiles && \ cd ../profiles && \
cp -r * /opt && \ cp -r * /opt && \
\
strip /usr/local/bin/* && \ strip /usr/local/bin/* && \
rm -rf /src /usr/local/lib/libosrm* rm -rf /src /usr/local/lib/libosrm*
@@ -34,13 +33,12 @@ RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
FROM debian:buster-slim as runstage FROM debian:buster-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.62.0 libboost-regex1.62.0 \ apt-get install -y --no-install-recommends libboost-program-options1.67.0 libboost-regex1.67.0 \
libboost-date-time1.62.0 libboost-chrono1.62.0 libboost-filesystem1.62.0 \ libboost-date-time1.67.0 libboost-chrono1.67.0 libboost-filesystem1.67.0 \
libboost-iostreams1.62.0 libboost-thread1.62.0 expat liblua5.2-0 libtbb2 &&\ libboost-iostreams1.67.0 libboost-thread1.67.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 chmod 0644 -R /opt
WORKDIR /opt WORKDIR /opt
EXPOSE 5000 EXPOSE 5000
+6
View File
@@ -284,6 +284,7 @@ curl 'http://router.project-osrm.org/table/v1/driving/13.388860,52.517037;13.397
the i-th waypoint to the j-th waypoint. Values are given in meters. Can be `null` if no route between `i` and `j` can be found. Note that computing the `distances` table is currently only implemented for CH. If `annotations=distance` or `annotations=duration,distance` is requested when running a MLD router, a `NotImplemented` error will be returned. the i-th waypoint to the j-th waypoint. Values are given in meters. Can be `null` if no route between `i` and `j` can be found. Note that computing the `distances` table is currently only implemented for CH. If `annotations=distance` or `annotations=duration,distance` is requested when running a MLD router, a `NotImplemented` error will be returned.
- `sources` array of `Waypoint` objects describing all sources in order - `sources` array of `Waypoint` objects describing all sources in order
- `destinations` array of `Waypoint` objects describing all destinations in order - `destinations` array of `Waypoint` objects describing all destinations in order
- `fallback_speed_cells` (optional) array of arrays containing `i,j` pairs indicating which cells contain estimated values based on `fallback_speed`. Will be absent if `fallback_speed` is not used.
In case of error the following `code`s are supported in addition to the general ones: In case of error the following `code`s are supported in addition to the general ones:
@@ -384,6 +385,10 @@ All other properties might be undefined.
2361.73, 2361.73,
0 0
] ]
],
"fallback_speed_cells": [
[ 0, 1 ],
[ 1, 0 ]
] ]
} }
``` ```
@@ -552,6 +557,7 @@ Vector tiles contain two layers:
| `weight ` | `integer` | how long this segment takes to traverse, in units (may differ from `duration` when artificial biasing is applied in the Lua profiles). ACTUAL ROUTING USES THIS VALUE. | | `weight ` | `integer` | how long this segment takes to traverse, in units (may differ from `duration` when artificial biasing is applied in the Lua profiles). ACTUAL ROUTING USES THIS VALUE. |
| `name` | `string` | the name of the road this segment belongs to | | `name` | `string` | the name of the road this segment belongs to |
| `rate` | `float` | the value of `length/weight` - analagous to `speed`, but using the `weight` value rather than `duration`, rounded to the nearest integer | | `rate` | `float` | the value of `length/weight` - analagous to `speed`, but using the `weight` value rather than `duration`, rounded to the nearest integer |
| `is_startpoint` | `boolean` | whether this segment can be used as a start/endpoint for routes |
`turns` layer: `turns` layer:
+1
View File
@@ -157,6 +157,7 @@ Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refer
Values are given in seconds. Values are given in seconds.
**`sources`**: array of [`Ẁaypoint`](#waypoint) objects describing all sources in order. **`sources`**: array of [`Ẁaypoint`](#waypoint) objects describing all sources in order.
**`destinations`**: array of [`Ẁaypoint`](#waypoint) objects describing all destinations in order. **`destinations`**: array of [`Ẁaypoint`](#waypoint) objects describing all destinations in order.
**`fallback_speed_cells`**: (optional) if `fallback_speed` is used, will be an array of arrays of `row,column` values, indicating which cells contain estimated values.
### tile ### tile
+9
View File
@@ -109,3 +109,12 @@ Feature: Car - Handle ferry routes
When I route I should get When I route I should get
| from | to | route | modes | time | | from | to | route | modes | time |
| c | d | bcde,bcde | ferry,ferry | 600s | | c | d | bcde,bcde | ferry,ferry | 600s |
Given the query options
| geometries | geojson |
| overview | full |
# Note that matching *should* work across unsnappable ferries
When I match I should get
| trace | geometry | duration |
| abcdef| 1,1,1.000899,1,1.000899,1,1.002697,1,1.002697,1,1.003596,1,1.003596,1,1.005394,1,1.005394,1,1.006293,1 | 610.9 |
+25
View File
@@ -137,3 +137,28 @@ OSRM will use 4/5 of the projected free-flow speed.
| primary | | | 30 | -1 | | 23 km/h | | 6.7 | | primary | | | 30 | -1 | | 23 km/h | | 6.7 |
| primary | 20 | 30 | | -1 | | 15 km/h | | 4.4 | | primary | 20 | 30 | | -1 | | 15 km/h | | 4.4 |
| primary | 20 | | 30 | -1 | | 23 km/h | | 6.7 | | primary | 20 | | 30 | -1 | | 23 km/h | | 6.7 |
Scenario: Car - Respect source:maxspeed
Given the node map
"""
a b c d e f g
"""
And the ways
| nodes | highway | source:maxspeed | maxspeed |
| ab | trunk | | |
| bc | trunk | | 60 |
| cd | trunk | FR:urban | |
| de | trunk | CH:rural | |
| ef | trunk | CH:trunk | |
| fg | trunk | CH:motorway | |
When I route I should get
| from | to | route | speed |
| a | b | ab,ab | 85 km/h |
| b | c | bc,bc | 48 km/h |
| c | d | cd,cd | 40 km/h |
| d | e | de,de | 64 km/h |
| e | f | ef,ef | 80 km/h |
| f | g | fg,fg | 96 km/h |
+25
View File
@@ -35,3 +35,28 @@ Feature: Car - Allowed start/end modes
| from | to | route | modes | | from | to | route | modes |
| 1 | 2 | ab,ab | driving,driving | | 1 | 2 | ab,ab | driving,driving |
| 2 | 1 | ab,ab | driving,driving | | 2 | 1 | ab,ab | driving,driving |
Scenario: Car - URL override of non-startpoints
Given the node map
"""
a 1 b c 2 d
"""
Given the query options
| snapping | any |
And the ways
| nodes | highway | access |
| ab | service | private |
| bc | primary | |
| cd | service | private |
When I request a travel time matrix I should get
| | 2 | c |
| 1 | 59.1 | 35.1 |
| b | 35.1 | 11.1 |
When I route I should get
| from | to | route |
| 1 | 2 | ab,bc,cd |
| 2 | 1 | cd,bc,ab |
+1 -1
View File
@@ -295,7 +295,7 @@ module.exports = function () {
this.reprocess(callback); this.reprocess(callback);
}); });
this.Given(/^osrm\-routed is stopped$/, (callback) => { this.Given(/^osrm-routed is stopped$/, (callback) => {
this.OSRMLoader.shutdown(callback); this.OSRMLoader.shutdown(callback);
}); });
+25 -7
View File
@@ -3,22 +3,25 @@ var util = require('util');
module.exports = function () { module.exports = function () {
const durationsRegex = new RegExp(/^I request a travel time matrix I should get$/); const durationsRegex = new RegExp(/^I request a travel time matrix I should get$/);
const distancesRegex = new RegExp(/^I request a travel distance matrix I should get$/); const distancesRegex = new RegExp(/^I request a travel distance matrix I should get$/);
const estimatesRegex = new RegExp(/^I request a travel time matrix I should get estimates for$/);
const DURATIONS_NO_ROUTE = 2147483647; // MAX_INT const DURATIONS_NO_ROUTE = 2147483647; // MAX_INT
const DISTANCES_NO_ROUTE = 3.40282e+38; // MAX_FLOAT const DISTANCES_NO_ROUTE = 3.40282e+38; // MAX_FLOAT
this.When(durationsRegex, function(table, callback) {tableParse.call(this, table, DURATIONS_NO_ROUTE, 'durations', callback);}.bind(this)); this.When(durationsRegex, function(table, callback) {tableParse.call(this, table, DURATIONS_NO_ROUTE, 'durations', callback);}.bind(this));
this.When(distancesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'distances', callback);}.bind(this)); this.When(distancesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'distances', callback);}.bind(this));
this.When(estimatesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'fallback_speed_cells', callback);}.bind(this));
}; };
const durationsParse = function(v) { return isNaN(parseInt(v)); }; const durationsParse = function(v) { return isNaN(parseInt(v)); };
const distancesParse = function(v) { return isNaN(parseFloat(v)); }; const distancesParse = function(v) { return isNaN(parseFloat(v)); };
const estimatesParse = function(v) { return isNaN(parseFloat(v)); };
function tableParse(table, noRoute, annotation, callback) { function tableParse(table, noRoute, annotation, callback) {
const parse = annotation == 'distances' ? distancesParse : durationsParse; const parse = annotation == 'distances' ? distancesParse : (annotation == 'durations' ? durationsParse : estimatesParse);
const params = this.queryParams; const params = this.queryParams;
params.annotations = annotation == 'distances' ? 'distance' : 'duration'; params.annotations = ['durations','fallback_speed_cells'].indexOf(annotation) !== -1 ? 'duration' : 'distance';
var tableRows = table.raw(); var tableRows = table.raw();
@@ -61,11 +64,26 @@ function tableParse(table, noRoute, annotation, callback) {
var json = JSON.parse(response.body); var json = JSON.parse(response.body);
var result = json[annotation].map(row => { var result = {};
var hashes = {}; if (annotation === 'fallback_speed_cells') {
row.forEach((v, i) => { hashes[tableRows[0][i+1]] = parse(v) ? '' : v; }); result = table.raw().map(row => row.map(() => ''));
return hashes; json[annotation].forEach(pair => {
}); result[pair[0]+1][pair[1]+1] = 'Y';
});
result = result.slice(1).map(row => {
var hashes = {};
row.slice(1).forEach((v,i) => {
hashes[tableRows[0][i+1]] = v;
});
return hashes;
});
} else {
result = json[annotation].map(row => {
var hashes = {};
row.forEach((v, i) => { hashes[tableRows[0][i+1]] = parse(v) ? '' : v; });
return hashes;
});
}
var testRow = (row, ri, cb) => { var testRow = (row, ri, cb) => {
for (var k in result[ri]) { for (var k in result[ri]) {
+6 -6
View File
@@ -21,11 +21,11 @@ module.exports = function () {
}); });
}; };
this.When(/^I run "osrm\-routed\s?(.*?)"$/, { timeout: this.TIMEOUT }, (options, callback) => { this.When(/^I run "osrm-routed\s?(.*?)"$/, { timeout: this.TIMEOUT }, (options, callback) => {
this.runAndSafeOutput('osrm-routed', options, callback); this.runAndSafeOutput('osrm-routed', options, callback);
}); });
this.When(/^I run "osrm\-(extract|contract|partition|customize)\s?(.*?)"$/, (binary, options, callback) => { this.When(/^I run "osrm-(extract|contract|partition|customize)\s?(.*?)"$/, (binary, options, callback) => {
const stamp = this.processedCacheFile + '.stamp_' + binary; const stamp = this.processedCacheFile + '.stamp_' + binary;
this.runAndSafeOutput('osrm-' + binary, options, (err) => { this.runAndSafeOutput('osrm-' + binary, options, (err) => {
if (err) return callback(err); if (err) return callback(err);
@@ -33,11 +33,11 @@ module.exports = function () {
}); });
}); });
this.When(/^I try to run "(osrm\-[a-z]+)\s?(.*?)"$/, (binary, options, callback) => { this.When(/^I try to run "(osrm-[a-z]+)\s?(.*?)"$/, (binary, options, callback) => {
this.runAndSafeOutput(binary, options, () => { callback(); }); this.runAndSafeOutput(binary, options, () => { callback(); });
}); });
this.When(/^I run "osrm\-datastore\s?(.*?)"(?: with input "([^"]*)")?$/, (options, input, callback) => { this.When(/^I run "osrm-datastore\s?(.*?)"(?: with input "([^"]*)")?$/, (options, input, callback) => {
let child = this.runAndSafeOutput('osrm-datastore', options, callback); let child = this.runAndSafeOutput('osrm-datastore', options, callback);
if (input !== undefined) if (input !== undefined)
child.stdin.write(input); child.stdin.write(input);
@@ -55,13 +55,13 @@ module.exports = function () {
this.Then(/^stdout should( not)? contain "(.*?)"$/, (not, str) => { this.Then(/^stdout should( not)? contain "(.*?)"$/, (not, str) => {
const contains = this.stdout.indexOf(str) > -1; const contains = this.stdout.indexOf(str) > -1;
assert.ok(typeof not === 'undefined' ? contains : !contains, assert.ok(typeof not === 'undefined' ? contains : !contains,
'stdout ' + (typeof not === 'undefined' ? 'does not contain' : 'contains') + ' "' + str + '"'); 'stdout ' + (typeof not === 'undefined' ? 'does not contain' : 'contains') + ' "' + str + '"');
}); });
this.Then(/^stderr should( not)? contain "(.*?)"$/, (not, str) => { this.Then(/^stderr should( not)? contain "(.*?)"$/, (not, str) => {
const contains = this.stderr.indexOf(str) > -1; const contains = this.stderr.indexOf(str) > -1;
assert.ok(typeof not === 'undefined' ? contains : !contains, assert.ok(typeof not === 'undefined' ? contains : !contains,
'stderr ' + (typeof not === 'undefined' ? 'does not contain' : 'contains') + ' "' + str + '"'); 'stderr ' + (typeof not === 'undefined' ? 'does not contain' : 'contains') + ' "' + str + '"');
}); });
this.Then(/^stdout should contain \/(.*)\/$/, (regexStr) => { this.Then(/^stdout should contain \/(.*)\/$/, (regexStr) => {
+1 -1
View File
@@ -69,7 +69,7 @@ module.exports = function () {
outputRow[direction] = result[direction].status ? outputRow[direction] = result[direction].status ?
'x' : ''; 'x' : '';
break; break;
case /^[\d\.]+ s/.test(want): case /^[\d.]+ s/.test(want):
// the result here can come back as a non-number value like // the result here can come back as a non-number value like
// `diff`, but we only want to apply the unit when it comes // `diff`, but we only want to apply the unit when it comes
// back as a number, for tableDiff's literal comparison // back as a number, for tableDiff's literal comparison
+7 -7
View File
@@ -29,7 +29,7 @@ module.exports = function() {
// setup cache for feature data // setup cache for feature data
// if OSRM_PROFILE is set to force a specific profile, then // if OSRM_PROFILE is set to force a specific profile, then
// include the profile name in the hash of the profile file // include the profile name in the hash of the profile file
hash.hashOfFile(uri, this.OSRM_PROFILE, (err, hash) => { hash.hashOfFile(uri, this.OSRM_PROFILE, (err, hash) => {
if (err) return callback(err); if (err) return callback(err);
@@ -45,10 +45,10 @@ module.exports = function() {
this.featureProcessedCacheDirectories[uri] = featureProcessedCacheDirectory; this.featureProcessedCacheDirectories[uri] = featureProcessedCacheDirectory;
d3.queue(1) d3.queue(1)
.defer(mkdirp, featureProcessedCacheDirectory) .defer(mkdirp, featureProcessedCacheDirectory)
.defer(this.cleanupFeatureCache.bind(this), featureCacheDirectory, hash) .defer(this.cleanupFeatureCache.bind(this), featureCacheDirectory, hash)
.defer(this.cleanupProcessedFeatureCache.bind(this), featureProcessedCacheDirectory, this.osrmHash) .defer(this.cleanupProcessedFeatureCache.bind(this), featureProcessedCacheDirectory, this.osrmHash)
.awaitAll(callback); .awaitAll(callback);
}); });
} }
@@ -87,7 +87,7 @@ module.exports = function() {
fs.readdir(parentPath, (err, files) => { fs.readdir(parentPath, (err, files) => {
let q = d3.queue(); let q = d3.queue();
files.filter(name => { return name !== featureHash;}) files.filter(name => { return name !== featureHash;})
.map((f) => { q.defer(rimraf, path.join(parentPath, f)); }); .map((f) => { q.defer(rimraf, path.join(parentPath, f)); });
q.awaitAll(callback); q.awaitAll(callback);
}); });
}; };
@@ -145,7 +145,7 @@ module.exports = function() {
// converts the scenario titles in file prefixes // converts the scenario titles in file prefixes
this.getScenarioID = (scenario) => { this.getScenarioID = (scenario) => {
let name = scenario.getName().toLowerCase().replace(/[\/\-'=,\(\):\*#]/g, '') let name = scenario.getName().toLowerCase().replace(/[/\-'=,():*#]/g, '')
.replace(/\s/g, '_').replace(/__/g, '_').replace(/\.\./g, '.') .replace(/\s/g, '_').replace(/__/g, '_').replace(/\.\./g, '.')
.substring(0, 64); .substring(0, 64);
return util.format('%d_%s', scenario.getLine(), name); return util.format('%d_%s', scenario.getLine(), name);
+10 -10
View File
@@ -17,12 +17,12 @@ module.exports = {
return true; return true;
var matchPercent = want.match(/(.*)\s+~(.+)%$/), var matchPercent = want.match(/(.*)\s+~(.+)%$/),
matchAbs = want.match(/(.*)\s+\+\-(.+)$/), matchAbs = want.match(/(.*)\s+\+-(.+)$/),
matchRe = want.match(/^\/(.*)\/$/), matchRe = want.match(/^\/(.*)\/$/),
// we use this for matching before/after bearing // we use this for matching before/after bearing
matchBearingListAbs = want.match(/^((\d+)->(\d+))(,(\d+)->(\d+))*\s+\+\-(.+)$/), matchBearingListAbs = want.match(/^((\d+)->(\d+))(,(\d+)->(\d+))*\s+\+-(.+)$/),
matchIntersectionListAbs = want.match(/^(((((true|false):\d+)\s{0,1})+,{0,1})+;{0,1})+\s+\+\-(.+)$/), matchIntersectionListAbs = want.match(/^(((((true|false):\d+)\s{0,1})+,{0,1})+;{0,1})+\s+\+-(.+)$/),
matchRangeNumbers = want.match(/\d+\+\-\d+/); matchRangeNumbers = want.match(/\d+\+-\d+/);
function inRange(margin, got, want) { function inRange(margin, got, want) {
var fromR = parseFloat(want) - margin, var fromR = parseFloat(want) - margin,
@@ -31,12 +31,12 @@ module.exports = {
} }
function parseIntersectionString(str) { function parseIntersectionString(str) {
return str.split(';') return str.split(';')
.map((turn_intersections) => turn_intersections .map((turn_intersections) => turn_intersections
.split(',') .split(',')
.map((intersection) => intersection .map((intersection) => intersection
.split(' ') .split(' ')
.map((entry_bearing_pair) => entry_bearing_pair .map((entry_bearing_pair) => entry_bearing_pair
.split(':')))); .split(':'))));
} }
if (got === want) { if (got === want) {
+2 -2
View File
@@ -115,7 +115,7 @@ module.exports = function () {
if (headers.has('weight')) { if (headers.has('weight')) {
if (row.weight.length) { if (row.weight.length) {
if (!row.weight.match(/[\d\.]+/)) if (!row.weight.match(/[\d.]+/))
return cb(new Error('*** Weight must be specified as a numeric value. (ex: 8)')); return cb(new Error('*** Weight must be specified as a numeric value. (ex: 8)'));
got.weight = instructions ? util.format('%d', weight) : ''; got.weight = instructions ? util.format('%d', weight) : '';
} else { } else {
@@ -151,7 +151,7 @@ module.exports = function () {
if (headers.has('locations')){ if (headers.has('locations')){
got.locations = (locations || '').trim(); got.locations = (locations || '').trim();
} }
/* /*
if (headers.has('approaches')){ if (headers.has('approaches')){
got.approaches = (approaches || '').trim(); got.approaches = (approaches || '').trim();
}*/ }*/
+25 -3
View File
@@ -616,7 +616,7 @@ Feature: Basic Distance Matrix
| | a | b | f | 1 | | | a | b | f | 1 |
| a | 0 | 300.2 | 900.7 | 1501.1 | | a | 0 | 300.2 | 900.7 | 1501.1 |
| b | 300.2 | 0 | 600.5 | 1200.9 | | b | 300.2 | 0 | 600.5 | 1200.9 |
| f | 900.7 | 600.5 | 0 | 302.2 | | f | 900.7 | 600.5 | 0 | 300.2 |
| 1 | 1501.1 | 1200.9 | 300.2 | 0 | | 1 | 1501.1 | 1200.9 | 300.2 | 0 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
@@ -651,7 +651,7 @@ Feature: Basic Distance Matrix
| | a | b | f | 1 | | | a | b | f | 1 |
| a | 0 | 300.2 | 900.7 | 1501.1 | | a | 0 | 300.2 | 900.7 | 1501.1 |
| b | 300.2 | 0 | 600.5 | 1200.9 | | b | 300.2 | 0 | 600.5 | 1200.9 |
| f | 900.7 | 600.5 | 0 | 302.2 | | f | 900.7 | 600.5 | 0 | 300.2 |
| 1 | 1501.1 | 1200.9 | 300.2 | 0 | | 1 | 1501.1 | 1200.9 | 300.2 | 0 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
@@ -687,7 +687,7 @@ Feature: Basic Distance Matrix
| | a | b | f | 1 | | | a | b | f | 1 |
| a | 0 | 300.2 | 900.7 | 1200.9 | | a | 0 | 300.2 | 900.7 | 1200.9 |
| b | 300.2 | 0 | 600.5 | 900.7 | | b | 300.2 | 0 | 600.5 | 900.7 |
| f | 900.7 | 600.5 | 0 | 302.2 | | f | 900.7 | 600.5 | 0 | 300.2 |
| 1 | 1200.9 | 900.7 | 300.2 | 0 | | 1 | 1200.9 | 900.7 | 300.2 | 0 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
@@ -701,3 +701,25 @@ Feature: Basic Distance Matrix
| f | 900.7 | | f | 900.7 |
| 1 | 1200.9 | | 1 | 1200.9 |
Scenario: Ensure consistency with route, and make sure offsets work in both directions
Given a grid size of 100 meters
Given the node map
"""
a b c d e f g h i j
1 2
"""
And the ways
| nodes |
| abcdef |
| fghij |
When I route I should get
| from | to | route | distance |
| 1 | 2 | abcdef,fghij,fghij | 999.9m |
# TODO: this is "correct", but inconsistent with viaroute
When I request a travel distance matrix I should get
| | 1 | 2 |
| 1 | 0 | 1000.7 |
| 2 | 1000.7 | 0 |
+89 -16
View File
@@ -545,6 +545,24 @@ Feature: Basic Duration Matrix
| f | 18 | | f | 18 |
| 1 | 30 | | 1 | 30 |
When I request a travel time matrix I should get estimates for
| | a | b | f | 1 |
| a | | | Y | Y |
| b | | | Y | Y |
| f | Y | Y | | |
| 1 | Y | Y | | |
When I request a travel time matrix I should get estimates for
| | a | b | f | 1 |
| a | | | Y | Y |
When I request a travel time matrix I should get estimates for
| | a |
| a | |
| b | |
| f | Y |
| 1 | Y |
Scenario: Testbot - Filling in noroutes with estimates - use input coordinate Scenario: Testbot - Filling in noroutes with estimates - use input coordinate
Given a grid size of 300 meters Given a grid size of 300 meters
Given the extract extra arguments "--small-component-size 4" Given the extract extra arguments "--small-component-size 4"
@@ -580,6 +598,25 @@ Feature: Basic Duration Matrix
| f | 18 | | f | 18 |
| 1 | 30 | | 1 | 30 |
When I request a travel time matrix I should get estimates for
| | a | b | f | 1 |
| a | | | Y | Y |
| b | | | Y | Y |
| f | Y | Y | | |
| 1 | Y | Y | | |
When I request a travel time matrix I should get estimates for
| | a | b | f | 1 |
| a | | | Y | Y |
When I request a travel time matrix I should get estimates for
| | a |
| a | |
| b | |
| f | Y |
| 1 | Y |
Scenario: Testbot - Filling in noroutes with estimates - use snapped coordinate Scenario: Testbot - Filling in noroutes with estimates - use snapped coordinate
Given a grid size of 300 meters Given a grid size of 300 meters
Given the extract extra arguments "--small-component-size 4" Given the extract extra arguments "--small-component-size 4"
@@ -615,18 +652,35 @@ Feature: Basic Duration Matrix
| f | 18 | | f | 18 |
| 1 | 24 | | 1 | 24 |
When I request a travel time matrix I should get estimates for
| | a | b | f | 1 |
| a | | | Y | Y |
| b | | | Y | Y |
| f | Y | Y | | |
| 1 | Y | Y | | |
When I request a travel time matrix I should get estimates for
| | a | b | f | 1 |
| a | | | Y | Y |
When I request a travel time matrix I should get estimates for
| | a |
| a | |
| b | |
| f | Y |
| 1 | Y |
Scenario: Testbot - Travel time matrix of minimal network with scale factor Scenario: Testbot - Travel time matrix of minimal network with scale factor
Given the query options Given the query options
| scale_factor | 2 | | scale_factor | 2 |
Given the node map Given the node map
""" """
a b a b
""" """
And the ways And the ways
| nodes | | nodes |
| ab | | ab |
When I request a travel time matrix I should get When I request a travel time matrix I should get
| | a | b | | | a | b |
| a | 0 | 20 | | a | 0 | 20 |
| b | 20 | 0 | | b | 20 | 0 |
@@ -638,67 +692,86 @@ Feature: Basic Duration Matrix
| fallback_speed | 5 | | fallback_speed | 5 |
| fallback_coordinate | snapped | | fallback_coordinate | snapped |
Given the node map Given the node map
""" """
a b f h 1 a b f h 1
d e g i d e g i
""" """
And the ways And the ways
| nodes | | nodes |
| abeda | | abeda |
| fhigf | | fhigf |
When I request a travel time matrix I should get When I request a travel time matrix I should get
| | a | b | f | 1 | | | a | b | f | 1 |
| a | 0 | 60 | 36 | 48 | | a | 0 | 60 | 36 | 48 |
| b | 60 | 0 | 24 | 36 | | b | 60 | 0 | 24 | 36 |
| f | 36 | 24 | 0 | 60 | | f | 36 | 24 | 0 | 60 |
| 1 | 48 | 36 | 60 | 0 | | 1 | 48 | 36 | 60 | 0 |
When I request a travel time matrix I should get When I request a travel time matrix I should get
| | a | b | f | 1 | | | a | b | f | 1 |
| a | 0 | 60 | 36 | 48 | | a | 0 | 60 | 36 | 48 |
When I request a travel time matrix I should get When I request a travel time matrix I should get
| | a | | | a |
| a | 0 | | a | 0 |
| b | 60 | | b | 60 |
| f | 36 | | f | 36 |
| 1 | 48 | | 1 | 48 |
When I request a travel time matrix I should get estimates for
| | a | b | f | 1 |
| a | | | Y | Y |
| b | | | Y | Y |
| f | Y | Y | | |
| 1 | Y | Y | | |
When I request a travel time matrix I should get estimates for
| | a | b | f | 1 |
| a | | | Y | Y |
When I request a travel time matrix I should get estimates for
| | a |
| a | |
| b | |
| f | Y |
| 1 | Y |
Scenario: Testbot - Travel time matrix of minimal network with overflow scale factor Scenario: Testbot - Travel time matrix of minimal network with overflow scale factor
Given the query options Given the query options
| scale_factor | 2147483647 | | scale_factor | 2147483647 |
Given the node map Given the node map
""" """
a b a b
""" """
And the ways And the ways
| nodes | | nodes |
| ab | | ab |
When I request a travel time matrix I should get When I request a travel time matrix I should get
| | a | b | | | a | b |
| a | 0 | 214748364.6 | | a | 0 | 214748364.6 |
| b | 214748364.6 | 0 | | b | 214748364.6 | 0 |
Scenario: Testbot - Travel time matrix of minimal network with fraction scale factor Scenario: Testbot - Travel time matrix of minimal network with fraction scale factor
Given the query options Given the query options
| scale_factor | 0.5 | | scale_factor | 0.5 |
Given the node map Given the node map
""" """
a b a b
""" """
And the ways And the ways
| nodes | | nodes |
| ab | | ab |
When I request a travel time matrix I should get When I request a travel time matrix I should get
| | a | b | | | a | b |
| a | 0 | 5 | | a | 0 | 5 |
| b | 5 | 0 | | b | 5 | 0 |
+10 -10
View File
@@ -111,9 +111,9 @@ Feature: Multi level routing
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | f | l | o | | | a | f | l | o |
| a | 0 | 2383.7 | 1566.9 | 1366.8 | | a | 0 | 2383.7 | 1566.9 | 1366.8 |
| f | 2339.9 | 0 | 1198.1 | 1522.1 | | f | 2383.7 | 0 | 1293.3 | 1617.3 |
| l | 1618.3 | 1293.3 | 0 | 800.5 | | l | 1566.9 | 1293.3 | 0 | 800.5 |
| o | 1418.2 | 1617.3 | 800.5 | 0 | | o | 1366.8 | 1617.3 | 800.5 | 0 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | f | l | o | | | a | f | l | o |
@@ -122,21 +122,21 @@ Feature: Multi level routing
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | | | a |
| a | 0 | | a | 0 |
| f | 2339.9 | | f | 2383.7 |
| l | 1618.3 | | l | 1566.9 |
| o | 1418.2 | | o | 1366.8 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | f | l | o | | | a | f | l | o |
| a | 0 | 2383.7 | 1566.9 | 1366.8 | | a | 0 | 2383.7 | 1566.9 | 1366.8 |
| f | 2339.9 | 0 | 1198.1 | 1522.1 | | f | 2383.7 | 0 | 1293.3 | 1617.3 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | o | | | a | o |
| a | 0 | 1366.8 | | a | 0 | 1366.8 |
| f | 2339.9 | 1522.1 | | f | 2383.7 | 1617.3 |
| l | 1618.3 | 800.5 | | l | 1566.9 | 800.5 |
| o | 1418.2 | 0 | | o | 1366.8 | 0 |
Scenario: Testbot - Multi level routing: horizontal road Scenario: Testbot - Multi level routing: horizontal road
Given the node map Given the node map
+13 -2
View File
@@ -63,6 +63,13 @@ namespace api
*/ */
struct BaseParameters struct BaseParameters
{ {
enum class SnappingType
{
Default,
Any
};
std::vector<util::Coordinate> coordinates; std::vector<util::Coordinate> coordinates;
std::vector<boost::optional<Hint>> hints; std::vector<boost::optional<Hint>> hints;
std::vector<boost::optional<double>> radiuses; std::vector<boost::optional<double>> radiuses;
@@ -73,15 +80,19 @@ struct BaseParameters
// Adds hints to response which can be included in subsequent requests, see `hints` above. // Adds hints to response which can be included in subsequent requests, see `hints` above.
bool generate_hints = true; bool generate_hints = true;
SnappingType snapping = SnappingType::Default;
BaseParameters(const std::vector<util::Coordinate> coordinates_ = {}, BaseParameters(const std::vector<util::Coordinate> coordinates_ = {},
const std::vector<boost::optional<Hint>> hints_ = {}, const std::vector<boost::optional<Hint>> hints_ = {},
std::vector<boost::optional<double>> radiuses_ = {}, std::vector<boost::optional<double>> radiuses_ = {},
std::vector<boost::optional<Bearing>> bearings_ = {}, std::vector<boost::optional<Bearing>> bearings_ = {},
std::vector<boost::optional<Approach>> approaches_ = {}, std::vector<boost::optional<Approach>> approaches_ = {},
bool generate_hints_ = true, bool generate_hints_ = true,
std::vector<std::string> exclude = {}) std::vector<std::string> exclude = {},
const SnappingType snapping_ = SnappingType::Default)
: coordinates(coordinates_), hints(hints_), radiuses(radiuses_), bearings(bearings_), : coordinates(coordinates_), hints(hints_), radiuses(radiuses_), bearings(bearings_),
approaches(approaches_), exclude(std::move(exclude)), generate_hints(generate_hints_) approaches(approaches_), exclude(std::move(exclude)), generate_hints(generate_hints_),
snapping(snapping_)
{ {
} }
+29
View File
@@ -31,6 +31,15 @@ namespace api
class TableAPI final : public BaseAPI class TableAPI final : public BaseAPI
{ {
public: public:
struct TableCellRef
{
TableCellRef(const std::size_t &row, const std::size_t &column) : row{row}, column{column}
{
}
std::size_t row;
std::size_t column;
};
TableAPI(const datafacade::BaseDataFacade &facade_, const TableParameters &parameters_) TableAPI(const datafacade::BaseDataFacade &facade_, const TableParameters &parameters_)
: BaseAPI(facade_, parameters_), parameters(parameters_) : BaseAPI(facade_, parameters_), parameters(parameters_)
{ {
@@ -39,6 +48,7 @@ class TableAPI final : public BaseAPI
virtual void virtual void
MakeResponse(const std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> &tables, MakeResponse(const std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> &tables,
const std::vector<PhantomNode> &phantoms, const std::vector<PhantomNode> &phantoms,
const std::vector<TableCellRef> &fallback_speed_cells,
util::json::Object &response) const util::json::Object &response) const
{ {
auto number_of_sources = parameters.sources.size(); auto number_of_sources = parameters.sources.size();
@@ -77,6 +87,11 @@ class TableAPI final : public BaseAPI
MakeDistanceTable(tables.second, number_of_sources, number_of_destinations); MakeDistanceTable(tables.second, number_of_sources, number_of_destinations);
} }
if (parameters.fallback_speed != INVALID_FALLBACK_SPEED && parameters.fallback_speed > 0)
{
response.values["fallback_speed_cells"] = MakeEstimatesTable(fallback_speed_cells);
}
response.values["code"] = "Ok"; response.values["code"] = "Ok";
} }
@@ -163,6 +178,20 @@ class TableAPI final : public BaseAPI
return json_table; return json_table;
} }
virtual util::json::Array
MakeEstimatesTable(const std::vector<TableCellRef> &fallback_speed_cells) const
{
util::json::Array json_table;
std::for_each(
fallback_speed_cells.begin(), fallback_speed_cells.end(), [&](const auto &cell) {
util::json::Array row;
row.values.push_back(util::json::Number(cell.row));
row.values.push_back(util::json::Number(cell.column));
json_table.values.push_back(std::move(row));
});
return json_table;
}
const TableParameters &parameters; const TableParameters &parameters;
}; };
@@ -312,12 +312,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance, const float max_distance,
const Approach approach) const override final const Approach approach,
const bool use_all_edges) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodesInRange( return m_geospatial_query->NearestPhantomNodesInRange(
input_coordinate, max_distance, approach); input_coordinate, max_distance, approach, use_all_edges);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
@@ -325,12 +326,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
const float max_distance, const float max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const override final const Approach approach,
const bool use_all_edges) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodesInRange( return m_geospatial_query->NearestPhantomNodesInRange(
input_coordinate, max_distance, bearing, bearing_range, approach); input_coordinate, max_distance, bearing, bearing_range, approach, use_all_edges);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
@@ -384,23 +386,25 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const Approach approach) const override final const Approach approach,
const bool use_all_edges) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, approach); input_coordinate, approach, use_all_edges);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const Approach approach) const override final const Approach approach,
const bool use_all_edges) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance, approach); input_coordinate, max_distance, approach, use_all_edges);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
@@ -408,24 +412,26 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const override final const Approach approach,
const bool use_all_edges) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance, bearing, bearing_range, approach); input_coordinate, max_distance, bearing, bearing_range, approach, use_all_edges);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const override final const Approach approach,
const bool use_all_edges) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, bearing, bearing_range, approach); input_coordinate, bearing, bearing_range, approach, use_all_edges);
} }
std::uint32_t GetCheckSum() const override final { return m_check_sum; } std::uint32_t GetCheckSum() const override final { return m_check_sum; }
+12 -6
View File
@@ -126,11 +126,13 @@ class BaseDataFacade
const float max_distance, const float max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const = 0; const Approach approach,
const bool use_all_edges) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance, const float max_distance,
const Approach approach) const = 0; const Approach approach,
const bool use_all_edges) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
@@ -157,22 +159,26 @@ class BaseDataFacade
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const Approach approach) const = 0; const Approach approach,
const bool use_all_edges) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const Approach approach) const = 0; const Approach approach,
const bool use_all_edges) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const = 0; const Approach approach,
const bool use_all_edges) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const = 0; const Approach approach,
const bool use_all_edges = false) const = 0;
virtual bool HasLaneData(const EdgeID id) const = 0; virtual bool HasLaneData(const EdgeID id) const = 0;
virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0; virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0;
+48 -24
View File
@@ -53,13 +53,15 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const Approach approach) const const Approach approach,
const bool use_all_edges) const
{ {
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, approach, &input_coordinate](const CandidateSegment &segment) { [this, approach, &input_coordinate, use_all_edges](const CandidateSegment &segment) {
return boolPairAnd(boolPairAnd(HasValidEdge(segment), CheckSegmentExclude(segment)), return boolPairAnd(
CheckApproach(input_coordinate, segment, approach)); boolPairAnd(HasValidEdge(segment, use_all_edges), CheckSegmentExclude(segment)),
CheckApproach(input_coordinate, segment, approach));
}, },
[this, max_distance, input_coordinate](const std::size_t, [this, max_distance, input_coordinate](const std::size_t,
const CandidateSegment &segment) { const CandidateSegment &segment) {
@@ -76,15 +78,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const const Approach approach,
const bool use_all_edges) const
{ {
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, approach, &input_coordinate, bearing, bearing_range]( [this, approach, &input_coordinate, bearing, bearing_range, use_all_edges](
const CandidateSegment &segment) { const CandidateSegment &segment) {
auto use_direction = auto use_direction =
boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
boolPairAnd(HasValidEdge(segment), CheckSegmentExclude(segment))); boolPairAnd(HasValidEdge(segment, use_all_edges),
CheckSegmentExclude(segment)));
use_direction = use_direction =
boolPairAnd(use_direction, CheckApproach(input_coordinate, segment, approach)); boolPairAnd(use_direction, CheckApproach(input_coordinate, segment, approach));
return use_direction; return use_direction;
@@ -201,18 +205,23 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const Approach approach) const const Approach approach,
const bool use_all_edges) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, approach, &input_coordinate, &has_big_component, &has_small_component]( [this,
const CandidateSegment &segment) { approach,
&input_coordinate,
&has_big_component,
&has_small_component,
&use_all_edges](const CandidateSegment &segment) {
auto use_segment = auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment))); (!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
const auto valid_edges = HasValidEdge(segment); const auto valid_edges = HasValidEdge(segment, use_all_edges);
const auto admissible_segments = CheckSegmentExclude(segment); const auto admissible_segments = CheckSegmentExclude(segment);
use_directions = boolPairAnd(use_directions, admissible_segments); use_directions = boolPairAnd(use_directions, admissible_segments);
use_directions = boolPairAnd(use_directions, valid_edges); use_directions = boolPairAnd(use_directions, valid_edges);
@@ -247,19 +256,24 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// a second phantom node is return that is the nearest coordinate in a big component. // a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const Approach approach) const const Approach approach,
const bool use_all_edges) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, approach, &input_coordinate, &has_big_component, &has_small_component]( [this,
const CandidateSegment &segment) { approach,
&input_coordinate,
&has_big_component,
&has_small_component,
&use_all_edges](const CandidateSegment &segment) {
auto use_segment = auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment))); (!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
const auto valid_edges = HasValidEdge(segment); const auto valid_edges = HasValidEdge(segment, use_all_edges);
const auto admissible_segments = CheckSegmentExclude(segment); const auto admissible_segments = CheckSegmentExclude(segment);
use_directions = boolPairAnd(use_directions, admissible_segments); use_directions = boolPairAnd(use_directions, admissible_segments);
use_directions = boolPairAnd(use_directions, valid_edges); use_directions = boolPairAnd(use_directions, valid_edges);
@@ -294,7 +308,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const const Approach approach,
const bool use_all_edges) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
@@ -306,12 +321,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bearing, bearing,
bearing_range, bearing_range,
&has_big_component, &has_big_component,
&has_small_component](const CandidateSegment &segment) { &has_small_component,
&use_all_edges](const CandidateSegment &segment) {
auto use_segment = auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment))); (!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
const auto admissible_segments = CheckSegmentExclude(segment); const auto admissible_segments = CheckSegmentExclude(segment);
use_directions = boolPairAnd(use_directions, HasValidEdge(segment)); use_directions = boolPairAnd(use_directions, HasValidEdge(segment, use_all_edges));
if (use_segment) if (use_segment)
{ {
@@ -352,7 +368,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range, const int bearing_range,
const Approach approach) const const Approach approach,
const bool use_all_edges) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
@@ -364,12 +381,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bearing, bearing,
bearing_range, bearing_range,
&has_big_component, &has_big_component,
&has_small_component](const CandidateSegment &segment) { &has_small_component,
&use_all_edges](const CandidateSegment &segment) {
auto use_segment = auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment))); (!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
const auto admissible_segments = CheckSegmentExclude(segment); const auto admissible_segments = CheckSegmentExclude(segment);
use_directions = boolPairAnd(use_directions, HasValidEdge(segment)); use_directions = boolPairAnd(use_directions, HasValidEdge(segment, use_all_edges));
if (use_segment) if (use_segment)
{ {
@@ -461,6 +479,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
EdgeDuration{0}); EdgeDuration{0});
EdgeDistance forward_distance_offset = 0; EdgeDistance forward_distance_offset = 0;
// Sum up the distance from the start to the fwd_segment_position
for (auto current = forward_geometry.begin(); for (auto current = forward_geometry.begin();
current < forward_geometry.begin() + data.fwd_segment_position; current < forward_geometry.begin() + data.fwd_segment_position;
++current) ++current)
@@ -490,8 +509,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
EdgeDuration{0}); EdgeDuration{0});
EdgeDistance reverse_distance_offset = 0; EdgeDistance reverse_distance_offset = 0;
for (auto current = forward_geometry.begin(); // Sum up the distance from just after the fwd_segment_position to the end
current < forward_geometry.end() - data.fwd_segment_position - 2; for (auto current = forward_geometry.begin() + data.fwd_segment_position + 1;
current != std::prev(forward_geometry.end());
++current) ++current)
{ {
reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance( reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance(
@@ -628,7 +648,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
* which means that this edge is not currently traversible. If this is the case, * which means that this edge is not currently traversible. If this is the case,
* then we shouldn't snap to this edge. * then we shouldn't snap to this edge.
*/ */
std::pair<bool, bool> HasValidEdge(const CandidateSegment &segment) const std::pair<bool, bool> HasValidEdge(const CandidateSegment &segment,
const bool use_all_edges = false) const
{ {
bool forward_edge_valid = false; bool forward_edge_valid = false;
@@ -652,6 +673,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
reverse_edge_valid = data.reverse_segment_id.enabled; reverse_edge_valid = data.reverse_segment_id.enabled;
} }
forward_edge_valid = forward_edge_valid && (data.is_startpoint || use_all_edges);
reverse_edge_valid = reverse_edge_valid && (data.is_startpoint || use_all_edges);
return std::make_pair(forward_edge_valid, reverse_edge_valid); return std::make_pair(forward_edge_valid, reverse_edge_valid);
} }
+15 -7
View File
@@ -138,7 +138,8 @@ class BasePlugin
std::vector<std::vector<PhantomNodeWithDistance>> std::vector<std::vector<PhantomNodeWithDistance>>
GetPhantomNodesInRange(const datafacade::BaseDataFacade &facade, GetPhantomNodesInRange(const datafacade::BaseDataFacade &facade,
const api::BaseParameters &parameters, const api::BaseParameters &parameters,
const std::vector<double> radiuses) const const std::vector<double> radiuses,
bool use_all_edges = false) const
{ {
std::vector<std::vector<PhantomNodeWithDistance>> phantom_nodes( std::vector<std::vector<PhantomNodeWithDistance>> phantom_nodes(
parameters.coordinates.size()); parameters.coordinates.size());
@@ -171,12 +172,13 @@ class BasePlugin
radiuses[i], radiuses[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range, parameters.bearings[i]->range,
approach); approach,
use_all_edges);
} }
else else
{ {
phantom_nodes[i] = facade.NearestPhantomNodesInRange( phantom_nodes[i] = facade.NearestPhantomNodesInRange(
parameters.coordinates[i], radiuses[i], approach); parameters.coordinates[i], radiuses[i], approach, use_all_edges);
} }
} }
@@ -268,6 +270,7 @@ class BasePlugin
const bool use_bearings = !parameters.bearings.empty(); const bool use_bearings = !parameters.bearings.empty();
const bool use_radiuses = !parameters.radiuses.empty(); const bool use_radiuses = !parameters.radiuses.empty();
const bool use_approaches = !parameters.approaches.empty(); const bool use_approaches = !parameters.approaches.empty();
const bool use_all_edges = parameters.snapping == api::BaseParameters::SnappingType::Any;
BOOST_ASSERT(parameters.IsValid()); BOOST_ASSERT(parameters.IsValid());
for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size())) for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
@@ -294,7 +297,8 @@ class BasePlugin
*parameters.radiuses[i], *parameters.radiuses[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range, parameters.bearings[i]->range,
approach); approach,
use_all_edges);
} }
else else
{ {
@@ -303,7 +307,8 @@ class BasePlugin
parameters.coordinates[i], parameters.coordinates[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range, parameters.bearings[i]->range,
approach); approach,
use_all_edges);
} }
} }
else else
@@ -312,13 +317,16 @@ class BasePlugin
{ {
phantom_node_pairs[i] = phantom_node_pairs[i] =
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i], *parameters.radiuses[i], approach); parameters.coordinates[i],
*parameters.radiuses[i],
approach,
use_all_edges);
} }
else else
{ {
phantom_node_pairs[i] = phantom_node_pairs[i] =
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i], approach); parameters.coordinates[i], approach, use_all_edges);
} }
} }
@@ -89,7 +89,6 @@ class EdgeBasedGraphFactory
// The following get access functions destroy the content in the factory // The following get access functions destroy the content in the factory
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges); void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
void GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSegment> &nodes); void GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSegment> &nodes);
void GetStartPointMarkers(std::vector<bool> &node_is_startpoint);
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights); void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
void GetEdgeBasedNodeDurations(std::vector<EdgeWeight> &output_node_durations); void GetEdgeBasedNodeDurations(std::vector<EdgeWeight> &output_node_durations);
void GetEdgeBasedNodeDistances(std::vector<EdgeDistance> &output_node_distances); void GetEdgeBasedNodeDistances(std::vector<EdgeDistance> &output_node_distances);
@@ -112,10 +111,6 @@ class EdgeBasedGraphFactory
std::vector<ConditionalTurnPenalty> std::vector<ConditionalTurnPenalty>
IndexConditionals(std::vector<Conditional> &&conditionals) const; IndexConditionals(std::vector<Conditional> &&conditionals) const;
//! maps index from m_edge_based_node_list to ture/false if the node is an entry point to the
//! graph
std::vector<bool> m_edge_based_node_is_startpoint;
//! node weights that indicate the length of the segment (node based) represented by the //! node weights that indicate the length of the segment (node based) represented by the
//! edge-based node //! edge-based node
std::vector<EdgeWeight> m_edge_based_node_weights; std::vector<EdgeWeight> m_edge_based_node_weights;
@@ -22,7 +22,9 @@ struct EdgeBasedNodeSegment
EdgeBasedNodeSegment() EdgeBasedNodeSegment()
: forward_segment_id{SPECIAL_SEGMENTID, false}, : forward_segment_id{SPECIAL_SEGMENTID, false},
reverse_segment_id{SPECIAL_SEGMENTID, false}, u(SPECIAL_NODEID), v(SPECIAL_NODEID), reverse_segment_id{SPECIAL_SEGMENTID, false}, u(SPECIAL_NODEID), v(SPECIAL_NODEID),
fwd_segment_position(std::numeric_limits<unsigned short>::max()) fwd_segment_position(std::numeric_limits<unsigned short>::max() >>
1), // >> 1 because we've only got 15 bits
is_startpoint(false)
{ {
} }
@@ -30,9 +32,10 @@ struct EdgeBasedNodeSegment
const SegmentID reverse_segment_id_, const SegmentID reverse_segment_id_,
NodeID u, NodeID u,
NodeID v, NodeID v,
unsigned short fwd_segment_position) unsigned short fwd_segment_position,
bool is_startpoint_)
: forward_segment_id(forward_segment_id_), reverse_segment_id(reverse_segment_id_), u(u), : forward_segment_id(forward_segment_id_), reverse_segment_id(reverse_segment_id_), u(u),
v(v), fwd_segment_position(fwd_segment_position) v(v), fwd_segment_position(fwd_segment_position), is_startpoint(is_startpoint_)
{ {
BOOST_ASSERT(forward_segment_id.enabled || reverse_segment_id.enabled); BOOST_ASSERT(forward_segment_id.enabled || reverse_segment_id.enabled);
} }
@@ -41,7 +44,8 @@ struct EdgeBasedNodeSegment
SegmentID reverse_segment_id; // edge-based graph node ID in reverse direction (v->u if exists) SegmentID reverse_segment_id; // edge-based graph node ID in reverse direction (v->u if exists)
NodeID u; // node-based graph node ID of the start node NodeID u; // node-based graph node ID of the start node
NodeID v; // node-based graph node ID of the target node NodeID v; // node-based graph node ID of the target node
unsigned short fwd_segment_position; // segment id in a compressed geometry unsigned short fwd_segment_position : 15; // segment id in a compressed geometry
bool is_startpoint : 1;
}; };
} }
} }
-2
View File
@@ -85,7 +85,6 @@ class Extractor
// output data // output data
EdgeBasedNodeDataContainer &edge_based_nodes_container, EdgeBasedNodeDataContainer &edge_based_nodes_container,
std::vector<EdgeBasedNodeSegment> &edge_based_node_segments, std::vector<EdgeBasedNodeSegment> &edge_based_node_segments,
std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights, std::vector<EdgeWeight> &edge_based_node_weights,
std::vector<EdgeDuration> &edge_based_node_durations, std::vector<EdgeDuration> &edge_based_node_durations,
std::vector<EdgeDistance> &edge_based_node_distances, std::vector<EdgeDistance> &edge_based_node_distances,
@@ -97,7 +96,6 @@ class Extractor
const std::vector<EdgeBasedNodeSegment> &input_node_segments, const std::vector<EdgeBasedNodeSegment> &input_node_segments,
EdgeBasedNodeDataContainer &nodes_container) const; EdgeBasedNodeDataContainer &nodes_container) const;
void BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_segments, void BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_segments,
std::vector<bool> node_is_startpoint,
const std::vector<util::Coordinate> &coordinates); const std::vector<util::Coordinate> &coordinates);
std::shared_ptr<RestrictionMap> LoadRestrictionMap(); std::shared_ptr<RestrictionMap> LoadRestrictionMap();
+29
View File
@@ -692,6 +692,35 @@ 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;
}
}
return true; return true;
} }
+11 -1
View File
@@ -162,6 +162,13 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
(-approach_type % (-approach_type %
';')[ph::bind(&engine::api::BaseParameters::approaches, qi::_r1) = qi::_1]; ';')[ph::bind(&engine::api::BaseParameters::approaches, qi::_r1) = qi::_1];
snapping_type.add("default", engine::api::BaseParameters::SnappingType::Default)(
"any", engine::api::BaseParameters::SnappingType::Any);
snapping_rule =
qi::lit("snapping=") >
snapping_type[ph::bind(&engine::api::BaseParameters::snapping, qi::_r1) = qi::_1];
exclude_rule = qi::lit("exclude=") > exclude_rule = qi::lit("exclude=") >
(qi::as_string[+qi::char_("a-zA-Z0-9")] % (qi::as_string[+qi::char_("a-zA-Z0-9")] %
',')[ph::bind(&engine::api::BaseParameters::exclude, qi::_r1) = qi::_1]; ',')[ph::bind(&engine::api::BaseParameters::exclude, qi::_r1) = qi::_1];
@@ -171,7 +178,8 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
| bearings_rule(qi::_r1) // | bearings_rule(qi::_r1) //
| generate_hints_rule(qi::_r1) // | generate_hints_rule(qi::_r1) //
| approach_rule(qi::_r1) // | approach_rule(qi::_r1) //
| exclude_rule(qi::_r1); | exclude_rule(qi::_r1) //
| snapping_rule(qi::_r1);
} }
protected: protected:
@@ -197,8 +205,10 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
qi::rule<Iterator, unsigned char()> base64_char; qi::rule<Iterator, unsigned char()> base64_char;
qi::rule<Iterator, std::string()> polyline_chars; qi::rule<Iterator, std::string()> polyline_chars;
qi::rule<Iterator, double()> unlimited_rule; qi::rule<Iterator, double()> unlimited_rule;
qi::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;
}; };
} }
} }
+3520 -3532
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -1,13 +1,13 @@
{ {
"name": "osrm", "name": "osrm",
"version": "5.20.1-rc.2", "version": "5.21.0-customsnapping.2",
"private": false, "private": false,
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.", "description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
"dependencies": { "dependencies": {
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"nan": "^2.11.1", "nan": "^2.11.1",
"node-cmake": "^2.3.2", "node-cmake": "^2.3.2",
"node-pre-gyp": "^0.6.36", "node-pre-gyp": "^0.12.0",
"rimraf": "^2.5.4" "rimraf": "^2.5.4"
}, },
"browserify": { "browserify": {
@@ -47,14 +47,14 @@
"csv-stringify": "^3.0.0", "csv-stringify": "^3.0.0",
"cucumber": "^1.2.1", "cucumber": "^1.2.1",
"d3-queue": "^2.0.3", "d3-queue": "^2.0.3",
"docbox": "^1.0.6", "docbox": "^1.0.11",
"documentation": "^4.0.0-rc.1", "documentation": "^4.0.0-rc.1",
"eslint": "^2.4.0", "eslint": "^5.10.0",
"faucet": "^0.0.1", "faucet": "^0.0.1",
"jsonpath": "^1.0.0", "jsonpath": "^1.0.0",
"node-timeout": "0.0.4", "node-timeout": "0.0.4",
"polyline": "^0.2.0", "polyline": "^0.2.0",
"request": "^2.69.0", "request": "^2.88.0",
"tape": "^4.7.0", "tape": "^4.7.0",
"turf": "^3.0.14", "turf": "^3.0.14",
"xmlbuilder": "^4.2.1" "xmlbuilder": "^4.2.1"
+4 -17
View File
@@ -7,6 +7,7 @@ Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers") Handlers = require("lib/way_handlers")
find_access_tag = require("lib/access").find_access_tag find_access_tag = require("lib/access").find_access_tag
limit = require("lib/maxspeed").limit limit = require("lib/maxspeed").limit
Measure = require("lib/measure")
function setup() function setup()
local default_speed = 15 local default_speed = 15
@@ -206,20 +207,6 @@ function setup()
} }
end end
local function parse_maxspeed(source)
if not source then
return 0
end
local n = tonumber(source:match("%d*"))
if not n then
n = 0
end
if string.match(source, "mph") or string.match(source, "mp/h") then
n = (n*1609)/1000
end
return n
end
function process_node(profile, node, result) function process_node(profile, node, result)
-- parse access and barrier tags -- parse access and barrier tags
local highway = node:get_value_by_key("highway") local highway = node:get_value_by_key("highway")
@@ -276,9 +263,9 @@ function handle_bicycle_tags(profile,way,result,data)
-- other tags -- other tags
data.junction = way:get_value_by_key("junction") data.junction = way:get_value_by_key("junction")
data.maxspeed = parse_maxspeed(way:get_value_by_key ( "maxspeed") ) data.maxspeed = Measure.get_max_speed(way:get_value_by_key ("maxspeed")) or 0
data.maxspeed_forward = parse_maxspeed(way:get_value_by_key( "maxspeed:forward")) data.maxspeed_forward = Measure.get_max_speed(way:get_value_by_key("maxspeed:forward")) or 0
data.maxspeed_backward = parse_maxspeed(way:get_value_by_key( "maxspeed:backward")) data.maxspeed_backward = Measure.get_max_speed(way:get_value_by_key("maxspeed:backward")) or 0
data.barrier = way:get_value_by_key("barrier") data.barrier = way:get_value_by_key("barrier")
data.oneway = way:get_value_by_key("oneway") data.oneway = way:get_value_by_key("oneway")
data.oneway_bicycle = way:get_value_by_key("oneway:bicycle") data.oneway_bicycle = way:get_value_by_key("oneway:bicycle")
+1
View File
@@ -269,6 +269,7 @@ function setup()
["at:rural"] = 100, ["at:rural"] = 100,
["at:trunk"] = 100, ["at:trunk"] = 100,
["be:motorway"] = 120, ["be:motorway"] = 120,
["be-vlg:rural"] = 70,
["by:urban"] = 60, ["by:urban"] = 60,
["by:motorway"] = 110, ["by:motorway"] = 110,
["ch:rural"] = 80, ["ch:rural"] = 80,
+19
View File
@@ -6,6 +6,18 @@ Measure = {}
local inch_to_meters = 0.0254 local inch_to_meters = 0.0254
local feet_to_inches = 12 local feet_to_inches = 12
local pound_to_kilograms = 0.45359237 local pound_to_kilograms = 0.45359237
local miles_to_kilometers = 1.609
-- Parse speed value as kilometers by hours.
function Measure.parse_value_speed(source)
local n = tonumber(source:match("%d*"))
if n then
if string.match(source, "mph") or string.match(source, "mp/h") then
n = n * miles_to_kilometers
end
return n
end
end
--- Parse string as a height in meters. --- Parse string as a height in meters.
--- according to http://wiki.openstreetmap.org/wiki/Key:maxheight --- according to http://wiki.openstreetmap.org/wiki/Key:maxheight
@@ -42,6 +54,13 @@ function Measure.parse_value_kilograms(value)
end end
end end
--- Get maxspeed of specified way in kilometers by hours.
function Measure.get_max_speed(raw_value)
if raw_value then
return Measure.parse_value_speed(raw_value)
end
end
-- default maxheight value defined in https://wiki.openstreetmap.org/wiki/Key:maxheight#Non-numerical_values -- default maxheight value defined in https://wiki.openstreetmap.org/wiki/Key:maxheight#Non-numerical_values
local default_maxheight = 4.5 local default_maxheight = 4.5
-- Available Non numerical values equal to 4.5; below_default and no_indications are not considered -- Available Non numerical values equal to 4.5; below_default and no_indications are not considered
+4 -7
View File
@@ -432,7 +432,7 @@ end
-- maxspeed and advisory maxspeed -- maxspeed and advisory maxspeed
function WayHandlers.maxspeed(profile,way,result,data) function WayHandlers.maxspeed(profile,way,result,data)
local keys = Sequence { 'maxspeed:advisory', 'maxspeed' } local keys = Sequence { 'maxspeed:advisory', 'maxspeed', 'source:maxspeed', 'maxspeed:type' }
local forward, backward = Tags.get_forward_backward_by_set(way,data,keys) local forward, backward = Tags.get_forward_backward_by_set(way,data,keys)
forward = WayHandlers.parse_maxspeed(forward,profile) forward = WayHandlers.parse_maxspeed(forward,profile)
backward = WayHandlers.parse_maxspeed(backward,profile) backward = WayHandlers.parse_maxspeed(backward,profile)
@@ -450,12 +450,9 @@ function WayHandlers.parse_maxspeed(source,profile)
if not source then if not source then
return 0 return 0
end end
local n = tonumber(source:match("%d*"))
if n then local n = Measure.get_max_speed(source)
if string.match(source, "mph") or string.match(source, "mp/h") then if not n then
n = (n*1609)/1000
end
else
-- parse maxspeed like FR:urban -- parse maxspeed like FR:urban
source = string.lower(source) source = string.lower(source)
n = profile.maxspeed_table[source] n = profile.maxspeed_table[source]
+2 -1
View File
@@ -213,7 +213,8 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
}); });
} }
auto candidates_lists = GetPhantomNodesInRange(facade, tidied.parameters, search_radiuses); auto candidates_lists =
GetPhantomNodesInRange(facade, tidied.parameters, search_radiuses, true);
filterCandidates(tidied.parameters.coordinates, candidates_lists); filterCandidates(tidied.parameters.coordinates, candidates_lists);
if (std::all_of(candidates_lists.begin(), if (std::all_of(candidates_lists.begin(),
+5 -1
View File
@@ -95,6 +95,8 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
return Error("NoTable", "No table found", result); return Error("NoTable", "No table found", result);
} }
std::vector<api::TableAPI::TableCellRef> estimated_pairs;
// 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)
{ {
@@ -127,6 +129,8 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
{ {
result_tables_pair.second[table_index] = distance_estimate; result_tables_pair.second[table_index] = distance_estimate;
} }
estimated_pairs.emplace_back(row, column);
} }
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 &&
@@ -150,7 +154,7 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
} }
api::TableAPI table_api{facade, params}; api::TableAPI table_api{facade, params};
table_api.MakeResponse(result_tables_pair, snapped_phantoms, result); table_api.MakeResponse(result_tables_pair, snapped_phantoms, estimated_pairs, result);
return Status::Ok; return Status::Ok;
} }
+12 -1
View File
@@ -294,6 +294,7 @@ struct SpeedLayer : public vtzero::layer_builder
vtzero::index_value key_duration; vtzero::index_value key_duration;
vtzero::index_value key_name; vtzero::index_value key_name;
vtzero::index_value key_rate; vtzero::index_value key_rate;
vtzero::index_value key_is_startpoint;
SpeedLayer(vtzero::tile_builder &tile) SpeedLayer(vtzero::tile_builder &tile)
: layer_builder(tile, "speeds"), uint_index(*this), double_index(*this), : layer_builder(tile, "speeds"), uint_index(*this), double_index(*this),
@@ -302,7 +303,8 @@ struct SpeedLayer : public vtzero::layer_builder
key_datasource(add_key_without_dup_check("datasource")), key_datasource(add_key_without_dup_check("datasource")),
key_weight(add_key_without_dup_check("weight")), key_weight(add_key_without_dup_check("weight")),
key_duration(add_key_without_dup_check("duration")), key_duration(add_key_without_dup_check("duration")),
key_name(add_key_without_dup_check("name")), key_rate(add_key_without_dup_check("rate")) key_name(add_key_without_dup_check("name")), key_rate(add_key_without_dup_check("rate")),
key_is_startpoint(add_key_without_dup_check("is_startpoint"))
{ {
} }
@@ -349,6 +351,11 @@ class SpeedLayerFeatureBuilder : public vtzero::linestring_feature_builder
void set_rate(double value) { add_property(m_layer.key_rate, m_layer.double_index(value)); } void set_rate(double value) { add_property(m_layer.key_rate, m_layer.double_index(value)); }
void set_is_startpoint(bool value)
{
add_property(m_layer.key_is_startpoint, m_layer.bool_index(value));
}
}; // class SpeedLayerFeatureBuilder }; // class SpeedLayerFeatureBuilder
struct TurnsLayer : public vtzero::layer_builder struct TurnsLayer : public vtzero::layer_builder
@@ -485,6 +492,8 @@ void encodeVectorTile(const DataFacadeBase &facade,
const auto reverse_datasource_idx = reverse_datasource_range( const auto reverse_datasource_idx = reverse_datasource_range(
reverse_datasource_range.size() - edge.fwd_segment_position - 1); reverse_datasource_range.size() - edge.fwd_segment_position - 1);
const auto is_startpoint = edge.is_startpoint;
const auto component_id = facade.GetComponentID(edge.forward_segment_id.id); const auto component_id = facade.GetComponentID(edge.forward_segment_id.id);
const auto name_id = facade.GetNameIndex(edge.forward_segment_id.id); const auto name_id = facade.GetNameIndex(edge.forward_segment_id.id);
auto name = facade.GetNameForID(name_id); auto name = facade.GetNameForID(name_id);
@@ -516,6 +525,7 @@ void encodeVectorTile(const DataFacadeBase &facade,
fbuilder.set_duration(forward_duration / 10.0); fbuilder.set_duration(forward_duration / 10.0);
fbuilder.set_name(name); fbuilder.set_name(name);
fbuilder.set_rate(forward_rate / 10.0); fbuilder.set_rate(forward_rate / 10.0);
fbuilder.set_is_startpoint(is_startpoint);
fbuilder.commit(); fbuilder.commit();
} }
@@ -549,6 +559,7 @@ void encodeVectorTile(const DataFacadeBase &facade,
fbuilder.set_duration(reverse_duration / 10.0); fbuilder.set_duration(reverse_duration / 10.0);
fbuilder.set_name(name); fbuilder.set_name(name);
fbuilder.set_rate(reverse_rate / 10.0); fbuilder.set_rate(reverse_rate / 10.0);
fbuilder.set_is_startpoint(is_startpoint);
fbuilder.commit(); fbuilder.commit();
} }
+2 -10
View File
@@ -95,12 +95,6 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSe
swap(nodes, m_edge_based_node_segments); swap(nodes, m_edge_based_node_segments);
} }
void EdgeBasedGraphFactory::GetStartPointMarkers(std::vector<bool> &node_is_startpoint)
{
using std::swap; // Koenig swap
swap(m_edge_based_node_is_startpoint, node_is_startpoint);
}
void EdgeBasedGraphFactory::GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights) void EdgeBasedGraphFactory::GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights)
{ {
using std::swap; // Koenig swap using std::swap; // Koenig swap
@@ -229,10 +223,9 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N
edge_id_to_segment_id(nbe_to_ebn_mapping[edge_id_2]), edge_id_to_segment_id(nbe_to_ebn_mapping[edge_id_2]),
current_edge_source_coordinate_id, current_edge_source_coordinate_id,
current_edge_target_coordinate_id, current_edge_target_coordinate_id,
i); i,
forward_data.flags.startpoint || reverse_data.flags.startpoint);
m_edge_based_node_is_startpoint.push_back(forward_data.flags.startpoint ||
reverse_data.flags.startpoint);
current_edge_source_coordinate_id = current_edge_target_coordinate_id; current_edge_source_coordinate_id = current_edge_target_coordinate_id;
} }
@@ -427,7 +420,6 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
} }
} }
BOOST_ASSERT(m_edge_based_node_segments.size() == m_edge_based_node_is_startpoint.size());
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_weights.size()); BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_weights.size());
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_durations.size()); BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_durations.size());
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_distances.size()); BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_distances.size());
+8 -23
View File
@@ -239,7 +239,6 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
EdgeBasedNodeDataContainer edge_based_nodes_container; EdgeBasedNodeDataContainer edge_based_nodes_container;
std::vector<EdgeBasedNodeSegment> edge_based_node_segments; std::vector<EdgeBasedNodeSegment> edge_based_node_segments;
util::DeallocatingVector<EdgeBasedEdge> edge_based_edge_list; util::DeallocatingVector<EdgeBasedEdge> edge_based_edge_list;
std::vector<bool> node_is_startpoint;
std::vector<EdgeWeight> edge_based_node_weights; std::vector<EdgeWeight> edge_based_node_weights;
std::vector<EdgeDuration> edge_based_node_durations; std::vector<EdgeDuration> edge_based_node_durations;
std::vector<EdgeDistance> edge_based_node_distances; std::vector<EdgeDistance> edge_based_node_distances;
@@ -320,7 +319,6 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
scripting_environment, scripting_environment,
edge_based_nodes_container, edge_based_nodes_container,
edge_based_node_segments, edge_based_node_segments,
node_is_startpoint,
edge_based_node_weights, edge_based_node_weights,
edge_based_node_durations, edge_based_node_durations,
edge_based_node_distances, edge_based_node_distances,
@@ -362,7 +360,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
util::Log() << "Building r-tree ..."; util::Log() << "Building r-tree ...";
TIMER_START(rtree); TIMER_START(rtree);
BuildRTree(std::move(edge_based_node_segments), std::move(node_is_startpoint), coordinates); BuildRTree(std::move(edge_based_node_segments), coordinates);
TIMER_STOP(rtree); TIMER_STOP(rtree);
@@ -737,7 +735,6 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
// output data // output data
EdgeBasedNodeDataContainer &edge_based_nodes_container, EdgeBasedNodeDataContainer &edge_based_nodes_container,
std::vector<EdgeBasedNodeSegment> &edge_based_node_segments, std::vector<EdgeBasedNodeSegment> &edge_based_node_segments,
std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights, std::vector<EdgeWeight> &edge_based_node_weights,
std::vector<EdgeDuration> &edge_based_node_durations, std::vector<EdgeDuration> &edge_based_node_durations,
std::vector<EdgeDistance> &edge_based_node_distances, std::vector<EdgeDistance> &edge_based_node_distances,
@@ -788,7 +785,6 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list); edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list);
edge_based_graph_factory.GetEdgeBasedNodeSegments(edge_based_node_segments); edge_based_graph_factory.GetEdgeBasedNodeSegments(edge_based_node_segments);
edge_based_graph_factory.GetStartPointMarkers(node_is_startpoint);
edge_based_graph_factory.GetEdgeBasedNodeWeights(edge_based_node_weights); edge_based_graph_factory.GetEdgeBasedNodeWeights(edge_based_node_weights);
edge_based_graph_factory.GetEdgeBasedNodeDurations(edge_based_node_durations); edge_based_graph_factory.GetEdgeBasedNodeDurations(edge_based_node_durations);
edge_based_graph_factory.GetEdgeBasedNodeDistances(edge_based_node_distances); edge_based_graph_factory.GetEdgeBasedNodeDistances(edge_based_node_distances);
@@ -803,35 +799,24 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
Saves tree into '.ramIndex' and leaves into '.fileIndex'. Saves tree into '.ramIndex' and leaves into '.fileIndex'.
*/ */
void Extractor::BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_segments, void Extractor::BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_segments,
std::vector<bool> node_is_startpoint,
const std::vector<util::Coordinate> &coordinates) const std::vector<util::Coordinate> &coordinates)
{ {
util::Log() << "Constructing r-tree of " << edge_based_node_segments.size() util::Log() << "Constructing r-tree of " << edge_based_node_segments.size()
<< " segments build on-top of " << coordinates.size() << " coordinates"; << " segments build on-top of " << coordinates.size() << " coordinates";
BOOST_ASSERT(node_is_startpoint.size() == edge_based_node_segments.size());
// Filter node based edges based on startpoint // Filter node based edges based on startpoint
auto out_iter = edge_based_node_segments.begin(); auto start_point_count = std::accumulate(edge_based_node_segments.begin(),
auto in_iter = edge_based_node_segments.begin(); edge_based_node_segments.end(),
for (auto index : util::irange<std::size_t>(0UL, node_is_startpoint.size())) 0,
{ [](const size_t so_far, const auto &segment) {
BOOST_ASSERT(in_iter != edge_based_node_segments.end()); return so_far + (segment.is_startpoint ? 1 : 0);
if (node_is_startpoint[index]) });
{ if (start_point_count == 0)
*out_iter = *in_iter;
out_iter++;
}
in_iter++;
}
auto new_size = out_iter - edge_based_node_segments.begin();
if (new_size == 0)
{ {
throw util::exception("There are no snappable edges left after processing. Are you " throw util::exception("There are no snappable edges left after processing. Are you "
"setting travel modes correctly in the profile? Cannot continue." + "setting travel modes correctly in the profile? Cannot continue." +
SOURCE_REF); SOURCE_REF);
} }
edge_based_node_segments.resize(new_size);
TIMER_START(construction); TIMER_START(construction);
util::StaticRTree<EdgeBasedNodeSegment> rtree( util::StaticRTree<EdgeBasedNodeSegment> rtree(
+1
View File
@@ -148,6 +148,7 @@
{"key": "maxspeed", "value": "AT:rural"}, {"key": "maxspeed", "value": "AT:rural"},
{"key": "maxspeed", "value": "AT:trunk"}, {"key": "maxspeed", "value": "AT:trunk"},
{"key": "maxspeed", "value": "BE:motorway"}, {"key": "maxspeed", "value": "BE:motorway"},
{"key": "maxspeed", "value": "BE-VLG:rural"},
{"key": "maxspeed", "value": "BY:urban"}, {"key": "maxspeed", "value": "BY:urban"},
{"key": "maxspeed", "value": "BY:motorway"}, {"key": "maxspeed", "value": "BY:motorway"},
{"key": "maxspeed", "value": "CH:rural"}, {"key": "maxspeed", "value": "CH:rural"},
+1 -1
View File
@@ -10,7 +10,7 @@ exports.three_test_coordinates = [[7.41337, 43.72956],
exports.two_test_coordinates = exports.three_test_coordinates.slice(0, 2) exports.two_test_coordinates = exports.three_test_coordinates.slice(0, 2)
exports.test_tile = {'at': [17059, 11948, 15], 'size': 148750}; exports.test_tile = {'at': [17059, 11948, 15], 'size': 156624};
// Test files generated by the routing engine; check test/data // Test files generated by the routing engine; check test/data
if (process.env.OSRM_DATA_PATH !== undefined) { if (process.env.OSRM_DATA_PATH !== undefined) {
+20
View File
@@ -606,3 +606,23 @@ test('route: route in Monaco without motorways', function(assert) {
}); });
}); });
test('route: throws on invalid snapping values', function (assert) {
assert.plan(1);
var osrm = new OSRM(monaco_path);
var options = {
steps: true,
coordinates: three_test_coordinates.concat(three_test_coordinates),
snapping: "zing"
};
assert.throws(function () { osrm.route(options, function (err, response) { console.error(`response: ${response}`); console.error(`error: ${err}`); }); },
/'snapping' param must be one of \[default, any\]/);
});
test('route: snapping parameter passed through OK', function(assert) {
assert.plan(2);
var osrm = new OSRM(monaco_path);
osrm.route({snapping: "any", coordinates: [[7.448205209414596,43.754001097311544],[7.447122039202185,43.75306156811368]]}, function(err, route) {
assert.ifError(err);
assert.equal(Math.round(route.routes[0].distance * 10), 1314); // Round it to nearest 0.1m to eliminate floating point comparison error
});
});
+19 -2
View File
@@ -48,6 +48,21 @@ test('table: test annotations paramater combination', function(assert) {
}); });
}); });
test('table: snapping parameter passed through OK', function(assert) {
assert.plan(2);
var osrm = new OSRM(data_path);
var options = {
coordinates: [[7.448205209414596,43.754001097311544],[7.447122039202185,43.75306156811368]],
annotations: ['duration', 'distance'],
snapping: 'any'
};
console.log(options);
osrm.table(options, function(err, result) {
assert.ifError(err);
assert.equal(Math.round(result.distances[0][1] * 10), 1315); // Round it to nearest 0.1m to eliminate floating point comparison error
});
});
test('table: returns buffer', function(assert) { test('table: returns buffer', function(assert) {
assert.plan(3); assert.plan(3);
var osrm = new OSRM(data_path); var osrm = new OSRM(data_path);
@@ -234,7 +249,7 @@ tables.forEach(function(annotation) {
}); });
test('table: ' + annotation + ' table in Monaco without motorways', function(assert) { test('table: ' + annotation + ' table in Monaco without motorways', function(assert) {
assert.plan(1); assert.plan(2);
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'}); var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
var options = { var options = {
coordinates: two_test_coordinates, coordinates: two_test_coordinates,
@@ -243,11 +258,12 @@ tables.forEach(function(annotation) {
}; };
osrm.table(options, function(err, response) { osrm.table(options, function(err, response) {
assert.equal(response[annotation].length, 2); assert.equal(response[annotation].length, 2);
assert.strictEqual(response.fallback_speed_cells, undefined);
}); });
}); });
test('table: ' + annotation + ' table in Monaco with fallback speeds', function(assert) { test('table: ' + annotation + ' table in Monaco with fallback speeds', function(assert) {
assert.plan(1); assert.plan(2);
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'}); var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
var options = { var options = {
coordinates: two_test_coordinates, coordinates: two_test_coordinates,
@@ -257,6 +273,7 @@ tables.forEach(function(annotation) {
}; };
osrm.table(options, function(err, response) { osrm.table(options, function(err, response) {
assert.equal(response[annotation].length, 2); assert.equal(response[annotation].length, 2);
assert.equal(response['fallback_speed_cells'].length, 0);
}); });
}); });
+12 -6
View File
@@ -229,7 +229,8 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
const float /*max_distance*/, const float /*max_distance*/,
const int /*bearing*/, const int /*bearing*/,
const int /*bearing_range*/, const int /*bearing_range*/,
const Approach /*approach*/) const override const Approach /*approach*/,
const bool /*use_all_edges*/) const override
{ {
return {}; return {};
} }
@@ -237,7 +238,8 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate /*input_coordinate*/, NearestPhantomNodesInRange(const util::Coordinate /*input_coordinate*/,
const float /*max_distance*/, const float /*max_distance*/,
const Approach /*approach*/) const override const Approach /*approach*/,
const bool /*use_all_edges*/) const override
{ {
return {}; return {};
} }
@@ -282,7 +284,8 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/,
const Approach /*approach*/) const override const Approach /*approach*/,
const bool /* use_all_edges */) const override
{ {
return {}; return {};
} }
@@ -290,7 +293,8 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/,
const double /*max_distance*/, const double /*max_distance*/,
const Approach /*approach*/) const override const Approach /*approach*/,
const bool /* use_all_edges */) const override
{ {
return {}; return {};
} }
@@ -300,7 +304,8 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
const double /*max_distance*/, const double /*max_distance*/,
const int /*bearing*/, const int /*bearing*/,
const int /*bearing_range*/, const int /*bearing_range*/,
const Approach /*approach*/) const override const Approach /*approach*/,
const bool /* use_all_edges */) const override
{ {
return {}; return {};
} }
@@ -309,7 +314,8 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/,
const int /*bearing*/, const int /*bearing*/,
const int /*bearing_range*/, const int /*bearing_range*/,
const Approach /*approach*/) const override const Approach /*approach*/,
const bool /* use_all_edges */) const override
{ {
return {}; return {};
} }
+6 -3
View File
@@ -36,7 +36,7 @@ void validate_feature_layer(vtzero::layer layer)
BOOST_CHECK_EQUAL(layer.version(), 2); BOOST_CHECK_EQUAL(layer.version(), 2);
BOOST_CHECK_EQUAL(to_string(layer.name()), "speeds"); BOOST_CHECK_EQUAL(to_string(layer.name()), "speeds");
BOOST_CHECK_EQUAL(layer.extent(), osrm::util::vector_tile::EXTENT); BOOST_CHECK_EQUAL(layer.extent(), osrm::util::vector_tile::EXTENT);
BOOST_CHECK_EQUAL(layer.key_table().size(), 7); BOOST_CHECK_EQUAL(layer.key_table().size(), 8);
BOOST_CHECK(layer.num_features() > 2500); BOOST_CHECK(layer.num_features() > 2500);
while (auto feature = layer.next_feature()) while (auto feature = layer.next_feature())
@@ -62,6 +62,9 @@ void validate_feature_layer(vtzero::layer layer)
BOOST_CHECK(props.find("is_small") != props.end()); BOOST_CHECK(props.find("is_small") != props.end());
BOOST_CHECK(props["is_small"].type() == typeid(bool)); BOOST_CHECK(props["is_small"].type() == typeid(bool));
BOOST_CHECK(props.find("is_startpoint") != props.end());
BOOST_CHECK(props["is_startpoint"].type() == typeid(bool));
BOOST_CHECK(props.find("datasource") != props.end()); BOOST_CHECK(props.find("datasource") != props.end());
BOOST_CHECK(props["datasource"].type() == typeid(std::string)); BOOST_CHECK(props["datasource"].type() == typeid(std::string));
@@ -73,7 +76,7 @@ void validate_feature_layer(vtzero::layer layer)
std::count_if(layer.value_table().begin(), layer.value_table().end(), [](auto v) { std::count_if(layer.value_table().begin(), layer.value_table().end(), [](auto v) {
return v.type() == vtzero::property_value_type::uint_value; return v.type() == vtzero::property_value_type::uint_value;
}); });
BOOST_CHECK_EQUAL(number_of_uint_values, 77); BOOST_CHECK_EQUAL(number_of_uint_values, 78);
} }
void validate_turn_layer(vtzero::layer layer) void validate_turn_layer(vtzero::layer layer)
@@ -125,7 +128,7 @@ void validate_node_layer(vtzero::layer layer)
BOOST_CHECK_EQUAL(to_string(layer.name()), "osmnodes"); BOOST_CHECK_EQUAL(to_string(layer.name()), "osmnodes");
BOOST_CHECK_EQUAL(layer.extent(), osrm::util::vector_tile::EXTENT); BOOST_CHECK_EQUAL(layer.extent(), osrm::util::vector_tile::EXTENT);
BOOST_CHECK_EQUAL(layer.key_table().size(), 0); BOOST_CHECK_EQUAL(layer.key_table().size(), 0);
BOOST_CHECK_EQUAL(layer.num_features(), 1791); BOOST_CHECK_EQUAL(layer.num_features(), 1810);
while (auto feature = layer.next_feature()) while (auto feature = layer.next_feature())
{ {
+22 -20
View File
@@ -113,7 +113,8 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
const float /*max_distance*/, const float /*max_distance*/,
const int /*bearing*/, const int /*bearing*/,
const int /*bearing_range*/, const int /*bearing_range*/,
const engine::Approach /*approach*/) const override const engine::Approach /*approach*/,
const bool /*use_all_edges*/) const override
{ {
return {}; return {};
} }
@@ -121,7 +122,8 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
std::vector<engine::PhantomNodeWithDistance> std::vector<engine::PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate /*input_coordinate*/, NearestPhantomNodesInRange(const util::Coordinate /*input_coordinate*/,
const float /*max_distance*/, const float /*max_distance*/,
const engine::Approach /*approach*/) const override const engine::Approach /*approach*/,
const bool /*use_all_edges*/) const override
{ {
return {}; return {};
} }
@@ -165,39 +167,39 @@ 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 override
{ {
return {}; return {};
} }
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 double /*max_distance*/,
const double /*max_distance*/, const engine::Approach /*approach*/,
const engine::Approach /*approach*/) const override const bool /* use_all_edges */) const override
{ {
return {}; return {};
} }
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 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 override
{ {
return {}; return {};
} }
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 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 override
{ {
return {}; return {};
} }
+53 -19
View File
@@ -135,6 +135,7 @@ template <unsigned NUM_NODES, unsigned NUM_EDGES> struct RandomGraphFixture
TestData data; TestData data;
data.u = edge_udist(g); data.u = edge_udist(g);
data.v = edge_udist(g); data.v = edge_udist(g);
data.is_startpoint = true;
if (used_edges.find(std::pair<unsigned, unsigned>( if (used_edges.find(std::pair<unsigned, unsigned>(
std::min(data.u, data.v), std::max(data.u, data.v))) == used_edges.end()) std::min(data.u, data.v), std::max(data.u, data.v))) == used_edges.end())
{ {
@@ -151,7 +152,7 @@ template <unsigned NUM_NODES, unsigned NUM_EDGES> struct RandomGraphFixture
struct GraphFixture struct GraphFixture
{ {
GraphFixture(const std::vector<std::pair<FloatLongitude, FloatLatitude>> &input_coords, GraphFixture(const std::vector<std::pair<FloatLongitude, FloatLatitude>> &input_coords,
const std::vector<std::pair<unsigned, unsigned>> &input_edges) const std::vector<std::tuple<unsigned, unsigned, bool>> &input_edges)
{ {
for (unsigned i = 0; i < input_coords.size(); i++) for (unsigned i = 0; i < input_coords.size(); i++)
@@ -162,15 +163,16 @@ struct GraphFixture
for (const auto &pair : input_edges) for (const auto &pair : input_edges)
{ {
TestData d; TestData d;
d.u = pair.first; d.u = std::get<0>(pair);
d.v = pair.second; d.v = std::get<1>(pair);
// We set the forward nodes to the target node-based-node IDs, just // We set the forward nodes to the target node-based-node IDs, just
// so we have something to test against. Because this isn't a real // so we have something to test against. Because this isn't a real
// graph, the actual values aren't important, we just need something // graph, the actual values aren't important, we just need something
// to examine during tests. // to examine during tests.
d.forward_segment_id = {pair.second, true}; d.forward_segment_id = {std::get<1>(pair), true};
d.reverse_segment_id = {pair.first, true}; d.reverse_segment_id = {std::get<0>(pair), true};
d.fwd_segment_position = 0; d.fwd_segment_position = 0;
d.is_startpoint = std::get<2>(pair);
edges.emplace_back(d); edges.emplace_back(d);
} }
} }
@@ -299,7 +301,7 @@ BOOST_FIXTURE_TEST_CASE(construct_multiple_levels_test, TestRandomGraphFixture_M
BOOST_AUTO_TEST_CASE(regression_test) BOOST_AUTO_TEST_CASE(regression_test)
{ {
using Coord = std::pair<FloatLongitude, FloatLatitude>; using Coord = std::pair<FloatLongitude, FloatLatitude>;
using Edge = std::pair<unsigned, unsigned>; using Edge = std::tuple<unsigned, unsigned, bool>;
GraphFixture fixture( GraphFixture fixture(
{ {
Coord{FloatLongitude{0.0}, FloatLatitude{40.0}}, // Coord{FloatLongitude{0.0}, FloatLatitude{40.0}}, //
@@ -313,7 +315,7 @@ BOOST_AUTO_TEST_CASE(regression_test)
Coord{FloatLongitude{105.0}, FloatLatitude{5.0}}, // Coord{FloatLongitude{105.0}, FloatLatitude{5.0}}, //
Coord{FloatLongitude{110.0}, FloatLatitude{0.0}}, // Coord{FloatLongitude{110.0}, FloatLatitude{0.0}}, //
}, },
{Edge(0, 1), Edge(2, 3), Edge(4, 5), Edge(6, 7), Edge(8, 9)}); {Edge(0, 1, true), Edge(2, 3, true), Edge(4, 5, true), Edge(6, 7, true), Edge(8, 9, true)});
TemporaryFile tmp; TemporaryFile tmp;
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture); auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
@@ -335,13 +337,13 @@ BOOST_AUTO_TEST_CASE(regression_test)
BOOST_AUTO_TEST_CASE(radius_regression_test) BOOST_AUTO_TEST_CASE(radius_regression_test)
{ {
using Coord = std::pair<FloatLongitude, FloatLatitude>; using Coord = std::pair<FloatLongitude, FloatLatitude>;
using Edge = std::pair<unsigned, unsigned>; using Edge = std::tuple<unsigned, unsigned, bool>;
GraphFixture fixture( GraphFixture fixture(
{ {
Coord(FloatLongitude{0.0}, FloatLatitude{0.0}), Coord(FloatLongitude{0.0}, FloatLatitude{0.0}),
Coord(FloatLongitude{10.0}, FloatLatitude{10.0}), Coord(FloatLongitude{10.0}, FloatLatitude{10.0}),
}, },
{Edge(0, 1), Edge(1, 0)}); {Edge(0, 1, true), Edge(1, 0, true)});
TemporaryFile tmp; TemporaryFile tmp;
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture); auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
@@ -352,22 +354,54 @@ BOOST_AUTO_TEST_CASE(radius_regression_test)
Coordinate input(FloatLongitude{5.2}, FloatLatitude{5.0}); Coordinate input(FloatLongitude{5.2}, FloatLatitude{5.0});
{ {
auto results = auto results = query.NearestPhantomNodesInRange(
query.NearestPhantomNodesInRange(input, 0.01, osrm::engine::Approach::UNRESTRICTED); input, 0.01, osrm::engine::Approach::UNRESTRICTED, true);
BOOST_CHECK_EQUAL(results.size(), 0); BOOST_CHECK_EQUAL(results.size(), 0);
} }
} }
BOOST_AUTO_TEST_CASE(permissive_edge_snapping)
{
using Coord = std::pair<FloatLongitude, FloatLatitude>;
using Edge = std::tuple<unsigned, unsigned, bool>;
GraphFixture fixture(
{
Coord(FloatLongitude{0.0}, FloatLatitude{0.0}),
Coord(FloatLongitude{0.001}, FloatLatitude{0.001}),
},
{Edge(0, 1, true), Edge(1, 0, false)});
TemporaryFile tmp;
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
TestDataFacade mockfacade;
engine::GeospatialQuery<MiniStaticRTree, TestDataFacade> query(
rtree, fixture.coords, mockfacade);
Coordinate input(FloatLongitude{0.0005}, FloatLatitude{0.0005});
{
auto results = query.NearestPhantomNodesInRange(
input, 1000, osrm::engine::Approach::UNRESTRICTED, false);
BOOST_CHECK_EQUAL(results.size(), 1);
}
{
auto results = query.NearestPhantomNodesInRange(
input, 1000, osrm::engine::Approach::UNRESTRICTED, true);
BOOST_CHECK_EQUAL(results.size(), 2);
}
}
BOOST_AUTO_TEST_CASE(bearing_tests) BOOST_AUTO_TEST_CASE(bearing_tests)
{ {
using Coord = std::pair<FloatLongitude, FloatLatitude>; using Coord = std::pair<FloatLongitude, FloatLatitude>;
using Edge = std::pair<unsigned, unsigned>; using Edge = std::tuple<unsigned, unsigned, bool>;
GraphFixture fixture( GraphFixture fixture(
{ {
Coord(FloatLongitude{0.0}, FloatLatitude{0.0}), Coord(FloatLongitude{0.0}, FloatLatitude{0.0}),
Coord(FloatLongitude{10.0}, FloatLatitude{10.0}), Coord(FloatLongitude{10.0}, FloatLatitude{10.0}),
}, },
{Edge(0, 1), Edge(1, 0)}); {Edge(0, 1, true), Edge(1, 0, true)});
TemporaryFile tmp; TemporaryFile tmp;
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture); auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
@@ -405,20 +439,20 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
} }
{ {
auto results = auto results = query.NearestPhantomNodesInRange(
query.NearestPhantomNodesInRange(input, 11000, osrm::engine::Approach::UNRESTRICTED); input, 11000, osrm::engine::Approach::UNRESTRICTED, true);
BOOST_CHECK_EQUAL(results.size(), 2); BOOST_CHECK_EQUAL(results.size(), 2);
} }
{ {
auto results = query.NearestPhantomNodesInRange( auto results = query.NearestPhantomNodesInRange(
input, 11000, 270, 10, osrm::engine::Approach::UNRESTRICTED); input, 11000, 270, 10, osrm::engine::Approach::UNRESTRICTED, true);
BOOST_CHECK_EQUAL(results.size(), 0); BOOST_CHECK_EQUAL(results.size(), 0);
} }
{ {
auto results = query.NearestPhantomNodesInRange( auto results = query.NearestPhantomNodesInRange(
input, 11000, 45, 10, osrm::engine::Approach::UNRESTRICTED); input, 11000, 45, 10, osrm::engine::Approach::UNRESTRICTED, true);
BOOST_CHECK_EQUAL(results.size(), 2); BOOST_CHECK_EQUAL(results.size(), 2);
BOOST_CHECK(results[0].phantom_node.forward_segment_id.enabled); BOOST_CHECK(results[0].phantom_node.forward_segment_id.enabled);
@@ -434,7 +468,7 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
BOOST_AUTO_TEST_CASE(bbox_search_tests) BOOST_AUTO_TEST_CASE(bbox_search_tests)
{ {
using Coord = std::pair<FloatLongitude, FloatLatitude>; using Coord = std::pair<FloatLongitude, FloatLatitude>;
using Edge = std::pair<unsigned, unsigned>; using Edge = std::tuple<unsigned, unsigned, bool>;
GraphFixture fixture( GraphFixture fixture(
{ {
@@ -444,7 +478,7 @@ BOOST_AUTO_TEST_CASE(bbox_search_tests)
Coord(FloatLongitude{3.0}, FloatLatitude{3.0}), Coord(FloatLongitude{3.0}, FloatLatitude{3.0}),
Coord(FloatLongitude{4.0}, FloatLatitude{4.0}), Coord(FloatLongitude{4.0}, FloatLatitude{4.0}),
}, },
{Edge(0, 1), Edge(1, 2), Edge(2, 3), Edge(3, 4)}); {Edge(0, 1, true), Edge(1, 2, true), Edge(2, 3, true), Edge(3, 4, true)});
TemporaryFile tmp; TemporaryFile tmp;
auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture); auto rtree = make_rtree<MiniStaticRTree>(tmp.path, fixture);
-7040
View File
File diff suppressed because it is too large Load Diff