Fix distance calculation consistency. (#6315)

Consolidate great circle distance calculations to use cheap ruler library.
This commit is contained in:
Siarhei Fedartsou 2022-08-19 23:31:40 +02:00 committed by GitHub
parent 8f0cd5cf7b
commit aadc088084
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
84 changed files with 780 additions and 683 deletions

View File

@ -472,9 +472,9 @@ jobs:
uses: actions/cache@v2
with:
path: ${{github.workspace}}/test/cache
key: test-${{ matrix.name }}-${{ github.sha }}
key: v2-test-${{ matrix.name }}-${{ github.sha }}
restore-keys: |
test-${{ matrix.name }}-
v2-test-${{ matrix.name }}-
- name: Prepare environment
run: |

View File

@ -4,6 +4,7 @@
- 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)
- Misc:
- 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)

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

@ -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

@ -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

@ -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

@ -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

@ -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,13 @@ 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

@ -280,7 +280,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 +356,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 +652,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 +683,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 +713,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 +741,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 +766,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 +791,5 @@ 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

@ -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

@ -221,7 +221,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)

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

@ -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

@ -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

@ -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

@ -67,7 +67,7 @@ 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
@ -103,7 +103,7 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
}
}
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);

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

@ -428,7 +428,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

@ -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

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)
{
@ -406,7 +406,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)
{
@ -463,7 +463,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 +474,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 &&

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

@ -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

@ -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

@ -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) {

View File

@ -708,6 +708,6 @@ test('route: snapping parameter passed through OK', function(assert) {
var osrm = new OSRM(monaco_path);
osrm.route({snapping: "any", coordinates: [[7.448205209414596,43.754001097311544],[7.447122039202185,43.75306156811368]]}, function(err, route) {
assert.ifError(err);
assert.equal(Math.round(route.routes[0].distance * 10), 1314); // Round it to nearest 0.1m to eliminate floating point comparison error
assert.equal(Math.round(route.routes[0].distance * 10), 1315); // Round it to nearest 0.1m to eliminate floating point comparison error
});
});

View File

@ -1,7 +1,10 @@
#pragma once
#include <mapbox/geometry.hpp>
#include <mapbox/geometry/box.hpp>
#include <mapbox/geometry/multi_line_string.hpp>
#include <mapbox/geometry/polygon.hpp>
#include <cassert>
#include <cmath>
#include <cstdint>
#include <limits>
@ -19,6 +22,14 @@ using point = geometry::point<double>;
using polygon = geometry::polygon<double>;
class CheapRuler {
// Values that define WGS84 ellipsoid model of the Earth
static constexpr double RE = 6378.137; // equatorial radius
static constexpr double FE = 1.0 / 298.257223563; // flattening
static constexpr double E2 = FE * (2 - FE);
static constexpr double RAD = M_PI / 180.0;
public:
enum Unit {
Kilometers,
@ -63,68 +74,61 @@ public:
break;
}
auto cos = std::cos(latitude * M_PI / 180.);
auto cos2 = 2. * cos * cos - 1.;
auto cos3 = 2. * cos * cos2 - cos;
auto cos4 = 2. * cos * cos3 - cos2;
auto cos5 = 2. * cos * cos4 - cos3;
// Curvature formulas from https://en.wikipedia.org/wiki/Earth_radius#Meridional
double mul = RAD * RE * m;
double coslat = std::cos(latitude * RAD);
double w2 = 1 / (1 - E2 * (1 - coslat * coslat));
double w = std::sqrt(w2);
// multipliers for converting longitude and latitude
// degrees into distance (http://1.usa.gov/1Wb1bv7)
kx = m * (111.41513 * cos - 0.09455 * cos3 + 0.00012 * cos5);
ky = m * (111.13209 - 0.56605 * cos2 + 0.0012 * cos4);
// multipliers for converting longitude and latitude degrees into distance
kx = mul * w * coslat; // based on normal radius of curvature
ky = mul * w * w2 * (1 - E2); // based on meridonal radius of curvature
}
static CheapRuler fromTile(uint32_t y, uint32_t z) {
double n = M_PI * (1. - 2. * (y + 0.5) / std::pow(2., z));
double latitude = std::atan(0.5 * (std::exp(n) - std::exp(-n))) * 180. / M_PI;
assert(z < 32);
double n = M_PI * (1. - 2. * (y + 0.5) / double(uint32_t(1) << z));
double latitude = std::atan(std::sinh(n)) / RAD;
return CheapRuler(latitude);
}
double squareDistance(point a, point b) const {
auto dx = longDiff(a.x, b.x) * kx;
auto dy = (a.y - b.y) * ky;
return dx * dx + dy * dy;
}
//
// Given two points of the form [x = longitude, y = latitude], returns the distance.
//
double distance(point a, point b) {
auto dx = (a.x - b.x) * kx;
auto dy = (a.y - b.y) * ky;
return std::sqrt(dx * dx + dy * dy);
double distance(point a, point b) const {
return std::sqrt(squareDistance(a, b));
}
//
// Returns the bearing between two points in angles.
//
double bearing(point a, point b) {
auto dx = (b.x - a.x) * kx;
double bearing(point a, point b) const {
auto dx = longDiff(b.x, a.x) * kx;
auto dy = (b.y - a.y) * ky;
if (!dx && !dy) {
return 0.;
}
auto value = std::atan2(dx, dy) * 180. / M_PI;
if (value > 180.) {
value -= 360.;
}
return value;
return std::atan2(dx, dy) / RAD;
}
//
// Returns a new point given distance and bearing from the starting point.
//
point destination(point origin, double dist, double bearing_) {
auto a = (90. - bearing_) * M_PI / 180.;
point destination(point origin, double dist, double bearing_) const {
auto a = bearing_ * RAD;
return offset(origin, std::cos(a) * dist, std::sin(a) * dist);
return offset(origin, std::sin(a) * dist, std::cos(a) * dist);
}
//
// Returns a new point given easting and northing offsets from the starting point.
//
point offset(point origin, double dx, double dy) {
point offset(point origin, double dx, double dy) const {
return point(origin.x + dx / kx, origin.y + dy / ky);
}
@ -134,8 +138,8 @@ public:
double lineDistance(const line_string& points) {
double total = 0.;
for (unsigned i = 0; i < points.size() - 1; ++i) {
total += distance(points[i], points[i + 1]);
for (size_t i = 1; i < points.size(); ++i) {
total += distance(points[i - 1], points[i]);
}
return total;
@ -145,14 +149,15 @@ public:
// Given a polygon (an array of rings, where each ring is an array of points),
// returns the area.
//
double area(polygon poly) {
double area(polygon poly) const {
double sum = 0.;
for (unsigned i = 0; i < poly.size(); ++i) {
auto& ring = poly[i];
for (unsigned j = 0, len = ring.size(), k = len - 1; j < len; k = j++) {
sum += (ring[j].x - ring[k].x) * (ring[j].y + ring[k].y) * (i ? -1. : 1.);
sum += longDiff(ring[j].x, ring[k].x) *
(ring[j].y + ring[k].y) * (i ? -1. : 1.);
}
}
@ -162,9 +167,13 @@ public:
//
// Returns the point at a specified distance along the line.
//
point along(const line_string& line, double dist) {
point along(const line_string& line, double dist) const {
double sum = 0.;
if (line.empty()) {
return {};
}
if (dist <= 0.) {
return line[0];
}
@ -184,25 +193,52 @@ public:
return line[line.size() - 1];
}
//
// Returns the distance from a point `p` to a line segment `a` to `b`.
//
double pointToSegmentDistance(const point& p, const point& a, const point& b) const {
auto t = 0.0;
auto x = a.x;
auto y = a.y;
auto dx = longDiff(b.x, x) * kx;
auto dy = (b.y - y) * ky;
if (dx != 0.0 || dy != 0.0) {
t = (longDiff(p.x, x) * kx * dx + (p.y - y) * ky * dy) / (dx * dx + dy * dy);
if (t > 1.0) {
x = b.x;
y = b.y;
} else if (t > 0.0) {
x += (dx / kx) * t;
y += (dy / ky) * t;
}
}
return distance(p, { x, y });
}
//
// Returns a tuple of the form <point, index, t> where point is closest point on the line
// from the given point, index is the start index of the segment with the closest point,
// and t is a parameter from 0 to 1 that indicates where the closest point is on that segment.
//
std::tuple<point, unsigned, double> pointOnLine(const line_string& line, point p) {
std::tuple<point, unsigned, double> pointOnLine(const line_string& line, point p) const {
double minDist = std::numeric_limits<double>::infinity();
double minX = 0., minY = 0., minI = 0., minT = 0.;
if (line.empty()) {
return std::make_tuple(point(), 0., 0.);
}
for (unsigned i = 0; i < line.size() - 1; ++i) {
auto t = 0.;
auto x = line[i].x;
auto y = line[i].y;
auto dx = (line[i + 1].x - x) * kx;
auto dx = longDiff(line[i + 1].x, x) * kx;
auto dy = (line[i + 1].y - y) * ky;
if (dx != 0. || dy != 0.) {
t = ((p.x - x) * kx * dx + (p.y - y) * ky * dy) / (dx * dx + dy * dy);
t = (longDiff(p.x, x) * kx * dx +
(p.y - y) * ky * dy) / (dx * dx + dy * dy);
if (t > 1) {
x = line[i + 1].x;
y = line[i + 1].y;
@ -213,10 +249,7 @@ public:
}
}
dx = (p.x - x) * kx;
dy = (p.y - y) * ky;
auto sqDist = dx * dx + dy * dy;
auto sqDist = squareDistance(p, {x, y});
if (sqDist < minDist) {
minDist = sqDist;
@ -235,7 +268,7 @@ public:
// Returns a part of the given line between the start and the stop points (or their closest
// points on the line).
//
line_string lineSlice(point start, point stop, const line_string& line) {
line_string lineSlice(point start, point stop, const line_string& line) const {
auto getPoint = [](auto tuple) { return std::get<0>(tuple); };
auto getIndex = [](auto tuple) { return std::get<1>(tuple); };
auto getT = [](auto tuple) { return std::get<2>(tuple); };
@ -273,13 +306,13 @@ public:
// Returns a part of the given line between the start and the stop points
// indicated by distance along the line.
//
line_string lineSliceAlong(double start, double stop, const line_string& line) {
line_string lineSliceAlong(double start, double stop, const line_string& line) const {
double sum = 0.;
line_string slice;
for (unsigned i = 0; i < line.size() - 1; ++i) {
auto p0 = line[i];
auto p1 = line[i + 1];
for (size_t i = 1; i < line.size(); ++i) {
auto p0 = line[i - 1];
auto p1 = line[i];
auto d = distance(p0, p1);
sum += d;
@ -305,7 +338,7 @@ public:
// Given a point, returns a bounding box object ([w, s, e, n])
// created from the given point buffered by a given distance.
//
box bufferPoint(point p, double buffer) {
box bufferPoint(point p, double buffer) const {
auto v = buffer / ky;
auto h = buffer / kx;
@ -318,7 +351,7 @@ public:
//
// Given a bounding box, returns the box buffered by a given distance.
//
box bufferBBox(box bbox, double buffer) {
box bufferBBox(box bbox, double buffer) const {
auto v = buffer / ky;
auto h = buffer / kx;
@ -331,15 +364,15 @@ public:
//
// Returns true if the given point is inside in the given bounding box, otherwise false.
//
bool insideBBox(point p, box bbox) {
return p.x >= bbox.min.x &&
p.x <= bbox.max.x &&
p.y >= bbox.min.y &&
p.y <= bbox.max.y;
static bool insideBBox(point p, box bbox) {
return p.y >= bbox.min.y &&
p.y <= bbox.max.y &&
longDiff(p.x, bbox.min.x) >= 0 &&
longDiff(p.x, bbox.max.x) <= 0;
}
static point interpolate(point a, point b, double t) {
double dx = b.x - a.x;
double dx = longDiff(b.x, a.x);
double dy = b.y - a.y;
return point(a.x + dx * t, a.y + dy * t);
@ -348,6 +381,9 @@ public:
private:
double ky;
double kx;
static double longDiff(double a, double b) {
return std::remainder(a - b, 360);
}
};
} // namespace cheap_ruler

View File

@ -1,5 +1,6 @@
#include <mapbox/cheap_ruler.hpp>
#include <gtest/gtest.h>
#include <random>
#include "fixtures/lines.hpp"
#include "fixtures/turf.hpp"
@ -60,6 +61,13 @@ TEST_F(CheapRulerTest, destination) {
}
TEST_F(CheapRulerTest, lineDistance) {
{
cr::line_string emptyLine {};
auto expected = 0.0;
auto actual = ruler.lineDistance(emptyLine);
assertErr(expected, actual, 0.0);
}
for (unsigned i = 0; i < lines.size(); ++i) {
auto expected = turf_lineDistance[i];
auto actual = ruler.lineDistance(lines[i]);
@ -88,6 +96,16 @@ TEST_F(CheapRulerTest, area) {
}
TEST_F(CheapRulerTest, along) {
{
cr::point emptyPoint {};
cr::line_string emptyLine {};
auto expected = emptyPoint;
auto actual = ruler.along(emptyLine, 0.0);
assertErr(expected.x, actual.x, 0.0);
assertErr(expected.y, actual.y, 0.0);
}
for (unsigned i = 0; i < lines.size(); ++i) {
auto expected = turf_along[i];
auto actual = ruler.along(lines[i], turf_along_dist[i]);
@ -110,14 +128,23 @@ TEST_F(CheapRulerTest, pointOnLine) {
cr::line_string line = {{ -77.031669, 38.878605 }, { -77.029609, 38.881946 }};
auto result = ruler.pointOnLine(line, { -77.034076, 38.882017 });
ASSERT_EQ(std::get<0>(result), cr::point(-77.03052697027461, 38.880457194811896)); // point
assertErr(std::get<0>(result).x, -77.03052689033436, 1e-6);
assertErr(std::get<0>(result).y, 38.880457324462576, 1e-6);
ASSERT_EQ(std::get<1>(result), 0u); // index
ASSERT_EQ(std::get<2>(result), 0.5543833618360235); // t
assertErr(std::get<2>(result), 0.5544221677861756, 1e-6); // t
ASSERT_EQ(std::get<2>(ruler.pointOnLine(line, { -80., 38. })), 0.) << "t is not less than 0";
ASSERT_EQ(std::get<2>(ruler.pointOnLine(line, { -75., 38. })), 1.) << "t is not bigger than 1";
}
TEST_F(CheapRulerTest, pointToSegmentDistance) {
cr::point p{ -77.034076, 38.882017 };
cr::point p0{ -77.031669, 38.878605 };
cr::point p1{ -77.029609, 38.881946 };
const auto distance = ruler.pointToSegmentDistance(p, p0, p1);
assertErr(0.37461484020420416, distance, 1e-6);
}
TEST_F(CheapRulerTest, lineSlice) {
for (unsigned i = 0; i < lines.size(); ++i) {
auto line = lines[i];
@ -127,11 +154,19 @@ TEST_F(CheapRulerTest, lineSlice) {
auto expected = turf_lineSlice[i];
auto actual = ruler.lineDistance(ruler.lineSlice(start, stop, line));
assertErr(expected, actual, 1e-5);
/// @todo Should update turf_lineSlice and revert maxError back.
assertErr(expected, actual, 1e-4);
}
}
TEST_F(CheapRulerTest, lineSliceAlong) {
{
cr::line_string emptyLine {};
auto expected = ruler.lineDistance(emptyLine);
auto actual = ruler.lineDistance(ruler.lineSliceAlong(0.0, 0.0, emptyLine));
assertErr(expected, actual, 0.0);
}
for (unsigned i = 0; i < lines.size(); ++i) {
if (i == 46) {
// skip due to Turf bug https://github.com/Turfjs/turf/issues/351
@ -143,7 +178,8 @@ TEST_F(CheapRulerTest, lineSliceAlong) {
auto expected = turf_lineSlice[i];
auto actual = ruler.lineDistance(ruler.lineSliceAlong(dist * 0.3, dist * 0.7, line));
assertErr(expected, actual, 1e-5);
/// @todo Should update turf_lineSlice and revert maxError back.
assertErr(expected, actual, 1e-4);
}
}
@ -154,7 +190,7 @@ TEST_F(CheapRulerTest, lineSliceReverse) {
auto stop = ruler.along(line, dist * 0.3);
auto actual = ruler.lineDistance(ruler.lineSlice(start, stop, line));
ASSERT_EQ(actual, 0.018676802802910702);
assertErr(0.018676476689649835, actual, 1e-6);
}
TEST_F(CheapRulerTest, bufferPoint) {
@ -173,7 +209,10 @@ TEST_F(CheapRulerTest, bufferBBox) {
cr::box bbox({ 30, 38 }, { 40, 39 });
cr::box bbox2 = ruler.bufferBBox(bbox, 1);
ASSERT_EQ(bbox2, cr::box({ 29.989319515875376, 37.99098271225711 }, { 40.01068048412462, 39.00901728774289 }));
assertErr(bbox2.min.x, 29.989319515875376, 1e-6);
assertErr(bbox2.min.y, 37.99098271225711, 1e-6);
assertErr(bbox2.max.x, 40.01068048412462, 1e-6);
assertErr(bbox2.max.y, 39.00901728774289, 1e-6);
}
TEST_F(CheapRulerTest, insideBBox) {
@ -193,6 +232,43 @@ TEST_F(CheapRulerTest, fromTile) {
assertErr(ruler1.distance(p1, p2), ruler2.distance(p1, p2), 2e-5);
}
TEST_F(CheapRulerTest, longitudeWrap) {
std::random_device rd;
std::mt19937 gen(rd());
std::bernoulli_distribution d(0.5); // true with prob 0.5
auto r = cr::CheapRuler(50.5);
cr::polygon poly(1);
auto& ring = poly[0];
cr::line_string line;
cr::point origin(0, 50.5); // Greenwich
auto rad = 1000.0;
// construct a regular dodecagon
for (int i = -180; i <= 180; i += 30) {
auto p = r.destination(origin, rad, i);
// shift randomly east/west to the international date line
p.x += d(gen) ? 180 : -180;
ring.push_back(p);
line.push_back(p);
}
auto p = r.lineDistance(line);
auto a = r.area(poly);
// cheap_ruler does planar calculations, so the perimeter and area of a
// planar regular dodecagon with circumradius rad are used in these checks.
// For the record, the results for rad = 1000 km are:
// perimeter area
// planar 6211.657082 3000000
// WGS84 6187.959236 2996317.6328
// error 0.38% 0.12%
assertErr(12 * rad / sqrt(2 + sqrt(3.0)), p, 1e-12);
assertErr(3 * rad * rad, a, 1e-12);
for (int j = 1; j < (int)line.size(); ++j) {
auto azi = r.bearing(line[j-1], line[j]);
// offset expect and actual by 1 to make err criterion absolute
assertErr(1, std::remainder(270 - 15 + 30*j - azi, 360) + 1, 1e-12);
}
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);

View File

@ -90,7 +90,7 @@ void validate_feature_layer(vtzero::layer layer)
std::count_if(layer.value_table().begin(), layer.value_table().end(), [](auto v) {
return v.type() == vtzero::property_value_type::uint_value;
});
BOOST_CHECK_EQUAL(number_of_uint_values, 78);
BOOST_CHECK_EQUAL(number_of_uint_values, 79);
}
void validate_turn_layer(vtzero::layer layer)
@ -133,7 +133,7 @@ void validate_turn_layer(vtzero::layer layer)
return v.type() == vtzero::property_value_type::float_value;
});
BOOST_CHECK_EQUAL(number_of_float_values, 74);
BOOST_CHECK_EQUAL(number_of_float_values, 73);
}
void validate_node_layer(vtzero::layer layer)
@ -322,13 +322,13 @@ void test_tile_turns(const osrm::OSRM &osrm, bool use_string_only_api)
// Verify the expected turn angles
std::sort(actual_turn_angles.begin(), actual_turn_angles.end());
const std::vector<std::int64_t> expected_turn_angles = {
-122, -120, -117, -65, -57, -30, -28, -3, -2, 2, 3, 28, 30, 57, 65, 117, 120, 122};
-122, -120, -117, -65, -58, -30, -28, -2, -2, 2, 2, 28, 30, 58, 65, 117, 120, 122};
CHECK_EQUAL_RANGE(actual_turn_angles, expected_turn_angles);
// Verify the expected bearings
std::sort(actual_turn_bearings.begin(), actual_turn_bearings.end());
const std::vector<std::int64_t> expected_turn_bearings = {
49, 49, 107, 107, 169, 169, 171, 171, 229, 229, 257, 257, 286, 286, 349, 349, 352, 352};
49, 49, 107, 107, 169, 169, 171, 171, 229, 229, 257, 257, 286, 286, 349, 349, 351, 351};
CHECK_EQUAL_RANGE(actual_turn_bearings, expected_turn_bearings);
}

View File

@ -420,7 +420,7 @@ BOOST_AUTO_TEST_CASE(computeArea)
{FloatLongitude{.01}, FloatLatitude{-.01}},
{FloatLongitude{.00}, FloatLatitude{.00}}};
BOOST_CHECK_CLOSE(2 * 1112.263 * 1112.263, computeArea(rhombus), 1e-3);
BOOST_CHECK_CLOSE(2 * 1109.462 * 1109.462, computeArea(rhombus), 1e-3);
// edge cases
auto self_intersection = std::vector<Coordinate>{{FloatLongitude{.00}, FloatLatitude{.00}},