Merge branch 'master' into sf-performance-move-const-arg2

This commit is contained in:
Siarhei Fedartsou 2022-08-23 17:59:55 +02:00
commit 812908b948
120 changed files with 1819 additions and 1250 deletions

View File

@ -46,7 +46,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v2 uses: actions/setup-node@v3
with: with:
node-version: 12 node-version: 12
- name: Enable Node.js cache - name: Enable Node.js cache
@ -68,12 +68,12 @@ jobs:
./scripts/format.sh && ./scripts/error_on_dirty.sh ./scripts/format.sh && ./scripts/error_on_dirty.sh
node ./scripts/validate_changelog.js node ./scripts/validate_changelog.js
npm run docs && ./scripts/error_on_dirty.sh npm run docs && ./scripts/error_on_dirty.sh
docker-image: docker-image:
needs: format-taginfo-docs needs: format-taginfo-docs
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
continue-on-error: false continue-on-error: false
steps: steps:
- name: Check out the repo - name: Check out the repo
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Enable osm.pbf cache - name: Enable osm.pbf cache
@ -85,7 +85,7 @@ jobs:
v1-berlin-osm-pbf v1-berlin-osm-pbf
- name: Docker build - name: Docker build
run: | run: |
docker build -t osrm-backend-local -f docker/Dockerfile . docker build -t osrm-backend-local -f docker/Dockerfile .
- name: Test Docker image - name: Test Docker image
run: | run: |
if [ ! -f "${PWD}/berlin-latest.osm.pbf" ]; then if [ ! -f "${PWD}/berlin-latest.osm.pbf" ]; then
@ -348,8 +348,7 @@ jobs:
- name: conan-osx-release-node-latest - name: conan-osx-release-node-latest
build_node_package: true build_node_package: true
continue-on-error: true continue-on-error: true
# TODO: Use node 'latest' once supported: https://github.com/actions/setup-node/issues/257 node: latest
node: 16
runs-on: macos-11 runs-on: macos-11
BUILD_TYPE: Release BUILD_TYPE: Release
CCOMPILER: clang CCOMPILER: clang
@ -361,8 +360,7 @@ jobs:
- name: node-latest-conan-linux-release - name: node-latest-conan-linux-release
build_node_package: true build_node_package: true
continue-on-error: true continue-on-error: true
# TODO: Use node 'latest' once supported: https://github.com/actions/setup-node/issues/257 node: latest
node: 16
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TYPE: Release BUILD_TYPE: Release
CLANG_VERSION: 6.0.0 CLANG_VERSION: 6.0.0
@ -373,8 +371,7 @@ jobs:
- name: node-latest-conan-linux-debug - name: node-latest-conan-linux-debug
build_node_package: true build_node_package: true
continue-on-error: true continue-on-error: true
# TODO: Use node 'latest' once supported: https://github.com/actions/setup-node/issues/257 node: latest
node: 16
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TYPE: Debug BUILD_TYPE: Debug
CLANG_VERSION: 6.0.0 CLANG_VERSION: 6.0.0
@ -431,7 +428,7 @@ jobs:
CXXCOMPILER: ${{ matrix.CXXCOMPILER }} CXXCOMPILER: ${{ matrix.CXXCOMPILER }}
CXXFLAGS: ${{ matrix.CXXFLAGS }} CXXFLAGS: ${{ matrix.CXXFLAGS }}
ENABLE_ASSERTIONS: ${{ matrix.ENABLE_ASSERTIONS }} ENABLE_ASSERTIONS: ${{ matrix.ENABLE_ASSERTIONS }}
ENABLE_CLANG_TIDY: ${{ matrix.ENABLE_CLANG_TIDY }} ENABLE_CLANG_TIDY: ${{ matrix.ENABLE_CLANG_TIDY }}
ENABLE_COVERAGE: ${{ matrix.ENABLE_COVERAGE }} ENABLE_COVERAGE: ${{ matrix.ENABLE_COVERAGE }}
ENABLE_GLIBC_WORKAROUND: ${{ matrix.ENABLE_GLIBC_WORKAROUND }} ENABLE_GLIBC_WORKAROUND: ${{ matrix.ENABLE_GLIBC_WORKAROUND }}
ENABLE_CONAN: ${{ matrix.ENABLE_CONAN }} ENABLE_CONAN: ${{ matrix.ENABLE_CONAN }}
@ -444,7 +441,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v2 uses: actions/setup-node@v3
with: with:
node-version: ${{ matrix.node }} node-version: ${{ matrix.node }}
- name: Enable Node.js cache - name: Enable Node.js cache
@ -472,9 +469,9 @@ jobs:
uses: actions/cache@v2 uses: actions/cache@v2
with: with:
path: ${{github.workspace}}/test/cache path: ${{github.workspace}}/test/cache
key: test-${{ matrix.name }}-${{ github.sha }} key: v3-test-${{ matrix.name }}-${{ github.sha }}
restore-keys: | restore-keys: |
test-${{ matrix.name }}- v3-test-${{ matrix.name }}-
- name: Prepare environment - name: Prepare environment
run: | run: |
@ -662,7 +659,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
ci-complete: ci-complete:
runs-on: ubuntu-18.04 runs-on: ubuntu-22.04
needs: [build-test-publish, docker-image, windows] needs: [build-test-publish, docker-image, windows]
steps: steps:
- run: echo "CI complete" - run: echo "CI complete"

View File

@ -1,15 +1,23 @@
# Unreleased # Unreleased
- Changes from 5.26.0 - Changes from 5.26.0
- API: - API:
- CHANGED: Add `data_version` field to responses of all services. [#5387](https://github.com/Project-OSRM/osrm-backend/pull/5387)
- FIXED: Use Boost.Beast to parse HTTP request. [#6294](https://github.com/Project-OSRM/osrm-backend/pull/6294) - FIXED: Use Boost.Beast to parse HTTP request. [#6294](https://github.com/Project-OSRM/osrm-backend/pull/6294)
- FIXED: Fix inefficient osrm-routed connection handling [#6113](https://github.com/Project-OSRM/osrm-backend/pull/6113) - FIXED: Fix inefficient osrm-routed connection handling [#6113](https://github.com/Project-OSRM/osrm-backend/pull/6113)
- NodeJS:
- FIXED: Support `skip_waypoints` in Node bindings [#6060](https://github.com/Project-OSRM/osrm-backend/pull/6060)
- Misc: - Misc:
- CHANGED: missing files list is included in exception message. [#5360](https://github.com/Project-OSRM/osrm-backend/pull/5360)
- CHANGED: Do not use deprecated Callback::Call overload in Node bindings. [#6318](https://github.com/Project-OSRM/osrm-backend/pull/6318)
- FIXED: Fix distance calculation consistency. [#6315](https://github.com/Project-OSRM/osrm-backend/pull/6315)
- FIXED: Fix performance issue after migration to sol2 3.3.0. [#6304](https://github.com/Project-OSRM/osrm-backend/pull/6304) - FIXED: Fix performance issue after migration to sol2 3.3.0. [#6304](https://github.com/Project-OSRM/osrm-backend/pull/6304)
- CHANGED: Pass osm_node_ids by reference in osrm::updater::Updater class. [#6298](https://github.com/Project-OSRM/osrm-backend/pull/6298) - CHANGED: Pass osm_node_ids by reference in osrm::updater::Updater class. [#6298](https://github.com/Project-OSRM/osrm-backend/pull/6298)
- FIXED: Fix bug with reading Set values from Lua scripts. [#6285](https://github.com/Project-OSRM/osrm-backend/pull/6285) - FIXED: Fix bug with reading Set values from Lua scripts. [#6285](https://github.com/Project-OSRM/osrm-backend/pull/6285)
- FIXED: Bug in bicycle profile that caused exceptions if there is a highway=bicycle in the data. [#6296](https://github.com/Project-OSRM/osrm-backend/pull/6296) - FIXED: Bug in bicycle profile that caused exceptions if there is a highway=bicycle in the data. [#6296](https://github.com/Project-OSRM/osrm-backend/pull/6296)
- FIXED: Internal refactoring of identifier types used in data facade [#6044](https://github.com/Project-OSRM/osrm-backend/pull/6044)
- Build: - Build:
- CHANGED: Enable performance-move-const-arg clang-tidy check. [#6319](https://github.com/Project-OSRM/osrm-backend/pull/6319) - CHANGED: Enable performance-move-const-arg clang-tidy check. [#6319](https://github.com/Project-OSRM/osrm-backend/pull/6319)
- CHANGED: Use the latest node on CI. [#6317](https://github.com/Project-OSRM/osrm-backend/pull/6317)
- CHANGED: Migrate Windows CI to GitHub Actions. [#6312](https://github.com/Project-OSRM/osrm-backend/pull/6312) - CHANGED: Migrate Windows CI to GitHub Actions. [#6312](https://github.com/Project-OSRM/osrm-backend/pull/6312)
- ADDED: Add smoke test for Docker image. [#6313](https://github.com/Project-OSRM/osrm-backend/pull/6313) - ADDED: Add smoke test for Docker image. [#6313](https://github.com/Project-OSRM/osrm-backend/pull/6313)
- CHANGED: Update libosmium to version 2.18.0. [#6303](https://github.com/Project-OSRM/osrm-backend/pull/6303) - CHANGED: Update libosmium to version 2.18.0. [#6303](https://github.com/Project-OSRM/osrm-backend/pull/6303)
@ -31,6 +39,11 @@
- FIXED: Fixed Node docs generation check in CI. [#6058](https://github.com/Project-OSRM/osrm-backend/pull/6058) - FIXED: Fixed Node docs generation check in CI. [#6058](https://github.com/Project-OSRM/osrm-backend/pull/6058)
- CHANGED: Docker build, enabled arm64 build layer [#6172](https://github.com/Project-OSRM/osrm-backend/pull/6172) - CHANGED: Docker build, enabled arm64 build layer [#6172](https://github.com/Project-OSRM/osrm-backend/pull/6172)
- CHANGED: Docker build, enabled apt-get update/install caching in separate layer for build phase [#6175](https://github.com/Project-OSRM/osrm-backend/pull/6175) - CHANGED: Docker build, enabled apt-get update/install caching in separate layer for build phase [#6175](https://github.com/Project-OSRM/osrm-backend/pull/6175)
- FIXED: Bump CI complete meta job to ubuntu-20.04 [#6323](https://github.com/Project-OSRM/osrm-backend/pull/6323)
- Routing:
- CHANGED: Lazily generate optional route path data [#6045](https://github.com/Project-OSRM/osrm-backend/pull/6045)
- FIXED: Completed support for no_entry and no_exit turn restrictions. [#5988](https://github.com/Project-OSRM/osrm-backend/pull/5988)
- ADDED: Add support for non-round-trips with a single fixed endpoint. [#6050](https://github.com/Project-OSRM/osrm-backend/pull/6050)
# 5.26.0 # 5.26.0
- Changes from 5.25.0 - Changes from 5.25.0

View File

@ -425,7 +425,7 @@ include_directories(SYSTEM ${MICROTAR_INCLUDE_DIR})
set(MBXGEOM_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/geometry.hpp-0.9.2/include") set(MBXGEOM_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/geometry.hpp-0.9.2/include")
include_directories(SYSTEM ${MBXGEOM_INCLUDE_DIR}) include_directories(SYSTEM ${MBXGEOM_INCLUDE_DIR})
set(CHEAPRULER_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/cheap-ruler-cpp-2.5.4/include") set(CHEAPRULER_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/cheap-ruler-cpp-2778eb8/include")
include_directories(SYSTEM ${CHEAPRULER_INCLUDE_DIR}) include_directories(SYSTEM ${CHEAPRULER_INCLUDE_DIR})
add_library(MICROTAR OBJECT "${CMAKE_CURRENT_SOURCE_DIR}/third_party/microtar/src/microtar.c") add_library(MICROTAR OBJECT "${CMAKE_CURRENT_SOURCE_DIR}/third_party/microtar/src/microtar.c")

View File

@ -507,8 +507,8 @@ Right now, the following combinations are possible:
| true | any | last | **yes** | | true | any | last | **yes** |
| true | any | any | **yes** | | true | any | any | **yes** |
| false | first | last | **yes** | | false | first | last | **yes** |
| false | first | any | no | | false | first | any | **yes** |
| false | any | last | no | | false | any | last | **yes** |
| false | any | any | no | | false | any | any | no |
#### Example Requests #### Example Requests

View File

@ -12,20 +12,14 @@ Prepare directories for dependencies, build and target file location.Target dire
### Bzip2 ### Bzip2
1. Download either from Wolt OSRM mirror or original distribution and unpack. 1. Download from https://sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz
* https://project-osrm.wolt.com/deps/bzip2-1.0.8.tar.gz
* https://sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz
2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree. 2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
3. Issue `nmake /f makefile.msc` 3. Issue `nmake /f makefile.msc`
4. Copy bzlib.h to $target\include and libbz2.lib to $target\lib 4. Copy bzlib.h to $target\include and libbz2.lib to $target\lib
### ZLib ### ZLib
1. Download either from Wolt OSRM mirror or original distribution and unpack. 1. Download https://www.zlib.net/zlib-1.2.11.tar.gz
* https://project-osrm.wolt.com/deps/zlib-1.2.11.tar.gz
* https://www.zlib.net/zlib-1.2.11.tar.gz
2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree. 2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
3. Switch to `contrib\vstudio\vc14` 3. Switch to `contrib\vstudio\vc14`
4. If needed, open `zlibvc.sln` with Visual Studio and retarget to your version of compiler and SDK. 4. If needed, open `zlibvc.sln` with Visual Studio and retarget to your version of compiler and SDK.
@ -34,10 +28,8 @@ Prepare directories for dependencies, build and target file location.Target dire
### ICU ### ICU
1. Download either from Wolt OSRM mirror or original distribution and unpack. 1. Download and unpack.
* https://wolt-project.wolt.com/deps/icu4c-66_1-src.zip
* https://github.com/unicode-org/icu/releases/download/release-66-1/icu4c-66_1-src.zip * https://github.com/unicode-org/icu/releases/download/release-66-1/icu4c-66_1-src.zip
* https://wolt-project.wolt.com/deps/icu4c-66_1-data.zip
* https://github.com/unicode-org/icu/releases/download/release-66-1/icu4c-66_1-data.zip * https://github.com/unicode-org/icu/releases/download/release-66-1/icu4c-66_1-data.zip
2. Do retarget if neededby openinig .\source\allinone\allinone.sln and editing projects 2. Do retarget if neededby openinig .\source\allinone\allinone.sln and editing projects
3. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree. 3. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
@ -48,10 +40,7 @@ Prepare directories for dependencies, build and target file location.Target dire
### Boost ### Boost
1. Download either from Wolt OSRM mirror or original distribution and unpack. 1. Download and unpack https://dl.bintray.com/boostorg/release/1.73.0/source/boost_1_73_0.zip
* https://project-osrm.wolt.com/deps/boost_1_73_0.zip
* https://dl.bintray.com/boostorg/release/1.73.0/source/boost_1_73_0.zip
2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree. 2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
3. Build b2: 3. Build b2:
bootstrap.bat --with-toolset=msvc-14.2 bootstrap.bat --with-toolset=msvc-14.2
@ -61,9 +50,7 @@ Prepare directories for dependencies, build and target file location.Target dire
### Expat ### Expat
1. Download either from Wolt OSRM mirror or original distribution and unpack. 1. Download and unpack https://github.com/libexpat/libexpat/archive/R_2_2_9.zip
* https://project-osrm.wolt.com/deps/libexpat-2_2_9.zip
* https://github.com/libexpat/libexpat/archive/R_2_2_9.zip
2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree. 2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
3. Configure build my calling cmake: 3. Configure build my calling cmake:
mkdir expat\build mkdir expat\build
@ -74,9 +61,7 @@ Prepare directories for dependencies, build and target file location.Target dire
### LUA ### LUA
1. Download either from Wolt OSRM mirror or original distribution and unpack. 1. Download and unpack https://www.lua.org/ftp/lua-5.3.5.tar.gz
* https://project-osrm.wolt.com/deps/lua-5.3.5.tar.gz
* https://www.lua.org/ftp/lua-5.3.5.tar.gz
2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree. 2. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
3. Lua doesn't have native MSVC support, so you have to compile it by hand: 3. Lua doesn't have native MSVC support, so you have to compile it by hand:
cd src cd src
@ -88,9 +73,7 @@ Prepare directories for dependencies, build and target file location.Target dire
### TBB ### TBB
1. Download either from Wolt OSRM mirror or original distribution and unpack. 1. Download and unpack https://github.com/oneapi-src/oneTBB/archive/v2020.2.zip
* https://project-osrm.wolt.com/deps/oneTBB-v2020.2.zip
* https://github.com/oneapi-src/oneTBB/archive/v2020.2.zip
2. Retarget by opening build\vs2013\makefile.sln 2. Retarget by opening build\vs2013\makefile.sln
3. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree. 3. Start 'x64 Native Tools Command Prompt for VS2019' and change directory to unpacked source tree.
4. Switch to build\vs2013 and build: `msbuild makefle.sln /nologo /p:Configuration=Release /p:Platform=x64` 4. Switch to build\vs2013 and build: `msbuild makefle.sln /nologo /p:Configuration=Release /p:Platform=x64`

View File

@ -45,7 +45,7 @@ Feature: Bicycle - Exclude flags
When I match I should get When I match I should get
| trace | matchings | duration | | trace | matchings | duration |
| abcf | abcf | 301.2 | | abcf | abcf | 301 |
When I request a travel time matrix I should get When I request a travel time matrix I should get
| | a | f | | | a | f |

View File

@ -9,7 +9,7 @@ Feature: Bike - Max speed restrictions
Then routability should be Then routability should be
| highway | maxspeed | bothw | | highway | maxspeed | bothw |
| residential | | 15 km/h | | residential | | 15 km/h |
| residential | 10 | 9 km/h | | residential | 10 | 10 km/h |
Scenario: Bicycle - Ignore maxspeed when higher than way speed Scenario: Bicycle - Ignore maxspeed when higher than way speed
Then routability should be Then routability should be
@ -65,12 +65,12 @@ Feature: Bike - Max speed restrictions
Then routability should be Then routability should be
| maxspeed | maxspeed:forward | maxspeed:backward | forw | backw | | maxspeed | maxspeed:forward | maxspeed:backward | forw | backw |
| | | | 15 km/h | 15 km/h | | | | | 15 km/h | 15 km/h |
| 10 | | | 9 km/h | 9 km/h | | 10 | | | 10 km/h | 10 km/h |
| | 10 | | 9 km/h | 15 km/h | | | 10 | | 10 km/h | 15 km/h |
| | | 10 | 14 km/h | 9 km/h | | | | 10 | 15 km/h | 10 km/h |
| 2 | 10 | | 9 km/h | 2 km/h | | 2 | 10 | | 10 km/h | 2 km/h |
| 2 | | 10 | 2 km/h | 9 km/h | | 2 | | 10 | 2 km/h | 10 km/h |
| 2 | 5 | 10 | 5 km/h | 9 km/h | | 2 | 5 | 10 | 5 km/h | 10 km/h |
Scenario: Bike - Maxspeed should not allow routing on unroutable ways Scenario: Bike - Maxspeed should not allow routing on unroutable ways
Then routability should be Then routability should be

View File

@ -33,7 +33,7 @@ Feature: Bicycle - Adds penalties to unsafe roads
| tertiary_link | track | 15 km/h | 15 km/h | 4.2 | 4.2 | | tertiary_link | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| residential | track | 15 km/h | 15 km/h | 4.2 | 4.2 | | residential | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | track | 15 km/h | 15 km/h | 4.2 | 4.2 | | cycleway | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | track | 15 km/h | 15 km/h | 4.2 | 4.2 | | footway | track | 14 km/h | 14 km/h | 4.2 | 4.2 |
| motorway | lane | 15 km/h | | 4.2 | | | motorway | lane | 15 km/h | | 4.2 | |
| primary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 | | primary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| secondary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 | | secondary | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
@ -41,7 +41,7 @@ Feature: Bicycle - Adds penalties to unsafe roads
| primary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 | | primary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| secondary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 | | secondary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| tertiary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 | | tertiary_link | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| residential | lane | 15 km/h | 15 km/h | 4.2 | 4.2 | | residential | lane | 14 km/h | 14 km/h | 4.2 | 4.2 |
| cycleway | lane | 15 km/h | 15 km/h | 4.2 | 4.2 | | cycleway | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | lane | 15 km/h | 15 km/h | 4.2 | 4.2 | | footway | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
| motorway | shared_lane | 15 km/h | | 4.2 | | | motorway | shared_lane | 15 km/h | | 4.2 | |
@ -59,7 +59,7 @@ Feature: Bicycle - Adds penalties to unsafe roads
| tertiary_link | track | | 15 km/h | 15 km/h | 4.2 | 3.3 | | tertiary_link | track | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| residential | track | | 15 km/h | 15 km/h | 4.2 | 4.2 | | residential | track | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| cycleway | track | | 15 km/h | 15 km/h | 4.2 | 4.2 | | cycleway | track | | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | track | | 15 km/h | 4 km/h +-1 | 4.2 | 1.1 | | footway | track | | 14 km/h | 4 km/h +-1 | 4.2 | 1.1 |
| motorway | | track | 15 km/h | | 4.2 | | | motorway | | track | 15 km/h | | 4.2 | |
| primary | | track | 15 km/h | 15 km/h | 2.1 | 4.2 | | primary | | track | 15 km/h | 15 km/h | 2.1 | 4.2 |
| secondary | | track | 15 km/h | 15 km/h | 2.7 | 4.2 | | secondary | | track | 15 km/h | 15 km/h | 2.7 | 4.2 |
@ -67,7 +67,7 @@ Feature: Bicycle - Adds penalties to unsafe roads
| primary_link | | track | 15 km/h | 15 km/h | 2.1 | 4.2 | | primary_link | | track | 15 km/h | 15 km/h | 2.1 | 4.2 |
| secondary_link | | track | 15 km/h | 15 km/h | 2.7 | 4.2 | | secondary_link | | track | 15 km/h | 15 km/h | 2.7 | 4.2 |
| tertiary_link | | track | 15 km/h | 15 km/h | 3.3 | 4.2 | | tertiary_link | | track | 15 km/h | 15 km/h | 3.3 | 4.2 |
| residential | | track | 15 km/h | 15 km/h | 4.2 | 4.2 | | residential | | track | 14 km/h | 14 km/h | 4.2 | 4.2 |
| cycleway | | track | 15 km/h | 15 km/h | 4.2 | 4.2 | | cycleway | | track | 15 km/h | 15 km/h | 4.2 | 4.2 |
| footway | | track | 4 km/h +-1 | 15 km/h | 1.1 | 4.2 | | footway | | track | 4 km/h +-1 | 15 km/h | 1.1 | 4.2 |
| motorway | lane | | 15 km/h | | 4.2 | | | motorway | lane | | 15 km/h | | 4.2 | |
@ -75,7 +75,7 @@ Feature: Bicycle - Adds penalties to unsafe roads
| secondary | lane | | 15 km/h | 15 km/h | 4.2 | 2.7 | | secondary | lane | | 15 km/h | 15 km/h | 4.2 | 2.7 |
| tertiary | lane | | 15 km/h | 15 km/h | 4.2 | 3.3 | | tertiary | lane | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| primary_link | lane | | 15 km/h | 15 km/h | 4.2 | 2.1 | | primary_link | lane | | 15 km/h | 15 km/h | 4.2 | 2.1 |
| secondary_link | lane | | 15 km/h | 15 km/h | 4.2 | 2.7 | | secondary_link | lane | | 14 km/h | 14 km/h | 4.2 | 2.7 |
| tertiary_link | lane | | 15 km/h | 15 km/h | 4.2 | 3.3 | | tertiary_link | lane | | 15 km/h | 15 km/h | 4.2 | 3.3 |
| residential | lane | | 15 km/h +-1 | 15 km/h +-1 | 4.2 | 4.2 | | residential | lane | | 15 km/h +-1 | 15 km/h +-1 | 4.2 | 4.2 |
| cycleway | lane | | 15 km/h | 15 km/h | 4.2 | 4.2 | | cycleway | lane | | 15 km/h | 15 km/h | 4.2 | 4.2 |
@ -84,7 +84,7 @@ Feature: Bicycle - Adds penalties to unsafe roads
| primary | | lane | 15 km/h | 15 km/h | 2.1 | 4.2 | | primary | | lane | 15 km/h | 15 km/h | 2.1 | 4.2 |
| secondary | | lane | 15 km/h +-1 | 15 km/h +-1 | 2.7 | 4.2 | | secondary | | lane | 15 km/h +-1 | 15 km/h +-1 | 2.7 | 4.2 |
| tertiary | | lane | 15 km/h | 15 km/h | 3.3 | 4.2 | | tertiary | | lane | 15 km/h | 15 km/h | 3.3 | 4.2 |
| primary_link | | lane | 15 km/h | 15 km/h | 2.1 | 4.2 | | primary_link | | lane | 14 km/h | 14 km/h | 2.1 | 4.2 |
| secondary_link | | lane | 15 km/h | 15 km/h | 2.7 | 4.2 | | secondary_link | | lane | 15 km/h | 15 km/h | 2.7 | 4.2 |
| tertiary_link | | lane | 15 km/h | 15 km/h | 3.3 | 4.2 | | tertiary_link | | lane | 15 km/h | 15 km/h | 3.3 | 4.2 |
| residential | | lane | 15 km/h | 15 km/h | 4.2 | 4.2 | | residential | | lane | 15 km/h | 15 km/h | 4.2 | 4.2 |
@ -92,7 +92,7 @@ Feature: Bicycle - Adds penalties to unsafe roads
| footway | | lane | 4 km/h +-1 | 15 km/h | 1.1 | 4.2 | | footway | | lane | 4 km/h +-1 | 15 km/h | 1.1 | 4.2 |
| motorway | shared_lane | | 15 km/h | | 4.2 | | | motorway | shared_lane | | 15 km/h | | 4.2 | |
| primary | shared_lane | | 15 km/h | 15 km/h | 4.2 | 2.1 | | primary | shared_lane | | 15 km/h | 15 km/h | 4.2 | 2.1 |
| motorway | | shared_lane | 15 km/h | | 4.2 | | | motorway | | shared_lane | 14 km/h | | 4.2 | |
| primary | | shared_lane | 15 km/h | 15 km/h | 2.1 | 4.2 | | primary | | shared_lane | 15 km/h | 15 km/h | 2.1 | 4.2 |

View File

@ -8,29 +8,29 @@ Feature: Bike - Surfaces
Then routability should be Then routability should be
| highway | surface | bothw | | highway | surface | bothw |
| cycleway | | 48 s | | cycleway | | 48 s |
| cycleway | asphalt | 48 s | | cycleway | asphalt | 47.9 s |
| cycleway | cobblestone:flattened | 72 s | | cycleway | cobblestone:flattened | 72 s |
| cycleway | paving_stones | 72 s | | cycleway | paving_stones | 72 s |
| cycleway | compacted | 72 s | | cycleway | compacted | 72 s |
| cycleway | cobblestone | 120 s | | cycleway | cobblestone | 120 s |
| cycleway | fine_gravel | 120 s | | cycleway | fine_gravel | 120 s |
| cycleway | gravel | 120 s | | cycleway | gravel | 120 s |
| cycleway | pebblestone | 120.1 s | | cycleway | pebblestone | 120 s |
| cycleway | dirt | 120 s | | cycleway | dirt | 120 s |
| cycleway | earth | 120 s | | cycleway | earth | 120 s |
| cycleway | grass | 120 s | | cycleway | grass | 120 s |
| cycleway | mud | 240 s | | cycleway | mud | 240 s |
| cycleway | sand | 240.1 s | | cycleway | sand | 240 s |
| cycleway | sett | 72 s | | cycleway | sett | 72 s |
Scenario: Bicycle - Good surfaces on small paths Scenario: Bicycle - Good surfaces on small paths
Then routability should be Then routability should be
| highway | surface | bothw | | highway | surface | bothw |
| cycleway | | 48 s | | cycleway | | 48 s |
| path | | 60 s | | path | | 59.9 s |
| track | | 60 s | | track | | 60 s |
| track | asphalt | 60 s | | track | asphalt | 60 s |
| path | asphalt | 60 s | | path | asphalt | 60 s |
Scenario: Bicycle - Surfaces should not make unknown ways routable Scenario: Bicycle - Surfaces should not make unknown ways routable
Then routability should be Then routability should be

View File

@ -37,6 +37,6 @@ Feature: Turn Penalties
| from | to | distance | weight | # | | from | to | distance | weight | # |
| a | c | 900m +- 1 | 216 | Going straight has no penalties | | a | c | 900m +- 1 | 216 | Going straight has no penalties |
| a | d | 900m +- 1 | 220.2 | Turning right had penalties | | a | d | 900m +- 1 | 220.2 | Turning right had penalties |
| e | g | 2100m +- 4| 503.9 | Going straght has no penalties | | e | g | 2100m +- 5| 503.9 | Going straght has no penalties |
| e | h | 2100m +- 4| 515.1 | Turn sharp right has even higher penalties| | e | h | 2100m +- 5| 515.1 | Turn sharp right has even higher penalties|

View File

@ -185,7 +185,7 @@ Feature: Car - Restricted access
Then routability should be Then routability should be
| highway | hov | bothw | forw_rate | backw_rate | | highway | hov | bothw | forw_rate | backw_rate |
| primary | designated | x | 18.2 | 18.2 | | primary | designated | x | 18.2 | 18.2 |
| primary | yes | x | 18.2 | 18.2 | | primary | yes | x | 18.3 | 18.3 |
| primary | no | x | 18.2 | 18.2 | | primary | no | x | 18.2 | 18.2 |
# Models: # Models:
@ -196,7 +196,7 @@ Feature: Car - Restricted access
Then routability should be Then routability should be
| highway | hov | hov:lanes | lanes | access | oneway | forw | backw | forw_rate | | highway | hov | hov:lanes | lanes | access | oneway | forw | backw | forw_rate |
| motorway | designated | designated\|designated\|designated | 3 | hov | yes | x | | 25 | | motorway | designated | designated\|designated\|designated | 3 | hov | yes | x | | 25 |
| motorway | lane | | 3 | designated | yes | x | | 25 | | motorway | lane | | 3 | designated | yes | x | | 25.3 |
@hov @hov
Scenario: Car - a way with all lanes HOV-designated is highly penalized by default (similar to hov=designated) Scenario: Car - a way with all lanes HOV-designated is highly penalized by default (similar to hov=designated)
@ -206,7 +206,7 @@ Feature: Car - Restricted access
# This test is flaky because non-deterministic turn generation sometimes emits a NoTurn here that is marked as restricted. #3769 # This test is flaky because non-deterministic turn generation sometimes emits a NoTurn here that is marked as restricted. #3769
#| primary | | designated | | | x | x | 18.2 | 18.2 | #| primary | | designated | | | x | x | 18.2 | 18.2 |
#| primary | designated | | | | x | x | 18.2 | 18.2 | #| primary | designated | | | | x | x | 18.2 | 18.2 |
| primary | designated\|designated | designated\|designated | | | x | x | 18.2 | 18.2 | | primary | designated\|designated | designated\|designated | | | x | x | 18.3 | 18.3 |
| primary | designated\|no | designated\|no | | | x | x | 18.2 | 18.2 | | primary | designated\|no | designated\|no | | | x | x | 18.2 | 18.2 |
| primary | yes\|no | yes\|no | | | x | x | 18.2 | 18.2 | | primary | yes\|no | yes\|no | | | x | x | 18.2 | 18.2 |
| primary | | | | | x | x | 18.2 | 18.2 | | primary | | | | | x | x | 18.2 | 18.2 |

View File

@ -46,10 +46,10 @@ Feature: Car - Handle ferry routes
When I route I should get When I route I should get
| from | to | route | modes | speed | time | | from | to | route | modes | speed | time |
| a | g | abc,cde,efg,efg | driving,ferry,driving,driving | 12 km/h | 173.4s | | a | g | abc,cde,efg,efg | driving,ferry,driving,driving | 12 km/h | 173.5s |
| b | f | abc,cde,efg,efg | driving,ferry,driving,driving | 9 km/h | 162.4s | | b | f | abc,cde,efg,efg | driving,ferry,driving,driving | 9 km/h | 162.5s |
| c | e | cde,cde | ferry,ferry | 5 km/h | 151.4s | | c | e | cde,cde | ferry,ferry | 5 km/h | 151.5s |
| e | c | cde,cde | ferry,ferry | 5 km/h | 151.4s | | e | c | cde,cde | ferry,ferry | 5 km/h | 151.5s |
Scenario: Car - Properly handle simple durations Scenario: Car - Properly handle simple durations
Given the node map Given the node map
@ -117,4 +117,4 @@ Feature: Car - Handle ferry routes
# Note that matching *should* work across unsnappable ferries # Note that matching *should* work across unsnappable ferries
When I match I should get When I match I should get
| trace | geometry | duration | | 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 | | abcdef| 1,1,1.000898,1,1.000898,1,1.002695,1,1.002695,1,1.003594,1,1.003594,1,1.005391,1,1.005391,1,1.006289,1 | 611 |

View File

@ -86,57 +86,57 @@ OSRM will use 4/5 of the projected free-flow speed.
Then routability should be Then routability should be
| highway | maxspeed | width | maxspeed:forward | maxspeed:backward | forw | backw | forw_rate | backw_rate | | highway | maxspeed | width | maxspeed:forward | maxspeed:backward | forw | backw | forw_rate | backw_rate |
| primary | | | | | 64 km/h | 64 km/h | 18 | 18 | | primary | | | | | 64 km/h | 64 km/h | 18.1 | 18.1 |
| primary | | 3 | | | 64 km/h | 64 km/h | 9 | 9 | | primary | | 3 | | | 64 km/h | 64 km/h | 9 | 9 |
| primary | 60 | | | | 47 km/h | 47 km/h | 13.3 | 13.3 | | primary | 60 | | | | 48 km/h | 48 km/h | 13.3 | 13.3 |
| primary | 60 | 3 | | | 47 km/h | 47 km/h | 6.7 | 6.7 | | primary | 60 | 3 | | | 48 km/h | 48 km/h | 6.7 | 6.7 |
| primary | | | 60 | | 47 km/h | 64 km/h | 13.3 | 18 | | primary | | | 60 | | 48 km/h | 64 km/h | 13.3 | 18.1 |
| primary | | 3 | 60 | | 47 km/h | 64 km/h | 6.7 | 9 | | primary | | 3 | 60 | | 48 km/h | 64 km/h | 6.7 | 9 |
| primary | | | | 60 | 64 km/h | 47 km/h | 18 | 13.3 | | primary | | | | 60 | 64 km/h | 48 km/h | 18.1 | 13.3 |
| primary | | 3 | | 60 | 64 km/h | 47 km/h | 9 | 6.7 | | primary | | 3 | | 60 | 64 km/h | 48 km/h | 9 | 6.7 |
| primary | 15 | | 60 | | 47 km/h | 11 km/h | 13.3 | 3.3 | | primary | 15 | | 60 | | 48 km/h | 12 km/h | 13.3 | 3.3 |
| primary | 15 | 3 | 60 | | 48 km/h | 12 km/h | 6.7 | 1.7 | | primary | 15 | 3 | 60 | | 48 km/h | 12 km/h | 6.7 | 1.7 |
| primary | 15 | | | 60 | 12 km/h | 47 km/h | 3.3 | 13.3 | | primary | 15 | | | 60 | 12 km/h | 48 km/h | 3.3 | 13.3 |
| primary | 15 | 3 | | 60 | 12 km/h | 47 km/h | 1.7 | 6.7 | | primary | 15 | 3 | | 60 | 12 km/h | 48 km/h | 1.7 | 6.7 |
| primary | 15 | | 30 | 60 | 23 km/h | 47 km/h | 6.7 | 13.3 | | primary | 15 | | 30 | 60 | 24 km/h | 48 km/h | 6.7 | 13.3 |
| primary | 15 | 3 | 30 | 60 | 23 km/h | 47 km/h | 3.3 | 6.7 | | primary | 15 | 3 | 30 | 60 | 24 km/h | 48 km/h | 3.3 | 6.7 |
Scenario: Car - Single lane streets be ignored or incur a penalty Scenario: Car - Single lane streets be ignored or incur a penalty
Then routability should be Then routability should be
| highway | maxspeed | lanes | maxspeed:forward | maxspeed:backward | forw | backw | forw_rate | backw_rate | | highway | maxspeed | lanes | maxspeed:forward | maxspeed:backward | forw | backw | forw_rate | backw_rate |
| primary | | | | | 64 km/h | 64 km/h | 18 | 18 | | primary | | | | | 64 km/h | 64 km/h | 18.1 | 18.1 |
| primary | | 1 | | | 64 km/h | 64 km/h | 9 | 9 | | primary | | 1 | | | 64 km/h | 64 km/h | 9 | 9 |
| primary | 60 | | | | 47 km/h | 47 km/h | 13.3 | 13.3 | | primary | 60 | | | | 48 km/h | 48 km/h | 13.3 | 13.3 |
| primary | 60 | 1 | | | 47 km/h | 47 km/h | 6.7 | 6.7 | | primary | 60 | 1 | | | 48 km/h | 48 km/h | 6.7 | 6.7 |
| primary | | | 60 | | 47 km/h | 64 km/h | 13.3 | 18 | | primary | | | 60 | | 48 km/h | 64 km/h | 13.3 | 18.1 |
| primary | | 1 | 60 | | 47 km/h | 64 km/h | 6.7 | 9 | | primary | | 1 | 60 | | 48 km/h | 64 km/h | 6.7 | 9 |
| primary | | | | 60 | 64 km/h | 47 km/h | 18 | 13.3 | | primary | | | | 60 | 64 km/h | 48 km/h | 18.1 | 13.3 |
| primary | | 1 | | 60 | 64 km/h | 47 km/h | 9 | 6.7 | | primary | | 1 | | 60 | 64 km/h | 48 km/h | 9 | 6.7 |
| primary | 15 | | 60 | | 47 km/h | 11 km/h | 13.3 | 3.3 | | primary | 15 | | 60 | | 48 km/h | 12 km/h | 13.3 | 3.3 |
| primary | 15 | 1 | 60 | | 48 km/h | 12 km/h | 6.7 | 1.7 | | primary | 15 | 1 | 60 | | 48 km/h | 12 km/h | 6.7 | 1.7 |
| primary | 15 | | | 60 | 12 km/h | 47 km/h | 3.3 | 13.3 | | primary | 15 | | | 60 | 12 km/h | 48 km/h | 3.3 | 13.3 |
| primary | 15 | 1 | | 60 | 12 km/h | 47 km/h | 1.7 | 6.7 | | primary | 15 | 1 | | 60 | 12 km/h | 48 km/h | 1.7 | 6.7 |
| primary | 15 | | 30 | 60 | 23 km/h | 47 km/h | 6.7 | 13.3 | | primary | 15 | | 30 | 60 | 24 km/h | 48 km/h | 6.7 | 13.3 |
| primary | 15 | 1 | 30 | 60 | 23 km/h | 47 km/h | 3.3 | 6.7 | | primary | 15 | 1 | 30 | 60 | 24 km/h | 48 km/h | 3.3 | 6.7 |
Scenario: Car - Single lane streets only incur a penalty for two-way streets Scenario: Car - Single lane streets only incur a penalty for two-way streets
Then routability should be Then routability should be
| highway | maxspeed | lanes | oneway | forw | backw | forw_rate | backw_rate | | highway | maxspeed | lanes | oneway | forw | backw | forw_rate | backw_rate |
| primary | 30 | 1 | yes | 23 km/h | | 6.7 | | | primary | 30 | 1 | yes | 24 km/h | | 6.7 | |
| primary | 30 | 1 | -1 | | 23 km/h | | 6.7 | | primary | 30 | 1 | -1 | | 24 km/h | | 6.7 |
| primary | 30 | 1 | | 23 km/h | 23 km/h | 3.3 | 3.3 | | primary | 30 | 1 | | 24 km/h | 24 km/h | 3.3 | 3.3 |
| primary | 30 | 2 | | 23 km/h | 23 km/h | 6.7 | 6.7 | | primary | 30 | 2 | | 24 km/h | 24 km/h | 6.7 | 6.7 |
Scenario: Car - Forward/backward maxspeed on reverse oneways Scenario: Car - Forward/backward maxspeed on reverse oneways
Then routability should be Then routability should be
| highway | maxspeed | maxspeed:forward | maxspeed:backward | oneway | forw | backw | forw_rate | backw_rate | | highway | maxspeed | maxspeed:forward | maxspeed:backward | oneway | forw | backw | forw_rate | backw_rate |
| primary | | | | -1 | | 64 km/h | | 18 | | primary | | | | -1 | | 64 km/h | | 18.1 |
| primary | 30 | | | -1 | | 23 km/h | | 6.7 | | primary | 30 | | | -1 | | 24 km/h | | 6.7 |
| primary | | 30 | | -1 | | 64 km/h | | 18 | | primary | | 30 | | -1 | | 64 km/h | | 18.1 |
| primary | | | 30 | -1 | | 23 km/h | | 6.7 | | primary | | | 30 | -1 | | 24 km/h | | 6.7 |
| primary | 20 | 30 | | -1 | | 15 km/h | | 4.4 | | primary | 20 | 30 | | -1 | | 16 km/h | | 4.4 |
| primary | 20 | | 30 | -1 | | 23 km/h | | 6.7 | | primary | 20 | | 30 | -1 | | 24 km/h | | 6.7 |
Scenario: Car - Respect source:maxspeed Scenario: Car - Respect source:maxspeed

View File

@ -1008,3 +1008,123 @@ Feature: Car - Turn restrictions
| from | to | route | | from | to | route |
| d | x | bd,abc,xa,xa | | d | x | bd,abc,xa,xa |
| d | z | bd,abc,cz,cz | | d | z | bd,abc,cz,cz |
Scenario: Multiple restricted entrances
Given the node map
"""
b
|
a----e----c
|
d
"""
And the ways
| nodes |
| ae |
| be |
| ce |
| de |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | ae,be | ed | e | no_entry |
When I route I should get
| from | to | route |
| a | d | ae,ce,ce,de,de |
| b | d | be,ce,ce,de,de |
| c | d | ce,de,de |
Scenario: Multiple restricted exits
Given the node map
"""
b
|
a----e----c
|
d
"""
And the ways
| nodes |
| ae |
| be |
| ce |
| de |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | ae | ce,de | e | no_exit |
When I route I should get
| from | to | route |
| a | b | ae,be,be |
| a | c | ae,be,be,ce,ce |
| a | d | ae,be,be,de,de |
Scenario: Invalid restricted entrances/exits
Given the node map
"""
b
|
a----e----c
|
d
"""
And the ways
| nodes |
| ae |
| be |
| ce |
| de |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | ae | ce,de | e | no_entry |
| restriction | ae,be | ed | e | no_exit |
When I route I should get
| from | to | route |
| a | b | ae,be,be |
| a | c | ae,ce,ce |
| a | d | ae,de,de |
| b | d | be,de,de |
| c | d | ce,de,de |
Scenario: Invalid multi from/to restrictions
Given the node map
"""
b
|
a----e----c
|
d
"""
And the ways
| nodes |
| ae |
| be |
| ce |
| de |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | ae,de | ce,de | e | no_right_turn |
| restriction | ae,be | ce,de | e | no_straight_on |
| restriction | ae,be | be,ce | e | only_left_turn |
| restriction | ae,be | ce,de | e | only_straight_on |
When I route I should get
| from | to | route |
| a | b | ae,be,be |
| a | c | ae,ce,ce |
| a | d | ae,de,de |
| b | d | be,de,de |
| c | d | ce,de,de |

View File

@ -9,29 +9,29 @@ Feature: Car - speeds
Scenario: Car - speed of various way types Scenario: Car - speed of various way types
Then routability should be Then routability should be
| highway | oneway | bothw | | highway | oneway | bothw |
| motorway | no | 89 km/h | | motorway | no | 90 km/h |
| motorway_link | no | 44 km/h | | motorway_link | no | 45 km/h |
| trunk | no | 85 km/h | | trunk | no | 84 km/h |
| trunk_link | no | 39 km/h | | trunk_link | no | 40 km/h |
| primary | no | 64 km/h | | primary | no | 64 km/h |
| primary_link | no | 29 km/h | | primary_link | no | 30 km/h |
| secondary | no | 55 km/h | | secondary | no | 54 km/h |
| secondary_link | no | 24 km/h | | secondary_link | no | 25 km/h |
| tertiary | no | 39 km/h | | tertiary | no | 40 km/h |
| tertiary_link | no | 20 km/h | | tertiary_link | no | 20 km/h |
| unclassified | no | 24 km/h | | unclassified | no | 25 km/h |
| residential | no | 24 km/h | | residential | no | 25 km/h |
| living_street | no | 9 km/h | | living_street | no | 10 km/h |
| service | no | 15 km/h | | service | no | 15 km/h |
# Alternating oneways scale rates but not speeds # Alternating oneways scale rates but not speeds
Scenario: Car - scaled speeds for oneway=alternating Scenario: Car - scaled speeds for oneway=alternating
Then routability should be Then routability should be
| highway | oneway | junction | forw | backw | # | | highway | oneway | junction | forw | backw | # |
| tertiary | | | 39 km/h | 39 km/h | | | tertiary | | | 40 km/h | 40 km/h | |
| tertiary | alternating | | 39 km/h | 39 km/h | | | tertiary | alternating | | 40 km/h | 40 km/h | |
| motorway | | | 89 km/h | | implied oneway | | motorway | | | 90 km/h | | implied oneway |
| motorway | alternating | | 89 km/h | | implied oneway | | motorway | alternating | | 90 km/h | | implied oneway |
| motorway | reversible | | | | unroutable | | motorway | reversible | | | | unroutable |
| primary | | roundabout | 64 km/h | | implied oneway | | primary | | roundabout | 64 km/h | | implied oneway |
| primary | alternating | roundabout | 64 km/h | | implied oneway | | primary | alternating | roundabout | 64 km/h | | implied oneway |
@ -42,12 +42,12 @@ Feature: Car - speeds
| highway | maxspeed | forw | backw | | highway | maxspeed | forw | backw |
| primary | | 64 km/h | 64 km/h | | primary | | 64 km/h | 64 km/h |
| primary | 60 | 47 km/h | 47 km/h | | primary | 60 | 48 km/h | 48 km/h |
| primary | 60 | 47 km/h | 47 km/h | | primary | 60 | 48 km/h | 48 km/h |
| primary | 60 | 47 km/h | 47 km/h | | primary | 60 | 48 km/h | 48 km/h |
Scenario: Car - Side road penalties Scenario: Car - Side road penalties
Then routability should be Then routability should be
| highway | side_road | forw | backw | forw_rate | backw_rate | | highway | side_road | forw | backw | forw_rate | backw_rate |
| primary | yes | 64 km/h | 64 km/h | 14.4 | 14.4 | | primary | yes | 64 km/h | 64 km/h | 14.5 | 14.5 |

View File

@ -53,8 +53,8 @@ Feature: Car - Allowed start/end modes
When I request a travel time matrix I should get When I request a travel time matrix I should get
| | 2 | c | | | 2 | c |
| 1 | 59.1 | 35.1 | | 1 | 59.1 | 35.2 |
| b | 35.1 | 11.1 | | b | 35 | 11.1 |
When I route I should get When I route I should get
| from | to | route | | from | to | route |
@ -121,5 +121,5 @@ Feature: Car - Allowed start/end modes
When I request a travel time matrix I should get When I request a travel time matrix I should get
| | 2 | c | | | 2 | c |
| 1 | 59.1 | 35.1 | | 1 | 59.1 | 35.2 |
| b | 35.1 | 11.1 | | b | 35 | 11.1 |

View File

@ -65,7 +65,7 @@ Feature: Car - Surfaces
Then routability should be Then routability should be
| highway | oneway | surface | forw | backw | | highway | oneway | surface | forw | backw |
| motorway | no | | 90 km/h | 90 km/h | | motorway | no | | 90 km/h | 90 km/h |
| motorway | no | asphalt | 90 km/h | 90 km/h +-1 | | motorway | no | asphalt | 91 km/h | 90 km/h +-1 |
| motorway | no | concrete | 90 km/h +-1 | 90 km/h +-1 | | motorway | no | concrete | 90 km/h +-1 | 90 km/h +-1 |
| motorway | no | concrete:plates | 90 km/h +-1 | 90 km/h +-1 | | motorway | no | concrete:plates | 90 km/h +-1 | 90 km/h +-1 |
| motorway | no | concrete:lanes | 90 km/h +-1 | 90 km/h +-1 | | motorway | no | concrete:lanes | 90 km/h +-1 | 90 km/h +-1 |

View File

@ -59,7 +59,7 @@ Feature: Car - Handle traffic lights
When I route I should get When I route I should get
| from | to | route | geometry | | from | to | route | geometry |
| a | c | abc,abc | _ibE_ibE?gJ?gJ | | a | c | abc,abc | _ibE_ibE?gJ?eJ |
@traffic @traffic
Scenario: Traffic update on the edge with a traffic signal Scenario: Traffic update on the edge with a traffic signal
@ -89,5 +89,5 @@ Feature: Car - Handle traffic lights
When I route I should get When I route I should get
| from | to | route | speed | weights | time | distances | a:datasources | a:nodes | a:speed | a:duration | a:weight | | from | to | route | speed | weights | time | distances | a:datasources | a:nodes | a:speed | a:duration | a:weight |
| a | c | abc,abc | 59 km/h | 24.2,0 | 24.2s | 399.9m,0m | 1:0 | 1:2:3 | 18:18 | 11.1:11.1 | 11.1:11.1 | | a | c | abc,abc | 60 km/h | 24.2,0 | 24.2s | 400m,0m | 1:0 | 1:2:3 | 18:18 | 11.1:11.1 | 11.1:11.1 |
| c | a | abc,abc | 59 km/h | 24.2,0 | 24.2s | 399.9m,0m | 0:1 | 3:2:1 | 18:18 | 11.1:11.1 | 11.1:11.1 | | c | a | abc,abc | 60 km/h | 24.2,0 | 24.2s | 400m,0m | 0:1 | 3:2:1 | 18:18 | 11.1:11.1 | 11.1:11.1 |

View File

@ -83,4 +83,4 @@ Feature: Car - weights
| waypoints | bearings | route | distance | weights | times | | waypoints | bearings | route | distance | weights | times |
| a,b | 90 90 | abc,abc | 200m | 200,0 | 11.1s,0s | | a,b | 90 90 | abc,abc | 200m | 200,0 | 11.1s,0s |
| b,c | 90 90 | abc,abc | 200m | 200,0 | 11.1s,0s | | b,c | 90 90 | abc,abc | 200m | 200,0 | 11.1s,0s |
| a,d | 90 180 | abc,bd,bd | 399.9m | 200,200,0 | 13.2s,11.1s,0s | | a,d | 90 180 | abc,bd,bd | 400m | 200,200,0 | 13.2s,11.1s,0s |

View File

@ -103,7 +103,7 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive | ,slight left:false slight left:true,straight:false slight right:true, | | a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive | ,slight left:true slight left:true,straight:false slight right:true, |
@anticipate @anticipate
@ -364,8 +364,8 @@ Feature: Turn Lane Guidance
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |
| a,d | main,left,left | depart,end of road left,arrive | ;left:false straight:false straight:true straight:false straight:false right:false;left:false straight:true straight:false right:false,left:true right:false, | | a,d | main,left,left | depart,end of road left,arrive | ;left:false straight:true straight:true straight:true straight:true right:false;left:false straight:true straight:true right:false,left:true right:false, |
| a,e | main,right,right | depart,end of road right,arrive | ;left:false straight:false straight:false straight:true straight:false right:false;left:false straight:false straight:true right:false,left:false right:true, | | a,e | main,right,right | depart,end of road right,arrive | ;left:false straight:true straight:true straight:true straight:true right:false;left:false straight:true straight:true right:false,left:false right:true, |
@anticipate @anticipate
Scenario: Anticipate Lanes for through with turn before / after Scenario: Anticipate Lanes for through with turn before / after
@ -390,15 +390,15 @@ Feature: Turn Lane Guidance
| il | | il | | | il | | il | |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | # | | waypoints | route | turns | lanes | # |
| a,f | ab,bdehi,ef,ef | depart,turn right,turn right,arrive | ,right:false right:false right:true right:true,left:false left:false straight:false straight:false straight:false straight:false right:true right:true, | | | a,f | ab,bdehi,ef,ef | depart,turn right,turn right,arrive | ,right:true right:true right:true right:true,left:false left:false straight:false straight:false straight:false straight:false right:true right:true, | |
| a,g | ab,bdehi,eg,eg | depart,turn right,turn left,arrive | ,right:true right:true right:false right:false,left:true left:true straight:false straight:false straight:false straight:false right:false right:false, | | | a,g | ab,bdehi,eg,eg | depart,turn right,turn left,arrive | ,right:true right:true right:true right:true,left:true left:true straight:false straight:false straight:false straight:false right:false right:false, | |
| a,j | ab,bdehi,ij,ij | depart,turn right,end of road right,arrive | ,right:true right:true right:false right:false;left:false left:false straight:false straight:false straight:true straight:true right:false right:false,left:false left:false right:true right:true, | | | a,j | ab,bdehi,ij,ij | depart,turn right,end of road right,arrive | ,right:true right:true right:true right:true;left:false left:false straight:false straight:false straight:true straight:true right:false right:false,left:false left:false right:true right:true, | |
| a,l | ab,bdehi,il,il | depart,turn right,end of road left,arrive | ,right:false right:false right:true right:true;left:false left:false straight:true straight:true straight:false straight:false right:false right:false,left:true left:true right:false right:false, | not perfect | | a,l | ab,bdehi,il,il | depart,turn right,end of road left,arrive | ,right:true right:true right:true right:true;left:false left:false straight:true straight:true straight:false straight:false right:false right:false,left:true left:true right:false right:false, | not perfect |
| c,g | cb,bdehi,eg,eg | depart,turn left,turn left,arrive | ,left:true left:true left:false left:false,left:true left:true straight:false straight:false straight:false straight:false right:false right:false, | | | c,g | cb,bdehi,eg,eg | depart,turn left,turn left,arrive | ,left:true left:true left:true left:true,left:true left:true straight:false straight:false straight:false straight:false right:false right:false, | |
| c,f | cb,bdehi,ef,ef | depart,turn left,turn right,arrive | ,left:false left:false left:true left:true,left:false left:false straight:false straight:false straight:false straight:false right:true right:true, | | | c,f | cb,bdehi,ef,ef | depart,turn left,turn right,arrive | ,left:true left:true left:true left:true,left:false left:false straight:false straight:false straight:false straight:false right:true right:true, | |
| c,l | cb,bdehi,il,il | depart,turn left,end of road left,arrive | ,left:false left:false left:true left:true;left:false left:false straight:true straight:true straight:false straight:false right:false right:false,left:true left:true right:false right:false, | | | c,l | cb,bdehi,il,il | depart,turn left,end of road left,arrive | ,left:true left:true left:true left:true;left:false left:false straight:true straight:true straight:false straight:false right:false right:false,left:true left:true right:false right:false, | |
| c,j | cb,bdehi,ij,ij | depart,turn left,end of road right,arrive | ,left:true left:true left:false left:false;left:false left:false straight:false straight:false straight:true straight:true right:false right:false,left:false left:false right:true right:true, | not perfect | | c,j | cb,bdehi,ij,ij | depart,turn left,end of road right,arrive | ,left:true left:true left:true left:true;left:false left:false straight:false straight:false straight:true straight:true right:false right:false,left:false left:false right:true right:true, | not perfect |
@anticipate @anticipate
Scenario: Anticipate Lanes for turns with through before and after Scenario: Anticipate Lanes for turns with through before and after
@ -811,9 +811,9 @@ Feature: Turn Lane Guidance
| hj | 7th | | no | | hj | 7th | | no |
When I route I should get When I route I should get
| waypoints | route | turns | locations | lanes | | waypoints | route | turns | locations | lanes |
| a,i | road,road | depart,arrive | a,i | ;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:false;none:true none:true right:false, | | a,i | road,road | depart,arrive | a,i | ;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;none:true none:true right:false, |
| a,j | road,7th,7th | depart,turn right,arrive | a,h,j | ;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:false none:false none:true;left:false none:false none:false none:true,none:false none:false right:true, | | a,j | road,7th,7th | depart,turn right,arrive | a,h,j | ;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:true none:true none:true;left:false none:false none:false none:true,none:false none:false right:true, |
@anticipate @anticipate
Scenario: Oak St, Franklin St Scenario: Oak St, Franklin St

View File

@ -687,7 +687,7 @@ Feature: Slipways and Dedicated Turn Lanes
When I route I should get When I route I should get
| waypoints | route | turns | locations | | waypoints | route | turns | locations |
| s,f | sabc,ae,dbef,dbef | depart,fork slight right,turn right,arrive | s,a,e,f | | s,f | sabc,ae,dbef,dbef | depart,turn straight,turn right,arrive | s,a,e,f |
@sliproads @sliproads
Scenario: Traffic Signal on Sliproad Scenario: Traffic Signal on Sliproad

View File

@ -64,7 +64,7 @@ Feature: Merge Segregated Roads
When I route I should get When I route I should get
| waypoints | route | intersections | | waypoints | route | intersections |
| a,f | road,road,road,road | true:90,false:45 true:135 false:270;true:45 true:180 false:315;true:90 false:225 true:315;true:270 | | a,f | road,road,road | true:90,false:45 true:135 false:270;true:45 true:180 false:315,true:90 false:225 true:315;true:270 |
#https://www.openstreetmap.org/#map=19/52.50003/13.33915 #https://www.openstreetmap.org/#map=19/52.50003/13.33915
@negative @negative
@ -193,7 +193,7 @@ Feature: Merge Segregated Roads
When I route I should get When I route I should get
| waypoints | route | intersections | | waypoints | route | intersections |
| a,g | road,road | true:90,false:90 true:150 false:270,true:90 false:270 true:345;true:270 | | a,g | road,road | true:90,false:90 true:165 false:270,true:90 false:270 true:345;true:270 |
Scenario: Merging parallel roads with intermediate bridges Scenario: Merging parallel roads with intermediate bridges
# https://www.mapillary.com/app/?lat=52.466483333333336&lng=13.431908333333332&z=17&focus=photo&pKey=LWXnKqoGqUNLnG0lofiO0Q # https://www.mapillary.com/app/?lat=52.466483333333336&lng=13.431908333333332&z=17&focus=photo&pKey=LWXnKqoGqUNLnG0lofiO0Q

View File

@ -277,7 +277,7 @@ Feature: Simple Turns
When I route I should get When I route I should get
| from | to | route | turns | | from | to | route | turns |
| a | c | menz,rem | depart,arrive | | a | c | menz,rem | depart,arrive |
| d | c | rem,rem,rem | depart,continue left,arrive | | d | c | rem,rem | depart,arrive |
| c | d | rem,rem,rem | depart,continue right,arrive | | c | d | rem,rem,rem | depart,continue right,arrive |
| c | a | rem,menz | depart,arrive | | c | a | rem,menz | depart,arrive |

View File

@ -160,8 +160,8 @@ Feature: Ramp Guidance
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,d | ab,bd,bd | depart,on ramp right,arrive | | a,d | ab,bd,bd | depart,on ramp right,arrive |
| a,c | ab,bc,bc | depart,turn left,arrive | | a,c | ab,bc | depart,arrive |
Scenario: Fork Slight Ramp Scenario: Fork Slight Ramp
Given the node map Given the node map
@ -179,8 +179,8 @@ Feature: Ramp Guidance
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| a,d | ab,bd,bd | depart,on ramp slight right,arrive | | a,d | ab,bd,bd | depart,on ramp slight right,arrive |
| a,c | ab,bc,bc | depart,turn slight left,arrive | | a,c | ab,bc | depart,arrive |
Scenario: Fork Slight Ramp on Through Street Scenario: Fork Slight Ramp on Through Street
Given the node map Given the node map

View File

@ -791,10 +791,10 @@ Feature: Basic Roundabout
# the turn angles here are quite strange, so we do get uturns for exiting # the turn angles here are quite strange, so we do get uturns for exiting
When I route I should get When I route I should get
| from | to | route | turns | distance | | from | to | route | turns | distance |
| e | f | ed,af,af,af | depart,roundabout-exit-1,exit roundabout left,arrive | 80.1m | | e | f | ed,af,af,af | depart,roundabout-exit-1,exit roundabout left,arrive | 80m |
| f | e | af,ed,ed,ed | depart,roundabout-exit-1,exit roundabout uturn,arrive | 120.1m | | f | e | af,ed,ed,ed | depart,roundabout-exit-1,exit roundabout uturn,arrive | 120m |
| k | l | kg,hl,hl,hl | depart,roundabout-exit-1,exit roundabout right,arrive | 80.1m | | k | l | kg,hl,hl,hl | depart,roundabout-exit-1,exit roundabout right,arrive | 80m |
| l | k | hl,kg,kg,kg | depart,roundabout-exit-1,exit roundabout uturn,arrive | 120.1m | | l | k | hl,kg,kg,kg | depart,roundabout-exit-1,exit roundabout uturn,arrive | 120m |
@4030 @4075 @4030 @4075
Scenario: Service roundabout with service exits Scenario: Service roundabout with service exits
@ -846,5 +846,5 @@ Feature: Basic Roundabout
When I route I should get When I route I should get
| from | to | route | turns | distance | | from | to | route | turns | distance |
| e | k | ebds,ufghl,ufghl,jhik,jhik | depart,rstur-exit-2,exit rotary right,turn right,arrive | 189.1m | | e | k | ebds,ufghl,ufghl,jhik,jhik | depart,rstur-exit-2,exit rotary right,turn right,arrive | 189.2m |
| 1 | k | ebds,ufghl,ufghl,jhik,jhik | depart,rstur-exit-2,exit rotary right,turn right,arrive | 159.1m | | 1 | k | ebds,ufghl,ufghl,jhik,jhik | depart,rstur-exit-2,exit rotary right,turn right,arrive | 159.1m |

View File

@ -836,9 +836,9 @@ Feature: Turn Lane Guidance
| cf | secondary | bottom | | | cf | secondary | bottom | |
When I route I should get When I route I should get
| waypoints | turns | route | lanes | | waypoints | turns | route | lanes |
| a,d | depart,continue right,continue right,arrive | road,road,road,road | ,straight:false right:true,, | | a,d | depart,continue uturn,arrive | road,road,road | ,straight:false right:true;, |
| d,a | depart,continue left,continue left,arrive | road,road,road,road | ,left:true straight:false,, | | d,a | depart,continue uturn,arrive | road,road,road | ,left:true straight:false;, |
@simple @simple
Scenario: Merge Lanes Onto Freeway Scenario: Merge Lanes Onto Freeway

View File

@ -59,6 +59,31 @@ Feature: Locating Nearest node on a Way - pick closest way
| 3 | u | | 3 | u |
| 4 | w | | 4 | w |
Scenario: Nearest - inside a oneway triangle
Given the node map
"""
c
y z
0 1
2 3 4
a x u w b
"""
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
| ca | yes |
When I request nearest I should get
| in | out |
| 0 | y |
| 1 | z |
| 2 | x |
| 3 | u |
| 4 | w |
Scenario: Nearest - High lat/lon Scenario: Nearest - High lat/lon
Given the node locations Given the node locations
| node | lat | lon | | node | lat | lon |
@ -78,3 +103,30 @@ Feature: Locating Nearest node on a Way - pick closest way
| x | a | | x | a |
| y | b | | y | b |
| z | c | | z | c |
Scenario: Nearest - data version
Given the node map
"""
c
y z
0 1
2 3 4
a x u w b
"""
And the ways
| nodes |
| ab |
| bc |
| ca |
And the extract extra arguments "--data_version cucumber_data_version"
When I request nearest I should get
| in | out | data_version |
| 0 | y | cucumber_data_version |
| 1 | z | cucumber_data_version |
| 2 | x | cucumber_data_version |
| 3 | u | cucumber_data_version |
| 4 | w | cucumber_data_version |

View File

@ -20,6 +20,6 @@ Feature: osrm-extract with a profile containing raster source
And the data has been saved to disk And the data has been saved to disk
When I run "osrm-extract {osm_file} -p {profile_file}" When I run "osrm-extract {osm_file} -p {profile_file}"
Then stdout should contain "source loader" Then stdout should contain "source loader"
Then stdout should contain "slope: 0.0899" Then stdout should contain "slope: 0.0904"
Then stdout should contain "slope: -0.0899" Then stdout should contain "slope: -0.0904"
And it should exit successfully And it should exit successfully

View File

@ -117,6 +117,10 @@ module.exports = function () {
got.duration = duration.toString(); got.duration = duration.toString();
} }
if (headers.has('data_version')) {
got.data_version = json.data_version || '';
}
// if header matches 'a:*', parse out the values for * // if header matches 'a:*', parse out the values for *
// and return in that header // and return in that header
headers.forEach((k) => { headers.forEach((k) => {

View File

@ -8,6 +8,7 @@ module.exports = function () {
this.reprocessAndLoadData((e) => { this.reprocessAndLoadData((e) => {
if (e) return callback(e); if (e) return callback(e);
var testRow = (row, ri, cb) => { var testRow = (row, ri, cb) => {
var inNode = this.findNodeByName(row.in); var inNode = this.findNodeByName(row.in);
if (!inNode) throw new Error(util.format('*** unknown in-node "%s"', row.in)); if (!inNode) throw new Error(util.format('*** unknown in-node "%s"', row.in));
@ -17,6 +18,7 @@ module.exports = function () {
this.requestNearest(inNode, this.queryParams, (err, response) => { this.requestNearest(inNode, this.queryParams, (err, response) => {
if (err) return cb(err); if (err) return cb(err);
var coord; var coord;
var headers = new Set(table.raw()[0]);
if (response.statusCode === 200 && response.body.length) { if (response.statusCode === 200 && response.body.length) {
var json = JSON.parse(response.body); var json = JSON.parse(response.body);
@ -25,6 +27,10 @@ module.exports = function () {
var got = { in: row.in, out: row.out }; var got = { in: row.in, out: row.out };
if (headers.has('data_version')) {
got.data_version = json.data_version || '';
}
Object.keys(row).forEach((key) => { Object.keys(row).forEach((key) => {
if (key === 'out') { if (key === 'out') {
if (this.FuzzyMatch.matchLocation(coord, outNode)) { if (this.FuzzyMatch.matchLocation(coord, outNode)) {

View File

@ -1,6 +1,6 @@
var util = require('util'); const util = require('util');
var d3 = require('d3-queue'); const d3 = require('d3-queue');
var classes = require('../support/data_classes'); const classes = require('../support/data_classes');
module.exports = function () { module.exports = function () {
this.Then(/^routability should be$/, (table, callback) => { this.Then(/^routability should be$/, (table, callback) => {
@ -115,8 +115,11 @@ module.exports = function () {
var result = {}; var result = {};
var testDirection = (dir, callback) => { var testDirection = (dir, callback) => {
var a = new classes.Location(this.origin[0] + (1+this.WAY_SPACING*i) * this.zoom, this.origin[1]), const coordA = this.offsetOriginBy(1+this.WAY_SPACING*i, 0);
b = new classes.Location(this.origin[0] + (3+this.WAY_SPACING*i) * this.zoom, this.origin[1]), const coordB = this.offsetOriginBy(3+this.WAY_SPACING*i, 0);
var a = new classes.Location(coordA[0], coordA[1]),
b = new classes.Location(coordB[0], coordB[1]),
r = {}; r = {};
r.which = dir; r.which = dir;

View File

@ -43,6 +43,10 @@ module.exports = function () {
got.message = json.message; got.message = json.message;
} }
if (headers.has('data_version')) {
got.data_version = json.data_version || '';
}
if (headers.has('geometry')) { if (headers.has('geometry')) {
if (this.queryParams['geometries'] === 'polyline') { if (this.queryParams['geometries'] === 'polyline') {
got.geometry = polyline.decode(json.trips[0].geometry).toString(); got.geometry = polyline.decode(json.trips[0].geometry).toString();
@ -61,7 +65,8 @@ module.exports = function () {
var subTrips; var subTrips;
var trip_durations; var trip_durations;
var trip_distance; var trip_distance;
if (res.statusCode === 200) { var ok = res.statusCode === 200;
if (ok) {
if (headers.has('trips')) { if (headers.has('trips')) {
subTrips = json.trips.filter(t => !!t).map(t => t.legs).map(tl => Array.prototype.concat.apply([], tl.map((sl, i) => { subTrips = json.trips.filter(t => !!t).map(t => t.legs).map(tl => Array.prototype.concat.apply([], tl.map((sl, i) => {
var toAdd = []; var toAdd = [];
@ -84,8 +89,7 @@ module.exports = function () {
} }
} }
var ok = true, var encodedResult = '';
encodedResult = '';
if (json.trips) row.trips.split(',').forEach((sub, si) => { if (json.trips) row.trips.split(',').forEach((sub, si) => {
if (si >= subTrips.length) { if (si >= subTrips.length) {

View File

@ -9,17 +9,27 @@ const classes = require('./data_classes');
const tableDiff = require('../lib/table_diff'); const tableDiff = require('../lib/table_diff');
const ensureDecimal = require('../lib/utils').ensureDecimal; const ensureDecimal = require('../lib/utils').ensureDecimal;
const errorReason = require('../lib/utils').errorReason; const errorReason = require('../lib/utils').errorReason;
const CheapRuler = require('cheap-ruler');
module.exports = function () { module.exports = function () {
this.setGridSize = (meters) => { this.setGridSize = (meters) => {
this.gridSize = parseFloat(meters);
// the constant is calculated (with BigDecimal as: 1.0/(DEG_TO_RAD*EARTH_RADIUS_IN_METERS // the constant is calculated (with BigDecimal as: 1.0/(DEG_TO_RAD*EARTH_RADIUS_IN_METERS
// see ApproximateDistance() in ExtractorStructs.h // see ApproximateDistance() in ExtractorStructs.h
// it's only accurate when measuring along the equator, or going exactly north-south // it's only accurate when measuring along the equator, or going exactly north-south
this.zoom = parseFloat(meters) * 0.8990679362704610899694577444566908445396483347536032203503E-5; this.zoom = this.gridSize * 0.8990679362704610899694577444566908445396483347536032203503E-5;
}; };
this.setOrigin = (origin) => { this.setOrigin = (origin) => {
this.origin = origin; this.origin = origin;
// we use C++ version of `cheap-ruler` inside OSRM in order to do distance calculations,
// so here we use it too to have a bit more precise assertions
this.ruler = new CheapRuler(this.origin[1], 'meters');
};
this.offsetOriginBy = (xCells, yCells) => {
return this.ruler.offset(this.origin, xCells * this.gridSize, yCells * this.gridSize);
}; };
this.buildWaysFromTable = (table, callback) => { this.buildWaysFromTable = (table, callback) => {
@ -35,9 +45,10 @@ module.exports = function () {
// add some nodes // add some nodes
var makeFakeNode = (namePrefix, offset) => { var makeFakeNode = (namePrefix, offset) => {
const coord = this.offsetOriginBy(offset + this.WAY_SPACING * ri, 0);
return new OSM.Node(this.makeOSMId(), this.OSM_USER, this.OSM_TIMESTAMP, return new OSM.Node(this.makeOSMId(), this.OSM_USER, this.OSM_TIMESTAMP,
this.OSM_UID, this.origin[0]+(offset + this.WAY_SPACING * ri) * this.zoom, this.OSM_UID, coord[0],
this.origin[1], {name: util.format('%s%d', namePrefix, ri)}); coord[1], {name: util.format('%s%d', namePrefix, ri)});
}; };
var nodes = ['a','b','c','d','e'].map((l, i) => makeFakeNode(l, i)); var nodes = ['a','b','c','d','e'].map((l, i) => makeFakeNode(l, i));
@ -98,7 +109,7 @@ module.exports = function () {
}; };
this.tableCoordToLonLat = (ci, ri) => { this.tableCoordToLonLat = (ci, ri) => {
return [this.origin[0] + ci * this.zoom, this.origin[1] - ri * this.zoom].map(ensureDecimal); return this.offsetOriginBy(ci, -ri).map(ensureDecimal);
}; };
this.addOSMNode = (name, lon, lat, id) => { this.addOSMNode = (name, lon, lat, id) => {

View File

@ -115,4 +115,4 @@ Feature: Annotations
When I route I should get When I route I should get
| from | to | route | a:speed | a:distance | a:duration | a:nodes | | from | to | route | a:speed | a:distance | a:duration | a:nodes |
| a | c | abc,abc | 10:10 | 249.998641:299.931643 | 25:30 | 1:2:3 | | a | c | abc,abc | 10:10 | 249.987619:299.962882 | 25:30 | 1:2:3 |

View File

@ -108,12 +108,12 @@ Feature: Bearing parameter
| ha | yes | ring | | ha | yes | ring |
When I route I should get When I route I should get
| from | to | bearings | route | bearing | | from | to | bearings | route | bearing |
| 0 | q | 0 90 | ia,ring,ring,ring,ring,ring | 0->0,0->90,180->270,270->0,0->90,90->0 | | 0 | q | 0 90 | ia,ring,ring,ring,ring,ring,ring | 0->0,0->90,90->180,180->270,270->0,0->90,90->0 |
| 0 | a | 45 90 | jb,ring,ring,ring,ring,ring | 0->45,45->180,180->270,270->0,0->90,90->0 | | 0 | a | 45 90 | jb,ring,ring,ring,ring,ring | 0->45,45->180,180->270,270->0,0->90,90->0 |
| 0 | q | 90 90 | kc,ring,ring,ring,ring | 0->90,90->180,270->0,0->90,90->0 | | 0 | q | 90 90 | kc,ring,ring,ring,ring,ring | 0->90,90->180,180->270,270->0,0->90,90->0 |
| 0 | a | 135 90 | ld,ring,ring,ring,ring | 0->135,135->270,270->0,0->90,90->0 | | 0 | a | 135 90 | ld,ring,ring,ring,ring | 0->135,135->270,270->0,0->90,90->0 |
| 0 | a | 180 90 | me,ring,ring,ring,ring | 0->180,180->270,270->0,0->90,90->0 | | 0 | a | 180 90 | me,ring,ring,ring | 0->180,180->270,0->90,90->0 |
| 0 | a | 225 90 | nf,ring,ring,ring | 0->225,225->0,0->90,90->0 | | 0 | a | 225 90 | nf,ring,ring,ring | 0->225,225->0,0->90,90->0 |
| 0 | a | 270 90 | og,ring,ring,ring | 0->270,270->0,0->90,90->0 | | 0 | a | 270 90 | og,ring,ring | 0->270,270->0,90->0 |
| 0 | a | 315 90 | ph,ring,ring | 0->315,315->90,90->0 | | 0 | a | 315 90 | ph,ring,ring | 0->315,315->90,90->0 |

View File

@ -20,5 +20,5 @@ Feature: Geometry Compression
When I route I should get When I route I should get
| from | to | route | distance | speed | | from | to | route | distance | speed |
| b | e | abcdef,abcdef | 588.5m | 36 km/h | | b | e | abcdef,abcdef | 588.7m | 36 km/h |
| e | b | abcdef,abcdef | 588.5m | 36 km/h | | e | b | abcdef,abcdef | 588.7m | 36 km/h |

View File

@ -90,8 +90,8 @@ Feature: Distance calculation
| b | a | abc,abc | 100m | | b | a | abc,abc | 100m |
| b | c | abc,abc | 100m | | b | c | abc,abc | 100m |
| c | b | abc,abc | 100m | | c | b | abc,abc | 100m |
| a | c | abc,abc | 200m | | a | c | abc,abc | 199.9m |
| c | a | abc,abc | 200m | | c | a | abc,abc | 199.9m |
Scenario: 1km distance Scenario: 1km distance
Given a grid size of 1000 meters Given a grid size of 1000 meters
@ -134,7 +134,7 @@ Feature: Distance calculation
| a | c | abcdefgh,abcdefgh | 20m | | a | c | abcdefgh,abcdefgh | 20m |
| a | d | abcdefgh,abcdefgh | 30m | | a | d | abcdefgh,abcdefgh | 30m |
| a | e | abcdefgh,abcdefgh | 40m | | a | e | abcdefgh,abcdefgh | 40m |
| a | f | abcdefgh,abcdefgh | 50m | | a | f | abcdefgh,abcdefgh | 50.1m |
| a | g | abcdefgh,abcdefgh | 60m +-1 | | a | g | abcdefgh,abcdefgh | 60m +-1 |
| a | h | abcdefgh,abcdefgh | 70m +-1 | | a | h | abcdefgh,abcdefgh | 70m +-1 |
@ -154,9 +154,9 @@ Feature: Distance calculation
| from | to | route | distance | | from | to | route | distance |
| a | b | abcdefgh,abcdefgh | 10m | | a | b | abcdefgh,abcdefgh | 10m |
| a | c | abcdefgh,abcdefgh | 20m | | a | c | abcdefgh,abcdefgh | 20m |
| a | d | abcdefgh,abcdefgh | 30m | | a | d | abcdefgh,abcdefgh | 29.9m |
| a | e | abcdefgh,abcdefgh | 40m | | a | e | abcdefgh,abcdefgh | 39.9m |
| a | f | abcdefgh,abcdefgh | 50m | | a | f | abcdefgh,abcdefgh | 49.9m |
| a | g | abcdefgh,abcdefgh | 60m +-1 | | a | g | abcdefgh,abcdefgh | 60m +-1 |
| a | h | abcdefgh,abcdefgh | 70m +-1 | | a | h | abcdefgh,abcdefgh | 70m +-1 |

View File

@ -22,10 +22,10 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | e | f | | | a | b | e | f |
| a | 0 | 100.1 | 199.5 | 299.5 | | a | 0 | 100 | 199.9 | 300 |
| b | 100.1 | 0 | 99.4 | 199.5 | | b | 100 | 0 | 100 | 200 |
| e | 199.5 | 99.4 | 0 | 100.1 | | e | 199.9 | 100 | 0 | 100.1 |
| f | 299.5 | 199.5 | 100.1 | 0 | | f | 300 | 200 | 100.1 | 0 |
Scenario: Testbot - Travel distance matrix of minimal network exact distances Scenario: Testbot - Travel distance matrix of minimal network exact distances
Given the node map Given the node map
@ -43,11 +43,11 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | z | b | c | d | | | a | z | b | c | d |
| a | 0 | 100.1 | 199.5 | 298.9 | 398.3 | | a | 0 | 100 | 199.9 | 300 | 399.9 |
| z | 100.1 | 0 | 99.4 | 198.8 | 298.2 | | z | 100 | 0 | 100 | 200 | 300 |
| b | 199.5 | 99.4 | 0 | 99.4 | 198.8 | | b | 199.9 | 100 | 0 | 100.1 | 200 |
| c | 298.9 | 198.8 | 99.4 | 0 | 99.4 | | c | 300 | 200 | 100.1 | 0 | 100 |
| d | 398.3 | 298.2 | 198.8 | 99.4 | 0 | | d | 399.9 | 300 | 200 | 100 | 0 |
Scenario: Testbot - Travel distance matrix of minimal network with toll exclude Scenario: Testbot - Travel distance matrix of minimal network with toll exclude
Given the query options Given the query options
@ -68,10 +68,10 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | c | d | | | a | b | c | d |
| a | 0 | 100.1 | | | | a | 0 | 100 | | |
| b | 100.1 | 0 | | | | b | 100 | 0 | | |
| c | | | 0 | 100.1 | | c | | | 0 | 100 |
| d | | | 100.1 | 0 | | d | | | 100 | 0 |
Scenario: Testbot - Travel distance matrix of minimal network with motorway exclude Scenario: Testbot - Travel distance matrix of minimal network with motorway exclude
Given the query options Given the query options
@ -92,7 +92,7 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | c | d | | | a | b | c | d |
| a | 0 | 298.9 | 99.4 | 199.5 | | a | 0 | 299.9 | 100 | 199.9 |
Scenario: Testbot - Travel distance matrix of minimal network disconnected motorway exclude Scenario: Testbot - Travel distance matrix of minimal network disconnected motorway exclude
Given the query options Given the query options
@ -113,7 +113,7 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | e | | | a | b | e |
| a | 0 | 50.1 | | | a | 0 | 50 | |
Scenario: Testbot - Travel distance matrix of minimal network with motorway and toll excludes Scenario: Testbot - Travel distance matrix of minimal network with motorway and toll excludes
Given the query options Given the query options
@ -134,7 +134,7 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | e | g | | | a | b | e | g |
| a | 0 | 100.1 | | | | a | 0 | 100 | | |
Scenario: Testbot - Travel distance matrix with different way speeds Scenario: Testbot - Travel distance matrix with different way speeds
Given the node map Given the node map
@ -150,21 +150,21 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | c | d | | | a | b | c | d |
| a | 0 | 100.1 | 200.1 | 300.2 | | a | 0 | 100 | 200 | 300 |
| b | 100.1 | 0 | 100.1 | 200.1 | | b | 100 | 0 | 100.1 | 200 |
| c | 200.1 | 100.1 | 0 | 100.1 | | c | 200 | 100.1 | 0 | 100 |
| d | 300.2 | 200.1 | 100.1 | 0 | | d | 300 | 200 | 100 | 0 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | c | d | | | a | b | c | d |
| a | 0 | 100.1 | 200.1 | 300.2 | | a | 0 | 100 | 200 | 300 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | | | a |
| a | 0 | | a | 0 |
| b | 100.1 | | b | 100 |
| c | 200.1 | | c | 200 |
| d | 300.2 | | d | 300 |
Scenario: Testbot - Travel distance matrix of small grid Scenario: Testbot - Travel distance matrix of small grid
Given the node map Given the node map
@ -183,10 +183,10 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | e | f | | | a | b | e | f |
| a | 0 | 100.1 | 199.5 | 299.5 | | a | 0 | 100 | 199.9 | 300 |
| b | 100.1 | 0 | 99.4 | 199.5 | | b | 100 | 0 | 100 | 200 |
| e | 199.5 | 99.4 | 0 | 100.1 | | e | 199.9 | 100 | 0 | 100.1 |
| f | 299.5 | 199.5 | 100.1 | 0 | | f | 300 | 200 | 100.1 | 0 |
Scenario: Testbot - Travel distance matrix of network with unroutable parts Scenario: Testbot - Travel distance matrix of network with unroutable parts
Given the node map Given the node map
@ -200,7 +200,7 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | | | a | b |
| a | 0 | 100.1 | | a | 0 | 100 |
| b | | 0 | | b | | 0 |
Scenario: Testbot - Travel distance matrix of network with oneways Scenario: Testbot - Travel distance matrix of network with oneways
@ -218,10 +218,10 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | x | y | d | e | | | x | y | d | e |
| x | 0 | 300.2 | 399.6 | 299.5 | | x | 0 | 300 | 400 | 300 |
| y | 499 | 0 | 299.5 | 199.5 | | y | 499.9 | 0 | 300 | 199.9 |
| d | 199.5 | 299.5 | 0 | 298.9 | | d | 199.9 | 300 | 0 | 300 |
| e | 299.5 | 399.6 | 100.1 | 0 | | e | 300 | 400 | 100.1 | 0 |
Scenario: Testbot - Rectangular travel distance matrix Scenario: Testbot - Rectangular travel distance matrix
Given the node map Given the node map
@ -240,53 +240,53 @@ Feature: Basic Distance Matrix
When I route I should get When I route I should get
| from | to | distance | | from | to | distance |
| e | a | 200m | | e | a | 199.9m |
| e | b | 100m | | e | b | 100m |
| f | a | 299.9m | | f | a | 300m |
| f | b | 200m | | f | b | 200m |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | e | f | | | a | b | e | f |
| a | 0 | 100.1 | 199.5 | 299.5 | | a | 0 | 100 | 199.9 | 300 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | | | a |
| a | 0 | | a | 0 |
| b | 100.1 | | b | 100 |
| e | 199.5 | | e | 199.9 |
| f | 299.5 | | f | 300 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | e | f | | | a | b | e | f |
| a | 0 | 100.1 | 199.5 | 299.5 | | a | 0 | 100 | 199.9 | 300 |
| b | 100.1 | 0 | 99.4 | 199.5 | | b | 100 | 0 | 100 | 200 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | | | a | b |
| a | 0 | 100.1 | | a | 0 | 100 |
| b | 100.1 | 0 | | b | 100 | 0 |
| e | 199.5 | 99.4 | | e | 199.9 | 100 |
| f | 299.5 | 199.5 | | f | 300 | 200 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | e | f | | | a | b | e | f |
| a | 0 | 100.1 | 199.5 | 299.5 | | a | 0 | 100 | 199.9 | 300 |
| b | 100.1 | 0 | 99.4 | 199.5 | | b | 100 | 0 | 100 | 200 |
| e | 199.5 | 99.4 | 0 | 100.1 | | e | 199.9 | 100 | 0 | 100.1 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | e | | | a | b | e |
| a | 0 | 100.1 | 199.5 | | a | 0 | 100 | 199.9 |
| b | 100.1 | 0 | 99.4 | | b | 100 | 0 | 100 |
| e | 199.5 | 99.4 | 0 | | e | 199.9 | 100 | 0 |
| f | 299.5 | 199.5 | 100.1 | | f | 300 | 200 | 100.1 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | e | f | | | a | b | e | f |
| a | 0 | 100.1 | 199.5 | 299.5 | | a | 0 | 100 | 199.9 | 300 |
| b | 100.1 | 0 | 99.4 | 199.5 | | b | 100 | 0 | 100 | 200 |
| e | 199.5 | 99.4 | 0 | 100.1 | | e | 199.9 | 100 | 0 | 100.1 |
| f | 299.5 | 199.5 | 100.1 | 0 | | f | 300 | 200 | 100.1 | 0 |
Scenario: Testbot - Travel distance 3x2 matrix Scenario: Testbot - Travel distance 3x2 matrix
Given the node map Given the node map
@ -306,8 +306,8 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | b | e | f | | | b | e | f |
| a | 100.1 | 199.5 | 299.5 | | a | 100 | 199.9 | 300 |
| b | 0 | 99.4 | 199.5 | | b | 0 | 100 | 200 |
Scenario: Testbot - All coordinates are from same small component Scenario: Testbot - All coordinates are from same small component
Given a grid size of 300 meters Given a grid size of 300 meters
@ -328,8 +328,8 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | f | g | | | f | g |
| f | 0 | 298.2 | | f | 0 | 300 |
| g | 298.2 | 0 | | g | 300 | 0 |
Scenario: Testbot - Coordinates are from different small component and snap to big CC Scenario: Testbot - Coordinates are from different small component and snap to big CC
Given a grid size of 300 meters Given a grid size of 300 meters
@ -362,10 +362,10 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | f | g | h | i | | | f | g | h | i |
| f | 0 | 298.2 | 0 | 298.2 | | f | 0 | 300 | 0 | 300 |
| g | 298.2 | 0 | 298.2 | 0 | | g | 300 | 0 | 300 | 0 |
| h | 0 | 298.2 | 0 | 298.2 | | h | 0 | 300 | 0 | 300 |
| i | 298.2 | 0 | 298.2 | 0 | | i | 300 | 0 | 300 | 0 |
Scenario: Testbot - Travel distance matrix with loops Scenario: Testbot - Travel distance matrix with loops
Given the node map Given the node map
@ -383,10 +383,10 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | 1 | 2 | 3 | 4 | | | 1 | 2 | 3 | 4 |
| 1 | 0 | 100.1 | 399.6 | 499.7 | | 1 | 0 | 100.1 | 399.9 | 500 |
| 2 | 699.1 | 0 | 299.5 | 399.6 | | 2 | 699.8 | 0 | 299.9 | 399.9 |
| 3 | 399.6 | 499.7 | 0 | 100.1 | | 3 | 399.9 | 500 | 0 | 100.1 |
| 4 | 299.5 | 399.6 | 699.1 | 0 | | 4 | 299.9 | 399.9 | 699.8 | 0 |
Scenario: Testbot - Travel distance matrix based on segment durations Scenario: Testbot - Travel distance matrix based on segment durations
@ -424,11 +424,11 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | c | d | e | | | a | b | c | d | e |
| a | 0 | 100.1 | 200.1 | 300.2 | 398.9 | | a | 0 | 100 | 200 | 300 | 400 |
| b | 100.1 | 0 | 100.1 | 200.1 | 298.9 | | b | 100 | 0 | 100.1 | 200 | 300.1 |
| c | 200.1 | 100.1 | 0 | 100.1 | 198.8 | | c | 200 | 100.1 | 0 | 100 | 200 |
| d | 300.2 | 200.1 | 100.1 | 0 | 298.9 | | d | 300 | 200 | 100 | 0 | 300 |
| e | 398.9 | 298.9 | 198.8 | 298.9 | 0 | | e | 400 | 300.1 | 200 | 300 | 0 |
Scenario: Testbot - Travel distance matrix for alternative loop paths Scenario: Testbot - Travel distance matrix for alternative loop paths
Given the profile file Given the profile file
@ -468,25 +468,25 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 1 | 0 | 1096.7 | 298.9 | 199.5 | 598.4 | 498.3 | 897.3 | 797.9 | | 1 | 0 | 1099.8 | 300 | 199.9 | 600 | 499.9 | 899.9 | 799.9 |
| 2 | 100.1 | 0 | 398.9 | 299.5 | 698.5 | 598.4 | 997.3 | 897.9 | | 2 | 100.1 | 0 | 400 | 300 | 700 | 600 | 1000 | 899.9 |
| 3 | 897.9 | 797.9 | 0 | 1097.4 | 299.5 | 199.5 | 598.4 | 499 | | 3 | 899.9 | 799.9 | 0 | 1099.8 | 300 | 199.9 | 600 | 499.9 |
| 4 | 997.3 | 897.3 | 99.4 | 0 | 398.9 | 298.9 | 697.8 | 598.4 | | 4 | 1000 | 899.9 | 100.1 | 0 | 400 | 300 | 700 | 600 |
| 5 | 598.4 | 498.3 | 897.3 | 797.9 | 0 | 1096.7 | 298.9 | 199.5 | | 5 | 600 | 499.9 | 899.9 | 799.9 | 0 | 1099.8 | 300 | 199.9 |
| 6 | 698.5 | 598.4 | 997.3 | 897.9 | 100.1 | 0 | 398.9 | 299.5 | | 6 | 700 | 600 | 1000 | 899.9 | 100.1 | 0 | 400 | 300 |
| 7 | 299.5 | 199.5 | 598.4 | 499 | 897.9 | 797.9 | 0 | 1097.4 | | 7 | 300 | 199.9 | 600 | 499.9 | 899.9 | 799.9 | 0 | 1099.8 |
| 8 | 398.9 | 298.9 | 697.8 | 598.4 | 997.3 | 897.3 | 99.4 | 0 | | 8 | 400 | 300 | 700 | 600 | 1000 | 899.9 | 100.1 | 0 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | 1 | | | 1 |
| 1 | 0 | | 1 | 0 |
| 2 | 100.1 | | 2 | 100.1 |
| 3 | 897.9 | | 3 | 899.9 |
| 4 | 997.3 | | 4 | 1000 |
| 5 | 598.4 | | 5 | 600 |
| 6 | 698.5 | | 6 | 700 |
| 7 | 299.5 | | 7 | 300 |
| 8 | 398.9 | | 8 | 400 |
Scenario: Testbot - Travel distance matrix with ties Scenario: Testbot - Travel distance matrix with ties
Given the node map Given the node map
@ -511,23 +511,23 @@ Feature: Basic Distance Matrix
| from | to | route | distance | | from | to | route | distance |
| a | b | ab,ab | 450m | | a | b | ab,ab | 450m |
| a | c | ac,ac | 200m | | a | c | ac,ac | 200m |
| a | d | ac,dc,dc | 499.9m | | a | d | ac,dc,dc | 500m |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | c | d | | | a | b | c | d |
| a | 0 | 450.3 | 198.8 | 499 | | a | 0 | 450 | 200 | 500 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | | | a |
| a | 0 | | a | 0 |
| b | 450.3 | | b | 450 |
| c | 198.8 | | c | 200 |
| d | 499 | | d | 500 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | c | | | a | c |
| a | 0 | 198.8 | | a | 0 | 200 |
| c | 198.8 | 0 | | c | 200 | 0 |
# Check rounding errors # Check rounding errors
@ -544,7 +544,7 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | c | d | | | a | b | c | d |
| a | 0 | 1000.7 | 2001.4 | 3002.1 | | a | 0 | 1000.1 | 2000 | 3000.1 |
Scenario: Testbot - OneToMany vs ManyToOne Scenario: Testbot - OneToMany vs ManyToOne
@ -562,12 +562,12 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | | | a | b |
| b | 240.4 | 0 | | b | 241.3 | 0 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | | | a |
| a | 0 | | a | 0 |
| b | 240.4 | | b | 241.3 |
Scenario: Testbot - Varying distances between nodes Scenario: Testbot - Varying distances between nodes
Given the node map Given the node map
@ -589,12 +589,13 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | c | d | e | f | | | a | b | c | d | e | f |
| a | 0 | 100.1 | 300.2 | 650.5 | 1930.6 | 1533 | | a | 0 | 100 | 300 | 650 | 1934.5 | 1534.6 |
| b | 759 | 0 | 200.1 | 550.4 | 1830.5 | 1432.9 | | b | 760.6 | 0 | 200 | 550.1 | 1834.6 | 1434.6 |
| c | 558.8 | 658.9 | 0 | 350.3 | 1630.4 | 1232.8 | | c | 560.6 | 660.5 | 0 | 350 | 1634.6 | 1234.6 |
| d | 1478.9 | 1579 | 1779.1 | 0 | 1280.1 | 882.5 | | d | 1484.6 | 1584.5| 1784.5 | 0 | 1284.5 | 884.6 |
| e | 198.8 | 298.9 | 499 | 710.3 | 0 | 1592.8 | | e | 200 | 300 | 500 | 710.6 | 0 | 1595.2 |
| f | 596.4 | 696.5 | 896.6 | 1107.9 | 397.6 | 0 | | f | 600 | 699.9 | 899.9 | 1110.5 | 399.9 | 0 |
Scenario: Testbot - Filling in noroutes with estimates (defaults to input coordinate location) Scenario: Testbot - Filling in noroutes with estimates (defaults to input coordinate location)
Given a grid size of 300 meters Given a grid size of 300 meters
@ -614,21 +615,21 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | f | 1 | | | a | b | f | 1 |
| a | 0 | 300.2 | 900.7 | 1501.1 | | a | 0 | 300 | 900 | 1500 |
| b | 300.2 | 0 | 600.5 | 1200.9 | | b | 300 | 0 | 600 | 1200.1 |
| f | 900.7 | 600.5 | 0 | 300.2 | | f | 900 | 600 | 0 | 300 |
| 1 | 1501.1 | 1200.9 | 300.2 | 0 | | 1 | 1500 | 1200.1 | 300 | 0 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | f | 1 | | | a | b | f | 1 |
| a | 0 | 300.2 | 900.7 | 1501.1 | | a | 0 | 300 | 900 | 1500 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | | | a |
| a | 0 | | a | 0 |
| b | 300.2 | | b | 300 |
| f | 900.7 | | f | 900 |
| 1 | 1501.1 | | 1 | 1500 |
Scenario: Testbot - Fise input coordinate Scenario: Testbot - Fise input coordinate
Given a grid size of 300 meters Given a grid size of 300 meters
@ -649,21 +650,21 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | f | 1 | | | a | b | f | 1 |
| a | 0 | 300.2 | 900.7 | 1501.1 | | a | 0 | 300 | 900 | 1500 |
| b | 300.2 | 0 | 600.5 | 1200.9 | | b | 300 | 0 | 600 | 1200.1 |
| f | 900.7 | 600.5 | 0 | 300.2 | | f | 900 | 600 | 0 | 300 |
| 1 | 1501.1 | 1200.9 | 300.2 | 0 | | 1 | 1500 | 1200.1 | 300 | 0 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | f | 1 | | | a | b | f | 1 |
| a | 0 | 300.2 | 900.7 | 1501.1 | | a | 0 | 300 | 900 | 1500 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | | | a |
| a | 0 | | a | 0 |
| b | 300.2 | | b | 300 |
| f | 900.7 | | f | 900 |
| 1 | 1501.1 | | 1 | 1500 |
Scenario: Testbot - Filling in noroutes with estimates - use snapped coordinate Scenario: Testbot - Filling in noroutes with estimates - use snapped coordinate
@ -685,28 +686,28 @@ Feature: Basic Distance Matrix
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | f | 1 | | | a | b | f | 1 |
| a | 0 | 300.2 | 900.7 | 1200.9 | | a | 0 | 300 | 900 | 1200 |
| b | 300.2 | 0 | 600.5 | 900.7 | | b | 300 | 0 | 600 | 900 |
| f | 900.7 | 600.5 | 0 | 300.2 | | f | 900 | 600 | 0 | 300 |
| 1 | 1200.9 | 900.7 | 300.2 | 0 | | 1 | 1200 | 900 | 300 | 0 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | b | f | 1 | | | a | b | f | 1 |
| a | 0 | 300.2 | 900.7 | 1200.9 | | a | 0 | 300 | 900 | 1200 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | | | a |
| a | 0 | | a | 0 |
| b | 300.2 | | b | 300 |
| f | 900.7 | | f | 900 |
| 1 | 1200.9 | | 1 | 1200 |
Scenario: Ensure consistency with route, and make sure offsets work in both directions Scenario: Ensure consistency with route, and make sure offsets work in both directions
Given a grid size of 100 meters Given a grid size of 100 meters
Given the node map Given the node map
""" """
a b c d e f g h i j a b c d e f g h i j
1 2 1 2 3
""" """
And the ways And the ways
@ -715,11 +716,15 @@ Feature: Basic Distance Matrix
| fghij | | fghij |
When I route I should get When I route I should get
| from | to | route | distance | | from | to | route | distance |
| 1 | 2 | abcdef,fghij,fghij | 999.9m | | 1 | 2 | abcdef,fghij,fghij | 1000.1m |
| 1 | 3 | abcdef,fghij,fghij | 1400.1m |
| 2 | 3 | fghij,fghij | 400m |
# TODO: this is "correct", but inconsistent with viaroute
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | 1 | 2 | | | 1 | 2 | 3 |
| 1 | 0 | 1000.7 | | 1 | 0 | 1000.1 | 1400.1 |
| 2 | 1000.7 | 0 | | 2 | 1000.1 | 0 | 400 |
| 3 | 1400.1 | 400 | 0 |

View File

@ -446,15 +446,15 @@ Feature: Basic Duration Matrix
| ca | yes | | ca | yes |
When I request a travel time matrix I should get When I request a travel time matrix I should get
| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 1 | 0 | 11 | 3 | 2 | 6 | 5 | 8.9 | 7.9 | | 1 | 0 | 10.9 | 3 | 1.9 | 6 | 4.9 | 9 | 7.9 |
| 2 | 1 | 0 | 4 | 3 | 7 | 6 | 9.9 | 8.9 | | 2 | 1.1 | 0 | 4.1 | 3 | 7.1 | 6 | 10.1 | 9 |
| 3 | 9 | 8 | 0 | 11 | 3 | 2 | 5.9 | 4.9 | | 3 | 9 | 7.9 | 0 | 10.9 | 3 | 1.9 | 6 | 4.9 |
| 4 | 10 | 9 | 1 | 0 | 4 | 3 | 6.9 | 5.9 | | 4 | 10.1 | 9 | 1.1 | 0 | 4.1 | 3 | 7.1 | 6 |
| 5 | 6 | 5 | 9 | 8 | 0 | 11 | 2.9 | 1.9 | | 5 | 6 | 4.9 | 9 | 7.9 | 0 | 10.9 | 3 | 1.9 |
| 6 | 7 | 6 | 10 | 9 | 1 | 0 | 3.9 | 2.9 | | 6 | 7.1 | 6 | 10.1 | 9 | 1.1 | 0 | 4.1 | 3 |
| 7 | 3.1 | 2.1 | 6.1 | 5.1 | 9.1 | 8.1 | 0 | 11 | | 7 | 3 | 1.9 | 6 | 4.9 | 9 | 7.9 | 0 | 10.9 |
| 8 | 4.1 | 3.1 | 7.1 | 6.1 | 10.1 | 9.1 | 1 | 0 | | 8 | 4.1 | 3 | 7.1 | 6 | 10.1 | 9 | 1.1 | 0 |
Scenario: Testbot - Travel time matrix with ties Scenario: Testbot - Travel time matrix with ties
@ -543,22 +543,22 @@ Feature: Basic Duration Matrix
| 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 | 30 | 18 | 30 | | a | 0 | 30 | 17.9 | 30 |
| b | 30 | 0 | 12 | 24 | | b | 30 | 0 | 12 | 24 |
| f | 18 | 12 | 0 | 30 | | f | 17.9 | 12 | 0 | 30 |
| 1 | 30 | 24 | 30 | 0 | | 1 | 30 | 24 | 30 | 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 | 30 | 18 | 30 | | a | 0 | 30 | 17.9 | 30 |
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 | 30 | | b | 30 |
| f | 18 | | f | 17.9 |
| 1 | 30 | | 1 | 30 |
When I request a travel time matrix I should get estimates for When I request a travel time matrix I should get estimates for
| | a | b | f | 1 | | | a | b | f | 1 |
@ -596,22 +596,22 @@ Feature: Basic Duration Matrix
| 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 | 30 | 18 | 30 | | a | 0 | 30 | 17.9 | 30 |
| b | 30 | 0 | 12 | 24 | | b | 30 | 0 | 12 | 24 |
| f | 18 | 12 | 0 | 30 | | f | 17.9 | 12 | 0 | 30 |
| 1 | 30 | 24 | 30 | 0 | | 1 | 30 | 24 | 30 | 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 | 30 | 18 | 30 | | a | 0 | 30 | 17.9 | 30 |
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 | 30 | | b | 30 |
| f | 18 | | f | 17.9 |
| 1 | 30 | | 1 | 30 |
When I request a travel time matrix I should get estimates for When I request a travel time matrix I should get estimates for
| | a | b | f | 1 | | | a | b | f | 1 |
@ -650,22 +650,22 @@ Feature: Basic Duration Matrix
| 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 | 30 | 18 | 24 | | a | 0 | 30 | 17.9 | 23.9 |
| b | 30 | 0 | 12 | 18 | | b | 30 | 0 | 12 | 17.9 |
| f | 18 | 12 | 0 | 30 | | f | 17.9 | 12 | 0 | 30 |
| 1 | 24 | 18 | 30 | 0 | | 1 | 23.9 | 17.9 | 30 | 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 | 30 | 18 | 24 | | a | 0 | 30 | 17.9 | 23.9 |
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 | 30 | | b | 30 |
| f | 18 | | f | 17.9 |
| 1 | 24 | | 1 | 23.9 |
When I request a travel time matrix I should get estimates for When I request a travel time matrix I should get estimates for
| | a | b | f | 1 | | | a | b | f | 1 |
@ -719,22 +719,22 @@ Feature: Basic Duration Matrix
| 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 | 35.8 | 47.8 |
| b | 60 | 0 | 24 | 36 | | b | 60 | 0 | 24 | 35.8 |
| f | 36 | 24 | 0 | 60 | | f | 35.8 | 24 | 0 | 60 |
| 1 | 48 | 36 | 60 | 0 | | 1 | 47.8 | 35.8 | 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 | 35.8 | 47.8 |
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 | 35.8 |
| 1 | 48 | | 1 | 47.8 |
When I request a travel time matrix I should get estimates for When I request a travel time matrix I should get estimates for
| | a | b | f | 1 | | | a | b | f | 1 |

View File

@ -21,8 +21,27 @@ Feature: Basic Map Matching
| abcd | no | | abcd | no |
When I match I should get When I match I should get
| trace | timestamps | matchings | | trace | timestamps | matchings | data_version |
| ab1d | 0 1 2 3 | ad | | ab1d | 0 1 2 3 | ad | |
Scenario: Data_version test on matching
Given a grid size of 100 meters
Given the node map
"""
a b c d
1
"""
And the extract extra arguments "--data_version cucumber_data_version"
And the ways
| nodes | oneway |
| abcd | no |
When I match I should get
| trace | timestamps | matchings | data_version |
| ab1d | 0 1 2 3 | ad | cucumber_data_version |
Scenario: Testbot - Map matching with trace splitting Scenario: Testbot - Map matching with trace splitting
Given the node map Given the node map
@ -279,8 +298,8 @@ Feature: Basic Map Matching
| fb | yes | | fb | yes |
When I match I should get When I match I should get
| trace | matchings | geometry | | trace | matchings | geometry |
| efbc | efbc | 1,0.99964,1.00036,0.99964,1.00036,1,1.000719,1 | | efbc | efbc | 1,0.999638,1.000359,0.999638,1.000359,1,1.000719,1 |
Scenario: Testbot - Geometry details using geojson Scenario: Testbot - Geometry details using geojson
Given the query options Given the query options
@ -356,7 +375,7 @@ Feature: Basic Map Matching
When I match I should get When I match I should get
| trace | matchings | alternatives | | trace | matchings | alternatives |
| abcdef | abcde | 0,0,0,0,1,1 | | abcdef | abcde | 0,0,0,1,1,1 |
Scenario: Testbot - Speed greater than speed threshold Scenario: Testbot - Speed greater than speed threshold
Given a grid size of 100 meters Given a grid size of 100 meters
@ -652,7 +671,7 @@ Feature: Basic Map Matching
When I match I should get When I match I should get
| trace | geometry | code | | trace | geometry | code |
| defgh | 1,1,1,0.999461,1.000674,0.999461 | Ok | | defgh | 1,1,1,0.999457,1.000674,0.999457 | Ok |
@match @testbot @match @testbot
Scenario: Regression test - waypoints trimming too much geometry Scenario: Regression test - waypoints trimming too much geometry
@ -682,8 +701,8 @@ Feature: Basic Map Matching
| waypoints | 0;3 | | waypoints | 0;3 |
| overview | full | | overview | full |
When I match I should get When I match I should get
| trace | geometry | code | | trace | geometry | code |
| bgkj | 1.000135,1,1.000135,0.99964,1.000387,0.999137 | Ok | | bgkj | 1.000135,1,1.000135,0.999638,1.000386,0.999132 | Ok |
@match @testbot @match @testbot
@ -712,12 +731,12 @@ Feature: Basic Map Matching
| overview | full | | overview | full |
| steps | true | | steps | true |
When I match I should get When I match I should get
| trace | geometry | turns | code | | trace | geometry | turns | code |
| abc | 1,0.99973,1.00027,0.99973,1.000539,0.99973 | depart,arrive | Ok | | abc | 1,0.999729,1.000269,0.999729,1.000539,0.999729 | depart,arrive | Ok |
| abd | 1,0.99973,1.00027,0.99973,1.00027,0.999461 | depart,turn right,arrive | Ok | | abd | 1,0.999729,1.000269,0.999729,1.000269,0.999457 | depart,turn right,arrive | Ok |
| abe | 1,0.99973,1.00027,0.99973,1.00027,1 | depart,turn left,arrive | Ok | | abe | 1,0.999729,1.000269,0.999729,1.000269,1 | depart,turn left,arrive | Ok |
| ahd | 1,0.99973,1.00027,0.99973,1.00027,0.999461 | depart,turn right,arrive | Ok | | ahd | 1,0.999729,1.000269,0.999729,1.000269,0.999457 | depart,turn right,arrive | Ok |
| ahe | 1,0.99973,1.00027,0.99973,1.00027,1 | depart,turn left,arrive | Ok | | ahe | 1,0.999729,1.000269,0.999729,1.000269,1 | depart,turn left,arrive | Ok |
@match @testbot @match @testbot
Scenario: Regression test - add source phantoms properly (one phantom on one edge) Scenario: Regression test - add source phantoms properly (one phantom on one edge)
@ -740,9 +759,9 @@ Feature: Basic Map Matching
| annotations | duration,weight | | annotations | duration,weight |
| generate_hints | false | | generate_hints | false |
When I match I should get When I match I should get
| trace | geometry | a:duration | a:weight | duration | | trace | geometry | a:duration | a:weight | duration |
| 123 | 1.000135,1,1.000225,1,1.00036,1,1.000405,1,1.00045,1 | 1:1.5:0.5:0.5 | 1:1.5:0.5:0.5 | 3.5 | | 123 | 1.000135,1,1.000225,1,1.000359,1,1.000404,1,1.000449,1 | 1:1.5:0.5:0.4 | 1:1.5:0.5:0.4 | 3.4 |
| 321 | 1.00045,1,1.000405,1,1.00036,1,1.000225,1,1.000135,1 | 0.5:0.5:1.5:1 | 0.5:0.5:1.5:1 | 3.5 | | 321 | 1.000449,1,1.000404,1,1.000359,1,1.000225,1,1.000135,1 | 0.4:0.5:1.5:1 | 0.4:0.5:1.5:1 | 3.4 |
@match @testbot @match @testbot
Scenario: Regression test - add source phantom properly (two phantoms on one edge) Scenario: Regression test - add source phantom properly (two phantoms on one edge)
@ -765,9 +784,9 @@ Feature: Basic Map Matching
| annotations | duration,weight | | annotations | duration,weight |
| generate_hints | false | | generate_hints | false |
When I match I should get When I match I should get
| trace | geometry | a:duration | a:weight | duration | | trace | geometry | a:duration | a:weight | duration |
| 1234 | 1.000135,1,1.000225,1,1.000405,1,1.00045,1 | 1:2:0.5 | 1:2:0.5 | 3.5 | | 1234 | 1.000135,1,1.000225,1,1.000404,1,1.000449,1 | 1:2:0.4 | 1:2:0.4 | 3.4 |
| 4321 | 1.00045,1,1.000405,1,1.000225,1,1.000135,1 | 0.5:2:1 | 0.5:2:1 | 3.5 | | 4321 | 1.000449,1,1.000404,1,1.000225,1,1.000135,1 | 0.4:2:1 | 0.4:2:1 | 3.4 |
@match @testbot @match @testbot
Scenario: Regression test - add source phantom properly (two phantoms on one edge) Scenario: Regression test - add source phantom properly (two phantoms on one edge)
@ -791,5 +810,6 @@ Feature: Basic Map Matching
# These should have the same weights/duration in either direction # These should have the same weights/duration in either direction
When I match I should get When I match I should get
| trace | geometry | a:distance | a:duration | a:weight | duration | | trace | geometry | a:distance | a:duration | a:weight | duration |
| 2345 | 1.00018,1,1.000315,1 | 15.013264 | 1.5 | 1.5 | 1.5 | | 2345 | 1.00018,1,1.000314,1 | 14.914666 | 1.4 | 1.4 | 1.4 |
| 4321 | 1.00027,1,1.000135,1 | 15.013264 | 1.5 | 1.5 | 1.5 | | 4321 | 1.00027,1,1.000135,1 | 15.02597 | 1.5 | 1.5 | 1.5 |

View File

@ -110,33 +110,34 @@ 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 | 2391.6 | 1570.8 | 1370.9 |
| f | 2383.7 | 0 | 1293.3 | 1617.3 | | f | 2391.6 | 0 | 1297.2 | 1620.9 |
| l | 1566.9 | 1293.3 | 0 | 800.5 | | l | 1570.8 | 1297.2 | 0 | 800 |
| o | 1366.8 | 1617.3 | 800.5 | 0 | | o | 1370.9 | 1620.9 | 800 | 0 |
When I request a travel distance matrix I should get When I request a travel distance matrix I should get
| | a | f | l | o | | | a | f | l | o |
| a | 0 | 2383.7 | 1566.9 | 1366.8 | | a | 0 | 2391.6 | 1570.8 | 1370.9 |
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 | 2383.7 | | f | 2391.6 |
| l | 1566.9 | | l | 1570.8 |
| o | 1366.8 | | o | 1370.9 |
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 | 2391.6 | 1570.8 | 1370.9 |
| f | 2383.7 | 0 | 1293.3 | 1617.3 | | f | 2391.6 | 0 | 1297.2 | 1620.9 |
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 | 1370.9 |
| f | 2383.7 | 1617.3 | | f | 2391.6 | 1620.9 |
| l | 1566.9 | 800.5 | | l | 1570.8 | 800 |
| o | 1366.8 | 0 | | o | 1370.9 | 0 |
Scenario: Testbot - Multi level routing: horizontal road Scenario: Testbot - Multi level routing: horizontal road
Given the node map Given the node map

View File

@ -53,7 +53,7 @@ Feature: Routing close to the [0,0] origin
When I route I should get When I route I should get
| from | to | route | distance | | from | to | route | distance |
| b | d | abcde,abcde | 200m | | b | d | abcde,abcde | 198.8m |
| d | b | | | | d | b | | |
Scenario: North-south oneways crossing the origin Scenario: North-south oneways crossing the origin
@ -71,5 +71,5 @@ Feature: Routing close to the [0,0] origin
When I route I should get When I route I should get
| from | to | route | distance | | from | to | route | distance |
| b | d | abcde,abcde | 200m | | b | d | abcde,abcde | 200.2m |
| d | b | | | | d | b | | |

View File

@ -26,8 +26,8 @@ Feature: Distance calculation
| cd | | cd |
When I route I should get When I route I should get
| from | to | route | distance | | from | to | route | distance |
| c | d | cd,cd | 6028844m ~4.5% | | c | d | cd,cd | 6310675.7m ~4.5% |
Scenario: Approximated Longitudinal distances at latitude 80 Scenario: Approximated Longitudinal distances at latitude 80
Given the node locations Given the node locations
@ -54,8 +54,8 @@ Feature: Distance calculation
| ab | | ab |
When I route I should get When I route I should get
| from | to | route | distance | | from | to | route | distance |
| a | b | ab,ab | 8905559m ~0.1% | | a | b | ab,ab | 8882574.6m ~0.1% |
Scenario: Approximated Latitudinal distances at longitude 45 Scenario: Approximated Latitudinal distances at longitude 45
Given the node locations Given the node locations
@ -68,8 +68,8 @@ Feature: Distance calculation
| ab | | ab |
When I route I should get When I route I should get
| from | to | route | distance | | from | to | route | distance |
| a | b | ab,ab | 8905559m ~0.1% | | a | b | ab,ab | 8882574.6m ~0.1% |
Scenario: Approximated Latitudinal distances at longitude 80 Scenario: Approximated Latitudinal distances at longitude 80
Given the node locations Given the node locations
@ -83,4 +83,4 @@ Feature: Distance calculation
When I route I should get When I route I should get
| from | to | route | distance | | from | to | route | distance |
| a | b | ab,ab | 8905559m ~0.1% | | a | b | ab,ab | 8882574.6m ~0.1% |

View File

@ -23,13 +23,13 @@ Feature: Projection to nearest point on road
Scenario: Projection onto way at high latitudes, 1km distance Scenario: Projection onto way at high latitudes, 1km distance
When I route I should get When I route I should get
| from | to | route | bearing | distance | | from | to | route | bearing | distance |
| b | a | abc,abc | 0->225,225->0 | 1000m | | b | a | abc,abc | 0->225,225->0 | 1002.9m |
| b | c | abc,abc | 0->45,45->0 | 1000m +- 3 | | b | c | abc,abc | 0->45,45->0 | 1005m +- 3 |
| a | d | abc,abc | 0->45,45->0 | 1000m | | a | d | abc,abc | 0->45,45->0 | 1002.9m |
| d | a | abc,abc | 0->225,225->0 | 1000m | | d | a | abc,abc | 0->225,225->0 | 1002.9m |
| c | d | abc,abc | 0->225,225->0 | 1000m +- 3 | | c | d | abc,abc | 0->225,225->0 | 1005m +- 3 |
| d | c | abc,abc | 0->45,45->0 | 1000m +- 3 | | d | c | abc,abc | 0->45,45->0 | 1005m +- 3 |
Scenario: Projection onto way at high latitudes, no distance Scenario: Projection onto way at high latitudes, no distance
When I route I should get When I route I should get

View File

@ -47,11 +47,31 @@ Feature: Snap start/end point to the nearest way
| adb | | adb |
When I route I should get When I route I should get
| from | to | route | | from | to | route | data_version |
| 1 | b | adb,adb | | 1 | b | adb,adb | |
| 2 | b | adb,adb | | 2 | b | adb,adb | |
| 6 | b | aub,aub | | 6 | b | aub,aub | |
| 7 | b | aub,aub | | 7 | b | aub,aub | |
Scenario: Data_version check on nearest
Given the node map
"""
4 5 6 7
3 a u
2
1 d b
"""
And the extract extra arguments "--data_version cucumber_data_version"
And the ways
| nodes |
| aub |
| adb |
When I route I should get
| from | to | route | data_version |
| 1 | b | adb,adb | cucumber_data_version |
Scenario: Snap to edge right under start/end point Scenario: Snap to edge right under start/end point
Given the node map Given the node map
@ -182,4 +202,4 @@ Feature: Snap start/end point to the nearest way
| x | m | xe,xe | | x | m | xe,xe |
| x | n | xf,xf | | x | n | xf,xf |
| x | o | xg,xg | | x | o | xg,xg |
| x | p | xh,xh | | x | p | xh,xh |

View File

@ -48,13 +48,13 @@ Feature: Traffic - speeds
When I route I should get When I route I should get
| from | to | route | speed | weights | a:datasources | | from | to | route | speed | weights | a:datasources |
| a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 | 1:0:0 | | a | b | ad,de,eb,eb | 30 km/h | 1273.9,400.8,378.5,0 | 1:0:0 |
| a | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | 1:0 | | a | c | ad,dc,dc | 31 km/h | 1273.9,955.4,0 | 1:0 |
| b | c | bc,bc | 27 km/h | 741.5,0 | 1 | | b | c | bc,bc | 27 km/h | 737.2,0 | 1 |
| a | d | ad,ad | 27 km/h | 1275.7,0 | 1 | | a | d | ad,ad | 27 km/h | 1273.9,0 | 1 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 | | d | c | dc,dc | 36 km/h | 955.4,0 | 0 |
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 | | g | b | fb,fb | 36 km/h | 164.4,0 | 0 |
| a | g | ad,df,fb,fb | 30 km/h | 1295.7,487.5,304.7,0 | 1:0:0 | | a | g | ad,df,fb,fb | 30 km/h | 1293.9,486.8,304.3,0 | 1:0:0 |
Scenario: Weighting based on speed file weights, ETA based on file durations Scenario: Weighting based on speed file weights, ETA based on file durations
@ -74,13 +74,13 @@ Feature: Traffic - speeds
When I route I should get When I route I should get
| from | to | route | speed | weights | a:datasources | | from | to | route | speed | weights | a:datasources |
| a | b | ad,de,eb,eb | 30 km/h | 1275.7,400.4,378.2,0 | 1:0:0 | | a | b | ad,de,eb,eb | 30 km/h | 1273.9,400.8,378.5,0 | 1:0:0 |
| a | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | 1:0 | | a | c | ad,dc,dc | 31 km/h | 1273.9,955.4,0 | 1:0 |
| b | c | bc,bc | 27 km/h | 741.5,0 | 1 | | b | c | bc,bc | 27 km/h | 737.2,0 | 1 |
| a | d | ad,ad | 27 km/h | 1275.7,0 | 1 | | a | d | ad,ad | 27 km/h | 1273.9,0 | 1 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 | | d | c | dc,dc | 36 km/h | 955.4,0 | 0 |
| g | b | ab,ab | 1 km/h | 10010.4,0 | 1 | | g | b | ab,ab | 1 km/h | 9951.7,0 | 1 |
| a | g | ab,ab | 1 km/h | 10010.3,0 | 1 | | a | g | ab,ab | 1 km/h | 9951.7,0 | 1 |
Scenario: Weighting based on speed file weights, ETA based on file durations Scenario: Weighting based on speed file weights, ETA based on file durations
@ -106,14 +106,14 @@ Feature: Traffic - speeds
When I route I should get When I route I should get
| from | to | route | speed | weights | a:datasources | | from | to | route | speed | weights | a:datasources |
| a | b | ab,ab | 1 km/h | 20020.73,0 | 1 | | a | b | ab,ab | 1 km/h | 19903.37,0 | 1 |
| a | c | ab,bc,bc | 2 km/h | 20020.73,741.51,0 | 1:1 | | a | c | ab,bc,bc | 2 km/h | 19903.37,737.16,0 | 1:1 |
| b | c | bc,bc | 27 km/h | 741.51,0 | 1 | | b | c | bc,bc | 27 km/h | 737.16,0 | 1 |
| a | d | ab,eb,de,de | 2 km/h | 20020.73,378.17,400.41,0 | 1:0:0 | | a | d | ab,eb,de,de | 2 km/h | 19903.37,378.49,400.75,0 | 1:0:0 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 | | d | c | dc,dc | 36 km/h | 955.45,0 | 0 |
| g | b | ab,ab | 1 km/h | 10010.37,0 | 1 | | g | b | ab,ab | 1 km/h | 9951.69,0 | 1 |
| a | g | ab,ab | 1 km/h | 10010.36,0 | 1 | | a | g | ab,ab | 1 km/h | 9951.68,0 | 1 |
| g | a | ab,ab | 1 km/h | 10010.36,0 | 1 | | g | a | ab,ab | 1 km/h | 9951.68,0 | 1 |
Scenario: Speeds that isolate a single node (a) Scenario: Speeds that isolate a single node (a)
@ -136,13 +136,13 @@ Feature: Traffic - speeds
When I route I should get When I route I should get
| from | to | route | speed | weights | a:datasources | a:speed | a:nodes| | from | to | route | speed | weights | a:datasources | a:speed | a:nodes|
| a | b | fb,fb | 36 km/h | 329.4,0 | 0 | 10 | 6:2 | | a | b | fb,fb | 36 km/h | 328.9,0 | 0 | 10 | 6:2 |
| a | c | fb,bc,bc | 30 km/h | 329.4,741.5,0 | 0:1 | 10:7.5 | 6:2:3 | | a | c | fb,bc,bc | 30 km/h | 328.9,737.2,0 | 0:1 | 10:7.5 | 6:2:3 |
| b | c | bc,bc | 27 km/h | 741.5,0 | 1 | 7.5 | 2:3 | | b | c | bc,bc | 27 km/h | 737.2,0 | 1 | 7.5 | 2:3 |
| a | d | fb,df,df | 36 km/h | 140,487.5,0 | 0:0 | 10:10 | 2:6:4 | | a | d | fb,df,df | 36 km/h | 139.8,486.8,0 | 0:0 | 10:10 | 2:6:4 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 | 10 | 4:3 | | d | c | dc,dc | 36 km/h | 955.4,0 | 0 | 10 | 4:3 |
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 | 10 | 6:2 | | g | b | fb,fb | 36 km/h | 164.4,0 | 0 | 10 | 6:2 |
| a | g | fb,fb | 36 km/h | 164.7,0 | 0 | 10 | 6:2 | | a | g | fb,fb | 36 km/h | 164.5,0 | 0 | 10 | 6:2 |
Scenario: Verify that negative values cause an error, they're not valid at all Scenario: Verify that negative values cause an error, they're not valid at all

View File

@ -62,8 +62,8 @@ Feature: Traffic - turn penalties applied to turn onto which a phantom node snap
When I route I should get When I route I should get
| from | to | route | speed | time | weights | | from | to | route | speed | time | weights |
| a | e | ab,be,be | 36 km/h | 40s +-1 | 16.7,20,0 | | a | e | ab,be,be | 36 km/h | 40s +-1 | 16.7,20,0 |
| 1 | e | ab,be,be | 36 km/h | 30s +-1 | 6.7,20,0 | | 1 | e | ab,be,be | 36 km/h | 30s +-1 | 6.8,20,0 |
| b | f | bc,cf,cf | 36 km/h | 40s +-1 | 20,20,0 | | b | f | bc,cf,cf | 36 km/h | 40s +-1 | 20,20,0 |
| 2 | f | bc,cf,cf | 36 km/h | 30s +-1 | 10,20,0 | | 2 | f | bc,cf,cf | 36 km/h | 30s +-1 | 10.1,20,0 |
| c | g | cd,dg,dg | 144 km/h | 10s +-1 | 120.8,20,0 | | c | g | cd,dg,dg | 144 km/h | 10s +-1 | 120.8,20,0 |
| 3 | g | cd,dg,dg | 54 km/h | 20s +-1 | 110.8,20,0 | | 3 | g | cd,dg,dg | 54 km/h | 20s +-1 | 110.9,20,0 |

View File

@ -5,7 +5,7 @@ Feature: Basic trip planning
Given the profile "testbot" Given the profile "testbot"
Given a grid size of 10 meters Given a grid size of 10 meters
Scenario: Testbot - Trip: Roundtrip with one waypoint Scenario: Testbot - Trip: Invalid options (like was in test suite for a long time)
Given the node map Given the node map
""" """
a b a b
@ -20,8 +20,46 @@ Feature: Basic trip planning
| da | | da |
When I plan a trip I should get When I plan a trip I should get
| waypoints | trips | | waypoints | trips | code |
| a | aa | | a | | InvalidOptions |
Scenario: Testbot - Trip: Roundtrip between same waypoint
Given the node map
"""
a b
c d
"""
And the ways
| nodes |
| ab |
| bc |
| cb |
| da |
When I plan a trip I should get
| waypoints | trips | code |
| a,a | aa | Ok |
Scenario: Testbot - Trip: data version check
Given the node map
"""
a b
c d
"""
And the ways
| nodes |
| ab |
| bc |
| cb |
| da |
And the extract extra arguments "--data_version cucumber_data_version"
When I plan a trip I should get
| waypoints | trips | data_version | code |
| a,a | aa | cucumber_data_version | Ok |
Scenario: Testbot - Trip: Roundtrip with waypoints (less than 10) Scenario: Testbot - Trip: Roundtrip with waypoints (less than 10)
Given the node map Given the node map
@ -38,9 +76,9 @@ Feature: Basic trip planning
| da | | da |
When I plan a trip I should get When I plan a trip I should get
| waypoints | trips | durations | | waypoints | trips | durations | code |
| a,b,c,d | abcda | 7.6 | | a,b,c,d | abcda | 7.6 | Ok |
| d,b,c,a | dbcad | 7.6 | | d,b,c,a | dbcad | 7.6 | Ok |
Scenario: Testbot - Trip: Roundtrip waypoints (more than 10) Scenario: Testbot - Trip: Roundtrip waypoints (more than 10)
Given the node map Given the node map
@ -69,36 +107,37 @@ Feature: Basic trip planning
| waypoints | trips | | waypoints | trips |
| a,b,c,d,e,f,g,h,i,j,k,l | alkjihgfedcba | | a,b,c,d,e,f,g,h,i,j,k,l | alkjihgfedcba |
Scenario: Testbot - Trip: Roundtrip FS waypoints (more than 10) Scenario: Testbot - Trip: FS waypoints (less than 10)
Given the node map
"""
a b c d
l e
k f
j i h g
"""
And the ways
| nodes |
| ab |
| bc |
| de |
| ef |
| fg |
| gh |
| hi |
| ij |
| jk |
| kl |
| la |
When I plan a trip I should get
| waypoints | source | trips |
| a,b,c,d,e,f,g,h,i,j,k,l | first | alkjihgfedcba |
Scenario: Testbot - Trip: Roundtrip FE waypoints (more than 10)
Given the query options Given the query options
| source | last | | source | first |
Given the node map
"""
a b c d
l e
j i g
"""
And the ways
| nodes |
| ab |
| bc |
| de |
| eg |
| gi |
| ij |
| jl |
| la |
When I plan a trip I should get
| waypoints | trips | roundtrip | durations |
| a,b,c,d,e,g,i,j,l | abcdegijla | true | 22 |
| a,b,c,d,e,g,i,j,l | abcljiged | false | 13 |
Scenario: Testbot - Trip: FS waypoints (more than 10)
Given the query options
| source | first |
Given the node map Given the node map
""" """
a b c d a b c d
@ -122,8 +161,67 @@ Feature: Basic trip planning
| la | | la |
When I plan a trip I should get When I plan a trip I should get
| waypoints | trips | | waypoints | trips | roundtrip | durations |
| a,b,c,d,e,f,g,h,i,j,k,l | lkjihgfedcbal | | a,b,c,d,e,f,g,h,i,j,k,l | alkjihgfedcba | true | 22 |
| a,b,c,d,e,f,g,h,i,j,k,l | acblkjihgfed | false | 13 |
Scenario: Testbot - Trip: FE waypoints (less than 10)
Given the query options
| destination | last |
Given the node map
"""
a b c d
l e
j i g
"""
And the ways
| nodes |
| ab |
| bc |
| de |
| eg |
| gi |
| ij |
| jl |
| la |
When I plan a trip I should get
| waypoints | trips | roundtrip | durations |
| a,b,c,d,e,g,i,j,l | labcdegijl | true | 22 |
| a,b,c,d,e,g,i,j,l | degijabcl | false | 14 |
Scenario: Testbot - Trip: FE waypoints (more than 10)
Given the query options
| destination | last |
Given the node map
"""
a b c d
l e
k f
j i h g
"""
And the ways
| nodes |
| ab |
| bc |
| de |
| ef |
| fg |
| gh |
| hi |
| ij |
| jk |
| kl |
| la |
When I plan a trip I should get
| waypoints | trips | roundtrip | durations |
| a,b,c,d,e,f,g,h,i,j,k,l | lkjihgfedcbal | true | 22 |
| a,b,c,d,e,f,g,h,i,j,k,l | cbakjihgfedl | false | 19 |
Scenario: Testbot - Trip: Unroutable roundtrip with waypoints (less than 10) Scenario: Testbot - Trip: Unroutable roundtrip with waypoints (less than 10)
Given the node map Given the node map
@ -221,7 +319,7 @@ Feature: Basic trip planning
When I plan a trip I should get When I plan a trip I should get
| waypoints | source | destination |roundtrip | trips | durations | distance | | waypoints | source | destination |roundtrip | trips | durations | distance |
| a,b,d,e,c | first | last | false | abedc | 8.200000000000001 | 81.6 | | a,b,d,e,c | first | last | false | abedc | 8.200000000000001 | 81.4 |
Scenario: Testbot - Trip: FSE with waypoints (more than 10) Scenario: Testbot - Trip: FSE with waypoints (more than 10)
@ -274,7 +372,7 @@ Feature: Basic trip planning
| a,b,d,e,c | first | last | true | abedca | | a,b,d,e,c | first | last | true | abedca |
Scenario: Testbot - Trip: midway points in isoldated roads should return no trips Scenario: Testbot - Trip: midway points in isolated roads should return no trips
Given the node map Given the node map
""" """
a 1 b a 1 b
@ -370,4 +468,4 @@ Feature: Basic trip planning
When I plan a trip I should get When I plan a trip I should get
| waypoints | trips | durations | geometry | | waypoints | trips | durations | geometry |
| a,b,c,d | abcda | 7.6 | 1,1,1,1.00009,0.99991,1,1,1.00009,1,1,0.99991,1.00009,1,1 | | a,b,c,d | abcda | 7.6 | 1,1,1,1.00009,0.99991,1,1,1.00009,1,1,0.99991,1.00009,1,1 |
| d,b,c,a | dbcad | 7.6 | 0.99991,1.00009,1,1,1,1.00009,0.99991,1,1,1.00009,1,1,0.99991,1.00009 | | d,b,c,a | dbcad | 7.6 | 0.99991,1.00009,1,1,1,1.00009,0.99991,1,1,1.00009,1,1,0.99991,1.00009 |

View File

@ -28,12 +28,12 @@ Feature: Weight tests
| cde | | cde |
When I route I should get When I route I should get
| waypoints | route | a:weight | | waypoints | route | a:weight |
| s,t | abc,cde | 1.1:2:2:1 | | s,t | abc,cde | 1.1:2:2:0.9 |
When I route I should get When I route I should get
| waypoints | route | times | weight_name | weights | | waypoints | route | times | weight_name | weights |
| s,t | abc,cde | 6.1s,0s | duration | 6.1,0 | | s,t | abc,cde | 6s,0s | duration | 6,0 |
# FIXME include/engine/guidance/assemble_geometry.hpp:95 # FIXME include/engine/guidance/assemble_geometry.hpp:95
Scenario: Start and target on the same and adjacent edge Scenario: Start and target on the same and adjacent edge
@ -53,10 +53,10 @@ Feature: Weight tests
When I route I should get When I route I should get
| waypoints | route | distances | weights | times | a:distance | a:duration | a:weight | a:speed | | waypoints | route | distances | weights | times | a:distance | a:duration | a:weight | a:speed |
| s,t | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 2.1 | 2.1 | 9.5 | | s,t | abc,abc | 20m,0m | 2,0 | 2s,0s | 20.034627 | 2 | 2 | 10 |
| t,s | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 2.1 | 2.1 | 9.5 | | t,s | abc,abc | 20m,0m | 2,0 | 2s,0s | 20.034627 | 2 | 2 | 10 |
| s,e | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 30.026527:10.008842 | 3.1:1 | 3.1:1 | 9.7:10 | | s,e | abc,abc | 40m,0m | 3.9,0 | 3.9s,0s | 29.940636:10.017313 | 3:0.9 | 3:0.9 | 10:11.1 |
| e,s | abc,abc | 40m,0m | 4.1,0 | 4.1s,0s | 10.008842:30.026527 | 1:3.1 | 1:3.1 | 10:9.7 | | e,s | abc,abc | 40m,0m | 3.9,0 | 3.9s,0s | 10.017313:29.940636 | 0.9:3 | 0.9:3 | 11.1:10 |
Scenario: Step weights -- way_function: fail if no weight or weight_per_meter property Scenario: Step weights -- way_function: fail if no weight or weight_per_meter property
@ -173,13 +173,13 @@ Feature: Weight tests
| fgh | | fgh |
When I route I should get When I route I should get
| waypoints | route | distance | weights | times | | waypoints | route | distance | weights | times |
| a,f | , | 100m | 99.9,0 | 30s,0s | | a,f | , | 100m | 99.8,0 | 30s,0s |
| f,a | , | 100m | 199.8,0 | 30s,0s | | f,a | , | 100m | 199.9,0 | 30s,0s |
| a,h | , | 140m | 139.9,0 | 42s,0s | | a,h | , | 140m | 139.8,0 | 42s,0s |
| h,a | , | 140m | 279.8,0 | 42s,0s | | h,a | , | 140m | 280.1,0 | 42s,0s |
| f,h | , | 40m | 40,0 | 12s,0s | | f,h | , | 40.1m | 40,0 | 12s,0s |
| h,f | , | 40m | 80,0 | 12s,0s | | h,f | , | 40.1m | 80.2,0 | 12s,0s |
Scenario: Step weights -- segment_function Scenario: Step weights -- segment_function
Given the profile file Given the profile file
@ -281,11 +281,11 @@ Feature: Weight tests
When I route I should get When I route I should get
| waypoints | route | distance | weights | times | | waypoints | route | distance | weights | times |
| a,c | , | 40m +-.1 | 5.119,0 | 289.9s,0s | | a,c | , | 40m +-.1 | 5.12,0 | 290s,0s |
| a,e | ,, | 60m +-.1 | 5.119,1.11,0 | 289.9s,100s,0s | | a,e | ,, | 60m +-.1 | 5.12,1.11,0 | 290s,100s,0s |
| e,a | ,, | 60m +-.1 | 2.21,2.22,0 | 10.1s,200s,0s | | e,a | ,, | 60m +-.1 | 2.21,2.22,0 | 10s,200s,0s |
| e,d | ,, | 40m +-.1 | 4.009,1.11,0 | 189.9s,100s,0s | | e,d | ,, | 40m +-.1 | 4.01,1.11,0 | 190s,100s,0s |
| d,e | ,, | 40m +-.1 | 2.21,1.11,0 | 10.1s,100s,0s | | d,e | ,, | 40m +-.1 | 2.21,1.11,0 | 10s,100s,0s |
@traffic @speed @traffic @speed
Scenario: Step weights -- segment_function with speed and turn updates Scenario: Step weights -- segment_function with speed and turn updates
@ -341,9 +341,9 @@ Feature: Weight tests
When I route I should get When I route I should get
| waypoints | route | distance | weights | times | | waypoints | route | distance | weights | times |
| a,d | , | 59.9m | 20.5,0 | 24s,0s | | a,d | , | 60m | 20.5,0 | 24s,0s |
| a,e | ,, | 60.1m | 27.2,10,0 | 38.5s,11s,0s | | a,e | ,, | 60m | 27.2,10,0 | 38.5s,11s,0s |
| d,e | ,, | 39.9m | 10,10,0 | 11s,11s,0s | | d,e | ,, | 40m | 10,10,0 | 11s,11s,0s |
@traffic @speed @traffic @speed
Scenario: Step weights -- segment_function with speed and turn updates with fallback to durations Scenario: Step weights -- segment_function with speed and turn updates with fallback to durations
@ -375,10 +375,10 @@ Feature: Weight tests
And the customize extra arguments "--segment-speed-file {speeds_file} --turn-penalty-file {penalties_file}" And the customize extra arguments "--segment-speed-file {speeds_file} --turn-penalty-file {penalties_file}"
When I route I should get When I route I should get
| waypoints | route | distance | weights | times | | waypoints | route | distance | weights | times |
| a,d | abcd,abcd | 59.9m | 6.996,0 | 7s,0s | | a,d | abcd,abcd | 60m | 7,0 | 7s,0s |
| a,e | abcd,ce,ce | 60.1m | 6.005,2.002,0 | 6s,2s,0s | | a,e | abcd,ce,ce | 60m | 5.997,2.001,0 | 6s,2s,0s |
| d,e | abcd,ce,ce | 39.9m | 1.991,2.002,0 | 2s,2s,0s | | d,e | abcd,ce,ce | 40m | 2.003,2.001,0 | 2s,2s,0s |
@traffic @speed @traffic @speed
Scenario: Updating speeds without affecting weights. Scenario: Updating speeds without affecting weights.
@ -410,5 +410,5 @@ Feature: Weight tests
And the customize extra arguments "--segment-speed-file {speeds_file}" And the customize extra arguments "--segment-speed-file {speeds_file}"
When I route I should get When I route I should get
| waypoints | route | distance | weights | times | | waypoints | route | distance | weights | times |
| a,b | acdb,acdb | 78.3m | 11.744,0 | 56.4s,0s | | a,b | acdb,acdb | 78.3m | 11.742,0 | 56.4s,0s |

View File

@ -187,5 +187,5 @@ Feature: Check zero speed updates
When I plan a trip I should get When I plan a trip I should get
| waypoints | trips | code | | waypoints | trips | code |
| a,b,c,d | abcda | NoTrips | | a,b,c,d | | NoTrips |
| d,b,c,a | dbcad | NoTrips | | d,b,c,a | | NoTrips |

View File

@ -56,8 +56,8 @@ class BaseAPI
// TODO: check forward/reverse // TODO: check forward/reverse
return json::makeWaypoint( return json::makeWaypoint(
phantom.location, phantom.location,
util::coordinate_calculation::fccApproximateDistance(phantom.location, util::coordinate_calculation::greatCircleDistance(phantom.location,
phantom.input_location), phantom.input_location),
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)).to_string(), facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)).to_string(),
Hint{phantom, facade.GetCheckSum()}); Hint{phantom, facade.GetCheckSum()});
} }
@ -66,8 +66,8 @@ class BaseAPI
// TODO: check forward/reverse // TODO: check forward/reverse
return json::makeWaypoint( return json::makeWaypoint(
phantom.location, phantom.location,
util::coordinate_calculation::fccApproximateDistance(phantom.location, util::coordinate_calculation::greatCircleDistance(phantom.location,
phantom.input_location), phantom.input_location),
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)) facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id))
.to_string()); .to_string());
} }
@ -114,7 +114,7 @@ class BaseAPI
auto waypoint = std::make_unique<fbresult::WaypointBuilder>(*builder); auto waypoint = std::make_unique<fbresult::WaypointBuilder>(*builder);
waypoint->add_location(&location); waypoint->add_location(&location);
waypoint->add_distance(util::coordinate_calculation::fccApproximateDistance( waypoint->add_distance(util::coordinate_calculation::greatCircleDistance(
phantom.location, phantom.input_location)); phantom.location, phantom.input_location));
waypoint->add_name(name_string); waypoint->add_name(name_string);
if (parameters.generate_hints) if (parameters.generate_hints)

View File

@ -89,6 +89,11 @@ class MatchAPI final : public RouteAPI
} }
response.values["matchings"] = std::move(routes); response.values["matchings"] = std::move(routes);
response.values["code"] = "Ok"; response.values["code"] = "Ok";
auto data_timestamp = facade.GetTimestamp();
if (!data_timestamp.empty())
{
response.values["data_version"] = data_timestamp;
}
} }
protected: protected:

View File

@ -122,7 +122,7 @@ inline Result tidy(const MatchParameters &params, Thresholds cfg = {15., 5})
// Walk over adjacent (coord, ts)-pairs, with rhs being the candidate to discard or keep // Walk over adjacent (coord, ts)-pairs, with rhs being the candidate to discard or keep
for (std::size_t current = 0, next = 1; next < params.coordinates.size() - 1; ++current, ++next) for (std::size_t current = 0, next = 1; next < params.coordinates.size() - 1; ++current, ++next)
{ {
auto distance_delta = util::coordinate_calculation::haversineDistance( auto distance_delta = util::coordinate_calculation::greatCircleDistance(
params.coordinates[current], params.coordinates[next]); params.coordinates[current], params.coordinates[next]);
running.distance_in_meters += distance_delta; running.distance_in_meters += distance_delta;
const auto over_distance = running.distance_in_meters >= cfg.distance_in_meters; const auto over_distance = running.distance_in_meters >= cfg.distance_in_meters;

View File

@ -116,6 +116,11 @@ class NearestAPI final : public BaseAPI
} }
response.values["code"] = "Ok"; response.values["code"] = "Ok";
auto data_timestamp = facade.GetTimestamp();
if (!data_timestamp.empty())
{
response.values["data_version"] = data_timestamp;
}
} }
const NearestParameters &parameters; const NearestParameters &parameters;

View File

@ -367,7 +367,7 @@ class RouteAPI : public BaseAPI
// To maintain support for uses of the old default constructors, we check // To maintain support for uses of the old default constructors, we check
// if annotations property was set manually after default construction // if annotations property was set manually after default construction
auto requested_annotations = parameters.annotations_type; auto requested_annotations = parameters.annotations_type;
if ((parameters.annotations == true) && if (parameters.annotations &&
(parameters.annotations_type == RouteParameters::AnnotationsType::None)) (parameters.annotations_type == RouteParameters::AnnotationsType::None))
{ {
requested_annotations = RouteParameters::AnnotationsType::All; requested_annotations = RouteParameters::AnnotationsType::All;
@ -497,10 +497,10 @@ class RouteAPI : public BaseAPI
std::vector<uint32_t> nodes; std::vector<uint32_t> nodes;
if (requested_annotations & RouteParameters::AnnotationsType::Nodes) if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
{ {
nodes.reserve(leg_geometry.osm_node_ids.size()); nodes.reserve(leg_geometry.node_ids.size());
for (const auto node_id : leg_geometry.osm_node_ids) for (const auto node_id : leg_geometry.node_ids)
{ {
nodes.emplace_back(static_cast<uint64_t>(node_id)); nodes.emplace_back(static_cast<uint64_t>(facade.GetOSMNodeIDOfNode(node_id)));
} }
} }
auto nodes_vector = fb_result.CreateVector(nodes); auto nodes_vector = fb_result.CreateVector(nodes);
@ -515,7 +515,7 @@ class RouteAPI : public BaseAPI
{ {
const auto name = facade.GetDatasourceName(i); const auto name = facade.GetDatasourceName(i);
// Length of 0 indicates the first empty name, so we can stop here // Length of 0 indicates the first empty name, so we can stop here
if (name.size() == 0) if (name.empty())
break; break;
names.emplace_back( names.emplace_back(
fb_result.CreateString(std::string(facade.GetDatasourceName(i)))); fb_result.CreateString(std::string(facade.GetDatasourceName(i))));
@ -763,7 +763,7 @@ class RouteAPI : public BaseAPI
// To maintain support for uses of the old default constructors, we check // To maintain support for uses of the old default constructors, we check
// if annotations property was set manually after default construction // if annotations property was set manually after default construction
auto requested_annotations = parameters.annotations_type; auto requested_annotations = parameters.annotations_type;
if ((parameters.annotations == true) && if (parameters.annotations &&
(parameters.annotations_type == RouteParameters::AnnotationsType::None)) (parameters.annotations_type == RouteParameters::AnnotationsType::None))
{ {
requested_annotations = RouteParameters::AnnotationsType::All; requested_annotations = RouteParameters::AnnotationsType::All;
@ -825,10 +825,11 @@ class RouteAPI : public BaseAPI
if (requested_annotations & RouteParameters::AnnotationsType::Nodes) if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
{ {
util::json::Array nodes; util::json::Array nodes;
nodes.values.reserve(leg_geometry.osm_node_ids.size()); nodes.values.reserve(leg_geometry.node_ids.size());
for (const auto node_id : leg_geometry.osm_node_ids) for (const auto node_id : leg_geometry.node_ids)
{ {
nodes.values.push_back(static_cast<std::uint64_t>(node_id)); nodes.values.push_back(
static_cast<std::uint64_t>(facade.GetOSMNodeIDOfNode(node_id)));
} }
annotation.values["nodes"] = std::move(nodes); annotation.values["nodes"] = std::move(nodes);
} }
@ -842,7 +843,7 @@ class RouteAPI : public BaseAPI
{ {
const auto name = facade.GetDatasourceName(i); const auto name = facade.GetDatasourceName(i);
// Length of 0 indicates the first empty name, so we can stop here // Length of 0 indicates the first empty name, so we can stop here
if (name.size() == 0) if (name.empty())
break; break;
datasource_names.values.push_back(std::string(facade.GetDatasourceName(i))); datasource_names.values.push_back(std::string(facade.GetDatasourceName(i)));
} }
@ -888,81 +889,92 @@ class RouteAPI : public BaseAPI
const bool reversed_source = source_traversed_in_reverse[idx]; const bool reversed_source = source_traversed_in_reverse[idx];
const bool reversed_target = target_traversed_in_reverse[idx]; const bool reversed_target = target_traversed_in_reverse[idx];
auto leg_geometry = guidance::assembleGeometry(BaseAPI::facade,
path_data,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_source,
reversed_target);
auto leg = guidance::assembleLeg(facade, auto leg = guidance::assembleLeg(facade,
path_data, path_data,
leg_geometry,
phantoms.source_phantom, phantoms.source_phantom,
phantoms.target_phantom, phantoms.target_phantom,
reversed_target, reversed_target);
parameters.steps);
util::Log(logDEBUG) << "Assembling steps " << std::endl; guidance::LegGeometry leg_geometry;
if (parameters.steps)
// Generate additional geometry data if request includes turn-by-turn steps,
// overview geometry or route geometry annotations.
// Note that overview geometry and route geometry annotations can return different
// results depending on whether turn-by-turn steps are also requested.
if (parameters.steps || parameters.annotations ||
parameters.overview != RouteParameters::OverviewType::False)
{ {
auto steps = guidance::assembleSteps(BaseAPI::facade,
path_data,
leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_source,
reversed_target);
// Apply maneuver overrides before any other post leg_geometry = guidance::assembleGeometry(BaseAPI::facade,
// processing is performed path_data,
guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry); phantoms.source_phantom,
phantoms.target_phantom,
reversed_source,
reversed_target);
// Collapse segregated steps before others util::Log(logDEBUG) << "Assembling steps " << std::endl;
steps = guidance::collapseSegregatedTurnInstructions(std::move(steps)); if (parameters.steps)
{
leg.summary = guidance::assembleSummary(
facade, path_data, phantoms.target_phantom, reversed_target);
/* Perform step-based post-processing. auto steps = guidance::assembleSteps(BaseAPI::facade,
* path_data,
* Using post-processing on basis of route-steps for a single leg at a time leg_geometry,
* comes at the cost that we cannot count the correct exit for roundabouts. phantoms.source_phantom,
* We can only emit the exit nr/intersections up to/starting at a part of the leg. phantoms.target_phantom,
* If a roundabout is not terminated in a leg, we will end up with a reversed_source,
*enter-roundabout reversed_target);
* and exit-roundabout-nr where the exit nr is out of sync with the previous enter.
*
* | S |
* * *
* ----* * ----
* T
* ----* * ----
* V * *
* | |
* | |
*
* Coming from S via V to T, we end up with the legs S->V and V->T. V-T will say to
*take
* the second exit, even though counting from S it would be the third.
* For S, we only emit `roundabout` without an exit number, showing that we enter a
*roundabout
* to find a via point.
* The same exit will be emitted, though, if we should start routing at S, making
* the overall response consistent.
*
* CAUTION: order of post-processing steps is important
* - handleRoundabouts must be called before collapseTurnInstructions that
* expects post-processed roundabouts
*/
guidance::trimShortSegments(steps, leg_geometry); // Apply maneuver overrides before any other post
leg.steps = guidance::handleRoundabouts(std::move(steps)); // processing is performed
leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps)); guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry);
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
leg.steps = guidance::buildIntersections(std::move(leg.steps)); // Collapse segregated steps before others
leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps)); steps = guidance::collapseSegregatedTurnInstructions(std::move(steps));
leg.steps = guidance::assignRelativeLocations(std::move(leg.steps),
leg_geometry, /* Perform step-based post-processing.
phantoms.source_phantom, *
phantoms.target_phantom); * Using post-processing on basis of route-steps for a single leg at a time
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps); * comes at the cost that we cannot count the correct exit for roundabouts.
* We can only emit the exit nr/intersections up to/starting at a part of the
*leg. If a roundabout is not terminated in a leg, we will end up with a
*enter-roundabout
* and exit-roundabout-nr where the exit nr is out of sync with the previous
*enter.
*
* | S |
* * *
* ----* * ----
* T
* ----* * ----
* V * *
* | |
* | |
*
* Coming from S via V to T, we end up with the legs S->V and V->T. V-T will say
*to take the second exit, even though counting from S it would be the third.
* For S, we only emit `roundabout` without an exit number, showing that we
*enter a roundabout to find a via point. The same exit will be emitted, though,
*if we should start routing at S, making the overall response consistent.
*
* CAUTION: order of post-processing steps is important
* - handleRoundabouts must be called before collapseTurnInstructions that
* expects post-processed roundabouts
*/
guidance::trimShortSegments(steps, leg_geometry);
leg.steps = guidance::handleRoundabouts(std::move(steps));
leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps));
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
leg.steps = guidance::buildIntersections(std::move(leg.steps));
leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps));
leg.steps = guidance::assignRelativeLocations(std::move(leg.steps),
leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom);
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps);
}
} }
leg_geometries.push_back(std::move(leg_geometry)); leg_geometries.push_back(std::move(leg_geometry));

View File

@ -226,6 +226,11 @@ class TableAPI final : public BaseAPI
} }
response.values["code"] = "Ok"; response.values["code"] = "Ok";
auto data_timestamp = facade.GetTimestamp();
if (!data_timestamp.empty())
{
response.values["data_version"] = data_timestamp;
}
} }
protected: protected:

View File

@ -87,6 +87,11 @@ class TripAPI final : public RouteAPI
} }
response.values["trips"] = std::move(routes); response.values["trips"] = std::move(routes);
response.values["code"] = "Ok"; response.values["code"] = "Ok";
auto data_timestamp = facade.GetTimestamp();
if (!data_timestamp.empty())
{
response.values["data_version"] = data_timestamp;
}
} }
protected: protected:

View File

@ -36,24 +36,27 @@ template <> class AlgorithmDataFacade<CH>
virtual unsigned GetNumberOfEdges() const = 0; virtual unsigned GetNumberOfEdges() const = 0;
virtual unsigned GetOutDegree(const NodeID n) const = 0; virtual unsigned GetOutDegree(const NodeID edge_based_node_id) const = 0;
virtual NodeID GetTarget(const EdgeID e) const = 0; virtual NodeID GetTarget(const EdgeID edge_based_edge_id) const = 0;
virtual const EdgeData &GetEdgeData(const EdgeID e) const = 0; virtual const EdgeData &GetEdgeData(const EdgeID edge_based_edge_id) const = 0;
virtual EdgeRange GetAdjacentEdgeRange(const NodeID node) const = 0; virtual EdgeRange GetAdjacentEdgeRange(const NodeID edge_based_node_id) const = 0;
// searches for a specific edge // searches for a specific edge
virtual EdgeID FindEdge(const NodeID from, const NodeID to) const = 0; virtual EdgeID FindEdge(const NodeID edge_based_node_from,
const NodeID edge_based_node_to) const = 0;
virtual EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const = 0; virtual EdgeID FindEdgeInEitherDirection(const NodeID edge_based_node_from,
const NodeID edge_based_node_to) const = 0;
virtual EdgeID virtual EdgeID FindEdgeIndicateIfReverse(const NodeID edge_based_node_from,
FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const = 0; const NodeID edge_based_node_to,
bool &result) const = 0;
virtual EdgeID FindSmallestEdge(const NodeID from, virtual EdgeID FindSmallestEdge(const NodeID edge_based_node_from,
const NodeID to, const NodeID edge_based_node_to,
const std::function<bool(EdgeData)> filter) const = 0; const std::function<bool(EdgeData)> filter) const = 0;
}; };
@ -70,23 +73,24 @@ template <> class AlgorithmDataFacade<MLD>
virtual unsigned GetNumberOfEdges() const = 0; virtual unsigned GetNumberOfEdges() const = 0;
virtual unsigned GetOutDegree(const NodeID n) const = 0; virtual unsigned GetOutDegree(const NodeID edge_based_node_id) const = 0;
virtual EdgeRange GetAdjacentEdgeRange(const NodeID node) const = 0; virtual EdgeRange GetAdjacentEdgeRange(const NodeID edge_based_node_id) const = 0;
virtual EdgeWeight GetNodeWeight(const NodeID node) const = 0; virtual EdgeWeight GetNodeWeight(const NodeID edge_based_node_id) const = 0;
virtual EdgeWeight GetNodeDuration(const NodeID node) const = 0; // TODO: to be removed virtual EdgeWeight
GetNodeDuration(const NodeID edge_based_node_id) const = 0; // TODO: to be removed
virtual EdgeDistance GetNodeDistance(const NodeID node) const = 0; virtual EdgeDistance GetNodeDistance(const NodeID edge_based_node_id) const = 0;
virtual bool IsForwardEdge(EdgeID edge) const = 0; virtual bool IsForwardEdge(EdgeID edge_based_edge_id) const = 0;
virtual bool IsBackwardEdge(EdgeID edge) const = 0; virtual bool IsBackwardEdge(EdgeID edge_based_edge_id) const = 0;
virtual NodeID GetTarget(const EdgeID e) const = 0; virtual NodeID GetTarget(const EdgeID edge_based_edge_id) const = 0;
virtual const EdgeData &GetEdgeData(const EdgeID e) const = 0; virtual const EdgeData &GetEdgeData(const EdgeID edge_based_edge_id) const = 0;
virtual const partitioner::MultiLevelPartitionView &GetMultiLevelPartition() const = 0; virtual const partitioner::MultiLevelPartitionView &GetMultiLevelPartition() const = 0;
@ -94,10 +98,12 @@ template <> class AlgorithmDataFacade<MLD>
virtual const customizer::CellMetricView &GetCellMetric() const = 0; virtual const customizer::CellMetricView &GetCellMetric() const = 0;
virtual EdgeRange GetBorderEdgeRange(const LevelID level, const NodeID node) const = 0; virtual EdgeRange GetBorderEdgeRange(const LevelID level,
const NodeID edge_based_node_id) const = 0;
// searches for a specific edge // searches for a specific edge
virtual EdgeID FindEdge(const NodeID from, const NodeID to) const = 0; virtual EdgeID FindEdge(const NodeID edge_based_node_from,
const NodeID edge_based_node_to) const = 0;
}; };
} // namespace datafacade } // namespace datafacade
} // namespace engine } // namespace engine

View File

@ -73,45 +73,52 @@ class ContiguousInternalMemoryAlgorithmDataFacade<CH> : public datafacade::Algor
unsigned GetNumberOfEdges() const override final { return m_query_graph.GetNumberOfEdges(); } unsigned GetNumberOfEdges() const override final { return m_query_graph.GetNumberOfEdges(); }
unsigned GetOutDegree(const NodeID n) const override final unsigned GetOutDegree(const NodeID edge_based_node_id) const override final
{ {
return m_query_graph.GetOutDegree(n); return m_query_graph.GetOutDegree(edge_based_node_id);
} }
NodeID GetTarget(const EdgeID e) const override final { return m_query_graph.GetTarget(e); } NodeID GetTarget(const EdgeID edge_based_edge_id) const override final
const EdgeData &GetEdgeData(const EdgeID e) const override final
{ {
return m_query_graph.GetEdgeData(e); return m_query_graph.GetTarget(edge_based_edge_id);
} }
EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final const EdgeData &GetEdgeData(const EdgeID edge_based_edge_id) const override final
{ {
return m_query_graph.GetAdjacentEdgeRange(node); return m_query_graph.GetEdgeData(edge_based_edge_id);
}
EdgeRange GetAdjacentEdgeRange(const NodeID edge_based_node_id) const override final
{
return m_query_graph.GetAdjacentEdgeRange(edge_based_node_id);
} }
// searches for a specific edge // searches for a specific edge
EdgeID FindEdge(const NodeID from, const NodeID to) const override final EdgeID FindEdge(const NodeID edge_based_node_from,
const NodeID edge_based_node_to) const override final
{ {
return m_query_graph.FindEdge(from, to); return m_query_graph.FindEdge(edge_based_node_from, edge_based_node_to);
} }
EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const override final EdgeID FindEdgeInEitherDirection(const NodeID edge_based_node_from,
const NodeID edge_based_node_to) const override final
{ {
return m_query_graph.FindEdgeInEitherDirection(from, to); return m_query_graph.FindEdgeInEitherDirection(edge_based_node_from, edge_based_node_to);
} }
EdgeID EdgeID FindEdgeIndicateIfReverse(const NodeID edge_based_node_from,
FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const override final const NodeID edge_based_node_to,
bool &result) const override final
{ {
return m_query_graph.FindEdgeIndicateIfReverse(from, to, result); return m_query_graph.FindEdgeIndicateIfReverse(
edge_based_node_from, edge_based_node_to, result);
} }
EdgeID FindSmallestEdge(const NodeID from, EdgeID FindSmallestEdge(const NodeID edge_based_node_from,
const NodeID to, const NodeID edge_based_node_to,
std::function<bool(EdgeData)> filter) const override final std::function<bool(EdgeData)> filter) const override final
{ {
return m_query_graph.FindSmallestEdge(from, to, filter); return m_query_graph.FindSmallestEdge(edge_based_node_from, edge_based_node_to, filter);
} }
}; };
@ -126,11 +133,9 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{ {
private: private:
using super = BaseDataFacade; using super = BaseDataFacade;
using IndexBlock = util::RangeTable<16, storage::Ownership::View>::BlockT;
using RTreeLeaf = super::RTreeLeaf; using RTreeLeaf = super::RTreeLeaf;
using SharedRTree = util::StaticRTree<RTreeLeaf, storage::Ownership::View>; using SharedRTree = util::StaticRTree<RTreeLeaf, storage::Ownership::View>;
using SharedGeospatialQuery = GeospatialQuery<SharedRTree, BaseDataFacade>; using SharedGeospatialQuery = GeospatialQuery<SharedRTree, BaseDataFacade>;
using RTreeNode = SharedRTree::TreeNode;
extractor::ClassData exclude_mask; extractor::ClassData exclude_mask;
extractor::ProfileProperties *m_profile_properties; extractor::ProfileProperties *m_profile_properties;
@ -231,76 +236,80 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
} }
// node and edge information access // node and edge information access
util::Coordinate GetCoordinateOfNode(const NodeID id) const override final util::Coordinate GetCoordinateOfNode(const NodeID node_based_node_id) const override final
{ {
return m_coordinate_list[id]; return m_coordinate_list[node_based_node_id];
} }
OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const override final OSMNodeID GetOSMNodeIDOfNode(const NodeID node_based_node_id) const override final
{ {
return m_osmnodeid_list[id]; return m_osmnodeid_list[node_based_node_id];
} }
NodeForwardRange GetUncompressedForwardGeometry(const EdgeID id) const override final NodeForwardRange GetUncompressedForwardGeometry(const PackedGeometryID id) const override final
{ {
return segment_data.GetForwardGeometry(id); return segment_data.GetForwardGeometry(id);
} }
NodeReverseRange GetUncompressedReverseGeometry(const EdgeID id) const override final NodeReverseRange GetUncompressedReverseGeometry(const PackedGeometryID id) const override final
{ {
return segment_data.GetReverseGeometry(id); return segment_data.GetReverseGeometry(id);
} }
DurationForwardRange GetUncompressedForwardDurations(const EdgeID id) const override final DurationForwardRange
GetUncompressedForwardDurations(const PackedGeometryID id) const override final
{ {
return segment_data.GetForwardDurations(id); return segment_data.GetForwardDurations(id);
} }
DurationReverseRange GetUncompressedReverseDurations(const EdgeID id) const override final DurationReverseRange
GetUncompressedReverseDurations(const PackedGeometryID id) const override final
{ {
return segment_data.GetReverseDurations(id); return segment_data.GetReverseDurations(id);
} }
WeightForwardRange GetUncompressedForwardWeights(const EdgeID id) const override final WeightForwardRange GetUncompressedForwardWeights(const PackedGeometryID id) const override final
{ {
return segment_data.GetForwardWeights(id); return segment_data.GetForwardWeights(id);
} }
WeightReverseRange GetUncompressedReverseWeights(const EdgeID id) const override final WeightReverseRange GetUncompressedReverseWeights(const PackedGeometryID id) const override final
{ {
return segment_data.GetReverseWeights(id); return segment_data.GetReverseWeights(id);
} }
// Returns the data source ids that were used to supply the edge // Returns the data source ids that were used to supply the edge
// weights. // weights.
DatasourceForwardRange GetUncompressedForwardDatasources(const EdgeID id) const override final DatasourceForwardRange
GetUncompressedForwardDatasources(const PackedGeometryID id) const override final
{ {
return segment_data.GetForwardDatasources(id); return segment_data.GetForwardDatasources(id);
} }
// Returns the data source ids that were used to supply the edge // Returns the data source ids that were used to supply the edge
// weights. // weights.
DatasourceReverseRange GetUncompressedReverseDatasources(const EdgeID id) const override final DatasourceReverseRange
GetUncompressedReverseDatasources(const PackedGeometryID id) const override final
{ {
return segment_data.GetReverseDatasources(id); return segment_data.GetReverseDatasources(id);
} }
TurnPenalty GetWeightPenaltyForEdgeID(const EdgeID id) const override final TurnPenalty GetWeightPenaltyForEdgeID(const EdgeID edge_based_edge_id) const override final
{ {
BOOST_ASSERT(m_turn_weight_penalties.size() > id); BOOST_ASSERT(m_turn_weight_penalties.size() > edge_based_edge_id);
return m_turn_weight_penalties[id]; return m_turn_weight_penalties[edge_based_edge_id];
} }
TurnPenalty GetDurationPenaltyForEdgeID(const EdgeID id) const override final TurnPenalty GetDurationPenaltyForEdgeID(const EdgeID edge_based_edge_id) const override final
{ {
BOOST_ASSERT(m_turn_duration_penalties.size() > id); BOOST_ASSERT(m_turn_duration_penalties.size() > edge_based_edge_id);
return m_turn_duration_penalties[id]; return m_turn_duration_penalties[edge_based_edge_id];
} }
osrm::guidance::TurnInstruction osrm::guidance::TurnInstruction
GetTurnInstructionForEdgeID(const EdgeID id) const override final GetTurnInstructionForEdgeID(const EdgeID edge_based_edge_id) const override final
{ {
return turn_data.GetTurnInstruction(id); return turn_data.GetTurnInstruction(edge_based_edge_id);
} }
std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west, std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west,
@ -444,29 +453,29 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return std::string(m_data_timestamp.begin(), m_data_timestamp.end()); return std::string(m_data_timestamp.begin(), m_data_timestamp.end());
} }
GeometryID GetGeometryIndex(const NodeID id) const override final GeometryID GetGeometryIndex(const NodeID edge_based_node_id) const override final
{ {
return edge_based_node_data.GetGeometryID(id); return edge_based_node_data.GetGeometryID(edge_based_node_id);
} }
ComponentID GetComponentID(const NodeID id) const override final ComponentID GetComponentID(const NodeID edge_based_node_id) const override final
{ {
return edge_based_node_data.GetComponentID(id); return edge_based_node_data.GetComponentID(edge_based_node_id);
} }
extractor::TravelMode GetTravelMode(const NodeID id) const override final extractor::TravelMode GetTravelMode(const NodeID edge_based_node_id) const override final
{ {
return edge_based_node_data.GetTravelMode(id); return edge_based_node_data.GetTravelMode(edge_based_node_id);
} }
extractor::ClassData GetClassData(const NodeID id) const override final extractor::ClassData GetClassData(const NodeID edge_based_node_id) const override final
{ {
return edge_based_node_data.GetClassData(id); return edge_based_node_data.GetClassData(edge_based_node_id);
} }
bool ExcludeNode(const NodeID id) const override final bool ExcludeNode(const NodeID edge_based_node_id) const override final
{ {
return (edge_based_node_data.GetClassData(id) & exclude_mask) > 0; return (edge_based_node_data.GetClassData(edge_based_node_id) & exclude_mask) > 0;
} }
std::vector<std::string> GetClasses(const extractor::ClassData class_data) const override final std::vector<std::string> GetClasses(const extractor::ClassData class_data) const override final
@ -480,9 +489,9 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return classes; return classes;
} }
NameID GetNameIndex(const NodeID id) const override final NameID GetNameIndex(const NodeID edge_based_node_id) const override final
{ {
return edge_based_node_data.GetNameID(id); return edge_based_node_data.GetNameID(edge_based_node_id);
} }
StringView GetNameForID(const NameID id) const override final StringView GetNameForID(const NameID id) const override final
@ -537,32 +546,37 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
return m_profile_properties->GetWeightMultiplier(); return m_profile_properties->GetWeightMultiplier();
} }
util::guidance::BearingClass GetBearingClass(const NodeID node) const override final util::guidance::BearingClass
GetBearingClass(const NodeID node_based_node_id) const override final
{ {
return intersection_bearings_view.GetBearingClass(node); return intersection_bearings_view.GetBearingClass(node_based_node_id);
} }
guidance::TurnBearing PreTurnBearing(const EdgeID eid) const override final guidance::TurnBearing PreTurnBearing(const EdgeID edge_based_edge_id) const override final
{ {
return turn_data.GetPreTurnBearing(eid); return turn_data.GetPreTurnBearing(edge_based_edge_id);
} }
guidance::TurnBearing PostTurnBearing(const EdgeID eid) const override final guidance::TurnBearing PostTurnBearing(const EdgeID edge_based_edge_id) const override final
{ {
return turn_data.GetPostTurnBearing(eid); return turn_data.GetPostTurnBearing(edge_based_edge_id);
} }
util::guidance::EntryClass GetEntryClass(const EdgeID turn_id) const override final util::guidance::EntryClass GetEntryClass(const EdgeID edge_based_edge_id) const override final
{ {
auto entry_class_id = turn_data.GetEntryClassID(turn_id); auto entry_class_id = turn_data.GetEntryClassID(edge_based_edge_id);
return m_entry_class_table.at(entry_class_id); return m_entry_class_table.at(entry_class_id);
} }
bool HasLaneData(const EdgeID id) const override final { return turn_data.HasLaneData(id); } bool HasLaneData(const EdgeID edge_based_edge_id) const override final
util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const override final
{ {
BOOST_ASSERT(HasLaneData(id)); return turn_data.HasLaneData(edge_based_edge_id);
return m_lane_tupel_id_pairs.at(turn_data.GetLaneDataID(id)); }
util::guidance::LaneTupleIdPair
GetLaneData(const EdgeID edge_based_edge_id) const override final
{
BOOST_ASSERT(HasLaneData(edge_based_edge_id));
return m_lane_tupel_id_pairs.at(turn_data.GetLaneDataID(edge_based_edge_id));
} }
extractor::TurnLaneDescription extractor::TurnLaneDescription
@ -577,15 +591,15 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
m_lane_description_offsets[lane_description_id + 1]); m_lane_description_offsets[lane_description_id + 1]);
} }
bool IsLeftHandDriving(const NodeID id) const override final bool IsLeftHandDriving(const NodeID edge_based_node_id) const override final
{ {
// TODO: can be moved to a data block indexed by GeometryID // TODO: can be moved to a data block indexed by GeometryID
return edge_based_node_data.IsLeftHandDriving(id); return edge_based_node_data.IsLeftHandDriving(edge_based_node_id);
} }
bool IsSegregated(const NodeID id) const override final bool IsSegregated(const NodeID edge_based_node_id) const override final
{ {
return edge_based_node_data.IsSegregated(id); return edge_based_node_data.IsSegregated(edge_based_node_id);
} }
std::vector<extractor::ManeuverOverride> std::vector<extractor::ManeuverOverride>
@ -691,57 +705,62 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
unsigned GetNumberOfEdges() const override final { return query_graph.GetNumberOfEdges(); } unsigned GetNumberOfEdges() const override final { return query_graph.GetNumberOfEdges(); }
unsigned GetOutDegree(const NodeID n) const override final unsigned GetOutDegree(const NodeID edge_based_node_id) const override final
{ {
return query_graph.GetOutDegree(n); return query_graph.GetOutDegree(edge_based_node_id);
} }
EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final EdgeRange GetAdjacentEdgeRange(const NodeID edge_based_node_id) const override final
{ {
return query_graph.GetAdjacentEdgeRange(node); return query_graph.GetAdjacentEdgeRange(edge_based_node_id);
} }
EdgeWeight GetNodeWeight(const NodeID node) const override final EdgeWeight GetNodeWeight(const NodeID edge_based_node_id) const override final
{ {
return query_graph.GetNodeWeight(node); return query_graph.GetNodeWeight(edge_based_node_id);
} }
EdgeDuration GetNodeDuration(const NodeID node) const override final EdgeDuration GetNodeDuration(const NodeID edge_based_node_id) const override final
{ {
return query_graph.GetNodeDuration(node); return query_graph.GetNodeDuration(edge_based_node_id);
} }
EdgeDistance GetNodeDistance(const NodeID node) const override final EdgeDistance GetNodeDistance(const NodeID edge_based_node_id) const override final
{ {
return query_graph.GetNodeDistance(node); return query_graph.GetNodeDistance(edge_based_node_id);
} }
bool IsForwardEdge(const NodeID node) const override final bool IsForwardEdge(const NodeID edge_based_node_id) const override final
{ {
return query_graph.IsForwardEdge(node); return query_graph.IsForwardEdge(edge_based_node_id);
} }
bool IsBackwardEdge(const NodeID node) const override final bool IsBackwardEdge(const NodeID edge_based_node_id) const override final
{ {
return query_graph.IsBackwardEdge(node); return query_graph.IsBackwardEdge(edge_based_node_id);
} }
NodeID GetTarget(const EdgeID e) const override final { return query_graph.GetTarget(e); } NodeID GetTarget(const EdgeID edge_based_edge_id) const override final
const EdgeData &GetEdgeData(const EdgeID e) const override final
{ {
return query_graph.GetEdgeData(e); return query_graph.GetTarget(edge_based_edge_id);
} }
EdgeRange GetBorderEdgeRange(const LevelID level, const NodeID node) const override final const EdgeData &GetEdgeData(const EdgeID edge_based_edge_id) const override final
{ {
return query_graph.GetBorderEdgeRange(level, node); return query_graph.GetEdgeData(edge_based_edge_id);
}
EdgeRange GetBorderEdgeRange(const LevelID level,
const NodeID edge_based_node_id) const override final
{
return query_graph.GetBorderEdgeRange(level, edge_based_node_id);
} }
// searches for a specific edge // searches for a specific edge
EdgeID FindEdge(const NodeID from, const NodeID to) const override final EdgeID FindEdge(const NodeID edge_based_node_from,
const NodeID edge_based_node_to) const override final
{ {
return query_graph.FindEdge(from, to); return query_graph.FindEdge(edge_based_node_from, edge_based_node_to);
} }
}; };

View File

@ -77,46 +77,51 @@ class BaseDataFacade
virtual std::string GetTimestamp() const = 0; virtual std::string GetTimestamp() const = 0;
// node and edge information access // node and edge information access
virtual util::Coordinate GetCoordinateOfNode(const NodeID id) const = 0; virtual util::Coordinate GetCoordinateOfNode(const NodeID node_based_node_id) const = 0;
virtual OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const = 0; virtual OSMNodeID GetOSMNodeIDOfNode(const NodeID node_based_node_id) const = 0;
virtual GeometryID GetGeometryIndex(const NodeID id) const = 0; virtual GeometryID GetGeometryIndex(const NodeID edge_based_node_id) const = 0;
virtual ComponentID GetComponentID(const NodeID id) const = 0; virtual ComponentID GetComponentID(const NodeID edge_based_node_id) const = 0;
virtual NodeForwardRange GetUncompressedForwardGeometry(const EdgeID id) const = 0; virtual NodeForwardRange GetUncompressedForwardGeometry(const PackedGeometryID id) const = 0;
virtual NodeReverseRange GetUncompressedReverseGeometry(const EdgeID id) const = 0; virtual NodeReverseRange GetUncompressedReverseGeometry(const PackedGeometryID id) const = 0;
virtual TurnPenalty GetWeightPenaltyForEdgeID(const EdgeID id) const = 0; virtual TurnPenalty GetWeightPenaltyForEdgeID(const EdgeID edge_based_edge_id) const = 0;
virtual TurnPenalty GetDurationPenaltyForEdgeID(const EdgeID id) const = 0; virtual TurnPenalty GetDurationPenaltyForEdgeID(const EdgeID edge_based_edge_id) const = 0;
// Gets the weight values for each segment in an uncompressed geometry. // Gets the weight values for each segment in an uncompressed geometry.
// Should always be 1 shorter than GetUncompressedGeometry // Should always be 1 shorter than GetUncompressedGeometry
virtual WeightForwardRange GetUncompressedForwardWeights(const EdgeID id) const = 0; virtual WeightForwardRange GetUncompressedForwardWeights(const PackedGeometryID id) const = 0;
virtual WeightReverseRange GetUncompressedReverseWeights(const EdgeID id) const = 0; virtual WeightReverseRange GetUncompressedReverseWeights(const PackedGeometryID id) const = 0;
// Gets the duration values for each segment in an uncompressed geometry. // Gets the duration values for each segment in an uncompressed geometry.
// Should always be 1 shorter than GetUncompressedGeometry // Should always be 1 shorter than GetUncompressedGeometry
virtual DurationForwardRange GetUncompressedForwardDurations(const EdgeID id) const = 0; virtual DurationForwardRange
virtual DurationReverseRange GetUncompressedReverseDurations(const EdgeID id) const = 0; GetUncompressedForwardDurations(const PackedGeometryID id) const = 0;
virtual DurationReverseRange
GetUncompressedReverseDurations(const PackedGeometryID id) const = 0;
// Returns the data source ids that were used to supply the edge // Returns the data source ids that were used to supply the edge
// weights. Will return an empty array when only the base profile is used. // weights. Will return an empty array when only the base profile is used.
virtual DatasourceForwardRange GetUncompressedForwardDatasources(const EdgeID id) const = 0; virtual DatasourceForwardRange
virtual DatasourceReverseRange GetUncompressedReverseDatasources(const EdgeID id) const = 0; GetUncompressedForwardDatasources(const PackedGeometryID id) const = 0;
virtual DatasourceReverseRange
GetUncompressedReverseDatasources(const PackedGeometryID id) const = 0;
// Gets the name of a datasource // Gets the name of a datasource
virtual StringView GetDatasourceName(const DatasourceID id) const = 0; virtual StringView GetDatasourceName(const DatasourceID id) const = 0;
virtual osrm::guidance::TurnInstruction GetTurnInstructionForEdgeID(const EdgeID id) const = 0; virtual osrm::guidance::TurnInstruction
GetTurnInstructionForEdgeID(const EdgeID edge_based_edge_id) const = 0;
virtual extractor::TravelMode GetTravelMode(const NodeID id) const = 0; virtual extractor::TravelMode GetTravelMode(const NodeID edge_based_node_id) const = 0;
virtual extractor::ClassData GetClassData(const NodeID id) const = 0; virtual extractor::ClassData GetClassData(const NodeID edge_based_node_id) const = 0;
virtual bool ExcludeNode(const NodeID id) const = 0; virtual bool ExcludeNode(const NodeID edge_based_node_id) const = 0;
virtual std::vector<std::string> GetClasses(const extractor::ClassData class_data) const = 0; virtual std::vector<std::string> GetClasses(const extractor::ClassData class_data) const = 0;
@ -182,12 +187,12 @@ class BaseDataFacade
const Approach approach, const Approach approach,
const bool use_all_edges = false) const = 0; const bool use_all_edges = false) const = 0;
virtual bool HasLaneData(const EdgeID id) const = 0; virtual bool HasLaneData(const EdgeID edge_based_edge_id) const = 0;
virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0; virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID edge_based_edge_id) const = 0;
virtual extractor::TurnLaneDescription virtual extractor::TurnLaneDescription
GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0; GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0;
virtual NameID GetNameIndex(const NodeID id) const = 0; virtual NameID GetNameIndex(const NodeID edge_based_node_id) const = 0;
virtual StringView GetNameForID(const NameID id) const = 0; virtual StringView GetNameForID(const NameID id) const = 0;
@ -209,16 +214,16 @@ class BaseDataFacade
virtual double GetWeightMultiplier() const = 0; virtual double GetWeightMultiplier() const = 0;
virtual osrm::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const = 0; virtual osrm::guidance::TurnBearing PreTurnBearing(const EdgeID edge_based_edge_id) const = 0;
virtual osrm::guidance::TurnBearing PostTurnBearing(const EdgeID eid) const = 0; virtual osrm::guidance::TurnBearing PostTurnBearing(const EdgeID edge_based_edge_id) const = 0;
virtual util::guidance::BearingClass GetBearingClass(const NodeID node) const = 0; virtual util::guidance::BearingClass GetBearingClass(const NodeID node_based_node_id) const = 0;
virtual util::guidance::EntryClass GetEntryClass(const EdgeID turn_id) const = 0; virtual util::guidance::EntryClass GetEntryClass(const EdgeID edge_based_edge_id) const = 0;
virtual bool IsLeftHandDriving(const NodeID id) const = 0; virtual bool IsLeftHandDriving(const NodeID edge_based_node_id) const = 0;
virtual bool IsSegregated(const NodeID) const = 0; virtual bool IsSegregated(const NodeID edge_based_node_id) const = 0;
virtual std::vector<extractor::ManeuverOverride> virtual std::vector<extractor::ManeuverOverride>
GetOverridesThatStartAt(const NodeID edge_based_node_id) const = 0; GetOverridesThatStartAt(const NodeID edge_based_node_id) const = 0;

View File

@ -484,7 +484,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
current < forward_geometry.begin() + data.fwd_segment_position; current < forward_geometry.begin() + data.fwd_segment_position;
++current) ++current)
{ {
forward_distance_offset += util::coordinate_calculation::fccApproximateDistance( forward_distance_offset += util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(*current), datafacade.GetCoordinateOfNode(*current),
datafacade.GetCoordinateOfNode(*std::next(current))); datafacade.GetCoordinateOfNode(*std::next(current)));
} }
@ -494,7 +494,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
EdgeWeight forward_weight = forward_weights[data.fwd_segment_position]; EdgeWeight forward_weight = forward_weights[data.fwd_segment_position];
EdgeDuration forward_duration = forward_durations[data.fwd_segment_position]; EdgeDuration forward_duration = forward_durations[data.fwd_segment_position];
EdgeDistance forward_distance = util::coordinate_calculation::fccApproximateDistance( EdgeDistance forward_distance = util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)), datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)),
point_on_segment); point_on_segment);
@ -514,7 +514,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
current != std::prev(forward_geometry.end()); current != std::prev(forward_geometry.end());
++current) ++current)
{ {
reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance( reverse_distance_offset += util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(*current), datafacade.GetCoordinateOfNode(*current),
datafacade.GetCoordinateOfNode(*std::next(current))); datafacade.GetCoordinateOfNode(*std::next(current)));
} }
@ -523,7 +523,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1]; reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1];
EdgeDuration reverse_duration = EdgeDuration reverse_duration =
reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1]; reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1];
EdgeDistance reverse_distance = util::coordinate_calculation::fccApproximateDistance( EdgeDistance reverse_distance = util::coordinate_calculation::greatCircleDistance(
point_on_segment, point_on_segment,
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1))); datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1)));
@ -592,8 +592,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
Coordinate wsg84_coordinate = Coordinate wsg84_coordinate =
util::web_mercator::toWGS84(segment.fixed_projected_coordinate); util::web_mercator::toWGS84(segment.fixed_projected_coordinate);
return util::coordinate_calculation::haversineDistance(input_coordinate, wsg84_coordinate) > return util::coordinate_calculation::greatCircleDistance(input_coordinate,
max_distance; wsg84_coordinate) > max_distance;
} }
std::pair<bool, bool> CheckSegmentExclude(const CandidateSegment &segment) const std::pair<bool, bool> CheckSegmentExclude(const CandidateSegment &segment) const

View File

@ -57,8 +57,7 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
const auto source_geometry_id = facade.GetGeometryIndex(source_node_id).id; const auto source_geometry_id = facade.GetGeometryIndex(source_node_id).id;
const auto source_geometry = facade.GetUncompressedForwardGeometry(source_geometry_id); const auto source_geometry = facade.GetUncompressedForwardGeometry(source_geometry_id);
geometry.osm_node_ids.push_back( geometry.node_ids.push_back(source_geometry(source_segment_start_coordinate));
facade.GetOSMNodeIDOfNode(source_geometry(source_segment_start_coordinate)));
auto cumulative_distance = 0.; auto cumulative_distance = 0.;
auto current_distance = 0.; auto current_distance = 0.;
@ -67,11 +66,14 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
{ {
auto coordinate = facade.GetCoordinateOfNode(path_point.turn_via_node); auto coordinate = facade.GetCoordinateOfNode(path_point.turn_via_node);
current_distance = current_distance =
util::coordinate_calculation::haversineDistance(prev_coordinate, coordinate); util::coordinate_calculation::greatCircleDistance(prev_coordinate, coordinate);
cumulative_distance += current_distance; cumulative_distance += current_distance;
// all changes to this check have to be matched with assemble_steps // all changes to this check have to be matched with assemble_steps
if (path_point.turn_instruction.type != osrm::guidance::TurnType::NoTurn) auto turn_instruction = path_point.turn_edge
? facade.GetTurnInstructionForEdgeID(*path_point.turn_edge)
: osrm::guidance::TurnInstruction::NO_TURN();
if (turn_instruction.type != osrm::guidance::TurnType::NoTurn)
{ {
geometry.segment_distances.push_back(cumulative_distance); geometry.segment_distances.push_back(cumulative_distance);
geometry.segment_offsets.push_back(geometry.locations.size()); geometry.segment_offsets.push_back(geometry.locations.size());
@ -79,11 +81,10 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
} }
prev_coordinate = coordinate; prev_coordinate = coordinate;
const auto node_id = path_point.turn_via_node;
const auto osm_node_id = facade.GetOSMNodeIDOfNode(path_point.turn_via_node); if (node_id != geometry.node_ids.back() ||
turn_instruction.type != osrm::guidance::TurnType::NoTurn)
if (osm_node_id != geometry.osm_node_ids.back() ||
path_point.turn_instruction.type != osrm::guidance::TurnType::NoTurn)
{ {
geometry.annotations.emplace_back(LegGeometry::Annotation{ geometry.annotations.emplace_back(LegGeometry::Annotation{
current_distance, current_distance,
@ -99,11 +100,11 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
facade.GetWeightMultiplier(), facade.GetWeightMultiplier(),
path_point.datasource_id}); path_point.datasource_id});
geometry.locations.push_back(coordinate); geometry.locations.push_back(coordinate);
geometry.osm_node_ids.push_back(osm_node_id); geometry.node_ids.push_back(node_id);
} }
} }
current_distance = current_distance =
util::coordinate_calculation::haversineDistance(prev_coordinate, target_node.location); util::coordinate_calculation::greatCircleDistance(prev_coordinate, target_node.location);
cumulative_distance += current_distance; cumulative_distance += current_distance;
// segment leading to the target node // segment leading to the target node
geometry.segment_distances.push_back(cumulative_distance); geometry.segment_distances.push_back(cumulative_distance);
@ -158,8 +159,7 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
const auto target_segment_end_coordinate = const auto target_segment_end_coordinate =
target_node.fwd_segment_position + (reversed_target ? 0 : 1); target_node.fwd_segment_position + (reversed_target ? 0 : 1);
const auto target_geometry = facade.GetUncompressedForwardGeometry(target_geometry_id); const auto target_geometry = facade.GetUncompressedForwardGeometry(target_geometry_id);
geometry.osm_node_ids.push_back( geometry.node_ids.push_back(target_geometry(target_segment_end_coordinate));
facade.GetOSMNodeIDOfNode(target_geometry(target_segment_end_coordinate)));
BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1); BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1);
BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size()); BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size());

View File

@ -75,10 +75,14 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
std::vector<NamedSegment> segments(route_data.size()); std::vector<NamedSegment> segments(route_data.size());
std::uint32_t index = 0; std::uint32_t index = 0;
std::transform( std::transform(route_data.begin(),
route_data.begin(), route_data.end(), segments.begin(), [&index](const PathData &point) { route_data.end(),
return NamedSegment{point.duration_until_turn, index++, point.name_id}; segments.begin(),
}); [&index, &facade](const PathData &point) {
return NamedSegment{point.duration_until_turn,
index++,
facade.GetNameIndex(point.from_edge_based_node)};
});
const auto target_duration = const auto target_duration =
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration; target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
const auto target_node_id = target_traversed_in_reverse ? target_node.reverse_segment_id.id const auto target_node_id = target_traversed_in_reverse ? target_node.reverse_segment_id.id
@ -124,21 +128,59 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
} }
} // namespace detail } // namespace detail
inline std::string assembleSummary(const datafacade::BaseDataFacade &facade,
const std::vector<PathData> &route_data,
const PhantomNode &target_node,
const bool target_traversed_in_reverse)
{
auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>(
facade, route_data, target_node, target_traversed_in_reverse);
BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0);
BOOST_ASSERT(summary_array.begin() != summary_array.end());
// transform a name_id into a string containing either the name, or -if the name is empty-
// the reference.
const auto name_id_to_string = [&](const NameID name_id) {
const auto name = facade.GetNameForID(name_id);
if (!name.empty())
return name.to_string();
else
{
const auto ref = facade.GetRefForID(name_id);
return ref.to_string();
}
};
const auto not_empty = [&](const std::string &name) { return !name.empty(); };
const auto summary_names = summary_array | boost::adaptors::transformed(name_id_to_string) |
boost::adaptors::filtered(not_empty);
return boost::algorithm::join(summary_names, ", ");
}
inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade, inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
const std::vector<PathData> &route_data, const std::vector<PathData> &route_data,
const LegGeometry &leg_geometry,
const PhantomNode &source_node, const PhantomNode &source_node,
const PhantomNode &target_node, const PhantomNode &target_node,
const bool target_traversed_in_reverse, const bool target_traversed_in_reverse)
const bool needs_summary)
{ {
auto distance = 0.;
auto prev_coordinate = source_node.location;
for (const auto &path_point : route_data)
{
auto coordinate = facade.GetCoordinateOfNode(path_point.turn_via_node);
distance += util::coordinate_calculation::greatCircleDistance(prev_coordinate, coordinate);
prev_coordinate = coordinate;
}
distance +=
util::coordinate_calculation::greatCircleDistance(prev_coordinate, target_node.location);
const auto target_duration = const auto target_duration =
(target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration); (target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration);
const auto target_weight = const auto target_weight =
(target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight); (target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight);
auto distance = std::accumulate(
leg_geometry.segment_distances.begin(), leg_geometry.segment_distances.end(), 0.);
auto duration = std::accumulate( auto duration = std::accumulate(
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) { route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
return sum + data.duration_until_turn; return sum + data.duration_until_turn;
@ -182,39 +224,10 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
duration = std::max(0, duration); duration = std::max(0, duration);
} }
std::string summary;
if (needs_summary)
{
auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>(
facade, route_data, target_node, target_traversed_in_reverse);
BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0);
BOOST_ASSERT(summary_array.begin() != summary_array.end());
// transform a name_id into a string containing either the name, or -if the name is empty-
// the reference.
const auto name_id_to_string = [&](const NameID name_id) {
const auto name = facade.GetNameForID(name_id);
if (!name.empty())
return name.to_string();
else
{
const auto ref = facade.GetRefForID(name_id);
return ref.to_string();
}
};
const auto not_empty = [&](const std::string &name) { return !name.empty(); };
const auto summary_names = summary_array | boost::adaptors::transformed(name_id_to_string) |
boost::adaptors::filtered(not_empty);
summary = boost::algorithm::join(summary_names, ", ");
}
return RouteLeg{std::round(distance * 10.) / 10., return RouteLeg{std::round(distance * 10.) / 10.,
duration / 10., duration / 10.,
weight / facade.GetWeightMultiplier(), weight / facade.GetWeightMultiplier(),
summary, "",
{}}; {}};
} }

View File

@ -19,6 +19,7 @@
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <cstddef> #include <cstddef>
#include <guidance/turn_bearing.hpp>
#include <vector> #include <vector>
namespace osrm namespace osrm
@ -96,7 +97,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
{}, {},
source_classes}; source_classes};
if (leg_data.size() > 0) if (!leg_data.empty())
{ {
// PathData saves the information we need of the segment _before_ the turn, // PathData saves the information we need of the segment _before_ the turn,
// but a RouteStep is with regard to the segment after the turn. // but a RouteStep is with regard to the segment after the turn.
@ -115,7 +116,10 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
segment_weight += path_point.weight_until_turn; segment_weight += path_point.weight_until_turn;
// all changes to this check have to be matched with assemble_geometry // all changes to this check have to be matched with assemble_geometry
if (path_point.turn_instruction.type != osrm::guidance::TurnType::NoTurn) const auto turn_instruction =
path_point.turn_edge ? facade.GetTurnInstructionForEdgeID(*path_point.turn_edge)
: osrm::guidance::TurnInstruction::NO_TURN();
if (turn_instruction.type != osrm::guidance::TurnType::NoTurn)
{ {
BOOST_ASSERT(segment_weight >= 0); BOOST_ASSERT(segment_weight >= 0);
const auto name = facade.GetNameForID(step_name_id); const auto name = facade.GetNameForID(step_name_id);
@ -125,7 +129,13 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const auto exits = facade.GetExitsForID(step_name_id); const auto exits = facade.GetExitsForID(step_name_id);
const auto distance = leg_geometry.segment_distances[segment_index]; const auto distance = leg_geometry.segment_distances[segment_index];
// intersections contain the classes of exiting road // intersections contain the classes of exiting road
intersection.classes = facade.GetClasses(path_point.classes); intersection.classes =
facade.GetClasses(facade.GetClassData(path_point.from_edge_based_node));
const auto is_left_hand_driving =
facade.IsLeftHandDriving(path_point.from_edge_based_node);
const auto travel_mode = facade.GetTravelMode(path_point.from_edge_based_node);
BOOST_ASSERT(travel_mode > 0);
steps.push_back(RouteStep{path_point.from_edge_based_node, steps.push_back(RouteStep{path_point.from_edge_based_node,
step_name_id, step_name_id,
@ -140,17 +150,19 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
segment_duration / 10., segment_duration / 10.,
distance, distance,
segment_weight / weight_multiplier, segment_weight / weight_multiplier,
path_point.travel_mode, travel_mode,
maneuver, maneuver,
leg_geometry.FrontIndex(segment_index), leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1, leg_geometry.BackIndex(segment_index) + 1,
{intersection}, {intersection},
path_point.is_left_hand_driving}); is_left_hand_driving});
if (leg_data_index + 1 < leg_data.size()) if (leg_data_index + 1 < leg_data.size())
{ {
step_name_id = leg_data[leg_data_index + 1].name_id; step_name_id =
is_segregated = leg_data[leg_data_index + 1].is_segregated; facade.GetNameIndex(leg_data[leg_data_index + 1].from_edge_based_node);
is_segregated =
facade.IsSegregated(leg_data[leg_data_index + 1].from_edge_based_node);
} }
else else
{ {
@ -159,20 +171,33 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
} }
// extract bearings // extract bearings
bearings = std::make_pair<std::uint16_t, std::uint16_t>( auto pre_turn_bearing = path_point.turn_edge
path_point.pre_turn_bearing.Get(), path_point.post_turn_bearing.Get()); ? facade.PreTurnBearing(*path_point.turn_edge)
: osrm::guidance::TurnBearing(0);
auto post_turn_bearing = path_point.turn_edge
? facade.PostTurnBearing(*path_point.turn_edge)
: osrm::guidance::TurnBearing(0);
bearings = std::make_pair<std::uint16_t, std::uint16_t>(pre_turn_bearing.Get(),
post_turn_bearing.Get());
const auto bearing_class = facade.GetBearingClass(path_point.turn_via_node); const auto bearing_class = facade.GetBearingClass(path_point.turn_via_node);
auto bearing_data = bearing_class.getAvailableBearings(); auto bearing_data = bearing_class.getAvailableBearings();
util::guidance::LaneTupleIdPair lane_data = {{0, INVALID_LANEID},
INVALID_LANE_DESCRIPTIONID};
if (path_point.turn_edge && facade.HasLaneData(*path_point.turn_edge))
{
lane_data = facade.GetLaneData(*path_point.turn_edge);
}
intersection.in = bearing_class.findMatchingBearing(bearings.first); intersection.in = bearing_class.findMatchingBearing(bearings.first);
intersection.out = bearing_class.findMatchingBearing(bearings.second); intersection.out = bearing_class.findMatchingBearing(bearings.second);
intersection.location = facade.GetCoordinateOfNode(path_point.turn_via_node); intersection.location = facade.GetCoordinateOfNode(path_point.turn_via_node);
intersection.bearings.clear(); intersection.bearings.clear();
intersection.bearings.reserve(bearing_data.size()); intersection.bearings.reserve(bearing_data.size());
intersection.lanes = path_point.lane_data.first; intersection.lanes = lane_data.first;
intersection.lane_description = intersection.lane_description = lane_data.second != INVALID_LANE_DESCRIPTIONID
path_point.lane_data.second != INVALID_LANE_DESCRIPTIONID ? facade.GetTurnDescription(lane_data.second)
? facade.GetTurnDescription(path_point.lane_data.second) : extractor::TurnLaneDescription();
: extractor::TurnLaneDescription();
// Lanes in turn are bound by total number of lanes at the location // Lanes in turn are bound by total number of lanes at the location
BOOST_ASSERT(intersection.lanes.lanes_in_turn <= BOOST_ASSERT(intersection.lanes.lanes_in_turn <=
@ -183,20 +208,23 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
(!intersection.lane_description.empty() && (!intersection.lane_description.empty() &&
intersection.lanes.lanes_in_turn != 0)); intersection.lanes.lanes_in_turn != 0));
auto entry_class = path_point.turn_edge
? facade.GetEntryClass(*path_point.turn_edge)
: EMPTY_ENTRY_CLASS;
std::copy(bearing_data.begin(), std::copy(bearing_data.begin(),
bearing_data.end(), bearing_data.end(),
std::back_inserter(intersection.bearings)); std::back_inserter(intersection.bearings));
intersection.entry.clear(); intersection.entry.clear();
for (auto idx : util::irange<std::size_t>(0, intersection.bearings.size())) for (auto idx : util::irange<std::size_t>(0, intersection.bearings.size()))
{ {
intersection.entry.push_back(path_point.entry_class.allowsEntry(idx)); intersection.entry.push_back(entry_class.allowsEntry(idx));
} }
std::int16_t bearing_in_driving_direction = std::int16_t bearing_in_driving_direction =
util::bearing::reverse(std::round(bearings.first)); util::bearing::reverse(std::round(bearings.first));
maneuver = {intersection.location, maneuver = {intersection.location,
bearing_in_driving_direction, bearing_in_driving_direction,
bearings.second, bearings.second,
path_point.turn_instruction, turn_instruction,
WaypointType::None, WaypointType::None,
0}; 0};
segment_index++; segment_index++;

View File

@ -32,7 +32,7 @@ struct LegGeometry
// length of the segment in meters // length of the segment in meters
std::vector<double> segment_distances; std::vector<double> segment_distances;
// original OSM node IDs for each coordinate // original OSM node IDs for each coordinate
std::vector<OSMNodeID> osm_node_ids; std::vector<NodeID> node_ids;
// Per-coordinate metadata // Per-coordinate metadata
struct Annotation struct Annotation

View File

@ -15,6 +15,7 @@
#include "util/integer_range.hpp" #include "util/integer_range.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <boost/optional.hpp>
#include <vector> #include <vector>
namespace osrm namespace osrm
@ -28,43 +29,22 @@ struct PathData
NodeID from_edge_based_node; NodeID from_edge_based_node;
// the internal OSRM id of the OSM node id that is the via node of the turn // the internal OSRM id of the OSM node id that is the via node of the turn
NodeID turn_via_node; NodeID turn_via_node;
// name of the street that leads to the turn
unsigned name_id;
// segregated edge-based node that leads to the turn
bool is_segregated;
// weight that is traveled on the segment until the turn is reached // weight that is traveled on the segment until the turn is reached
// including the turn weight, if one exists // including the turn weight, if one exists
EdgeWeight weight_until_turn; EdgeWeight weight_until_turn;
// If this segment immediately preceeds a turn, then duration_of_turn // If this segment immediately precedes a turn, then duration_of_turn
// will contain the weight of the turn. Otherwise it will be 0. // will contain the weight of the turn. Otherwise it will be 0.
EdgeWeight weight_of_turn; EdgeWeight weight_of_turn;
// duration that is traveled on the segment until the turn is reached, // duration that is traveled on the segment until the turn is reached,
// including a turn if the segment preceeds one. // including a turn if the segment precedes one.
EdgeWeight duration_until_turn; EdgeWeight duration_until_turn;
// If this segment immediately preceeds a turn, then duration_of_turn // If this segment immediately precedes a turn, then duration_of_turn
// will contain the duration of the turn. Otherwise it will be 0. // will contain the duration of the turn. Otherwise it will be 0.
EdgeWeight duration_of_turn; EdgeWeight duration_of_turn;
// instruction to execute at the turn
osrm::guidance::TurnInstruction turn_instruction;
// turn lane data
util::guidance::LaneTupleIdPair lane_data;
// travel mode of the street that leads to the turn
extractor::TravelMode travel_mode : 4;
// user defined classed of the street that leads to the turn
extractor::ClassData classes;
// entry class of the turn, indicating possibility of turns
util::guidance::EntryClass entry_class;
// Source of the speed value on this road segment // Source of the speed value on this road segment
DatasourceID datasource_id; DatasourceID datasource_id;
// If segment precedes a turn, ID of the turn itself
// bearing (as seen from the intersection) pre-turn boost::optional<EdgeID> turn_edge;
osrm::guidance::TurnBearing pre_turn_bearing;
// bearing (as seen from the intersection) post-turn
osrm::guidance::TurnBearing post_turn_bearing;
// Driving side of the turn
bool is_left_hand_driving;
}; };
struct InternalRouteResult struct InternalRouteResult

View File

@ -190,7 +190,7 @@ class BasePlugin
{ {
phantom_nodes[i].push_back(PhantomNodeWithDistance{ phantom_nodes[i].push_back(PhantomNodeWithDistance{
parameters.hints[i]->phantom, parameters.hints[i]->phantom,
util::coordinate_calculation::haversineDistance( util::coordinate_calculation::greatCircleDistance(
parameters.coordinates[i], parameters.hints[i]->phantom.location), parameters.coordinates[i], parameters.hints[i]->phantom.location),
}); });
continue; continue;
@ -240,7 +240,7 @@ class BasePlugin
{ {
phantom_nodes[i].push_back(PhantomNodeWithDistance{ phantom_nodes[i].push_back(PhantomNodeWithDistance{
parameters.hints[i]->phantom, parameters.hints[i]->phantom,
util::coordinate_calculation::haversineDistance( util::coordinate_calculation::greatCircleDistance(
parameters.coordinates[i], parameters.hints[i]->phantom.location), parameters.coordinates[i], parameters.hints[i]->phantom.location),
}); });
continue; continue;

View File

@ -176,11 +176,6 @@ void annotatePath(const FacadeT &facade,
const auto &edge_data = facade.GetEdgeData(*edge); const auto &edge_data = facade.GetEdgeData(*edge);
const auto turn_id = edge_data.turn_id; // edge-based graph edge index const auto turn_id = edge_data.turn_id; // edge-based graph edge index
const auto node_id = *node_from; // edge-based graph node index const auto node_id = *node_from; // edge-based graph node index
const auto name_index = facade.GetNameIndex(node_id);
const bool is_segregated = facade.IsSegregated(node_id);
const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id);
const extractor::TravelMode travel_mode = facade.GetTravelMode(node_id);
const auto classes = facade.GetClassData(node_id);
const auto geometry_index = facade.GetGeometryIndex(node_id); const auto geometry_index = facade.GetGeometryIndex(node_id);
get_segment_geometry(geometry_index); get_segment_geometry(geometry_index);
@ -206,45 +201,29 @@ void annotatePath(const FacadeT &facade,
} }
const std::size_t end_index = weight_vector.size(); const std::size_t end_index = weight_vector.size();
bool is_left_hand_driving = facade.IsLeftHandDriving(node_id);
BOOST_ASSERT(start_index < end_index); BOOST_ASSERT(start_index < end_index);
for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx) for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx)
{ {
unpacked_path.push_back( unpacked_path.push_back(
PathData{*node_from, PathData{node_id,
id_vector[segment_idx + 1], id_vector[segment_idx + 1],
name_index,
is_segregated,
static_cast<EdgeWeight>(weight_vector[segment_idx]), static_cast<EdgeWeight>(weight_vector[segment_idx]),
0, 0,
static_cast<EdgeDuration>(duration_vector[segment_idx]), static_cast<EdgeDuration>(duration_vector[segment_idx]),
0, 0,
guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
travel_mode,
classes,
EMPTY_ENTRY_CLASS,
datasource_vector[segment_idx], datasource_vector[segment_idx],
osrm::guidance::TurnBearing(0), boost::none});
osrm::guidance::TurnBearing(0),
is_left_hand_driving});
} }
BOOST_ASSERT(unpacked_path.size() > 0); BOOST_ASSERT(unpacked_path.size() > 0);
if (facade.HasLaneData(turn_id))
unpacked_path.back().lane_data = facade.GetLaneData(turn_id);
const auto turn_duration = facade.GetDurationPenaltyForEdgeID(turn_id); const auto turn_duration = facade.GetDurationPenaltyForEdgeID(turn_id);
const auto turn_weight = facade.GetWeightPenaltyForEdgeID(turn_id); const auto turn_weight = facade.GetWeightPenaltyForEdgeID(turn_id);
unpacked_path.back().entry_class = facade.GetEntryClass(turn_id);
unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().duration_until_turn += turn_duration; unpacked_path.back().duration_until_turn += turn_duration;
unpacked_path.back().duration_of_turn = turn_duration; unpacked_path.back().duration_of_turn = turn_duration;
unpacked_path.back().weight_until_turn += turn_weight; unpacked_path.back().weight_until_turn += turn_weight;
unpacked_path.back().weight_of_turn = turn_weight; unpacked_path.back().weight_of_turn = turn_weight;
unpacked_path.back().pre_turn_bearing = facade.PreTurnBearing(turn_id); unpacked_path.back().turn_edge = turn_id;
unpacked_path.back().post_turn_bearing = facade.PostTurnBearing(turn_id);
} }
std::size_t start_index = 0, end_index = 0; std::size_t start_index = 0, end_index = 0;
@ -280,33 +259,22 @@ void annotatePath(const FacadeT &facade,
// t: fwd_segment 3 // t: fwd_segment 3
// -> (U, v), (v, w), (w, x) // -> (U, v), (v, w), (w, x)
// note that (x, t) is _not_ included but needs to be added later. // note that (x, t) is _not_ included but needs to be added later.
bool is_target_left_hand_driving = facade.IsLeftHandDriving(target_node_id);
for (std::size_t segment_idx = start_index; segment_idx != end_index; for (std::size_t segment_idx = start_index; segment_idx != end_index;
(start_index < end_index ? ++segment_idx : --segment_idx)) (start_index < end_index ? ++segment_idx : --segment_idx))
{ {
BOOST_ASSERT(segment_idx < static_cast<std::size_t>(id_vector.size() - 1)); BOOST_ASSERT(segment_idx < static_cast<std::size_t>(id_vector.size() - 1));
BOOST_ASSERT(facade.GetTravelMode(target_node_id) > 0);
unpacked_path.push_back( unpacked_path.push_back(
PathData{target_node_id, PathData{target_node_id,
id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1], id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
facade.GetNameIndex(target_node_id),
facade.IsSegregated(target_node_id),
static_cast<EdgeWeight>(weight_vector[segment_idx]), static_cast<EdgeWeight>(weight_vector[segment_idx]),
0, 0,
static_cast<EdgeDuration>(duration_vector[segment_idx]), static_cast<EdgeDuration>(duration_vector[segment_idx]),
0, 0,
guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
facade.GetTravelMode(target_node_id),
facade.GetClassData(target_node_id),
EMPTY_ENTRY_CLASS,
datasource_vector[segment_idx], datasource_vector[segment_idx],
guidance::TurnBearing(0), boost::none});
guidance::TurnBearing(0),
is_target_left_hand_driving});
} }
if (unpacked_path.size() > 0) if (!unpacked_path.empty())
{ {
const auto source_weight = start_traversed_in_reverse const auto source_weight = start_traversed_in_reverse
? phantom_node_pair.source_phantom.reverse_weight ? phantom_node_pair.source_phantom.reverse_weight
@ -428,7 +396,7 @@ template <typename FacadeT> EdgeDistance computeEdgeDistance(const FacadeT &faca
auto geometry_range = facade.GetUncompressedForwardGeometry(geometry_index.id); auto geometry_range = facade.GetUncompressedForwardGeometry(geometry_index.id);
for (auto current = geometry_range.begin(); current < geometry_range.end() - 1; ++current) for (auto current = geometry_range.begin(); current < geometry_range.end() - 1; ++current)
{ {
total_distance += util::coordinate_calculation::fccApproximateDistance( total_distance += util::coordinate_calculation::greatCircleDistance(
facade.GetCoordinateOfNode(*current), facade.GetCoordinateOfNode(*std::next(current))); facade.GetCoordinateOfNode(*current), facade.GetCoordinateOfNode(*std::next(current)));
} }

View File

@ -301,7 +301,7 @@ struct DistanceToNextIntersectionAccumulator
using namespace util::coordinate_calculation; using namespace util::coordinate_calculation;
const auto coords = extractor.GetForwardCoordinatesAlongRoad(start, onto); const auto coords = extractor.GetForwardCoordinatesAlongRoad(start, onto);
distance += getLength(coords.begin(), coords.end(), &haversineDistance); distance += getLength(coords.begin(), coords.end(), &greatCircleDistance);
} }
const extractor::intersection::CoordinateExtractor &extractor; const extractor::intersection::CoordinateExtractor &extractor;

View File

@ -44,7 +44,7 @@ class RestrictionParser
RestrictionParser(bool use_turn_restrictions, RestrictionParser(bool use_turn_restrictions,
bool parse_conditionals, bool parse_conditionals,
std::vector<std::string> &restrictions); std::vector<std::string> &restrictions);
boost::optional<InputTurnRestriction> TryParse(const osmium::Relation &relation) const; std::vector<InputTurnRestriction> TryParse(const osmium::Relation &relation) const;
private: private:
bool ShouldIgnoreRestriction(const std::string &except_tag_string) const; bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;

View File

@ -675,6 +675,22 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
params->generate_hints = Nan::To<bool>(generate_hints).FromJust(); params->generate_hints = Nan::To<bool>(generate_hints).FromJust();
} }
if (Nan::Has(obj, Nan::New("skip_waypoints").ToLocalChecked()).FromJust())
{
v8::Local<v8::Value> skip_waypoints =
Nan::Get(obj, Nan::New("skip_waypoints").ToLocalChecked()).ToLocalChecked();
if (skip_waypoints.IsEmpty())
return false;
if (!skip_waypoints->IsBoolean())
{
Nan::ThrowError("skip_waypoints must be of type Boolean");
return false;
}
params->skip_waypoints = Nan::To<bool>(skip_waypoints).FromJust();
}
if (Nan::Has(obj, Nan::New("exclude").ToLocalChecked()).FromJust()) if (Nan::Has(obj, Nan::New("exclude").ToLocalChecked()).FromJust())
{ {
v8::Local<v8::Value> exclude = v8::Local<v8::Value> exclude =

View File

@ -25,6 +25,7 @@ struct IOConfig
} }
bool IsValid() const; bool IsValid() const;
std::vector<std::string> GetMissingFiles() const;
boost::filesystem::path GetPath(const std::string &fileName) const boost::filesystem::path GetPath(const std::string &fileName) const
{ {
if (!IsConfigured(fileName, required_input_files) && if (!IsConfigured(fileName, required_input_files) &&

View File

@ -43,11 +43,6 @@ inline double radToDeg(const double radian)
//! Takes the squared euclidean distance of the input coordinates. Does not return meters! //! Takes the squared euclidean distance of the input coordinates. Does not return meters!
std::uint64_t squaredEuclideanDistance(const Coordinate lhs, const Coordinate rhs); std::uint64_t squaredEuclideanDistance(const Coordinate lhs, const Coordinate rhs);
double fccApproximateDistance(const Coordinate first_coordinate,
const Coordinate second_coordinate);
double haversineDistance(const Coordinate first_coordinate, const Coordinate second_coordinate);
double greatCircleDistance(const Coordinate first_coordinate, const Coordinate second_coordinate); double greatCircleDistance(const Coordinate first_coordinate, const Coordinate second_coordinate);
// get the length of a full coordinate vector, using one of our basic functions to compute distances // get the length of a full coordinate vector, using one of our basic functions to compute distances

View File

@ -76,13 +76,13 @@ using NodeID = std::uint32_t;
using EdgeID = std::uint32_t; using EdgeID = std::uint32_t;
using NameID = std::uint32_t; using NameID = std::uint32_t;
using AnnotationID = std::uint32_t; using AnnotationID = std::uint32_t;
using PackedGeometryID = std::uint32_t;
using EdgeWeight = std::int32_t; using EdgeWeight = std::int32_t;
using EdgeDuration = std::int32_t; using EdgeDuration = std::int32_t;
using EdgeDistance = float; using EdgeDistance = float;
using SegmentWeight = std::uint32_t; using SegmentWeight = std::uint32_t;
using SegmentDuration = std::uint32_t; using SegmentDuration = std::uint32_t;
using TurnPenalty = std::int16_t; // turn penalty in 100ms units using TurnPenalty = std::int16_t; // turn penalty in 100ms units
using DataTimestamp = std::string;
static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max(); static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max();
@ -95,16 +95,13 @@ static const LaneDescriptionID INVALID_LANE_DESCRIPTIONID =
std::numeric_limits<LaneDescriptionID>::max(); std::numeric_limits<LaneDescriptionID>::max();
using BearingClassID = std::uint32_t; using BearingClassID = std::uint32_t;
static const BearingClassID INVALID_BEARING_CLASSID = std::numeric_limits<BearingClassID>::max();
using DiscreteBearing = std::uint16_t; using DiscreteBearing = std::uint16_t;
using EntryClassID = std::uint16_t; using EntryClassID = std::uint16_t;
static const EntryClassID INVALID_ENTRY_CLASSID = std::numeric_limits<EntryClassID>::max();
static const NodeID SPECIAL_NODEID = std::numeric_limits<NodeID>::max(); static const NodeID SPECIAL_NODEID = std::numeric_limits<NodeID>::max();
static const NodeID SPECIAL_SEGMENTID = std::numeric_limits<NodeID>::max() >> 1; static const NodeID SPECIAL_SEGMENTID = std::numeric_limits<NodeID>::max() >> 1;
static const NodeID SPECIAL_GEOMETRYID = std::numeric_limits<NodeID>::max() >> 1; static const PackedGeometryID SPECIAL_GEOMETRYID =
std::numeric_limits<PackedGeometryID>::max() >> 1;
static const EdgeID SPECIAL_EDGEID = std::numeric_limits<EdgeID>::max(); static const EdgeID SPECIAL_EDGEID = std::numeric_limits<EdgeID>::max();
static const RestrictionID SPECIAL_RESTRICTIONID = std::numeric_limits<RestrictionID>::max(); static const RestrictionID SPECIAL_RESTRICTIONID = std::numeric_limits<RestrictionID>::max();
static const NameID INVALID_NAMEID = std::numeric_limits<NameID>::max(); static const NameID INVALID_NAMEID = std::numeric_limits<NameID>::max();
@ -123,13 +120,6 @@ static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>
static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max(); static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits<double>::max(); static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits<double>::max();
// FIXME the bitfields we use require a reduced maximal duration, this should be kept consistent
// within the code base. For now we have to ensure that we don't case 30 bit to -1 and break any
// min() / operator< checks due to the invalid truncation. In addition, using signed and unsigned
// weights produces problems. As a result we can only store 1 << 29 since the MSB is still reserved
// for the sign bit. See https://github.com/Project-OSRM/osrm-backend/issues/3677
static const EdgeWeight MAXIMAL_EDGE_DURATION_INT_30 = (1 << 29) - 1;
using DatasourceID = std::uint8_t; using DatasourceID = std::uint8_t;
using BisectionID = std::uint32_t; using BisectionID = std::uint32_t;
@ -158,11 +148,11 @@ struct SegmentID
*/ */
struct GeometryID struct GeometryID
{ {
GeometryID(const NodeID id_, const bool forward_) : id{id_}, forward{forward_} {} GeometryID(const PackedGeometryID id_, const bool forward_) : id{id_}, forward{forward_} {}
GeometryID() : id(std::numeric_limits<unsigned>::max() >> 1), forward(false) {} GeometryID() : id(std::numeric_limits<unsigned>::max() >> 1), forward(false) {}
NodeID id : 31; PackedGeometryID id : 31;
std::uint32_t forward : 1; std::uint32_t forward : 1;
}; };

26
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "osrm", "name": "osrm",
"version": "5.26.0-unreleased", "version": "5.27.0-unreleased",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -3369,6 +3369,16 @@
"integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
"dev": true "dev": true
}, },
"bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"dev": true,
"optional": true,
"requires": {
"file-uri-to-path": "1.0.0"
}
},
"bit-twiddle": { "bit-twiddle": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz", "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz",
@ -3958,6 +3968,11 @@
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
"dev": true "dev": true
}, },
"cheap-ruler": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/cheap-ruler/-/cheap-ruler-3.0.2.tgz",
"integrity": "sha512-02T332h1/HTN6cDSufLP8x4JzDs2+VC+8qZ/N0kWIVPyc2xUkWwWh3B2fJxR7raXkL4Mq7k554mfuM9ofv/vGg=="
},
"chokidar": { "chokidar": {
"version": "3.5.2", "version": "3.5.2",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
@ -5284,6 +5299,7 @@
"dev": true, "dev": true,
"optional": true, "optional": true,
"requires": { "requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1" "nan": "^2.12.1"
} }
}, },
@ -5695,6 +5711,7 @@
"dev": true, "dev": true,
"optional": true, "optional": true,
"requires": { "requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1" "nan": "^2.12.1"
} }
}, },
@ -7220,6 +7237,13 @@
"object-assign": "^4.0.1" "object-assign": "^4.0.1"
} }
}, },
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"dev": true,
"optional": true
},
"filename-regex": { "filename-regex": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",

View File

@ -5,6 +5,7 @@
"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": {
"@mapbox/node-pre-gyp": "^1.0.1", "@mapbox/node-pre-gyp": "^1.0.1",
"cheap-ruler": "^3.0.2",
"mkdirp": "^0.5.5", "mkdirp": "^0.5.5",
"nan": "^2.14.2", "nan": "^2.14.2",
"node-cmake": "^2.5.1", "node-cmake": "^2.5.1",

View File

@ -25,7 +25,8 @@ std::pair<short, short> getDepartBearings(const LegGeometry &leg_geometry,
const auto turn_coordinate = leg_geometry.locations.front(); const auto turn_coordinate = leg_geometry.locations.front();
const auto post_turn_coordinate = *(leg_geometry.locations.begin() + 1); const auto post_turn_coordinate = *(leg_geometry.locations.begin() + 1);
if (util::coordinate_calculation::haversineDistance(turn_coordinate, post_turn_coordinate) <= 1) if (util::coordinate_calculation::greatCircleDistance(turn_coordinate, post_turn_coordinate) <=
1)
{ {
return std::make_pair<short, short>(0, source_node.GetBearing(traversed_in_reverse)); return std::make_pair<short, short>(0, source_node.GetBearing(traversed_in_reverse));
} }
@ -41,7 +42,8 @@ std::pair<short, short> getArriveBearings(const LegGeometry &leg_geometry,
BOOST_ASSERT(leg_geometry.locations.size() >= 2); BOOST_ASSERT(leg_geometry.locations.size() >= 2);
const auto turn_coordinate = leg_geometry.locations.back(); const auto turn_coordinate = leg_geometry.locations.back();
const auto pre_turn_coordinate = *(leg_geometry.locations.end() - 2); const auto pre_turn_coordinate = *(leg_geometry.locations.end() - 2);
if (util::coordinate_calculation::haversineDistance(turn_coordinate, pre_turn_coordinate) <= 1) if (util::coordinate_calculation::greatCircleDistance(turn_coordinate, pre_turn_coordinate) <=
1)
{ {
return std::make_pair<short, short>(target_node.GetBearing(traversed_in_reverse), 0); return std::make_pair<short, short>(target_node.GetBearing(traversed_in_reverse), 0);
} }

View File

@ -263,7 +263,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
BOOST_ASSERT(geometry.locations.size() >= steps.size()); BOOST_ASSERT(geometry.locations.size() >= steps.size());
// Look for distances under 1m // Look for distances under 1m
const bool zero_length_step = steps.front().distance <= 1 && steps.size() > 2; const bool zero_length_step = steps.front().distance <= 1 && steps.size() > 2;
const bool duplicated_coordinate = util::coordinate_calculation::haversineDistance( const bool duplicated_coordinate = util::coordinate_calculation::greatCircleDistance(
geometry.locations[0], geometry.locations[1]) <= 1; geometry.locations[0], geometry.locations[1]) <= 1;
if (zero_length_step || duplicated_coordinate) if (zero_length_step || duplicated_coordinate)
{ {
@ -279,8 +279,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
geometry.locations.begin() + offset); geometry.locations.begin() + offset);
geometry.annotations.erase(geometry.annotations.begin(), geometry.annotations.erase(geometry.annotations.begin(),
geometry.annotations.begin() + offset); geometry.annotations.begin() + offset);
geometry.osm_node_ids.erase(geometry.osm_node_ids.begin(), geometry.node_ids.erase(geometry.node_ids.begin(), geometry.node_ids.begin() + offset);
geometry.osm_node_ids.begin() + offset);
} }
auto const first_bearing = steps.front().maneuver.bearing_after; auto const first_bearing = steps.front().maneuver.bearing_after;
@ -377,7 +376,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
// remove all the last coordinates from the geometry // remove all the last coordinates from the geometry
geometry.locations.resize(geometry.segment_offsets.back() + 1); geometry.locations.resize(geometry.segment_offsets.back() + 1);
geometry.annotations.resize(geometry.segment_offsets.back()); geometry.annotations.resize(geometry.segment_offsets.back());
geometry.osm_node_ids.resize(geometry.segment_offsets.back() + 1); geometry.node_ids.resize(geometry.segment_offsets.back() + 1);
BOOST_ASSERT(geometry.segment_distances.back() <= 1); BOOST_ASSERT(geometry.segment_distances.back() <= 1);
geometry.segment_distances.pop_back(); geometry.segment_distances.pop_back();
@ -406,7 +405,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
next_to_last_step.mode = new_next_to_last.mode; next_to_last_step.mode = new_next_to_last.mode;
// the geometry indices of the last step are already correct; // the geometry indices of the last step are already correct;
} }
else if (util::coordinate_calculation::haversineDistance( else if (util::coordinate_calculation::greatCircleDistance(
geometry.locations[geometry.locations.size() - 2], geometry.locations[geometry.locations.size() - 2],
geometry.locations[geometry.locations.size() - 1]) <= 1) geometry.locations[geometry.locations.size() - 1]) <= 1)
{ {
@ -414,7 +413,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
// This can happen if the last coordinate snaps to a node in the unpacked geometry // This can happen if the last coordinate snaps to a node in the unpacked geometry
geometry.locations.pop_back(); geometry.locations.pop_back();
geometry.annotations.pop_back(); geometry.annotations.pop_back();
geometry.osm_node_ids.pop_back(); geometry.node_ids.pop_back();
geometry.segment_offsets.back()--; geometry.segment_offsets.back()--;
// since the last geometry includes the location of arrival, the arrival instruction // since the last geometry includes the location of arrival, the arrival instruction
// geometry overlaps with the previous segment // geometry overlaps with the previous segment
@ -436,7 +435,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
} }
BOOST_ASSERT(geometry.segment_offsets.back() + 1 == geometry.locations.size()); BOOST_ASSERT(geometry.segment_offsets.back() + 1 == geometry.locations.size());
BOOST_ASSERT(geometry.segment_offsets.back() + 1 == geometry.osm_node_ids.size()); BOOST_ASSERT(geometry.segment_offsets.back() + 1 == geometry.node_ids.size());
BOOST_ASSERT(geometry.segment_offsets.back() == geometry.annotations.size()); BOOST_ASSERT(geometry.segment_offsets.back() == geometry.annotations.size());
BOOST_ASSERT(steps.back().geometry_end == geometry.locations.size()); BOOST_ASSERT(steps.back().geometry_end == geometry.locations.size());
@ -463,7 +462,7 @@ std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps,
BOOST_ASSERT(steps.size() >= 2); BOOST_ASSERT(steps.size() >= 2);
BOOST_ASSERT(leg_geometry.locations.size() >= 2); BOOST_ASSERT(leg_geometry.locations.size() >= 2);
const constexpr double MINIMAL_RELATIVE_DISTANCE = 5., MAXIMAL_RELATIVE_DISTANCE = 300.; const constexpr double MINIMAL_RELATIVE_DISTANCE = 5., MAXIMAL_RELATIVE_DISTANCE = 300.;
const auto distance_to_start = util::coordinate_calculation::haversineDistance( const auto distance_to_start = util::coordinate_calculation::greatCircleDistance(
source_node.input_location, leg_geometry.locations[0]); source_node.input_location, leg_geometry.locations[0]);
const auto initial_modifier = const auto initial_modifier =
distance_to_start >= MINIMAL_RELATIVE_DISTANCE && distance_to_start >= MINIMAL_RELATIVE_DISTANCE &&
@ -474,7 +473,7 @@ std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps,
steps.front().maneuver.instruction.direction_modifier = initial_modifier; steps.front().maneuver.instruction.direction_modifier = initial_modifier;
const auto distance_from_end = util::coordinate_calculation::haversineDistance( const auto distance_from_end = util::coordinate_calculation::greatCircleDistance(
target_node.input_location, leg_geometry.locations.back()); target_node.input_location, leg_geometry.locations.back());
const auto final_modifier = const auto final_modifier =
distance_from_end >= MINIMAL_RELATIVE_DISTANCE && distance_from_end >= MINIMAL_RELATIVE_DISTANCE &&
@ -541,7 +540,7 @@ std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps)
{ {
// End of road is a turn that helps to identify the location of a turn. If the turn does // End of road is a turn that helps to identify the location of a turn. If the turn does
// not pass by any oter intersections, the end-of-road characteristic does not improve // not pass by any other intersections, the end-of-road characteristic does not improve
// the instructions. // the instructions.
// Here we reduce the verbosity of our output by reducing end-of-road emissions in cases // Here we reduce the verbosity of our output by reducing end-of-road emissions in cases
// where no intersections have been passed in between. // where no intersections have been passed in between.

View File

@ -116,9 +116,9 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
auto distance_estimate = auto distance_estimate =
params.fallback_coordinate_type == params.fallback_coordinate_type ==
api::TableParameters::FallbackCoordinateType::Input api::TableParameters::FallbackCoordinateType::Input
? util::coordinate_calculation::fccApproximateDistance( ? util::coordinate_calculation::greatCircleDistance(
source.input_location, destination.input_location) source.input_location, destination.input_location)
: util::coordinate_calculation::fccApproximateDistance( : util::coordinate_calculation::greatCircleDistance(
source.location, destination.location); source.location, destination.location);
result_tables_pair.first[table_index] = result_tables_pair.first[table_index] =

View File

@ -464,7 +464,7 @@ void encodeVectorTile(const DataFacadeBase &facade,
const auto b = facade.GetCoordinateOfNode(edge.v); const auto b = facade.GetCoordinateOfNode(edge.v);
// Calculate the length in meters // Calculate the length in meters
const double length = const double length =
osrm::util::coordinate_calculation::haversineDistance(a, b); osrm::util::coordinate_calculation::greatCircleDistance(a, b);
const auto forward_weight_range = const auto forward_weight_range =
facade.GetUncompressedForwardWeights(geometry_id); facade.GetUncompressedForwardWeights(geometry_id);

View File

@ -36,18 +36,7 @@ bool IsSupportedParameterCombination(const bool fixed_start,
const bool fixed_end, const bool fixed_end,
const bool roundtrip) const bool roundtrip)
{ {
if (fixed_start && fixed_end && !roundtrip) return roundtrip || fixed_start || fixed_end;
{
return true;
}
else if (roundtrip)
{
return true;
}
else
{
return false;
}
} }
// given the node order in which to visit, compute the actual route (with geometry, travel time and // given the node order in which to visit, compute the actual route (with geometry, travel time and
@ -142,6 +131,32 @@ void ManipulateTableForFSE(const std::size_t source_id,
//********* End of changes to table ************************************* //********* End of changes to table *************************************
} }
void ManipulateTableForNonRoundtripFS(const std::size_t source_id,
util::DistTableWrapper<EdgeWeight> &result_table)
{
// We can use the round-trip calculation to simulate non-round-trip fixed start
// by making all paths to the source location zero. Effectively finding an 'optimal'
// round-trip path that ignores the cost of getting back from any destination to the
// source.
for (const auto i : util::irange<size_t>(0, result_table.GetNumberOfNodes()))
{
result_table.SetValue(i, source_id, 0);
}
}
void ManipulateTableForNonRoundtripFE(const std::size_t destination_id,
util::DistTableWrapper<EdgeWeight> &result_table)
{
// We can use the round-trip calculation to simulate non-round-trip fixed end
// by making all paths from the destination to other locations zero.
// Effectively, finding an 'optimal' round-trip path that ignores the cost of getting
// from the destination to any source.
for (const auto i : util::irange<size_t>(0, result_table.GetNumberOfNodes()))
{
result_table.SetValue(destination_id, i, 0);
}
}
Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
const api::TripParameters &parameters, const api::TripParameters &parameters,
osrm::engine::api::ResultT &result) const osrm::engine::api::ResultT &result) const
@ -225,7 +240,7 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
return Status::Error; return Status::Error;
} }
const constexpr std::size_t BF_MAX_FEASABLE = 10; const constexpr std::size_t BF_MAX_FEASIBLE = 10;
BOOST_ASSERT_MSG(result_duration_table.size() == number_of_locations * number_of_locations, BOOST_ASSERT_MSG(result_duration_table.size() == number_of_locations * number_of_locations,
"Distance Table has wrong size"); "Distance Table has wrong size");
@ -238,11 +253,19 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
{ {
ManipulateTableForFSE(source_id, destination_id, result_duration_table); ManipulateTableForFSE(source_id, destination_id, result_duration_table);
} }
else if (!parameters.roundtrip && fixed_start)
{
ManipulateTableForNonRoundtripFS(source_id, result_duration_table);
}
else if (!parameters.roundtrip && fixed_end)
{
ManipulateTableForNonRoundtripFE(destination_id, result_duration_table);
}
std::vector<NodeID> duration_trip; std::vector<NodeID> duration_trip;
duration_trip.reserve(number_of_locations); duration_trip.reserve(number_of_locations);
// get an optimized order in which the destinations should be visited // get an optimized order in which the destinations should be visited
if (number_of_locations < BF_MAX_FEASABLE) if (number_of_locations < BF_MAX_FEASIBLE)
{ {
duration_trip = trip::BruteForceTrip(number_of_locations, result_duration_table); duration_trip = trip::BruteForceTrip(number_of_locations, result_duration_table);
} }
@ -251,20 +274,28 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
duration_trip = trip::FarthestInsertionTrip(number_of_locations, result_duration_table); duration_trip = trip::FarthestInsertionTrip(number_of_locations, result_duration_table);
} }
// rotate result such that roundtrip starts at node with index 0
// thist first if covers scenarios: !fixed_end || fixed_start || (fixed_start && fixed_end)
if (!fixed_end || fixed_start) if (!fixed_end || fixed_start)
{ {
// rotate result such that trip starts at node with index 0
auto desired_start_index = std::find(std::begin(duration_trip), std::end(duration_trip), 0); auto desired_start_index = std::find(std::begin(duration_trip), std::end(duration_trip), 0);
BOOST_ASSERT(desired_start_index != std::end(duration_trip)); BOOST_ASSERT(desired_start_index != std::end(duration_trip));
std::rotate(std::begin(duration_trip), desired_start_index, std::end(duration_trip)); std::rotate(std::begin(duration_trip), desired_start_index, std::end(duration_trip));
} }
else if (fixed_end && !fixed_start && parameters.roundtrip) else
{ { // fixed_end
auto desired_start_index = auto destination_index =
std::find(std::begin(duration_trip), std::end(duration_trip), destination_id); std::find(std::begin(duration_trip), std::end(duration_trip), destination_id);
BOOST_ASSERT(desired_start_index != std::end(duration_trip)); BOOST_ASSERT(destination_index != std::end(duration_trip));
std::rotate(std::begin(duration_trip), desired_start_index, std::end(duration_trip)); if (!parameters.roundtrip)
{
// We want the location after destination to be at the front
std::advance(destination_index, 1);
if (destination_index == std::end(duration_trip))
{
destination_index = std::begin(duration_trip);
}
}
std::rotate(std::begin(duration_trip), destination_index, std::end(duration_trip));
} }
// get the route when visiting all destinations in optimized order // get the route when visiting all destinations in optimized order

View File

@ -137,7 +137,7 @@ Parameters parametersFromRequest(const PhantomNodes &phantom_node_pair)
{ {
Parameters parameters; Parameters parameters;
const auto distance = util::coordinate_calculation::haversineDistance( const auto distance = util::coordinate_calculation::greatCircleDistance(
phantom_node_pair.source_phantom.location, phantom_node_pair.target_phantom.location); phantom_node_pair.source_phantom.location, phantom_node_pair.target_phantom.location);
// 10km // 10km

View File

@ -214,7 +214,7 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
const auto &current_timestamps_list = candidates_list[t]; const auto &current_timestamps_list = candidates_list[t];
const auto &current_coordinate = trace_coordinates[t]; const auto &current_coordinate = trace_coordinates[t];
const auto haversine_distance = util::coordinate_calculation::haversineDistance( const auto haversine_distance = util::coordinate_calculation::greatCircleDistance(
prev_coordinate, current_coordinate); prev_coordinate, current_coordinate);
// assumes minumum of 4 m/s // assumes minumum of 4 m/s
const EdgeWeight weight_upper_bound = const EdgeWeight weight_upper_bound =
@ -424,7 +424,7 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
reconstructed_indices, reconstructed_indices,
[&trace_distance, &trace_coordinates](const std::pair<std::size_t, std::size_t> &prev, [&trace_distance, &trace_coordinates](const std::pair<std::size_t, std::size_t> &prev,
const std::pair<std::size_t, std::size_t> &curr) { const std::pair<std::size_t, std::size_t> &curr) {
trace_distance += util::coordinate_calculation::haversineDistance( trace_distance += util::coordinate_calculation::greatCircleDistance(
trace_coordinates[prev.first], trace_coordinates[curr.first]); trace_coordinates[prev.first], trace_coordinates[curr.first]);
}); });

View File

@ -434,7 +434,7 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
const auto duration = edge_iterator->duration_data(distance); const auto duration = edge_iterator->duration_data(distance);
const auto accurate_distance = const auto accurate_distance =
util::coordinate_calculation::fccApproximateDistance(source_coord, target_coord); util::coordinate_calculation::greatCircleDistance(source_coord, target_coord);
ExtractionSegment segment(source_coord, target_coord, distance, weight, duration); ExtractionSegment segment(source_coord, target_coord, distance, weight, duration);
scripting_environment.ProcessSegment(segment); scripting_environment.ProcessSegment(segment);

View File

@ -146,12 +146,12 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
// do the best of what we can. // do the best of what we can.
coordinates = coordinates =
TrimCoordinatesToLength(std::move(coordinates), LOOKAHEAD_DISTANCE_WITHOUT_LANES); TrimCoordinatesToLength(std::move(coordinates), LOOKAHEAD_DISTANCE_WITHOUT_LANES);
if (coordinates.size() > 2 && util::coordinate_calculation::haversineDistance( if (coordinates.size() > 2 && util::coordinate_calculation::greatCircleDistance(
turn_coordinate, coordinates[1]) < ASSUMED_LANE_WIDTH) turn_coordinate, coordinates[1]) < ASSUMED_LANE_WIDTH)
{ {
const auto initial_distance = const auto initial_distance =
util::coordinate_calculation::haversineDistance(turn_coordinate, coordinates[1]); util::coordinate_calculation::greatCircleDistance(turn_coordinate, coordinates[1]);
const auto total_distance = util::coordinate_calculation::haversineDistance( const auto total_distance = util::coordinate_calculation::greatCircleDistance(
turn_coordinate, coordinates.back()); turn_coordinate, coordinates.back());
if (initial_distance > ASSUMED_LANE_WIDTH && total_distance > initial_distance) if (initial_distance > ASSUMED_LANE_WIDTH && total_distance > initial_distance)
@ -169,7 +169,7 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
} }
const auto first_distance = const auto first_distance =
util::coordinate_calculation::haversineDistance(coordinates[0], coordinates[1]); util::coordinate_calculation::greatCircleDistance(coordinates[0], coordinates[1]);
// the lane count might not always be set. We need to assume a positive number, though. Here we // the lane count might not always be set. We need to assume a positive number, though. Here we
// select the number of lanes to operate on // select the number of lanes to operate on
@ -369,7 +369,7 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
std::move(coordinates), 3 * skipping_inaccuracies_distance, segment_distances); std::move(coordinates), 3 * skipping_inaccuracies_distance, segment_distances);
BOOST_ASSERT(coordinates.size() >= 2); BOOST_ASSERT(coordinates.size() >= 2);
segment_distances.resize(coordinates.size()); segment_distances.resize(coordinates.size());
segment_distances.back() = util::coordinate_calculation::haversineDistance( segment_distances.back() = util::coordinate_calculation::greatCircleDistance(
*(coordinates.end() - 2), coordinates.back()); *(coordinates.end() - 2), coordinates.back());
const auto vector_head = coordinates.back(); const auto vector_head = coordinates.back();
coordinates = TrimCoordinatesToLength( coordinates = TrimCoordinatesToLength(
@ -476,7 +476,7 @@ util::Coordinate CoordinateExtractor::ExtractCoordinateAtLength(
[distance, &accumulated_distance, last_coordinate = coordinates.front()]( [distance, &accumulated_distance, last_coordinate = coordinates.front()](
const util::Coordinate coordinate) mutable { const util::Coordinate coordinate) mutable {
const double segment_distance = const double segment_distance =
util::coordinate_calculation::haversineDistance(last_coordinate, coordinate); util::coordinate_calculation::greatCircleDistance(last_coordinate, coordinate);
const auto result = (accumulated_distance + segment_distance) >= distance; const auto result = (accumulated_distance + segment_distance) >= distance;
if (!result) if (!result)
{ {
@ -497,7 +497,7 @@ util::Coordinate CoordinateExtractor::ExtractCoordinateAtLength(
const auto interpolation_factor = const auto interpolation_factor =
ComputeInterpolationFactor(distance - accumulated_distance, ComputeInterpolationFactor(distance - accumulated_distance,
0, 0,
util::coordinate_calculation::haversineDistance( util::coordinate_calculation::greatCircleDistance(
*std::prev(coordinate_after), *coordinate_after)); *std::prev(coordinate_after), *coordinate_after));
return util::coordinate_calculation::interpolateLinear( return util::coordinate_calculation::interpolateLinear(
@ -533,7 +533,7 @@ util::Coordinate CoordinateExtractor::GetCoordinateCloseToTurn(const NodeID from
const auto far_enough_away = const auto far_enough_away =
[start_coordinate, compressedGeometryToCoordinate]( [start_coordinate, compressedGeometryToCoordinate](
const CompressedEdgeContainer::OnewayCompressedEdge &compressed_edge) { const CompressedEdgeContainer::OnewayCompressedEdge &compressed_edge) {
return util::coordinate_calculation::haversineDistance( return util::coordinate_calculation::greatCircleDistance(
compressedGeometryToCoordinate(compressed_edge), start_coordinate) > 1; compressedGeometryToCoordinate(compressed_edge), start_coordinate) > 1;
}; };
@ -627,7 +627,7 @@ CoordinateExtractor::GetMaxDeviation(std::vector<util::Coordinate>::const_iterat
.second; .second;
// and calculate the distance between the intermediate coordinate and the coordinate // and calculate the distance between the intermediate coordinate and the coordinate
// on the osrm-way // on the osrm-way
return util::coordinate_calculation::haversineDistance(coord_between, coordinate); return util::coordinate_calculation::greatCircleDistance(coord_between, coordinate);
}; };
// note: we don't accumulate here but rather compute the maximum. The functor passed here is not // note: we don't accumulate here but rather compute the maximum. The functor passed here is not
@ -671,7 +671,7 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
auto coord_between = auto coord_between =
util::coordinate_calculation::projectPointOnSegment(line_start, line_end, point).second; util::coordinate_calculation::projectPointOnSegment(line_start, line_end, point).second;
// and calculate the distance between the intermediate coordinate and the coordinate // and calculate the distance between the intermediate coordinate and the coordinate
return util::coordinate_calculation::haversineDistance(coord_between, point); return util::coordinate_calculation::greatCircleDistance(coord_between, point);
}; };
// a curve needs to be on one side of the coordinate array // a curve needs to be on one side of the coordinate array
@ -899,7 +899,7 @@ CoordinateExtractor::PrepareLengthCache(const std::vector<util::Coordinate> &coo
limit, limit,
&segment_distances, &segment_distances,
accumulated_distance = 0.](const util::Coordinate current_coordinate) mutable { accumulated_distance = 0.](const util::Coordinate current_coordinate) mutable {
const auto distance = util::coordinate_calculation::haversineDistance( const auto distance = util::coordinate_calculation::greatCircleDistance(
last_coordinate, current_coordinate); last_coordinate, current_coordinate);
accumulated_distance += distance; accumulated_distance += distance;
last_coordinate = current_coordinate; last_coordinate = current_coordinate;
@ -924,8 +924,8 @@ CoordinateExtractor::TrimCoordinatesToLength(std::vector<util::Coordinate> coord
[&coordinate_index, &distance_to_current_coordinate, &coordinates]() { [&coordinate_index, &distance_to_current_coordinate, &coordinates]() {
const auto new_distance = const auto new_distance =
distance_to_current_coordinate + distance_to_current_coordinate +
util::coordinate_calculation::haversineDistance(coordinates[coordinate_index - 1], util::coordinate_calculation::greatCircleDistance(coordinates[coordinate_index - 1],
coordinates[coordinate_index]); coordinates[coordinate_index]);
return new_distance; return new_distance;
}; };
@ -941,8 +941,8 @@ CoordinateExtractor::TrimCoordinatesToLength(std::vector<util::Coordinate> coord
coordinates.erase(coordinates.begin() + length_cache.size(), coordinates.end()); coordinates.erase(coordinates.begin() + length_cache.size(), coordinates.end());
const auto distance_between_last_coordinates = const auto distance_between_last_coordinates =
util::coordinate_calculation::haversineDistance(*(coordinates.end() - 2), util::coordinate_calculation::greatCircleDistance(*(coordinates.end() - 2),
*(coordinates.end() - 1)); *(coordinates.end() - 1));
if (distance_between_last_coordinates > 0) if (distance_between_last_coordinates > 0)
{ {
@ -991,7 +991,7 @@ CoordinateExtractor::GetCorrectedCoordinate(const util::Coordinate fixpoint,
{ {
// if the coordinates are close together, we were not able to look far ahead, so // if the coordinates are close together, we were not able to look far ahead, so
// we can use the end-coordinate // we can use the end-coordinate
if (util::coordinate_calculation::haversineDistance(vector_base, vector_head) < if (util::coordinate_calculation::greatCircleDistance(vector_base, vector_head) <
DESIRED_COORDINATE_DIFFERENCE) DESIRED_COORDINATE_DIFFERENCE)
{ {
return vector_head; return vector_head;
@ -1054,7 +1054,7 @@ CoordinateExtractor::SampleCoordinates(const std::vector<util::Coordinate> &coor
if (total_length > max_sample_length) if (total_length > max_sample_length)
return true; return true;
const auto distance_between = util::coordinate_calculation::haversineDistance( const auto distance_between = util::coordinate_calculation::greatCircleDistance(
previous_coordinate, current_coordinate); previous_coordinate, current_coordinate);
if (carry_length + distance_between >= rate) if (carry_length + distance_between >= rate)
@ -1123,7 +1123,7 @@ CoordinateExtractor::TrimCoordinatesByLengthFront(std::vector<util::Coordinate>
for (std::size_t next_index = 1; next_index < coordinates.size(); ++next_index) for (std::size_t next_index = 1; next_index < coordinates.size(); ++next_index)
{ {
const double next_distance = const double next_distance =
distance_to_index + util::coordinate_calculation::haversineDistance( distance_to_index + util::coordinate_calculation::greatCircleDistance(
coordinates[index], coordinates[next_index]); coordinates[index], coordinates[next_index]);
if (next_distance >= desired_length) if (next_distance >= desired_length)
{ {

View File

@ -237,7 +237,7 @@ getIntersectionOutgoingGeometries(const util::NodeBasedDynamicGraph &graph,
util::coordinate_calculation::bearing(geometry[0], representative_coordinate); util::coordinate_calculation::bearing(geometry[0], representative_coordinate);
const auto edge_length = util::coordinate_calculation::getLength( const auto edge_length = util::coordinate_calculation::getLength(
geometry.begin(), geometry.end(), util::coordinate_calculation::haversineDistance); geometry.begin(), geometry.end(), util::coordinate_calculation::greatCircleDistance);
edge_geometries.push_back({outgoing_edge, initial_bearing, perceived_bearing, edge_length}); edge_geometries.push_back({outgoing_edge, initial_bearing, perceived_bearing, edge_length});
} }

View File

@ -225,7 +225,7 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node,
left_accumulator, left_accumulator,
selector); selector);
} }
const auto distance_to_triangle = util::coordinate_calculation::haversineDistance( const auto distance_to_triangle = util::coordinate_calculation::greatCircleDistance(
node_coordinates[intersection_node], node_coordinates[intersection_node],
node_coordinates[node_based_graph.GetTarget(left_accumulator.via_edge_id)]); node_coordinates[node_based_graph.GetTarget(left_accumulator.via_edge_id)]);
@ -274,9 +274,10 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node,
// the width we can bridge at the intersection // the width we can bridge at the intersection
const auto assumed_road_width = (num_lanes(lhs) + num_lanes(rhs)) * ASSUMED_LANE_WIDTH; const auto assumed_road_width = (num_lanes(lhs) + num_lanes(rhs)) * ASSUMED_LANE_WIDTH;
const constexpr auto MAXIMAL_ALLOWED_TRAFFIC_ISLAND_WIDTH = 10; const constexpr auto MAXIMAL_ALLOWED_TRAFFIC_ISLAND_WIDTH = 10;
const auto distance_between_triangle_corners = util::coordinate_calculation::haversineDistance( const auto distance_between_triangle_corners =
node_coordinates[node_based_graph.GetTarget(left_accumulator.via_edge_id)], util::coordinate_calculation::greatCircleDistance(
node_coordinates[node_based_graph.GetTarget(right_accumulator.via_edge_id)]); node_coordinates[node_based_graph.GetTarget(left_accumulator.via_edge_id)],
node_coordinates[node_based_graph.GetTarget(right_accumulator.via_edge_id)]);
if (distance_between_triangle_corners > if (distance_between_triangle_corners >
(assumed_road_width + MAXIMAL_ALLOWED_TRAFFIC_ISLAND_WIDTH)) (assumed_road_width + MAXIMAL_ALLOWED_TRAFFIC_ISLAND_WIDTH))
return false; return false;
@ -540,7 +541,7 @@ bool MergableRoadDetector::IsTrafficIsland(const NodeID intersection_node,
if (!degree_three_connect_in && !degree_three_connect_out) if (!degree_three_connect_in && !degree_three_connect_out)
return false; return false;
const auto distance_between_candidates = util::coordinate_calculation::haversineDistance( const auto distance_between_candidates = util::coordinate_calculation::greatCircleDistance(
node_coordinates[intersection_node], node_coordinates[left_candidate]); node_coordinates[intersection_node], node_coordinates[left_candidate]);
const auto both_split_join = degree_three_connect_in && degree_three_connect_out; const auto both_split_join = degree_three_connect_in && degree_three_connect_out;

View File

@ -50,7 +50,7 @@ void LengthLimitedCoordinateAccumulator::update(const NodeID from_node,
const auto length = const auto length =
util::coordinate_calculation::getLength(current_coordinates.begin(), util::coordinate_calculation::getLength(current_coordinates.begin(),
current_coordinates.end(), current_coordinates.end(),
util::coordinate_calculation::haversineDistance); util::coordinate_calculation::greatCircleDistance);
// in case we get too many coordinates, we limit them to our desired length // in case we get too many coordinates, we limit them to our desired length
if (length + accumulated_length > max_length) if (length + accumulated_length > max_length)

View File

@ -50,13 +50,13 @@ RestrictionParser::RestrictionParser(bool use_turn_restrictions_,
* in the corresponding profile. We use it for both namespacing restrictions, as in * in the corresponding profile. We use it for both namespacing restrictions, as in
* restriction:motorcar as well as whitelisting if its in except:motorcar. * restriction:motorcar as well as whitelisting if its in except:motorcar.
*/ */
boost::optional<InputTurnRestriction> std::vector<InputTurnRestriction>
RestrictionParser::TryParse(const osmium::Relation &relation) const RestrictionParser::TryParse(const osmium::Relation &relation) const
{ {
// return if turn restrictions should be ignored // return if turn restrictions should be ignored
if (!use_turn_restrictions) if (!use_turn_restrictions)
{ {
return boost::none; return {};
} }
osmium::tags::KeyFilter filter(false); osmium::tags::KeyFilter filter(false);
@ -85,17 +85,19 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
// if it's not a restriction, continue; // if it's not a restriction, continue;
if (std::distance(fi_begin, fi_end) == 0) if (std::distance(fi_begin, fi_end) == 0)
{ {
return boost::none; return {};
} }
// check if the restriction should be ignored // check if the restriction should be ignored
const char *except = relation.get_value_by_key("except"); const char *except = relation.get_value_by_key("except");
if (except != nullptr && ShouldIgnoreRestriction(except)) if (except != nullptr && ShouldIgnoreRestriction(except))
{ {
return boost::none; return {};
} }
bool is_only_restriction = false; bool is_only_restriction = false;
bool is_multi_from = false;
bool is_multi_to = false;
for (; fi_begin != fi_end; ++fi_begin) for (; fi_begin != fi_end; ++fi_begin)
{ {
@ -111,21 +113,26 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
else if (value.find("no_") == 0 && !boost::algorithm::ends_with(value, "_on_red")) else if (value.find("no_") == 0 && !boost::algorithm::ends_with(value, "_on_red"))
{ {
is_only_restriction = false; is_only_restriction = false;
if (boost::algorithm::starts_with(value, "no_exit"))
{
is_multi_to = true;
}
else if (boost::algorithm::starts_with(value, "no_entry"))
{
is_multi_from = true;
}
} }
else // unrecognized value type else // unrecognized value type
{ {
return boost::none; return {};
} }
} }
InputTurnRestriction restriction_container;
restriction_container.is_only = is_only_restriction;
constexpr auto INVALID_OSM_ID = std::numeric_limits<std::uint64_t>::max(); constexpr auto INVALID_OSM_ID = std::numeric_limits<std::uint64_t>::max();
auto from = INVALID_OSM_ID; std::vector<OSMWayID> from_ways;
auto via_node = INVALID_OSM_ID; auto via_node = INVALID_OSM_ID;
std::vector<OSMWayID> via_ways; std::vector<OSMWayID> via_ways;
auto to = INVALID_OSM_ID; std::vector<OSMWayID> to_ways;
bool is_node_restriction = true; bool is_node_restriction = true;
for (const auto &member : relation.members()) for (const auto &member : relation.members())
@ -157,11 +164,11 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
0 == strcmp("via", role)); 0 == strcmp("via", role));
if (0 == strcmp("from", role)) if (0 == strcmp("from", role))
{ {
from = static_cast<std::uint64_t>(member.ref()); from_ways.push_back({static_cast<std::uint64_t>(member.ref())});
} }
else if (0 == strcmp("to", role)) else if (0 == strcmp("to", role))
{ {
to = static_cast<std::uint64_t>(member.ref()); to_ways.push_back({static_cast<std::uint64_t>(member.ref())});
} }
else if (0 == strcmp("via", role)) else if (0 == strcmp("via", role))
{ {
@ -178,6 +185,7 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
} }
} }
std::vector<util::OpeningHours> condition;
// parse conditional tags // parse conditional tags
if (parse_conditionals) if (parse_conditionals)
{ {
@ -199,32 +207,54 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
std::vector<util::OpeningHours> hours = util::ParseOpeningHours(p.condition); std::vector<util::OpeningHours> hours = util::ParseOpeningHours(p.condition);
// found unrecognized condition, continue // found unrecognized condition, continue
if (hours.empty()) if (hours.empty())
return boost::none; return {};
restriction_container.condition = std::move(hours); condition = std::move(hours);
} }
} }
} }
if (from != INVALID_OSM_ID && (via_node != INVALID_OSM_ID || !via_ways.empty()) && std::vector<InputTurnRestriction> restriction_containers;
to != INVALID_OSM_ID) if (!from_ways.empty() && (via_node != INVALID_OSM_ID || !via_ways.empty()) && !to_ways.empty())
{ {
if (is_node_restriction) if (from_ways.size() > 1 && !is_multi_from)
{ {
// template struct requires bracket for ID initialisation :( util::Log(logDEBUG) << "Parsed restriction " << relation.id()
restriction_container.node_or_way = InputNodeRestriction{{from}, {via_node}, {to}}; << " unexpectedly contains " << from_ways.size()
<< " from ways, skipping...";
return {};
} }
else if (to_ways.size() > 1 && !is_multi_to)
{ {
// template struct requires bracket for ID initialisation :( util::Log(logDEBUG) << "Parsed restriction " << relation.id()
restriction_container.node_or_way = InputWayRestriction{{from}, via_ways, {to}}; << " unexpectedly contains " << to_ways.size()
<< " to ways, skipping...";
return {};
}
// Internally restrictions are represented with one 'from' and one 'to' way.
// Therefore we need to convert a multi from/to restriction into multiple restrictions.
for (const auto &from : from_ways)
{
for (const auto &to : to_ways)
{
InputTurnRestriction restriction;
restriction.is_only = is_only_restriction;
restriction.condition = condition;
if (is_node_restriction)
{
// template struct requires bracket for ID initialisation :(
restriction.node_or_way = InputNodeRestriction{{from}, {via_node}, {to}};
}
else
{
// template struct requires bracket for ID initialisation :(
restriction.node_or_way = InputWayRestriction{{from}, via_ways, {to}};
}
restriction_containers.push_back(std::move(restriction));
}
} }
return restriction_container;
}
else
{
return boost::none;
} }
return restriction_containers;
} }
bool RestrictionParser::ShouldIgnoreRestriction(const std::string &except_tag_string) const bool RestrictionParser::ShouldIgnoreRestriction(const std::string &except_tag_string) const

View File

@ -909,13 +909,15 @@ void Sol2ScriptingEnvironment::ProcessElements(
case osmium::item_type::relation: case osmium::item_type::relation:
{ {
const auto &relation = static_cast<const osmium::Relation &>(*entity); const auto &relation = static_cast<const osmium::Relation &>(*entity);
if (auto result_res = restriction_parser.TryParse(relation)) auto results = restriction_parser.TryParse(relation);
if (!results.empty())
{ {
resulting_restrictions.push_back(*result_res); std::move(
results.begin(), results.end(), std::back_inserter(resulting_restrictions));
} }
else if (auto result_res = maneuver_override_parser.TryParse(relation)) else if (auto result_res = maneuver_override_parser.TryParse(relation))
{ {
resulting_maneuver_overrides.push_back(*result_res); resulting_maneuver_overrides.push_back(std::move(*result_res));
} }
} }
break; break;

View File

@ -183,7 +183,7 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
// duration/weight of the traversal. We can only approximate the distance here // duration/weight of the traversal. We can only approximate the distance here
// or actually follow the full road. When 2399 lands, we can exchange here for a // or actually follow the full road. When 2399 lands, we can exchange here for a
// precalculated distance value. // precalculated distance value.
const auto distance = util::coordinate_calculation::haversineDistance( const auto distance = util::coordinate_calculation::greatCircleDistance(
node_coordinates[node_based_graph.GetTarget(via_edge)], node_coordinates[node_based_graph.GetTarget(via_edge)],
node_coordinates[node_based_graph.GetTarget(road.eid)]); node_coordinates[node_based_graph.GetTarget(road.eid)]);

View File

@ -274,7 +274,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
for (const auto &compressed_edge : edge_bucket) for (const auto &compressed_edge : edge_bucket)
{ {
const auto next_coord = node_coordinates[compressed_edge.node_id]; const auto next_coord = node_coordinates[compressed_edge.node_id];
length += util::coordinate_calculation::haversineDistance(last_coord, next_coord); length += util::coordinate_calculation::greatCircleDistance(last_coord, next_coord);
last_coord = next_coord; last_coord = next_coord;
} }
return length; return length;

View File

@ -56,7 +56,7 @@ std::unordered_set<EdgeID> findSegregatedNodes(const extractor::NodeBasedGraphFa
double length = 0.0; double length = 0.0;
for (size_t i = 1; i < geom.size(); ++i) for (size_t i = 1; i < geom.size(); ++i)
{ {
length += util::coordinate_calculation::haversineDistance(geom[i - 1], geom[i]); length += util::coordinate_calculation::greatCircleDistance(geom[i - 1], geom[i]);
} }
return length; return length;
}; };

View File

@ -452,8 +452,8 @@ Intersection SliproadHandler::operator()(const NodeID /*nid*/,
// Only check for curvature and ~90 degree when it makes sense to do so. // Only check for curvature and ~90 degree when it makes sense to do so.
const constexpr auto MIN_LENGTH = 3.; const constexpr auto MIN_LENGTH = 3.;
const auto length = haversineDistance(node_coordinates[intersection_node_id], const auto length = greatCircleDistance(node_coordinates[intersection_node_id],
node_coordinates[main_road_intersection->node]); node_coordinates[main_road_intersection->node]);
const double minimal_crossroad_angle_of_intersection = 40.; const double minimal_crossroad_angle_of_intersection = 40.;
@ -740,8 +740,8 @@ bool SliproadHandler::isValidSliproadArea(const double max_area,
const auto second = node_coordinates[b]; const auto second = node_coordinates[b];
const auto third = node_coordinates[c]; const auto third = node_coordinates[c];
const auto length = haversineDistance(first, second); const auto length = greatCircleDistance(first, second);
const auto heigth = haversineDistance(second, third); const auto heigth = greatCircleDistance(second, third);
const auto area = (length * heigth) / 2.; const auto area = (length * heigth) / 2.;

View File

@ -51,7 +51,7 @@ bool findPreviousIntersection(const NodeID node_v,
const auto via_edge_length = const auto via_edge_length =
util::coordinate_calculation::getLength(coordinates_along_via_edge.begin(), util::coordinate_calculation::getLength(coordinates_along_via_edge.begin(),
coordinates_along_via_edge.end(), coordinates_along_via_edge.end(),
&util::coordinate_calculation::haversineDistance); &util::coordinate_calculation::greatCircleDistance);
// we check if via-edge is too short. In this case the previous turn cannot influence the turn // we check if via-edge is too short. In this case the previous turn cannot influence the turn
// at via_edge and the intersection at NODE_W // at via_edge and the intersection at NODE_W

View File

@ -148,7 +148,7 @@ inline void async(const Nan::FunctionCallbackInfo<v8::Value> &info,
ServiceMemFn service, ServiceMemFn service,
Nan::Callback *callback, Nan::Callback *callback,
PluginParameters pluginParams_) PluginParameters pluginParams_)
: Base(callback), osrm{std::move(osrm_)}, service{std::move(service)}, : Base(callback, "osrm:async"), osrm{std::move(osrm_)}, service{std::move(service)},
params{std::move(params_)}, pluginParams{std::move(pluginParams_)} params{std::move(params_)}, pluginParams{std::move(pluginParams_)}
{ {
} }
@ -184,7 +184,7 @@ inline void async(const Nan::FunctionCallbackInfo<v8::Value> &info,
const constexpr auto argc = 2u; const constexpr auto argc = 2u;
v8::Local<v8::Value> argv[argc] = {Nan::Null(), render(result)}; v8::Local<v8::Value> argv[argc] = {Nan::Null(), render(result)};
callback->Call(argc, argv); callback->Call(argc, argv, async_resource);
} }
// Keeps the OSRM object alive even after shutdown until we're done with callback // Keeps the OSRM object alive even after shutdown until we're done with callback
@ -230,8 +230,9 @@ inline void asyncForTiles(const Nan::FunctionCallbackInfo<v8::Value> &info,
ServiceMemFn service, ServiceMemFn service,
Nan::Callback *callback, Nan::Callback *callback,
PluginParameters pluginParams_) PluginParameters pluginParams_)
: Base(callback), osrm{std::move(osrm_)}, service{std::move(service)}, : Base(callback, "osrm:asyncForTiles"), osrm{std::move(osrm_)},
params{std::move(params_)}, pluginParams{std::move(pluginParams_)} service{std::move(service)}, params{std::move(params_)}, pluginParams{
std::move(pluginParams_)}
{ {
} }
@ -256,7 +257,7 @@ inline void asyncForTiles(const Nan::FunctionCallbackInfo<v8::Value> &info,
auto str_result = result.get<std::string>(); auto str_result = result.get<std::string>();
v8::Local<v8::Value> argv[argc] = {Nan::Null(), render(str_result)}; v8::Local<v8::Value> argv[argc] = {Nan::Null(), render(str_result)};
callback->Call(argc, argv); callback->Call(argc, argv, async_resource);
} }
// Keeps the OSRM object alive even after shutdown until we're done with callback // Keeps the OSRM object alive even after shutdown until we're done with callback

View File

@ -10,6 +10,8 @@
#include "engine/engine_config.hpp" #include "engine/engine_config.hpp"
#include "engine/status.hpp" #include "engine/status.hpp"
#include <boost/algorithm/string/join.hpp>
#include <memory> #include <memory>
namespace osrm namespace osrm
@ -25,8 +27,11 @@ OSRM::OSRM(engine::EngineConfig &config)
// First, check that necessary core data is available // First, check that necessary core data is available
if (!config.use_shared_memory && !config.storage_config.IsValid()) if (!config.use_shared_memory && !config.storage_config.IsValid())
{ {
throw util::exception("Required files are missing, cannot continue. Have all the " const auto &missingFiles = config.storage_config.GetMissingFiles();
"pre-processing steps been run?"); throw util::exception("Required files are missing, cannot continue. Have all the "
"pre-processing steps been run? "
"Missing files: " +
boost::algorithm::join(missingFiles, ", "));
} }
// Now, check that the algorithm requested can be used with the data // Now, check that the algorithm requested can be used with the data

View File

@ -10,10 +10,11 @@ namespace osrm
{ {
namespace storage namespace storage
{ {
namespace fs = boost::filesystem;
bool IOConfig::IsValid() const bool IOConfig::IsValid() const
{ {
namespace fs = boost::filesystem;
bool success = true; bool success = true;
for (auto &fileName : required_input_files) for (auto &fileName : required_input_files)
{ {
@ -26,5 +27,18 @@ bool IOConfig::IsValid() const
} }
return success; return success;
} }
std::vector<std::string> IOConfig::GetMissingFiles() const
{
std::vector<std::string> missingFiles;
for (auto &fileName : required_input_files)
{
if (!fs::is_regular_file(fs::path(base_path.string() + fileName.string())))
{
missingFiles.push_back(base_path.string() + fileName.string());
}
}
return missingFiles;
}
} // namespace storage } // namespace storage
} // namespace osrm } // namespace osrm

View File

@ -72,12 +72,10 @@ std::uint64_t squaredEuclideanDistance(const Coordinate lhs, const Coordinate rh
return result; return result;
} }
// Uses method described here: double greatCircleDistance(const Coordinate coordinate_1, const Coordinate coordinate_2)
// https://www.gpo.gov/fdsys/pkg/CFR-2005-title47-vol4/pdf/CFR-2005-title47-vol4-sec73-208.pdf
// should be within 0.1% or so of Vincenty method (assuming 19 buckets are enough)
// Should be more faster and more precise than Haversine
double fccApproximateDistance(const Coordinate coordinate_1, const Coordinate coordinate_2)
{ {
// Should be within 0.1% or so of Vincenty method (assuming 19 buckets are enough)
// Should be more faster and more precise than Haversine
const auto lon1 = static_cast<double>(util::toFloating(coordinate_1.lon)); const auto lon1 = static_cast<double>(util::toFloating(coordinate_1.lon));
const auto lat1 = static_cast<double>(util::toFloating(coordinate_1.lat)); const auto lat1 = static_cast<double>(util::toFloating(coordinate_1.lat));
const auto lon2 = static_cast<double>(util::toFloating(coordinate_2.lon)); const auto lon2 = static_cast<double>(util::toFloating(coordinate_2.lon));
@ -86,56 +84,6 @@ double fccApproximateDistance(const Coordinate coordinate_1, const Coordinate co
.distance({lon1, lat1}, {lon2, lat2}); .distance({lon1, lat1}, {lon2, lat2});
} }
double haversineDistance(const Coordinate coordinate_1, const Coordinate coordinate_2)
{
auto lon1 = static_cast<int>(coordinate_1.lon);
auto lat1 = static_cast<int>(coordinate_1.lat);
auto lon2 = static_cast<int>(coordinate_2.lon);
auto lat2 = static_cast<int>(coordinate_2.lat);
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
const double lt1 = lat1 / COORDINATE_PRECISION;
const double ln1 = lon1 / COORDINATE_PRECISION;
const double lt2 = lat2 / COORDINATE_PRECISION;
const double ln2 = lon2 / COORDINATE_PRECISION;
const double dlat1 = lt1 * detail::DEGREE_TO_RAD;
const double dlong1 = ln1 * detail::DEGREE_TO_RAD;
const double dlat2 = lt2 * detail::DEGREE_TO_RAD;
const double dlong2 = ln2 * detail::DEGREE_TO_RAD;
const double dlong = dlong1 - dlong2;
const double dlat = dlat1 - dlat2;
const double aharv = std::pow(std::sin(dlat / 2.0), 2.0) +
std::cos(dlat1) * std::cos(dlat2) * std::pow(std::sin(dlong / 2.), 2);
const double charv = 2. * std::atan2(std::sqrt(aharv), std::sqrt(1.0 - aharv));
return detail::EARTH_RADIUS * charv;
}
double greatCircleDistance(const Coordinate coordinate_1, const Coordinate coordinate_2)
{
auto lon1 = static_cast<int>(coordinate_1.lon);
auto lat1 = static_cast<int>(coordinate_1.lat);
auto lon2 = static_cast<int>(coordinate_2.lon);
auto lat2 = static_cast<int>(coordinate_2.lat);
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
const double float_lat1 = (lat1 / COORDINATE_PRECISION) * detail::DEGREE_TO_RAD;
const double float_lon1 = (lon1 / COORDINATE_PRECISION) * detail::DEGREE_TO_RAD;
const double float_lat2 = (lat2 / COORDINATE_PRECISION) * detail::DEGREE_TO_RAD;
const double float_lon2 = (lon2 / COORDINATE_PRECISION) * detail::DEGREE_TO_RAD;
const double x_value = (float_lon2 - float_lon1) * std::cos((float_lat1 + float_lat2) / 2.0);
const double y_value = float_lat2 - float_lat1;
return std::hypot(x_value, y_value) * detail::EARTH_RADIUS;
}
double perpendicularDistance(const Coordinate segment_source, double perpendicularDistance(const Coordinate segment_source,
const Coordinate segment_target, const Coordinate segment_target,
const Coordinate query_location, const Coordinate query_location,
@ -153,7 +101,7 @@ double perpendicularDistance(const Coordinate segment_source,
web_mercator::fromWGS84(query_location)); web_mercator::fromWGS84(query_location));
nearest_location = web_mercator::toWGS84(projected_nearest); nearest_location = web_mercator::toWGS84(projected_nearest);
const double approximate_distance = fccApproximateDistance(query_location, nearest_location); const double approximate_distance = greatCircleDistance(query_location, nearest_location);
BOOST_ASSERT(0.0 <= approximate_distance); BOOST_ASSERT(0.0 <= approximate_distance);
return approximate_distance; return approximate_distance;
} }
@ -179,30 +127,24 @@ Coordinate centroid(const Coordinate lhs, const Coordinate rhs)
return centroid; return centroid;
} }
double bearing(const Coordinate first_coordinate, const Coordinate second_coordinate) double bearing(const Coordinate coordinate_1, const Coordinate coordinate_2)
{ {
const double lon_diff = const auto lon1 = static_cast<double>(util::toFloating(coordinate_1.lon));
static_cast<double>(toFloating(second_coordinate.lon - first_coordinate.lon)); const auto lat1 = static_cast<double>(util::toFloating(coordinate_1.lat));
const double lon_delta = detail::degToRad(lon_diff); const auto lon2 = static_cast<double>(util::toFloating(coordinate_2.lon));
const double lat1 = detail::degToRad(static_cast<double>(toFloating(first_coordinate.lat))); const auto lat2 = static_cast<double>(util::toFloating(coordinate_2.lat));
const double lat2 = detail::degToRad(static_cast<double>(toFloating(second_coordinate.lat))); const auto &ruler = cheap_ruler_container.getRuler(coordinate_1.lat, coordinate_2.lat);
const double y = std::sin(lon_delta) * std::cos(lat2); auto result = ruler.bearing({lon1, lat1}, {lon2, lat2});
const double x = if (result < 0.0)
std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(lon_delta);
double result = detail::radToDeg(std::atan2(y, x));
while (result < 0.0)
{ {
result += 360.0; result += 360.0;
} }
BOOST_ASSERT(0 <= result && result <= 360);
while (result >= 360.0)
{
result -= 360.0;
}
// If someone gives us two identical coordinates, then the concept of a bearing // If someone gives us two identical coordinates, then the concept of a bearing
// makes no sense. However, because it sometimes happens, we'll at least // makes no sense. However, because it sometimes happens, we'll at least
// return a consistent value of 0 so that the behaviour isn't random. // return a consistent value of 0 so that the behaviour isn't random.
BOOST_ASSERT(first_coordinate != second_coordinate || result == 0.); BOOST_ASSERT(coordinate_1 != coordinate_2 || result == 0.);
return result; return result;
} }
@ -322,7 +264,7 @@ double circleRadius(const Coordinate C1, const Coordinate C2, const Coordinate C
// a circle by three points requires thee distinct points // a circle by three points requires thee distinct points
auto center = circleCenter(C1, C2, C3); auto center = circleCenter(C1, C2, C3);
if (center) if (center)
return haversineDistance(C1, *center); return greatCircleDistance(C1, *center);
else else
return std::numeric_limits<double>::infinity(); return std::numeric_limits<double>::infinity();
} }
@ -372,8 +314,8 @@ double findClosestDistance(const Coordinate coordinate,
const Coordinate segment_begin, const Coordinate segment_begin,
const Coordinate segment_end) const Coordinate segment_end)
{ {
return haversineDistance(coordinate, return greatCircleDistance(
projectPointOnSegment(segment_begin, segment_end, coordinate).second); coordinate, projectPointOnSegment(segment_begin, segment_end, coordinate).second);
} }
// find the closes distance between two sets of coordinates // find the closes distance between two sets of coordinates
@ -437,7 +379,7 @@ Coordinate difference(const Coordinate lhs, const Coordinate rhs)
double computeArea(const std::vector<Coordinate> &polygon) double computeArea(const std::vector<Coordinate> &polygon)
{ {
using util::coordinate_calculation::haversineDistance; using util::coordinate_calculation::greatCircleDistance;
if (polygon.empty()) if (polygon.empty())
return 0.; return 0.;
@ -458,15 +400,15 @@ double computeArea(const std::vector<Coordinate> &polygon)
double area = 0.; double area = 0.;
auto first = polygon.begin(); auto first = polygon.begin();
auto previous_base = util::Coordinate{first->lon, ref_latitude}; auto previous_base = util::Coordinate{first->lon, ref_latitude};
auto previous_y = haversineDistance(previous_base, *first); auto previous_y = greatCircleDistance(previous_base, *first);
for (++first; first != polygon.end(); ++first) for (++first; first != polygon.end(); ++first)
{ {
BOOST_ASSERT(first->lat >= ref_latitude); BOOST_ASSERT(first->lat >= ref_latitude);
const auto current_base = util::Coordinate{first->lon, ref_latitude}; const auto current_base = util::Coordinate{first->lon, ref_latitude};
const auto current_y = haversineDistance(current_base, *first); const auto current_y = greatCircleDistance(current_base, *first);
const auto chunk_area = const auto chunk_area =
haversineDistance(previous_base, current_base) * (previous_y + current_y); greatCircleDistance(previous_base, current_base) * (previous_y + current_y);
area += (current_base.lon >= previous_base.lon) ? chunk_area : -chunk_area; area += (current_base.lon >= previous_base.lon) ? chunk_area : -chunk_area;

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': 156624}; exports.test_tile = {'at': [17059, 11948, 15], 'size': 156539};
// 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) {

Some files were not shown because too many files have changed in this diff Show More