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:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: 12
- name: Enable Node.js cache
@ -348,8 +348,7 @@ jobs:
- name: conan-osx-release-node-latest
build_node_package: true
continue-on-error: true
# TODO: Use node 'latest' once supported: https://github.com/actions/setup-node/issues/257
node: 16
node: latest
runs-on: macos-11
BUILD_TYPE: Release
CCOMPILER: clang
@ -361,8 +360,7 @@ jobs:
- name: node-latest-conan-linux-release
build_node_package: true
continue-on-error: true
# TODO: Use node 'latest' once supported: https://github.com/actions/setup-node/issues/257
node: 16
node: latest
runs-on: ubuntu-20.04
BUILD_TYPE: Release
CLANG_VERSION: 6.0.0
@ -373,8 +371,7 @@ jobs:
- name: node-latest-conan-linux-debug
build_node_package: true
continue-on-error: true
# TODO: Use node 'latest' once supported: https://github.com/actions/setup-node/issues/257
node: 16
node: latest
runs-on: ubuntu-20.04
BUILD_TYPE: Debug
CLANG_VERSION: 6.0.0
@ -444,7 +441,7 @@ jobs:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- name: Enable Node.js cache
@ -472,9 +469,9 @@ jobs:
uses: actions/cache@v2
with:
path: ${{github.workspace}}/test/cache
key: test-${{ matrix.name }}-${{ github.sha }}
key: v3-test-${{ matrix.name }}-${{ github.sha }}
restore-keys: |
test-${{ matrix.name }}-
v3-test-${{ matrix.name }}-
- name: Prepare environment
run: |
@ -662,7 +659,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
ci-complete:
runs-on: ubuntu-18.04
runs-on: ubuntu-22.04
needs: [build-test-publish, docker-image, windows]
steps:
- run: echo "CI complete"

View File

@ -1,15 +1,23 @@
# Unreleased
- Changes from 5.26.0
- 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: 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:
- 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)
- 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: 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:
- 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)
- 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)
@ -31,6 +39,11 @@
- 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 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
- 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")
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})
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 | any | **yes** |
| false | first | last | **yes** |
| false | first | any | no |
| false | any | last | no |
| false | first | any | **yes** |
| false | any | last | **yes** |
| false | any | any | no |
#### Example Requests

View File

@ -12,20 +12,14 @@ Prepare directories for dependencies, build and target file location.Target dire
### Bzip2
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://project-osrm.wolt.com/deps/bzip2-1.0.8.tar.gz
* https://sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz
1. Download from 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.
3. Issue `nmake /f makefile.msc`
4. Copy bzlib.h to $target\include and libbz2.lib to $target\lib
### ZLib
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://project-osrm.wolt.com/deps/zlib-1.2.11.tar.gz
* https://www.zlib.net/zlib-1.2.11.tar.gz
1. Download 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.
3. Switch to `contrib\vstudio\vc14`
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
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://wolt-project.wolt.com/deps/icu4c-66_1-src.zip
1. Download and unpack.
* 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
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.
@ -48,10 +40,7 @@ Prepare directories for dependencies, build and target file location.Target dire
### Boost
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* 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
1. Download and unpack 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.
3. Build b2:
bootstrap.bat --with-toolset=msvc-14.2
@ -61,9 +50,7 @@ Prepare directories for dependencies, build and target file location.Target dire
### Expat
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://project-osrm.wolt.com/deps/libexpat-2_2_9.zip
* https://github.com/libexpat/libexpat/archive/R_2_2_9.zip
1. Download and unpack 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.
3. Configure build my calling cmake:
mkdir expat\build
@ -74,9 +61,7 @@ Prepare directories for dependencies, build and target file location.Target dire
### LUA
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://project-osrm.wolt.com/deps/lua-5.3.5.tar.gz
* https://www.lua.org/ftp/lua-5.3.5.tar.gz
1. Download and unpack 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.
3. Lua doesn't have native MSVC support, so you have to compile it by hand:
cd src
@ -88,9 +73,7 @@ Prepare directories for dependencies, build and target file location.Target dire
### TBB
1. Download either from Wolt OSRM mirror or original distribution and unpack.
* https://project-osrm.wolt.com/deps/oneTBB-v2020.2.zip
* https://github.com/oneapi-src/oneTBB/archive/v2020.2.zip
1. Download and unpack https://github.com/oneapi-src/oneTBB/archive/v2020.2.zip
2. Retarget by opening build\vs2013\makefile.sln
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`

View File

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

View File

@ -9,7 +9,7 @@ Feature: Bike - Max speed restrictions
Then routability should be
| highway | maxspeed | bothw |
| residential | | 15 km/h |
| residential | 10 | 9 km/h |
| residential | 10 | 10 km/h |
Scenario: Bicycle - Ignore maxspeed when higher than way speed
Then routability should be
@ -65,12 +65,12 @@ Feature: Bike - Max speed restrictions
Then routability should be
| maxspeed | maxspeed:forward | maxspeed:backward | forw | backw |
| | | | 15 km/h | 15 km/h |
| 10 | | | 9 km/h | 9 km/h |
| | 10 | | 9 km/h | 15 km/h |
| | | 10 | 14 km/h | 9 km/h |
| 2 | 10 | | 9 km/h | 2 km/h |
| 2 | | 10 | 2 km/h | 9 km/h |
| 2 | 5 | 10 | 5 km/h | 9 km/h |
| 10 | | | 10 km/h | 10 km/h |
| | 10 | | 10 km/h | 15 km/h |
| | | 10 | 15 km/h | 10 km/h |
| 2 | 10 | | 10 km/h | 2 km/h |
| 2 | | 10 | 2 km/h | 10 km/h |
| 2 | 5 | 10 | 5 km/h | 10 km/h |
Scenario: Bike - Maxspeed should not allow routing on unroutable ways
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 |
| residential | 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 | |
| primary | 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 |
| 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 |
| 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 |
| footway | lane | 15 km/h | 15 km/h | 4.2 | 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 |
| residential | 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 | |
| primary | | track | 15 km/h | 15 km/h | 2.1 | 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 |
| 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 |
| 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 |
| footway | | track | 4 km/h +-1 | 15 km/h | 1.1 | 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 |
| 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 |
| 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 |
| 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 |
@ -84,7 +84,7 @@ Feature: Bicycle - Adds penalties to unsafe roads
| 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 |
| 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 |
| 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 |
@ -92,7 +92,7 @@ Feature: Bicycle - Adds penalties to unsafe roads
| footway | | lane | 4 km/h +-1 | 15 km/h | 1.1 | 4.2 |
| motorway | shared_lane | | 15 km/h | | 4.2 | |
| 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 |

View File

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

View File

@ -37,6 +37,6 @@ Feature: Turn Penalties
| from | to | distance | weight | # |
| a | c | 900m +- 1 | 216 | Going straight has no penalties |
| a | d | 900m +- 1 | 220.2 | Turning right had penalties |
| e | g | 2100m +- 4| 503.9 | Going straght has no penalties |
| e | h | 2100m +- 4| 515.1 | Turn sharp right has even higher penalties|
| e | g | 2100m +- 5| 503.9 | Going straght has no 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
| highway | hov | bothw | forw_rate | backw_rate |
| 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 |
# Models:
@ -196,7 +196,7 @@ Feature: Car - Restricted access
Then routability should be
| highway | hov | hov:lanes | lanes | access | oneway | forw | backw | forw_rate |
| 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
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
#| 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 | yes\|no | yes\|no | | | 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
| from | to | route | modes | speed | time |
| a | g | abc,cde,efg,efg | driving,ferry,driving,driving | 12 km/h | 173.4s |
| b | f | abc,cde,efg,efg | driving,ferry,driving,driving | 9 km/h | 162.4s |
| c | e | cde,cde | ferry,ferry | 5 km/h | 151.4s |
| e | c | cde,cde | ferry,ferry | 5 km/h | 151.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.5s |
| c | e | cde,cde | ferry,ferry | 5 km/h | 151.5s |
| e | c | cde,cde | ferry,ferry | 5 km/h | 151.5s |
Scenario: Car - Properly handle simple durations
Given the node map
@ -117,4 +117,4 @@ Feature: Car - Handle ferry routes
# Note that matching *should* work across unsnappable ferries
When I match I should get
| trace | geometry | duration |
| abcdef| 1,1,1.000899,1,1.000899,1,1.002697,1,1.002697,1,1.003596,1,1.003596,1,1.005394,1,1.005394,1,1.006293,1 | 610.9 |
| 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
| 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 | 60 | | | | 47 km/h | 47 km/h | 13.3 | 13.3 |
| primary | 60 | 3 | | | 47 km/h | 47 km/h | 6.7 | 6.7 |
| primary | | | 60 | | 47 km/h | 64 km/h | 13.3 | 18 |
| primary | | 3 | 60 | | 47 km/h | 64 km/h | 6.7 | 9 |
| primary | | | | 60 | 64 km/h | 47 km/h | 18 | 13.3 |
| primary | | 3 | | 60 | 64 km/h | 47 km/h | 9 | 6.7 |
| primary | 15 | | 60 | | 47 km/h | 11 km/h | 13.3 | 3.3 |
| primary | 60 | | | | 48 km/h | 48 km/h | 13.3 | 13.3 |
| primary | 60 | 3 | | | 48 km/h | 48 km/h | 6.7 | 6.7 |
| primary | | | 60 | | 48 km/h | 64 km/h | 13.3 | 18.1 |
| primary | | 3 | 60 | | 48 km/h | 64 km/h | 6.7 | 9 |
| primary | | | | 60 | 64 km/h | 48 km/h | 18.1 | 13.3 |
| primary | | 3 | | 60 | 64 km/h | 48 km/h | 9 | 6.7 |
| 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 | | | 60 | 12 km/h | 47 km/h | 3.3 | 13.3 |
| primary | 15 | 3 | | 60 | 12 km/h | 47 km/h | 1.7 | 6.7 |
| primary | 15 | | 30 | 60 | 23 km/h | 47 km/h | 6.7 | 13.3 |
| primary | 15 | 3 | 30 | 60 | 23 km/h | 47 km/h | 3.3 | 6.7 |
| primary | 15 | | | 60 | 12 km/h | 48 km/h | 3.3 | 13.3 |
| primary | 15 | 3 | | 60 | 12 km/h | 48 km/h | 1.7 | 6.7 |
| primary | 15 | | 30 | 60 | 24 km/h | 48 km/h | 6.7 | 13.3 |
| 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
Then routability should be
| 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 | 60 | | | | 47 km/h | 47 km/h | 13.3 | 13.3 |
| primary | 60 | 1 | | | 47 km/h | 47 km/h | 6.7 | 6.7 |
| primary | | | 60 | | 47 km/h | 64 km/h | 13.3 | 18 |
| primary | | 1 | 60 | | 47 km/h | 64 km/h | 6.7 | 9 |
| primary | | | | 60 | 64 km/h | 47 km/h | 18 | 13.3 |
| primary | | 1 | | 60 | 64 km/h | 47 km/h | 9 | 6.7 |
| primary | 15 | | 60 | | 47 km/h | 11 km/h | 13.3 | 3.3 |
| primary | 60 | | | | 48 km/h | 48 km/h | 13.3 | 13.3 |
| primary | 60 | 1 | | | 48 km/h | 48 km/h | 6.7 | 6.7 |
| primary | | | 60 | | 48 km/h | 64 km/h | 13.3 | 18.1 |
| primary | | 1 | 60 | | 48 km/h | 64 km/h | 6.7 | 9 |
| primary | | | | 60 | 64 km/h | 48 km/h | 18.1 | 13.3 |
| primary | | 1 | | 60 | 64 km/h | 48 km/h | 9 | 6.7 |
| 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 | | | 60 | 12 km/h | 47 km/h | 3.3 | 13.3 |
| primary | 15 | 1 | | 60 | 12 km/h | 47 km/h | 1.7 | 6.7 |
| primary | 15 | | 30 | 60 | 23 km/h | 47 km/h | 6.7 | 13.3 |
| primary | 15 | 1 | 30 | 60 | 23 km/h | 47 km/h | 3.3 | 6.7 |
| primary | 15 | | | 60 | 12 km/h | 48 km/h | 3.3 | 13.3 |
| primary | 15 | 1 | | 60 | 12 km/h | 48 km/h | 1.7 | 6.7 |
| primary | 15 | | 30 | 60 | 24 km/h | 48 km/h | 6.7 | 13.3 |
| 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
Then routability should be
| highway | maxspeed | lanes | oneway | forw | backw | forw_rate | backw_rate |
| primary | 30 | 1 | yes | 23 km/h | | 6.7 | |
| primary | 30 | 1 | -1 | | 23 km/h | | 6.7 |
| primary | 30 | 1 | | 23 km/h | 23 km/h | 3.3 | 3.3 |
| primary | 30 | 2 | | 23 km/h | 23 km/h | 6.7 | 6.7 |
| primary | 30 | 1 | yes | 24 km/h | | 6.7 | |
| primary | 30 | 1 | -1 | | 24 km/h | | 6.7 |
| primary | 30 | 1 | | 24 km/h | 24 km/h | 3.3 | 3.3 |
| primary | 30 | 2 | | 24 km/h | 24 km/h | 6.7 | 6.7 |
Scenario: Car - Forward/backward maxspeed on reverse oneways
Then routability should be
| highway | maxspeed | maxspeed:forward | maxspeed:backward | oneway | forw | backw | forw_rate | backw_rate |
| primary | | | | -1 | | 64 km/h | | 18 |
| primary | 30 | | | -1 | | 23 km/h | | 6.7 |
| primary | | 30 | | -1 | | 64 km/h | | 18 |
| primary | | | 30 | -1 | | 23 km/h | | 6.7 |
| primary | 20 | 30 | | -1 | | 15 km/h | | 4.4 |
| primary | 20 | | 30 | -1 | | 23 km/h | | 6.7 |
| primary | | | | -1 | | 64 km/h | | 18.1 |
| primary | 30 | | | -1 | | 24 km/h | | 6.7 |
| primary | | 30 | | -1 | | 64 km/h | | 18.1 |
| primary | | | 30 | -1 | | 24 km/h | | 6.7 |
| primary | 20 | 30 | | -1 | | 16 km/h | | 4.4 |
| primary | 20 | | 30 | -1 | | 24 km/h | | 6.7 |
Scenario: Car - Respect source:maxspeed

View File

@ -1008,3 +1008,123 @@ Feature: Car - Turn restrictions
| from | to | route |
| d | x | bd,abc,xa,xa |
| 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
Then routability should be
| highway | oneway | bothw |
| motorway | no | 89 km/h |
| motorway_link | no | 44 km/h |
| trunk | no | 85 km/h |
| trunk_link | no | 39 km/h |
| motorway | no | 90 km/h |
| motorway_link | no | 45 km/h |
| trunk | no | 84 km/h |
| trunk_link | no | 40 km/h |
| primary | no | 64 km/h |
| primary_link | no | 29 km/h |
| secondary | no | 55 km/h |
| secondary_link | no | 24 km/h |
| tertiary | no | 39 km/h |
| primary_link | no | 30 km/h |
| secondary | no | 54 km/h |
| secondary_link | no | 25 km/h |
| tertiary | no | 40 km/h |
| tertiary_link | no | 20 km/h |
| unclassified | no | 24 km/h |
| residential | no | 24 km/h |
| living_street | no | 9 km/h |
| unclassified | no | 25 km/h |
| residential | no | 25 km/h |
| living_street | no | 10 km/h |
| service | no | 15 km/h |
# Alternating oneways scale rates but not speeds
Scenario: Car - scaled speeds for oneway=alternating
Then routability should be
| highway | oneway | junction | forw | backw | # |
| tertiary | | | 39 km/h | 39 km/h | |
| tertiary | alternating | | 39 km/h | 39 km/h | |
| motorway | | | 89 km/h | | implied oneway |
| motorway | alternating | | 89 km/h | | implied oneway |
| tertiary | | | 40 km/h | 40 km/h | |
| tertiary | alternating | | 40 km/h | 40 km/h | |
| motorway | | | 90 km/h | | implied oneway |
| motorway | alternating | | 90 km/h | | implied oneway |
| motorway | reversible | | | | unroutable |
| primary | | 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 |
| primary | | 64 km/h | 64 km/h |
| primary | 60 | 47 km/h | 47 km/h |
| primary | 60 | 47 km/h | 47 km/h |
| primary | 60 | 47 km/h | 47 km/h |
| primary | 60 | 48 km/h | 48 km/h |
| primary | 60 | 48 km/h | 48 km/h |
| primary | 60 | 48 km/h | 48 km/h |
Scenario: Car - Side road penalties
Then routability should be
| 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
| | 2 | c |
| 1 | 59.1 | 35.1 |
| b | 35.1 | 11.1 |
| 1 | 59.1 | 35.2 |
| b | 35 | 11.1 |
When I route I should get
| from | to | route |
@ -121,5 +121,5 @@ Feature: Car - Allowed start/end modes
When I request a travel time matrix I should get
| | 2 | c |
| 1 | 59.1 | 35.1 |
| b | 35.1 | 11.1 |
| 1 | 59.1 | 35.2 |
| b | 35 | 11.1 |

View File

@ -65,7 +65,7 @@ Feature: Car - Surfaces
Then routability should be
| highway | oneway | surface | forw | backw |
| 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:plates | 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
| from | to | route | geometry |
| a | c | abc,abc | _ibE_ibE?gJ?gJ |
| a | c | abc,abc | _ibE_ibE?gJ?eJ |
@traffic
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
| 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 |
| 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 |
| 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 | 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 |
| a,b | 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
| 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
@ -364,8 +364,8 @@ Feature: Turn Lane Guidance
When I route I should get
| 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,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,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:true straight:true straight:true straight:true right:false;left:false straight:true straight:true right:false,left:false right:true, |
@anticipate
Scenario: Anticipate Lanes for through with turn before / after
@ -391,14 +391,14 @@ Feature: Turn Lane Guidance
When I route I should get
| 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,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,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,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 |
| 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,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,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,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 |
| 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: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: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: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: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: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: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: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
Scenario: Anticipate Lanes for turns with through before and after
@ -812,8 +812,8 @@ Feature: Turn Lane Guidance
When I route I should get
| 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,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,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:true none:true none:true;left:false none:false none:false none:true,none:false none:false right:true, |
@anticipate
Scenario: Oak St, Franklin St

View File

@ -687,7 +687,7 @@ Feature: Slipways and Dedicated Turn Lanes
When I route I should get
| 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
Scenario: Traffic Signal on Sliproad

View File

@ -64,7 +64,7 @@ Feature: Merge Segregated Roads
When I route I should get
| 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
@negative
@ -193,7 +193,7 @@ Feature: Merge Segregated Roads
When I route I should get
| 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
# 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
| from | to | route | turns |
| 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 | a | rem,menz | depart,arrive |

View File

@ -161,7 +161,7 @@ Feature: Ramp Guidance
When I route I should get
| waypoints | route | turns |
| 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
Given the node map
@ -180,7 +180,7 @@ Feature: Ramp Guidance
When I route I should get
| waypoints | route | turns |
| 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
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
When I route I should get
| from | to | route | turns | distance |
| e | f | ed,af,af,af | depart,roundabout-exit-1,exit roundabout left,arrive | 80.1m |
| f | e | af,ed,ed,ed | depart,roundabout-exit-1,exit roundabout uturn,arrive | 120.1m |
| k | l | kg,hl,hl,hl | depart,roundabout-exit-1,exit roundabout right,arrive | 80.1m |
| l | k | hl,kg,kg,kg | depart,roundabout-exit-1,exit roundabout uturn,arrive | 120.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 | 120m |
| 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 | 120m |
@4030 @4075
Scenario: Service roundabout with service exits
@ -846,5 +846,5 @@ Feature: Basic Roundabout
When I route I should get
| 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 |

View File

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

View File

@ -59,6 +59,31 @@ Feature: Locating Nearest node on a Way - pick closest way
| 3 | u |
| 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
Given the node locations
| node | lat | lon |
@ -78,3 +103,30 @@ Feature: Locating Nearest node on a Way - pick closest way
| x | a |
| y | b |
| 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
When I run "osrm-extract {osm_file} -p {profile_file}"
Then stdout should contain "source loader"
Then stdout should contain "slope: 0.0899"
Then stdout should contain "slope: -0.0899"
Then stdout should contain "slope: 0.0904"
Then stdout should contain "slope: -0.0904"
And it should exit successfully

View File

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

View File

@ -8,6 +8,7 @@ module.exports = function () {
this.reprocessAndLoadData((e) => {
if (e) return callback(e);
var testRow = (row, ri, cb) => {
var inNode = this.findNodeByName(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) => {
if (err) return cb(err);
var coord;
var headers = new Set(table.raw()[0]);
if (response.statusCode === 200 && response.body.length) {
var json = JSON.parse(response.body);
@ -25,6 +27,10 @@ module.exports = function () {
var got = { in: row.in, out: row.out };
if (headers.has('data_version')) {
got.data_version = json.data_version || '';
}
Object.keys(row).forEach((key) => {
if (key === 'out') {
if (this.FuzzyMatch.matchLocation(coord, outNode)) {

View File

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

View File

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

View File

@ -9,17 +9,27 @@ const classes = require('./data_classes');
const tableDiff = require('../lib/table_diff');
const ensureDecimal = require('../lib/utils').ensureDecimal;
const errorReason = require('../lib/utils').errorReason;
const CheapRuler = require('cheap-ruler');
module.exports = function () {
this.setGridSize = (meters) => {
this.gridSize = parseFloat(meters);
// the constant is calculated (with BigDecimal as: 1.0/(DEG_TO_RAD*EARTH_RADIUS_IN_METERS
// see ApproximateDistance() in ExtractorStructs.h
// 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.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) => {
@ -35,9 +45,10 @@ module.exports = function () {
// add some nodes
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,
this.OSM_UID, this.origin[0]+(offset + this.WAY_SPACING * ri) * this.zoom,
this.origin[1], {name: util.format('%s%d', namePrefix, ri)});
this.OSM_UID, coord[0],
coord[1], {name: util.format('%s%d', namePrefix, ri)});
};
var nodes = ['a','b','c','d','e'].map((l, i) => makeFakeNode(l, i));
@ -98,7 +109,7 @@ module.exports = function () {
};
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) => {

View File

@ -115,4 +115,4 @@ Feature: Annotations
When I route I should get
| 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

@ -109,11 +109,11 @@ Feature: Bearing parameter
When I route I should get
| 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 | 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 | 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 | 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 |

View File

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

View File

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

View File

@ -21,8 +21,27 @@ Feature: Basic Map Matching
| abcd | no |
When I match I should get
| trace | timestamps | matchings |
| ab1d | 0 1 2 3 | ad |
| trace | timestamps | matchings | data_version |
| 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
Given the node map
@ -280,7 +299,7 @@ Feature: Basic Map Matching
When I match I should get
| 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
Given the query options
@ -356,7 +375,7 @@ Feature: Basic Map Matching
When I match I should get
| 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
Given a grid size of 100 meters
@ -652,7 +671,7 @@ Feature: Basic Map Matching
When I match I should get
| 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
Scenario: Regression test - waypoints trimming too much geometry
@ -683,7 +702,7 @@ Feature: Basic Map Matching
| overview | full |
When I match I should get
| 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
@ -713,11 +732,11 @@ Feature: Basic Map Matching
| steps | true |
When I match I should get
| trace | geometry | turns | code |
| abc | 1,0.99973,1.00027,0.99973,1.000539,0.99973 | depart,arrive | Ok |
| abd | 1,0.99973,1.00027,0.99973,1.00027,0.999461 | depart,turn right,arrive | Ok |
| abe | 1,0.99973,1.00027,0.99973,1.00027,1 | depart,turn left,arrive | Ok |
| ahd | 1,0.99973,1.00027,0.99973,1.00027,0.999461 | depart,turn right,arrive | Ok |
| ahe | 1,0.99973,1.00027,0.99973,1.00027,1 | depart,turn left,arrive | Ok |
| abc | 1,0.999729,1.000269,0.999729,1.000539,0.999729 | depart,arrive | Ok |
| abd | 1,0.999729,1.000269,0.999729,1.000269,0.999457 | depart,turn right,arrive | Ok |
| abe | 1,0.999729,1.000269,0.999729,1.000269,1 | depart,turn left,arrive | Ok |
| ahd | 1,0.999729,1.000269,0.999729,1.000269,0.999457 | depart,turn right,arrive | Ok |
| ahe | 1,0.999729,1.000269,0.999729,1.000269,1 | depart,turn left,arrive | Ok |
@match @testbot
Scenario: Regression test - add source phantoms properly (one phantom on one edge)
@ -741,8 +760,8 @@ Feature: Basic Map Matching
| generate_hints | false |
When I match I should get
| 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 |
| 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 |
| 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.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
Scenario: Regression test - add source phantom properly (two phantoms on one edge)
@ -766,8 +785,8 @@ Feature: Basic Map Matching
| generate_hints | false |
When I match I should get
| 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 |
| 4321 | 1.00045,1,1.000405,1,1.000225,1,1.000135,1 | 0.5:2:1 | 0.5:2:1 | 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.000449,1,1.000404,1,1.000225,1,1.000135,1 | 0.4:2:1 | 0.4:2:1 | 3.4 |
@match @testbot
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
When I match I should get
| trace | geometry | a:distance | a:duration | a:weight | duration |
| 2345 | 1.00018,1,1.000315,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
| 4321 | 1.00027,1,1.000135,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.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
| | a | f | l | o |
| a | 0 | 2383.7 | 1566.9 | 1366.8 |
| f | 2383.7 | 0 | 1293.3 | 1617.3 |
| l | 1566.9 | 1293.3 | 0 | 800.5 |
| o | 1366.8 | 1617.3 | 800.5 | 0 |
| a | 0 | 2391.6 | 1570.8 | 1370.9 |
| f | 2391.6 | 0 | 1297.2 | 1620.9 |
| l | 1570.8 | 1297.2 | 0 | 800 |
| o | 1370.9 | 1620.9 | 800 | 0 |
When I request a travel distance matrix I should get
| | 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
| | a |
| a | 0 |
| f | 2383.7 |
| l | 1566.9 |
| o | 1366.8 |
| f | 2391.6 |
| l | 1570.8 |
| o | 1370.9 |
When I request a travel distance matrix I should get
| | a | f | l | o |
| a | 0 | 2383.7 | 1566.9 | 1366.8 |
| f | 2383.7 | 0 | 1293.3 | 1617.3 |
| a | 0 | 2391.6 | 1570.8 | 1370.9 |
| f | 2391.6 | 0 | 1297.2 | 1620.9 |
When I request a travel distance matrix I should get
| | a | o |
| a | 0 | 1366.8 |
| f | 2383.7 | 1617.3 |
| l | 1566.9 | 800.5 |
| o | 1366.8 | 0 |
| a | 0 | 1370.9 |
| f | 2391.6 | 1620.9 |
| l | 1570.8 | 800 |
| o | 1370.9 | 0 |
Scenario: Testbot - Multi level routing: horizontal road
Given the node map

View File

@ -53,7 +53,7 @@ Feature: Routing close to the [0,0] origin
When I route I should get
| from | to | route | distance |
| b | d | abcde,abcde | 200m |
| b | d | abcde,abcde | 198.8m |
| d | b | | |
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
| from | to | route | distance |
| b | d | abcde,abcde | 200m |
| b | d | abcde,abcde | 200.2m |
| d | b | | |

View File

@ -27,7 +27,7 @@ Feature: Distance calculation
When I route I should get
| 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
Given the node locations
@ -55,7 +55,7 @@ Feature: Distance calculation
When I route I should get
| 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
Given the node locations
@ -69,7 +69,7 @@ Feature: Distance calculation
When I route I should get
| 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
Given the node locations
@ -83,4 +83,4 @@ Feature: Distance calculation
When I route I should get
| from | to | route | distance |
| a | b | ab,ab | 8905559m ~0.1% |
| a | b | ab,ab | 8882574.6m ~0.1% |

View File

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

View File

@ -47,11 +47,31 @@ Feature: Snap start/end point to the nearest way
| adb |
When I route I should get
| from | to | route |
| 1 | b | adb,adb |
| 2 | b | adb,adb |
| 6 | b | aub,aub |
| 7 | b | aub,aub |
| from | to | route | data_version |
| 1 | b | adb,adb | |
| 2 | b | adb,adb | |
| 6 | 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
Given the node map

View File

@ -48,13 +48,13 @@ Feature: Traffic - speeds
When I route I should get
| 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 | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | 1:0 |
| b | c | bc,bc | 27 km/h | 741.5,0 | 1 |
| a | d | ad,ad | 27 km/h | 1275.7,0 | 1 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 |
| a | g | ad,df,fb,fb | 30 km/h | 1295.7,487.5,304.7,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 | 1273.9,955.4,0 | 1:0 |
| b | c | bc,bc | 27 km/h | 737.2,0 | 1 |
| a | d | ad,ad | 27 km/h | 1273.9,0 | 1 |
| d | c | dc,dc | 36 km/h | 955.4,0 | 0 |
| g | b | fb,fb | 36 km/h | 164.4,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
@ -74,13 +74,13 @@ Feature: Traffic - speeds
When I route I should get
| 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 | c | ad,dc,dc | 31 km/h | 1275.7,956.8,0 | 1:0 |
| b | c | bc,bc | 27 km/h | 741.5,0 | 1 |
| a | d | ad,ad | 27 km/h | 1275.7,0 | 1 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
| g | b | ab,ab | 1 km/h | 10010.4,0 | 1 |
| a | g | ab,ab | 1 km/h | 10010.3,0 | 1 |
| 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 | 1273.9,955.4,0 | 1:0 |
| b | c | bc,bc | 27 km/h | 737.2,0 | 1 |
| a | d | ad,ad | 27 km/h | 1273.9,0 | 1 |
| d | c | dc,dc | 36 km/h | 955.4,0 | 0 |
| g | b | ab,ab | 1 km/h | 9951.7,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
@ -106,14 +106,14 @@ Feature: Traffic - speeds
When I route I should get
| from | to | route | speed | weights | a:datasources |
| a | b | ab,ab | 1 km/h | 20020.73,0 | 1 |
| a | c | ab,bc,bc | 2 km/h | 20020.73,741.51,0 | 1:1 |
| b | c | bc,bc | 27 km/h | 741.51,0 | 1 |
| a | d | ab,eb,de,de | 2 km/h | 20020.73,378.17,400.41,0 | 1:0:0 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 |
| g | b | ab,ab | 1 km/h | 10010.37,0 | 1 |
| a | g | ab,ab | 1 km/h | 10010.36,0 | 1 |
| g | a | ab,ab | 1 km/h | 10010.36,0 | 1 |
| a | b | ab,ab | 1 km/h | 19903.37,0 | 1 |
| a | c | ab,bc,bc | 2 km/h | 19903.37,737.16,0 | 1:1 |
| b | c | bc,bc | 27 km/h | 737.16,0 | 1 |
| 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 | 955.45,0 | 0 |
| g | b | ab,ab | 1 km/h | 9951.69,0 | 1 |
| a | g | ab,ab | 1 km/h | 9951.68,0 | 1 |
| g | a | ab,ab | 1 km/h | 9951.68,0 | 1 |
Scenario: Speeds that isolate a single node (a)
@ -136,13 +136,13 @@ Feature: Traffic - speeds
When I route I should get
| 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 | c | fb,bc,bc | 30 km/h | 329.4,741.5,0 | 0:1 | 10:7.5 | 6:2:3 |
| b | c | bc,bc | 27 km/h | 741.5,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 |
| d | c | dc,dc | 36 km/h | 956.8,0 | 0 | 10 | 4:3 |
| g | b | fb,fb | 36 km/h | 164.7,0 | 0 | 10 | 6:2 |
| a | g | fb,fb | 36 km/h | 164.7,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 | 328.9,737.2,0 | 0:1 | 10:7.5 | 6: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 | 139.8,486.8,0 | 0:0 | 10:10 | 2:6:4 |
| d | c | dc,dc | 36 km/h | 955.4,0 | 0 | 10 | 4:3 |
| g | b | fb,fb | 36 km/h | 164.4,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

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
| from | to | route | speed | time | weights |
| 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 |
| 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 |
| 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 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
"""
a b
@ -20,8 +20,46 @@ Feature: Basic trip planning
| da |
When I plan a trip I should get
| waypoints | trips |
| a | aa |
| waypoints | trips | code |
| 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)
Given the node map
@ -38,9 +76,9 @@ Feature: Basic trip planning
| da |
When I plan a trip I should get
| waypoints | trips | durations |
| a,b,c,d | abcda | 7.6 |
| d,b,c,a | dbcad | 7.6 |
| waypoints | trips | durations | code |
| a,b,c,d | abcda | 7.6 | Ok |
| d,b,c,a | dbcad | 7.6 | Ok |
Scenario: Testbot - Trip: Roundtrip waypoints (more than 10)
Given the node map
@ -69,36 +107,37 @@ Feature: Basic trip planning
| waypoints | trips |
| a,b,c,d,e,f,g,h,i,j,k,l | alkjihgfedcba |
Scenario: Testbot - Trip: Roundtrip FS waypoints (more 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)
Scenario: Testbot - Trip: FS waypoints (less than 10)
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
"""
a b c d
@ -122,8 +161,67 @@ Feature: Basic trip planning
| la |
When I plan a trip I should get
| waypoints | trips |
| a,b,c,d,e,f,g,h,i,j,k,l | lkjihgfedcbal |
| waypoints | trips | roundtrip | durations |
| 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)
Given the node map
@ -221,7 +319,7 @@ Feature: Basic trip planning
When I plan a trip I should get
| 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)
@ -274,7 +372,7 @@ Feature: Basic trip planning
| 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
"""
a 1 b

View File

@ -29,11 +29,11 @@ Feature: Weight tests
When I route I should get
| 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
| 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
Scenario: Start and target on the same and adjacent edge
@ -53,10 +53,10 @@ Feature: Weight tests
When I route I should get
| 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 |
| t,s | abc,abc | 20m,0m | 2.1,0 | 2.1s,0s | 20.017685 | 2.1 | 2.1 | 9.5 |
| 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 |
| 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 |
| s,t | abc,abc | 20m,0m | 2,0 | 2s,0s | 20.034627 | 2 | 2 | 10 |
| t,s | abc,abc | 20m,0m | 2,0 | 2s,0s | 20.034627 | 2 | 2 | 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 | 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
@ -174,12 +174,12 @@ Feature: Weight tests
When I route I should get
| waypoints | route | distance | weights | times |
| a,f | , | 100m | 99.9,0 | 30s,0s |
| f,a | , | 100m | 199.8,0 | 30s,0s |
| a,h | , | 140m | 139.9,0 | 42s,0s |
| h,a | , | 140m | 279.8,0 | 42s,0s |
| f,h | , | 40m | 40,0 | 12s,0s |
| h,f | , | 40m | 80,0 | 12s,0s |
| a,f | , | 100m | 99.8,0 | 30s,0s |
| f,a | , | 100m | 199.9,0 | 30s,0s |
| a,h | , | 140m | 139.8,0 | 42s,0s |
| h,a | , | 140m | 280.1,0 | 42s,0s |
| f,h | , | 40.1m | 40,0 | 12s,0s |
| h,f | , | 40.1m | 80.2,0 | 12s,0s |
Scenario: Step weights -- segment_function
Given the profile file
@ -281,11 +281,11 @@ Feature: Weight tests
When I route I should get
| waypoints | route | distance | weights | times |
| a,c | , | 40m +-.1 | 5.119,0 | 289.9s,0s |
| a,e | ,, | 60m +-.1 | 5.119,1.11,0 | 289.9s,100s,0s |
| e,a | ,, | 60m +-.1 | 2.21,2.22,0 | 10.1s,200s,0s |
| e,d | ,, | 40m +-.1 | 4.009,1.11,0 | 189.9s,100s,0s |
| d,e | ,, | 40m +-.1 | 2.21,1.11,0 | 10.1s,100s,0s |
| a,c | , | 40m +-.1 | 5.12,0 | 290s,0s |
| a,e | ,, | 60m +-.1 | 5.12,1.11,0 | 290s,100s,0s |
| e,a | ,, | 60m +-.1 | 2.21,2.22,0 | 10s,200s,0s |
| e,d | ,, | 40m +-.1 | 4.01,1.11,0 | 190s,100s,0s |
| d,e | ,, | 40m +-.1 | 2.21,1.11,0 | 10s,100s,0s |
@traffic @speed
Scenario: Step weights -- segment_function with speed and turn updates
@ -341,9 +341,9 @@ Feature: Weight tests
When I route I should get
| waypoints | route | distance | weights | times |
| a,d | , | 59.9m | 20.5,0 | 24s,0s |
| a,e | ,, | 60.1m | 27.2,10,0 | 38.5s,11s,0s |
| d,e | ,, | 39.9m | 10,10,0 | 11s,11s,0s |
| a,d | , | 60m | 20.5,0 | 24s,0s |
| a,e | ,, | 60m | 27.2,10,0 | 38.5s,11s,0s |
| d,e | ,, | 40m | 10,10,0 | 11s,11s,0s |
@traffic @speed
Scenario: Step weights -- segment_function with speed and turn updates with fallback to durations
@ -376,9 +376,9 @@ Feature: Weight tests
When I route I should get
| waypoints | route | distance | weights | times |
| a,d | abcd,abcd | 59.9m | 6.996,0 | 7s,0s |
| a,e | abcd,ce,ce | 60.1m | 6.005,2.002,0 | 6s,2s,0s |
| d,e | abcd,ce,ce | 39.9m | 1.991,2.002,0 | 2s,2s,0s |
| a,d | abcd,abcd | 60m | 7,0 | 7s,0s |
| a,e | abcd,ce,ce | 60m | 5.997,2.001,0 | 6s,2s,0s |
| d,e | abcd,ce,ce | 40m | 2.003,2.001,0 | 2s,2s,0s |
@traffic @speed
Scenario: Updating speeds without affecting weights.
@ -411,4 +411,4 @@ Feature: Weight tests
When I route I should get
| 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
| waypoints | trips | code |
| a,b,c,d | abcda | NoTrips |
| d,b,c,a | dbcad | NoTrips |
| a,b,c,d | | NoTrips |
| d,b,c,a | | NoTrips |

View File

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

View File

@ -89,6 +89,11 @@ class MatchAPI final : public RouteAPI
}
response.values["matchings"] = std::move(routes);
response.values["code"] = "Ok";
auto data_timestamp = facade.GetTimestamp();
if (!data_timestamp.empty())
{
response.values["data_version"] = data_timestamp;
}
}
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
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]);
running.distance_in_meters += distance_delta;
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";
auto data_timestamp = facade.GetTimestamp();
if (!data_timestamp.empty())
{
response.values["data_version"] = data_timestamp;
}
}
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
// if annotations property was set manually after default construction
auto requested_annotations = parameters.annotations_type;
if ((parameters.annotations == true) &&
if (parameters.annotations &&
(parameters.annotations_type == RouteParameters::AnnotationsType::None))
{
requested_annotations = RouteParameters::AnnotationsType::All;
@ -497,10 +497,10 @@ class RouteAPI : public BaseAPI
std::vector<uint32_t> nodes;
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
{
nodes.reserve(leg_geometry.osm_node_ids.size());
for (const auto node_id : leg_geometry.osm_node_ids)
nodes.reserve(leg_geometry.node_ids.size());
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);
@ -515,7 +515,7 @@ class RouteAPI : public BaseAPI
{
const auto name = facade.GetDatasourceName(i);
// Length of 0 indicates the first empty name, so we can stop here
if (name.size() == 0)
if (name.empty())
break;
names.emplace_back(
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
// if annotations property was set manually after default construction
auto requested_annotations = parameters.annotations_type;
if ((parameters.annotations == true) &&
if (parameters.annotations &&
(parameters.annotations_type == RouteParameters::AnnotationsType::None))
{
requested_annotations = RouteParameters::AnnotationsType::All;
@ -825,10 +825,11 @@ class RouteAPI : public BaseAPI
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
{
util::json::Array nodes;
nodes.values.reserve(leg_geometry.osm_node_ids.size());
for (const auto node_id : leg_geometry.osm_node_ids)
nodes.values.reserve(leg_geometry.node_ids.size());
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);
}
@ -842,7 +843,7 @@ class RouteAPI : public BaseAPI
{
const auto name = facade.GetDatasourceName(i);
// Length of 0 indicates the first empty name, so we can stop here
if (name.size() == 0)
if (name.empty())
break;
datasource_names.values.push_back(std::string(facade.GetDatasourceName(i)));
}
@ -888,23 +889,35 @@ class RouteAPI : public BaseAPI
const bool reversed_source = source_traversed_in_reverse[idx];
const bool reversed_target = target_traversed_in_reverse[idx];
auto leg_geometry = guidance::assembleGeometry(BaseAPI::facade,
auto leg = guidance::assembleLeg(facade,
path_data,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_target);
guidance::LegGeometry leg_geometry;
// 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)
{
leg_geometry = guidance::assembleGeometry(BaseAPI::facade,
path_data,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_source,
reversed_target);
auto leg = guidance::assembleLeg(facade,
path_data,
leg_geometry,
phantoms.source_phantom,
phantoms.target_phantom,
reversed_target,
parameters.steps);
util::Log(logDEBUG) << "Assembling steps " << std::endl;
if (parameters.steps)
{
leg.summary = guidance::assembleSummary(
facade, path_data, phantoms.target_phantom, reversed_target);
auto steps = guidance::assembleSteps(BaseAPI::facade,
path_data,
leg_geometry,
@ -924,10 +937,11 @@ class RouteAPI : public BaseAPI
*
* Using post-processing on basis of route-steps for a single leg at a time
* 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
* 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.
* and exit-roundabout-nr where the exit nr is out of sync with the previous
*enter.
*
* | S |
* * *
@ -938,14 +952,11 @@ class RouteAPI : public BaseAPI
* | |
* | |
*
* 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.
* 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
@ -964,6 +975,7 @@ class RouteAPI : public BaseAPI
phantoms.target_phantom);
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps);
}
}
leg_geometries.push_back(std::move(leg_geometry));
legs.push_back(std::move(leg));

View File

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

View File

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

View File

@ -36,24 +36,27 @@ template <> class AlgorithmDataFacade<CH>
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
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
FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const = 0;
virtual EdgeID FindEdgeIndicateIfReverse(const NodeID edge_based_node_from,
const NodeID edge_based_node_to,
bool &result) const = 0;
virtual EdgeID FindSmallestEdge(const NodeID from,
const NodeID to,
virtual EdgeID FindSmallestEdge(const NodeID edge_based_node_from,
const NodeID edge_based_node_to,
const std::function<bool(EdgeData)> filter) const = 0;
};
@ -70,23 +73,24 @@ template <> class AlgorithmDataFacade<MLD>
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;
@ -94,10 +98,12 @@ template <> class AlgorithmDataFacade<MLD>
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
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 engine

View File

@ -73,45 +73,52 @@ class ContiguousInternalMemoryAlgorithmDataFacade<CH> : public datafacade::Algor
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); }
const EdgeData &GetEdgeData(const EdgeID e) const override final
NodeID GetTarget(const EdgeID edge_based_edge_id) 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
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
FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const override final
EdgeID FindEdgeIndicateIfReverse(const NodeID edge_based_node_from,
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,
const NodeID to,
EdgeID FindSmallestEdge(const NodeID edge_based_node_from,
const NodeID edge_based_node_to,
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:
using super = BaseDataFacade;
using IndexBlock = util::RangeTable<16, storage::Ownership::View>::BlockT;
using RTreeLeaf = super::RTreeLeaf;
using SharedRTree = util::StaticRTree<RTreeLeaf, storage::Ownership::View>;
using SharedGeospatialQuery = GeospatialQuery<SharedRTree, BaseDataFacade>;
using RTreeNode = SharedRTree::TreeNode;
extractor::ClassData exclude_mask;
extractor::ProfileProperties *m_profile_properties;
@ -231,76 +236,80 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
}
// 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);
}
NodeReverseRange GetUncompressedReverseGeometry(const EdgeID id) const override final
NodeReverseRange GetUncompressedReverseGeometry(const PackedGeometryID id) const override final
{
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);
}
DurationReverseRange GetUncompressedReverseDurations(const EdgeID id) const override final
DurationReverseRange
GetUncompressedReverseDurations(const PackedGeometryID id) const override final
{
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);
}
WeightReverseRange GetUncompressedReverseWeights(const EdgeID id) const override final
WeightReverseRange GetUncompressedReverseWeights(const PackedGeometryID id) const override final
{
return segment_data.GetReverseWeights(id);
}
// Returns the data source ids that were used to supply the edge
// weights.
DatasourceForwardRange GetUncompressedForwardDatasources(const EdgeID id) const override final
DatasourceForwardRange
GetUncompressedForwardDatasources(const PackedGeometryID id) const override final
{
return segment_data.GetForwardDatasources(id);
}
// Returns the data source ids that were used to supply the edge
// weights.
DatasourceReverseRange GetUncompressedReverseDatasources(const EdgeID id) const override final
DatasourceReverseRange
GetUncompressedReverseDatasources(const PackedGeometryID id) const override final
{
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);
return m_turn_weight_penalties[id];
BOOST_ASSERT(m_turn_weight_penalties.size() > edge_based_edge_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);
return m_turn_duration_penalties[id];
BOOST_ASSERT(m_turn_duration_penalties.size() > edge_based_edge_id);
return m_turn_duration_penalties[edge_based_edge_id];
}
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,
@ -444,29 +453,29 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
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
@ -480,9 +489,9 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
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
@ -537,32 +546,37 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
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);
}
bool HasLaneData(const EdgeID id) const override final { return turn_data.HasLaneData(id); }
util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const override final
bool HasLaneData(const EdgeID edge_based_edge_id) const override final
{
BOOST_ASSERT(HasLaneData(id));
return m_lane_tupel_id_pairs.at(turn_data.GetLaneDataID(id));
return turn_data.HasLaneData(edge_based_edge_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
@ -577,15 +591,15 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
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
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>
@ -691,57 +705,62 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : public Algo
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); }
const EdgeData &GetEdgeData(const EdgeID e) const override final
NodeID GetTarget(const EdgeID edge_based_edge_id) 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
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;
// 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 NodeReverseRange GetUncompressedReverseGeometry(const EdgeID id) const = 0;
virtual NodeForwardRange GetUncompressedForwardGeometry(const PackedGeometryID 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.
// Should always be 1 shorter than GetUncompressedGeometry
virtual WeightForwardRange GetUncompressedForwardWeights(const EdgeID id) const = 0;
virtual WeightReverseRange GetUncompressedReverseWeights(const EdgeID id) const = 0;
virtual WeightForwardRange GetUncompressedForwardWeights(const PackedGeometryID id) const = 0;
virtual WeightReverseRange GetUncompressedReverseWeights(const PackedGeometryID id) const = 0;
// Gets the duration values for each segment in an uncompressed geometry.
// Should always be 1 shorter than GetUncompressedGeometry
virtual DurationForwardRange GetUncompressedForwardDurations(const EdgeID id) const = 0;
virtual DurationReverseRange GetUncompressedReverseDurations(const EdgeID id) const = 0;
virtual DurationForwardRange
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
// weights. Will return an empty array when only the base profile is used.
virtual DatasourceForwardRange GetUncompressedForwardDatasources(const EdgeID id) const = 0;
virtual DatasourceReverseRange GetUncompressedReverseDatasources(const EdgeID id) const = 0;
virtual DatasourceForwardRange
GetUncompressedForwardDatasources(const PackedGeometryID id) const = 0;
virtual DatasourceReverseRange
GetUncompressedReverseDatasources(const PackedGeometryID id) const = 0;
// Gets the name of a datasource
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;
@ -182,12 +187,12 @@ class BaseDataFacade
const Approach approach,
const bool use_all_edges = false) const = 0;
virtual bool HasLaneData(const EdgeID id) const = 0;
virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0;
virtual bool HasLaneData(const EdgeID edge_based_edge_id) const = 0;
virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID edge_based_edge_id) const = 0;
virtual extractor::TurnLaneDescription
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;
@ -209,16 +214,16 @@ class BaseDataFacade
virtual double GetWeightMultiplier() const = 0;
virtual osrm::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const = 0;
virtual osrm::guidance::TurnBearing PostTurnBearing(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 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>
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_distance_offset += util::coordinate_calculation::fccApproximateDistance(
forward_distance_offset += util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(*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];
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)),
point_on_segment);
@ -514,7 +514,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
current != std::prev(forward_geometry.end());
++current)
{
reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance(
reverse_distance_offset += util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(*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];
EdgeDuration reverse_duration =
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,
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1)));
@ -592,8 +592,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
Coordinate wsg84_coordinate =
util::web_mercator::toWGS84(segment.fixed_projected_coordinate);
return util::coordinate_calculation::haversineDistance(input_coordinate, wsg84_coordinate) >
max_distance;
return util::coordinate_calculation::greatCircleDistance(input_coordinate,
wsg84_coordinate) > max_distance;
}
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 = facade.GetUncompressedForwardGeometry(source_geometry_id);
geometry.osm_node_ids.push_back(
facade.GetOSMNodeIDOfNode(source_geometry(source_segment_start_coordinate)));
geometry.node_ids.push_back(source_geometry(source_segment_start_coordinate));
auto cumulative_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);
current_distance =
util::coordinate_calculation::haversineDistance(prev_coordinate, coordinate);
util::coordinate_calculation::greatCircleDistance(prev_coordinate, coordinate);
cumulative_distance += current_distance;
// 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_offsets.push_back(geometry.locations.size());
@ -79,11 +81,10 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
}
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 (osm_node_id != geometry.osm_node_ids.back() ||
path_point.turn_instruction.type != osrm::guidance::TurnType::NoTurn)
if (node_id != geometry.node_ids.back() ||
turn_instruction.type != osrm::guidance::TurnType::NoTurn)
{
geometry.annotations.emplace_back(LegGeometry::Annotation{
current_distance,
@ -99,11 +100,11 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
facade.GetWeightMultiplier(),
path_point.datasource_id});
geometry.locations.push_back(coordinate);
geometry.osm_node_ids.push_back(osm_node_id);
geometry.node_ids.push_back(node_id);
}
}
current_distance =
util::coordinate_calculation::haversineDistance(prev_coordinate, target_node.location);
util::coordinate_calculation::greatCircleDistance(prev_coordinate, target_node.location);
cumulative_distance += current_distance;
// segment leading to the target node
geometry.segment_distances.push_back(cumulative_distance);
@ -158,8 +159,7 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
const auto target_segment_end_coordinate =
target_node.fwd_segment_position + (reversed_target ? 0 : 1);
const auto target_geometry = facade.GetUncompressedForwardGeometry(target_geometry_id);
geometry.osm_node_ids.push_back(
facade.GetOSMNodeIDOfNode(target_geometry(target_segment_end_coordinate)));
geometry.node_ids.push_back(target_geometry(target_segment_end_coordinate));
BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1);
BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size());

View File

@ -75,9 +75,13 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
std::vector<NamedSegment> segments(route_data.size());
std::uint32_t index = 0;
std::transform(
route_data.begin(), route_data.end(), segments.begin(), [&index](const PathData &point) {
return NamedSegment{point.duration_until_turn, index++, point.name_id};
std::transform(route_data.begin(),
route_data.end(),
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 =
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
@ -124,21 +128,59 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
}
} // 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,
const std::vector<PathData> &route_data,
const LegGeometry &leg_geometry,
const PhantomNode &source_node,
const PhantomNode &target_node,
const bool target_traversed_in_reverse,
const bool needs_summary)
const bool target_traversed_in_reverse)
{
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 =
(target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration);
const auto target_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(
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
return sum + data.duration_until_turn;
@ -182,39 +224,10 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
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.,
duration / 10.,
weight / facade.GetWeightMultiplier(),
summary,
"",
{}};
}

View File

@ -19,6 +19,7 @@
#include <boost/optional.hpp>
#include <cstddef>
#include <guidance/turn_bearing.hpp>
#include <vector>
namespace osrm
@ -96,7 +97,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
{},
source_classes};
if (leg_data.size() > 0)
if (!leg_data.empty())
{
// PathData saves the information we need of the segment _before_ 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;
// 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);
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 distance = leg_geometry.segment_distances[segment_index];
// 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,
step_name_id,
@ -140,17 +150,19 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
segment_duration / 10.,
distance,
segment_weight / weight_multiplier,
path_point.travel_mode,
travel_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1,
{intersection},
path_point.is_left_hand_driving});
is_left_hand_driving});
if (leg_data_index + 1 < leg_data.size())
{
step_name_id = leg_data[leg_data_index + 1].name_id;
is_segregated = leg_data[leg_data_index + 1].is_segregated;
step_name_id =
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
{
@ -159,19 +171,32 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
}
// extract bearings
bearings = std::make_pair<std::uint16_t, std::uint16_t>(
path_point.pre_turn_bearing.Get(), path_point.post_turn_bearing.Get());
auto pre_turn_bearing = path_point.turn_edge
? 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);
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.out = bearing_class.findMatchingBearing(bearings.second);
intersection.location = facade.GetCoordinateOfNode(path_point.turn_via_node);
intersection.bearings.clear();
intersection.bearings.reserve(bearing_data.size());
intersection.lanes = path_point.lane_data.first;
intersection.lane_description =
path_point.lane_data.second != INVALID_LANE_DESCRIPTIONID
? facade.GetTurnDescription(path_point.lane_data.second)
intersection.lanes = lane_data.first;
intersection.lane_description = lane_data.second != INVALID_LANE_DESCRIPTIONID
? facade.GetTurnDescription(lane_data.second)
: extractor::TurnLaneDescription();
// Lanes in turn are bound by total number of lanes at the location
@ -183,20 +208,23 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
(!intersection.lane_description.empty() &&
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(),
bearing_data.end(),
std::back_inserter(intersection.bearings));
intersection.entry.clear();
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 =
util::bearing::reverse(std::round(bearings.first));
maneuver = {intersection.location,
bearing_in_driving_direction,
bearings.second,
path_point.turn_instruction,
turn_instruction,
WaypointType::None,
0};
segment_index++;

View File

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

View File

@ -15,6 +15,7 @@
#include "util/integer_range.hpp"
#include "util/typedefs.hpp"
#include <boost/optional.hpp>
#include <vector>
namespace osrm
@ -28,43 +29,22 @@ struct PathData
NodeID from_edge_based_node;
// the internal OSRM id of the OSM node id that is the via node of the turn
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
// including the turn weight, if one exists
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.
EdgeWeight weight_of_turn;
// 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;
// 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.
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
DatasourceID datasource_id;
// bearing (as seen from the intersection) pre-turn
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;
// If segment precedes a turn, ID of the turn itself
boost::optional<EdgeID> turn_edge;
};
struct InternalRouteResult

View File

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

View File

@ -176,11 +176,6 @@ void annotatePath(const FacadeT &facade,
const auto &edge_data = facade.GetEdgeData(*edge);
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 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);
get_segment_geometry(geometry_index);
@ -206,45 +201,29 @@ void annotatePath(const FacadeT &facade,
}
const std::size_t end_index = weight_vector.size();
bool is_left_hand_driving = facade.IsLeftHandDriving(node_id);
BOOST_ASSERT(start_index < end_index);
for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx)
{
unpacked_path.push_back(
PathData{*node_from,
PathData{node_id,
id_vector[segment_idx + 1],
name_index,
is_segregated,
static_cast<EdgeWeight>(weight_vector[segment_idx]),
0,
static_cast<EdgeDuration>(duration_vector[segment_idx]),
0,
guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
travel_mode,
classes,
EMPTY_ENTRY_CLASS,
datasource_vector[segment_idx],
osrm::guidance::TurnBearing(0),
osrm::guidance::TurnBearing(0),
is_left_hand_driving});
boost::none});
}
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_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_of_turn = turn_duration;
unpacked_path.back().weight_until_turn += turn_weight;
unpacked_path.back().weight_of_turn = turn_weight;
unpacked_path.back().pre_turn_bearing = facade.PreTurnBearing(turn_id);
unpacked_path.back().post_turn_bearing = facade.PostTurnBearing(turn_id);
unpacked_path.back().turn_edge = turn_id;
}
std::size_t start_index = 0, end_index = 0;
@ -280,33 +259,22 @@ void annotatePath(const FacadeT &facade,
// t: fwd_segment 3
// -> (U, v), (v, w), (w, x)
// 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;
(start_index < end_index ? ++segment_idx : --segment_idx))
{
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(
PathData{target_node_id,
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]),
0,
static_cast<EdgeDuration>(duration_vector[segment_idx]),
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],
guidance::TurnBearing(0),
guidance::TurnBearing(0),
is_target_left_hand_driving});
boost::none});
}
if (unpacked_path.size() > 0)
if (!unpacked_path.empty())
{
const auto source_weight = start_traversed_in_reverse
? 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);
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)));
}

View File

@ -301,7 +301,7 @@ struct DistanceToNextIntersectionAccumulator
using namespace util::coordinate_calculation;
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;

View File

@ -44,7 +44,7 @@ class RestrictionParser
RestrictionParser(bool use_turn_restrictions,
bool parse_conditionals,
std::vector<std::string> &restrictions);
boost::optional<InputTurnRestriction> TryParse(const osmium::Relation &relation) const;
std::vector<InputTurnRestriction> TryParse(const osmium::Relation &relation) const;
private:
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();
}
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())
{
v8::Local<v8::Value> exclude =

View File

@ -25,6 +25,7 @@ struct IOConfig
}
bool IsValid() const;
std::vector<std::string> GetMissingFiles() const;
boost::filesystem::path GetPath(const std::string &fileName) const
{
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!
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);
// 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 NameID = std::uint32_t;
using AnnotationID = std::uint32_t;
using PackedGeometryID = std::uint32_t;
using EdgeWeight = std::int32_t;
using EdgeDuration = std::int32_t;
using EdgeDistance = float;
using SegmentWeight = std::uint32_t;
using SegmentDuration = std::uint32_t;
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();
@ -95,16 +95,13 @@ static const LaneDescriptionID INVALID_LANE_DESCRIPTIONID =
std::numeric_limits<LaneDescriptionID>::max();
using BearingClassID = std::uint32_t;
static const BearingClassID INVALID_BEARING_CLASSID = std::numeric_limits<BearingClassID>::max();
using DiscreteBearing = 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_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 RestrictionID SPECIAL_RESTRICTIONID = std::numeric_limits<RestrictionID>::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_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 BisectionID = std::uint32_t;
@ -158,11 +148,11 @@ struct SegmentID
*/
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) {}
NodeID id : 31;
PackedGeometryID id : 31;
std::uint32_t forward : 1;
};

26
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "osrm",
"version": "5.26.0-unreleased",
"version": "5.27.0-unreleased",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -3369,6 +3369,16 @@
"integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
"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": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz",
@ -3958,6 +3968,11 @@
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
"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": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
@ -5284,6 +5299,7 @@
"dev": true,
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
@ -5695,6 +5711,7 @@
"dev": true,
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
@ -7220,6 +7237,13 @@
"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": {
"version": "2.0.1",
"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.",
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.1",
"cheap-ruler": "^3.0.2",
"mkdirp": "^0.5.5",
"nan": "^2.14.2",
"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 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));
}
@ -41,7 +42,8 @@ std::pair<short, short> getArriveBearings(const LegGeometry &leg_geometry,
BOOST_ASSERT(leg_geometry.locations.size() >= 2);
const auto turn_coordinate = leg_geometry.locations.back();
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);
}

View File

@ -263,7 +263,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
BOOST_ASSERT(geometry.locations.size() >= steps.size());
// Look for distances under 1m
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;
if (zero_length_step || duplicated_coordinate)
{
@ -279,8 +279,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
geometry.locations.begin() + offset);
geometry.annotations.erase(geometry.annotations.begin(),
geometry.annotations.begin() + offset);
geometry.osm_node_ids.erase(geometry.osm_node_ids.begin(),
geometry.osm_node_ids.begin() + offset);
geometry.node_ids.erase(geometry.node_ids.begin(), geometry.node_ids.begin() + offset);
}
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
geometry.locations.resize(geometry.segment_offsets.back() + 1);
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);
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;
// 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() - 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
geometry.locations.pop_back();
geometry.annotations.pop_back();
geometry.osm_node_ids.pop_back();
geometry.node_ids.pop_back();
geometry.segment_offsets.back()--;
// since the last geometry includes the location of arrival, the arrival instruction
// 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.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(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(leg_geometry.locations.size() >= 2);
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]);
const auto initial_modifier =
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;
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());
const auto final_modifier =
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
// 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.
// Here we reduce the verbosity of our output by reducing end-of-road emissions in cases
// where no intersections have been passed in between.

View File

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

View File

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

View File

@ -36,18 +36,7 @@ bool IsSupportedParameterCombination(const bool fixed_start,
const bool fixed_end,
const bool roundtrip)
{
if (fixed_start && fixed_end && !roundtrip)
{
return true;
}
else if (roundtrip)
{
return true;
}
else
{
return false;
}
return roundtrip || fixed_start || fixed_end;
}
// 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 *************************************
}
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,
const api::TripParameters &parameters,
osrm::engine::api::ResultT &result) const
@ -225,7 +240,7 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
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,
"Distance Table has wrong size");
@ -238,11 +253,19 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
{
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;
duration_trip.reserve(number_of_locations);
// 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);
}
@ -251,20 +274,28 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
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)
{
// 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);
BOOST_ASSERT(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)
{
auto desired_start_index =
else
{ // fixed_end
auto destination_index =
std::find(std::begin(duration_trip), std::end(duration_trip), destination_id);
BOOST_ASSERT(desired_start_index != std::end(duration_trip));
std::rotate(std::begin(duration_trip), desired_start_index, std::end(duration_trip));
BOOST_ASSERT(destination_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

View File

@ -137,7 +137,7 @@ Parameters parametersFromRequest(const PhantomNodes &phantom_node_pair)
{
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);
// 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_coordinate = trace_coordinates[t];
const auto haversine_distance = util::coordinate_calculation::haversineDistance(
const auto haversine_distance = util::coordinate_calculation::greatCircleDistance(
prev_coordinate, current_coordinate);
// assumes minumum of 4 m/s
const EdgeWeight weight_upper_bound =
@ -424,7 +424,7 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
reconstructed_indices,
[&trace_distance, &trace_coordinates](const std::pair<std::size_t, std::size_t> &prev,
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]);
});

View File

@ -434,7 +434,7 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
const auto duration = edge_iterator->duration_data(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);
scripting_environment.ProcessSegment(segment);

View File

@ -146,12 +146,12 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
// do the best of what we can.
coordinates =
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)
{
const auto initial_distance =
util::coordinate_calculation::haversineDistance(turn_coordinate, coordinates[1]);
const auto total_distance = util::coordinate_calculation::haversineDistance(
util::coordinate_calculation::greatCircleDistance(turn_coordinate, coordinates[1]);
const auto total_distance = util::coordinate_calculation::greatCircleDistance(
turn_coordinate, coordinates.back());
if (initial_distance > ASSUMED_LANE_WIDTH && total_distance > initial_distance)
@ -169,7 +169,7 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
}
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
// 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);
BOOST_ASSERT(coordinates.size() >= 2);
segment_distances.resize(coordinates.size());
segment_distances.back() = util::coordinate_calculation::haversineDistance(
segment_distances.back() = util::coordinate_calculation::greatCircleDistance(
*(coordinates.end() - 2), coordinates.back());
const auto vector_head = coordinates.back();
coordinates = TrimCoordinatesToLength(
@ -476,7 +476,7 @@ util::Coordinate CoordinateExtractor::ExtractCoordinateAtLength(
[distance, &accumulated_distance, last_coordinate = coordinates.front()](
const util::Coordinate coordinate) mutable {
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;
if (!result)
{
@ -497,7 +497,7 @@ util::Coordinate CoordinateExtractor::ExtractCoordinateAtLength(
const auto interpolation_factor =
ComputeInterpolationFactor(distance - accumulated_distance,
0,
util::coordinate_calculation::haversineDistance(
util::coordinate_calculation::greatCircleDistance(
*std::prev(coordinate_after), *coordinate_after));
return util::coordinate_calculation::interpolateLinear(
@ -533,7 +533,7 @@ util::Coordinate CoordinateExtractor::GetCoordinateCloseToTurn(const NodeID from
const auto far_enough_away =
[start_coordinate, compressedGeometryToCoordinate](
const CompressedEdgeContainer::OnewayCompressedEdge &compressed_edge) {
return util::coordinate_calculation::haversineDistance(
return util::coordinate_calculation::greatCircleDistance(
compressedGeometryToCoordinate(compressed_edge), start_coordinate) > 1;
};
@ -627,7 +627,7 @@ CoordinateExtractor::GetMaxDeviation(std::vector<util::Coordinate>::const_iterat
.second;
// and calculate the distance between the intermediate coordinate and the coordinate
// 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
@ -671,7 +671,7 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
auto coord_between =
util::coordinate_calculation::projectPointOnSegment(line_start, line_end, point).second;
// 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
@ -899,7 +899,7 @@ CoordinateExtractor::PrepareLengthCache(const std::vector<util::Coordinate> &coo
limit,
&segment_distances,
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);
accumulated_distance += distance;
last_coordinate = current_coordinate;
@ -924,7 +924,7 @@ CoordinateExtractor::TrimCoordinatesToLength(std::vector<util::Coordinate> coord
[&coordinate_index, &distance_to_current_coordinate, &coordinates]() {
const auto new_distance =
distance_to_current_coordinate +
util::coordinate_calculation::haversineDistance(coordinates[coordinate_index - 1],
util::coordinate_calculation::greatCircleDistance(coordinates[coordinate_index - 1],
coordinates[coordinate_index]);
return new_distance;
};
@ -941,7 +941,7 @@ CoordinateExtractor::TrimCoordinatesToLength(std::vector<util::Coordinate> coord
coordinates.erase(coordinates.begin() + length_cache.size(), coordinates.end());
const auto distance_between_last_coordinates =
util::coordinate_calculation::haversineDistance(*(coordinates.end() - 2),
util::coordinate_calculation::greatCircleDistance(*(coordinates.end() - 2),
*(coordinates.end() - 1));
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
// 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)
{
return vector_head;
@ -1054,7 +1054,7 @@ CoordinateExtractor::SampleCoordinates(const std::vector<util::Coordinate> &coor
if (total_length > max_sample_length)
return true;
const auto distance_between = util::coordinate_calculation::haversineDistance(
const auto distance_between = util::coordinate_calculation::greatCircleDistance(
previous_coordinate, current_coordinate);
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)
{
const double next_distance =
distance_to_index + util::coordinate_calculation::haversineDistance(
distance_to_index + util::coordinate_calculation::greatCircleDistance(
coordinates[index], coordinates[next_index]);
if (next_distance >= desired_length)
{

View File

@ -237,7 +237,7 @@ getIntersectionOutgoingGeometries(const util::NodeBasedDynamicGraph &graph,
util::coordinate_calculation::bearing(geometry[0], representative_coordinate);
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});
}

View File

@ -225,7 +225,7 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node,
left_accumulator,
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[node_based_graph.GetTarget(left_accumulator.via_edge_id)]);
@ -274,7 +274,8 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node,
// the width we can bridge at the intersection
const auto assumed_road_width = (num_lanes(lhs) + num_lanes(rhs)) * ASSUMED_LANE_WIDTH;
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 =
util::coordinate_calculation::greatCircleDistance(
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 >
@ -540,7 +541,7 @@ bool MergableRoadDetector::IsTrafficIsland(const NodeID intersection_node,
if (!degree_three_connect_in && !degree_three_connect_out)
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]);
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 =
util::coordinate_calculation::getLength(current_coordinates.begin(),
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
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
* restriction:motorcar as well as whitelisting if its in except:motorcar.
*/
boost::optional<InputTurnRestriction>
std::vector<InputTurnRestriction>
RestrictionParser::TryParse(const osmium::Relation &relation) const
{
// return if turn restrictions should be ignored
if (!use_turn_restrictions)
{
return boost::none;
return {};
}
osmium::tags::KeyFilter filter(false);
@ -85,17 +85,19 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
// if it's not a restriction, continue;
if (std::distance(fi_begin, fi_end) == 0)
{
return boost::none;
return {};
}
// check if the restriction should be ignored
const char *except = relation.get_value_by_key("except");
if (except != nullptr && ShouldIgnoreRestriction(except))
{
return boost::none;
return {};
}
bool is_only_restriction = false;
bool is_multi_from = false;
bool is_multi_to = false;
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"))
{
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
{
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();
auto from = INVALID_OSM_ID;
std::vector<OSMWayID> from_ways;
auto via_node = INVALID_OSM_ID;
std::vector<OSMWayID> via_ways;
auto to = INVALID_OSM_ID;
std::vector<OSMWayID> to_ways;
bool is_node_restriction = true;
for (const auto &member : relation.members())
@ -157,11 +164,11 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
0 == strcmp("via", 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))
{
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))
{
@ -178,6 +185,7 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
}
}
std::vector<util::OpeningHours> condition;
// parse conditional tags
if (parse_conditionals)
{
@ -199,33 +207,55 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
std::vector<util::OpeningHours> hours = util::ParseOpeningHours(p.condition);
// found unrecognized condition, continue
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()) &&
to != INVALID_OSM_ID)
std::vector<InputTurnRestriction> restriction_containers;
if (!from_ways.empty() && (via_node != INVALID_OSM_ID || !via_ways.empty()) && !to_ways.empty())
{
if (from_ways.size() > 1 && !is_multi_from)
{
util::Log(logDEBUG) << "Parsed restriction " << relation.id()
<< " unexpectedly contains " << from_ways.size()
<< " from ways, skipping...";
return {};
}
if (to_ways.size() > 1 && !is_multi_to)
{
util::Log(logDEBUG) << "Parsed restriction " << relation.id()
<< " 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_container.node_or_way = InputNodeRestriction{{from}, {via_node}, {to}};
restriction.node_or_way = InputNodeRestriction{{from}, {via_node}, {to}};
}
else
{
// template struct requires bracket for ID initialisation :(
restriction_container.node_or_way = InputWayRestriction{{from}, via_ways, {to}};
restriction.node_or_way = InputWayRestriction{{from}, via_ways, {to}};
}
return restriction_container;
restriction_containers.push_back(std::move(restriction));
}
else
{
return boost::none;
}
}
return restriction_containers;
}
bool RestrictionParser::ShouldIgnoreRestriction(const std::string &except_tag_string) const
{

View File

@ -909,13 +909,15 @@ void Sol2ScriptingEnvironment::ProcessElements(
case osmium::item_type::relation:
{
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))
{
resulting_maneuver_overrides.push_back(*result_res);
resulting_maneuver_overrides.push_back(std::move(*result_res));
}
}
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
// or actually follow the full road. When 2399 lands, we can exchange here for a
// 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(road.eid)]);

View File

@ -274,7 +274,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
for (const auto &compressed_edge : edge_bucket)
{
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;
}
return length;

View File

@ -56,7 +56,7 @@ std::unordered_set<EdgeID> findSegregatedNodes(const extractor::NodeBasedGraphFa
double length = 0.0;
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;
};

View File

@ -452,7 +452,7 @@ Intersection SliproadHandler::operator()(const NodeID /*nid*/,
// Only check for curvature and ~90 degree when it makes sense to do so.
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]);
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 third = node_coordinates[c];
const auto length = haversineDistance(first, second);
const auto heigth = haversineDistance(second, third);
const auto length = greatCircleDistance(first, second);
const auto heigth = greatCircleDistance(second, third);
const auto area = (length * heigth) / 2.;

View File

@ -51,7 +51,7 @@ bool findPreviousIntersection(const NodeID node_v,
const auto via_edge_length =
util::coordinate_calculation::getLength(coordinates_along_via_edge.begin(),
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
// 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,
Nan::Callback *callback,
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_)}
{
}
@ -184,7 +184,7 @@ inline void async(const Nan::FunctionCallbackInfo<v8::Value> &info,
const constexpr auto argc = 2u;
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
@ -230,8 +230,9 @@ inline void asyncForTiles(const Nan::FunctionCallbackInfo<v8::Value> &info,
ServiceMemFn service,
Nan::Callback *callback,
PluginParameters pluginParams_)
: Base(callback), osrm{std::move(osrm_)}, service{std::move(service)},
params{std::move(params_)}, pluginParams{std::move(pluginParams_)}
: Base(callback, "osrm:asyncForTiles"), osrm{std::move(osrm_)},
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>();
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

View File

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

View File

@ -10,10 +10,11 @@ namespace osrm
{
namespace storage
{
bool IOConfig::IsValid() const
{
namespace fs = boost::filesystem;
bool IOConfig::IsValid() const
{
bool success = true;
for (auto &fileName : required_input_files)
{
@ -26,5 +27,18 @@ bool IOConfig::IsValid() const
}
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 osrm

View File

@ -72,12 +72,10 @@ std::uint64_t squaredEuclideanDistance(const Coordinate lhs, const Coordinate rh
return result;
}
// Uses method described here:
// 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)
double greatCircleDistance(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 lat1 = static_cast<double>(util::toFloating(coordinate_1.lat));
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});
}
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,
const Coordinate segment_target,
const Coordinate query_location,
@ -153,7 +101,7 @@ double perpendicularDistance(const Coordinate segment_source,
web_mercator::fromWGS84(query_location));
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);
return approximate_distance;
}
@ -179,30 +127,24 @@ Coordinate centroid(const Coordinate lhs, const Coordinate rhs)
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 =
static_cast<double>(toFloating(second_coordinate.lon - first_coordinate.lon));
const double lon_delta = detail::degToRad(lon_diff);
const double lat1 = detail::degToRad(static_cast<double>(toFloating(first_coordinate.lat)));
const double lat2 = detail::degToRad(static_cast<double>(toFloating(second_coordinate.lat)));
const double y = std::sin(lon_delta) * std::cos(lat2);
const double x =
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)
const auto lon1 = static_cast<double>(util::toFloating(coordinate_1.lon));
const auto lat1 = static_cast<double>(util::toFloating(coordinate_1.lat));
const auto lon2 = static_cast<double>(util::toFloating(coordinate_2.lon));
const auto lat2 = static_cast<double>(util::toFloating(coordinate_2.lat));
const auto &ruler = cheap_ruler_container.getRuler(coordinate_1.lat, coordinate_2.lat);
auto result = ruler.bearing({lon1, lat1}, {lon2, lat2});
if (result < 0.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
// 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.
BOOST_ASSERT(first_coordinate != second_coordinate || result == 0.);
BOOST_ASSERT(coordinate_1 != coordinate_2 || result == 0.);
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
auto center = circleCenter(C1, C2, C3);
if (center)
return haversineDistance(C1, *center);
return greatCircleDistance(C1, *center);
else
return std::numeric_limits<double>::infinity();
}
@ -372,8 +314,8 @@ double findClosestDistance(const Coordinate coordinate,
const Coordinate segment_begin,
const Coordinate segment_end)
{
return haversineDistance(coordinate,
projectPointOnSegment(segment_begin, segment_end, coordinate).second);
return greatCircleDistance(
coordinate, projectPointOnSegment(segment_begin, segment_end, coordinate).second);
}
// 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)
{
using util::coordinate_calculation::haversineDistance;
using util::coordinate_calculation::greatCircleDistance;
if (polygon.empty())
return 0.;
@ -458,15 +400,15 @@ double computeArea(const std::vector<Coordinate> &polygon)
double area = 0.;
auto first = polygon.begin();
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)
{
BOOST_ASSERT(first->lat >= 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 =
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;

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.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
if (process.env.OSRM_DATA_PATH !== undefined) {

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