Compare commits
53 Commits
v5.0.0-rc.2
...
v5.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 97c7bcd9c8 | |||
| c511b5a133 | |||
| e7ab764714 | |||
| cbc2283b58 | |||
| 598d5fbb67 | |||
| 823dcbf511 | |||
| 1933c5e8f4 | |||
| 807aa71a7c | |||
| 14d9b67b58 | |||
| 82df0ca766 | |||
| a6c7529a4e | |||
| 202bb6d3e2 | |||
| bc514926bf | |||
| 9fc16b6a83 | |||
| 2125e0175d | |||
| 6b5982d389 | |||
| a4a8aa63d4 | |||
| bedf451952 | |||
| 93b8f1993c | |||
| c693f4806b | |||
| b07275694a | |||
| 82177c101b | |||
| da6dbd2159 | |||
| b3957d87b4 | |||
| 5f9ccadd6c | |||
| 6e04da9f8f | |||
| 58c13d2c07 | |||
| bca8593eef | |||
| 3e2e10a4c3 | |||
| 6979763292 | |||
| 324f1739e4 | |||
| 1489662f57 | |||
| 1c1f407f67 | |||
| 8fb631417b | |||
| ae45ad1ad2 | |||
| 6b89803534 | |||
| f6116db957 | |||
| c824429458 | |||
| 23b2154d98 | |||
| 25c8711aad | |||
| cf30628d4e | |||
| 7675c730b6 | |||
| 2ce74c05e1 | |||
| 88e6558da3 | |||
| f1140ec903 | |||
| a2e114e852 | |||
| 8f6fc0146b | |||
| 6ad1cd3fb5 | |||
| 40443d1e25 | |||
| 4ec323c5cc | |||
| 300d901618 | |||
| fd6daa580a | |||
| c2fc47df34 |
+1
-1
@@ -13,7 +13,7 @@ notifications:
|
|||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
- develop
|
- "5.0"
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|||||||
@@ -1,3 +1,55 @@
|
|||||||
|
# 5.0.1
|
||||||
|
- Fixes:
|
||||||
|
- Issue #2309: Fixes local path looping, same coordinates crash
|
||||||
|
- Issue #2311: Fixes invalid assertion in loop unpacking
|
||||||
|
- Issue #2310: Local paths could falsely end up trying to remove the start step
|
||||||
|
|
||||||
|
# 5.0.0
|
||||||
|
Changes with regard 5.0.0 RC2:
|
||||||
|
- API:
|
||||||
|
- if `geometry=geojson` is passed the resulting geometry can be a LineString or Point
|
||||||
|
depending on how many coordinates are present.
|
||||||
|
- the removal of the summary field was revered. for `steps=flase` the field will always be an empty string.
|
||||||
|
|
||||||
|
Changes with regard to 4.9.1:
|
||||||
|
- API:
|
||||||
|
- BREAKING: Complete rewrite of the HTTP and library API. See detailed documentation in the wiki.
|
||||||
|
- BREAKING: The default coordinate order is now `longitude, latidue`. Exception: Polyline geometry
|
||||||
|
which follow the original Google specification of `latitdue, longitude`.
|
||||||
|
- BREAKING: Polyline geometries now use precision 5, instead of previously 6
|
||||||
|
- BREAKING: Removed GPX support
|
||||||
|
- New service `tile` which serves debug vector tiles of the road network
|
||||||
|
- Completely new engine for guidance generation:
|
||||||
|
- Support for highway ramps
|
||||||
|
- Support for different intersection types (end of street, forks, merges)
|
||||||
|
- Instruction post-processing to merge unimportant instructions
|
||||||
|
- Improved handling of roundabouts
|
||||||
|
|
||||||
|
- Tools:
|
||||||
|
- BREAKING: Renamed osrm-prepare to osrm-contract
|
||||||
|
- BREAKING: Removes profiles from osrm-contract, only needed in osrm-extract.
|
||||||
|
- Abort processing in osrm-extract if there are no snappable edges remaining.
|
||||||
|
- Added .properties file to osrm-extract ouput.
|
||||||
|
- Enables the use of multiple segment-speed-files on the osrm-contract command line
|
||||||
|
|
||||||
|
- Profile changes:
|
||||||
|
- Remove movable bridge mode
|
||||||
|
- Add `maxspeed=none` tag to car profile.
|
||||||
|
- A `side_road` tag support for the OSRM car profile.
|
||||||
|
|
||||||
|
- Fixes:
|
||||||
|
- Issue #2150: Prevents routing over delivery ways and nodes
|
||||||
|
- Issue #1972: Provide uninstall target
|
||||||
|
- Issue #2072: Disable alternatives by default and if core factor < 1.0
|
||||||
|
- Issue #1999: Fix unpacking for self-loop nodes not in core.
|
||||||
|
|
||||||
|
- Infrastructure:
|
||||||
|
- Cucumber test suit is now based on cucumber-js, removes Ruby as dependency
|
||||||
|
- Updated to mapbox/variant v1.1
|
||||||
|
- Updated to libosmium v2.6.1
|
||||||
|
- Remove GeoJSON based debugging output, replaced by debug tiles
|
||||||
|
|
||||||
|
|
||||||
# 5.0.0 RC2
|
# 5.0.0 RC2
|
||||||
- Profiles:
|
- Profiles:
|
||||||
- `properties.allow_uturns_at_via` -> `properties.continue_straight_at_waypoint` (value is inverted!)
|
- `properties.allow_uturns_at_via` -> `properties.continue_straight_at_waypoint` (value is inverted!)
|
||||||
|
|||||||
+8
-5
@@ -116,14 +116,17 @@ IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
|||||||
|
|
||||||
SET PATH=%PROJECT_DIR%\osrm-deps\libs\bin;%PATH%
|
SET PATH=%PROJECT_DIR%\osrm-deps\libs\bin;%PATH%
|
||||||
|
|
||||||
ECHO running engine-tests.exe ...
|
|
||||||
%Configuration%\unit_tests\engine-tests.exe
|
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
|
||||||
ECHO running extractor-tests.exe ...
|
ECHO running extractor-tests.exe ...
|
||||||
%Configuration%\unit_tests\extractor-tests.exe
|
unit_tests\%Configuration%\extractor-tests.exe
|
||||||
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
ECHO running engine-tests.exe ...
|
||||||
|
unit_tests\%Configuration%\engine-tests.exe
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
ECHO running util-tests.exe ...
|
ECHO running util-tests.exe ...
|
||||||
%Configuration%\unit_tests\util-tests.exe
|
unit_tests\%Configuration%\util-tests.exe
|
||||||
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
ECHO running server-tests.exe ...
|
||||||
|
unit_tests\%Configuration%\server-tests.exe
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
|
||||||
IF NOT "%APPVEYOR_REPO_BRANCH%"=="develop" GOTO DONE
|
IF NOT "%APPVEYOR_REPO_BRANCH%"=="develop" GOTO DONE
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Feature: Bike - Squares and other areas
|
|||||||
Background:
|
Background:
|
||||||
Given the profile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
@square @mokob @2154
|
@square
|
||||||
Scenario: Bike - Route along edge of a squares
|
Scenario: Bike - Route along edge of a squares
|
||||||
Given the node map
|
Given the node map
|
||||||
| x | |
|
| x | |
|
||||||
@@ -50,7 +50,7 @@ Feature: Bike - Squares and other areas
|
|||||||
| d | a | xa,xa |
|
| d | a | xa,xa |
|
||||||
| a | d | xa,xa |
|
| a | d | xa,xa |
|
||||||
|
|
||||||
@parking @mokob @2154
|
@parking
|
||||||
Scenario: Bike - parking areas
|
Scenario: Bike - parking areas
|
||||||
Given the node map
|
Given the node map
|
||||||
| e | | | f |
|
| e | | | f |
|
||||||
@@ -78,7 +78,7 @@ Feature: Bike - Squares and other areas
|
|||||||
| a | d | abcda,abcda |
|
| a | d | abcda,abcda |
|
||||||
|
|
||||||
|
|
||||||
@train @platform @mokob @2154
|
@train @platform
|
||||||
Scenario: Bike - railway platforms
|
Scenario: Bike - railway platforms
|
||||||
Given the node map
|
Given the node map
|
||||||
| x | a | b | y |
|
| x | a | b | y |
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
@routing @bicycle @bridge
|
@routing @bicycle @bridge
|
||||||
Feature: Bicycle - Handle movable bridge
|
Feature: Bicycle - Handle cycling
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the profile "bicycle"
|
Given the profile "bicycle"
|
||||||
@@ -18,14 +18,14 @@ Feature: Bicycle - Handle movable bridge
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | modes |
|
| from | to | route | modes |
|
||||||
| a | g | abc,cde,efg,efg | cycling,movable bridge,cycling,cycling |
|
| a | g | abc,cde,efg,efg | cycling,cycling,cycling,cycling |
|
||||||
| b | f | abc,cde,efg,efg | cycling,movable bridge,cycling,cycling |
|
| b | f | abc,cde,efg,efg | cycling,cycling,cycling,cycling |
|
||||||
| e | c | cde,cde | movable bridge,movable bridge |
|
| e | c | cde,cde | cycling,cycling |
|
||||||
| e | b | cde,abc,abc | movable bridge,cycling,cycling |
|
| e | b | cde,abc,abc | cycling,cycling,cycling |
|
||||||
| e | a | cde,abc,abc | movable bridge,cycling,cycling |
|
| e | a | cde,abc,abc | cycling,cycling,cycling |
|
||||||
| c | e | cde,cde | movable bridge,movable bridge |
|
| c | e | cde,cde | cycling,cycling |
|
||||||
| c | f | cde,efg,efg | movable bridge,cycling,cycling |
|
| c | f | cde,efg,efg | cycling,cycling,cycling |
|
||||||
| c | g | cde,efg,efg | movable bridge,cycling,cycling |
|
| c | g | cde,efg,efg | cycling,cycling,cycling |
|
||||||
|
|
||||||
Scenario: Bicycle - Properly handle durations
|
Scenario: Bicycle - Properly handle durations
|
||||||
Given the node map
|
Given the node map
|
||||||
@@ -41,7 +41,7 @@ Feature: Bicycle - Handle movable bridge
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | modes | speed |
|
| from | to | route | modes | speed |
|
||||||
| a | g | abc,cde,efg,efg | cycling,movable bridge,cycling,cycling | 5 km/h |
|
| a | g | abc,cde,efg,efg | cycling,cycling,cycling,cycling | 5 km/h |
|
||||||
| b | f | abc,cde,efg,efg | cycling,movable bridge,cycling,cycling | 4 km/h |
|
| b | f | abc,cde,efg,efg | cycling,cycling,cycling,cycling | 4 km/h |
|
||||||
| c | e | cde,cde | movable bridge,movable bridge | 2 km/h |
|
| c | e | cde,cde | cycling,cycling | 2 km/h |
|
||||||
| e | c | cde,cde | movable bridge,movable bridge | 2 km/h |
|
| e | c | cde,cde | cycling,cycling | 2 km/h |
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ OSRM will use 4/5 of the projected free-flow speed.
|
|||||||
| a | b | ab,ab | 47 km/h +- 1 |
|
| a | b | ab,ab | 47 km/h +- 1 |
|
||||||
| b | c | bc,bc | 47 km/h +- 1 |
|
| b | c | bc,bc | 47 km/h +- 1 |
|
||||||
|
|
||||||
@mokob @2162
|
|
||||||
Scenario: Car - Advisory speed overwrites backwards maxspeed
|
Scenario: Car - Advisory speed overwrites backwards maxspeed
|
||||||
Given the node map
|
Given the node map
|
||||||
| a | b | c |
|
| a | b | c |
|
||||||
@@ -49,7 +48,6 @@ OSRM will use 4/5 of the projected free-flow speed.
|
|||||||
| b | a | ab,ab | 47 km/h +- 1 |
|
| b | a | ab,ab | 47 km/h +- 1 |
|
||||||
| c | b | bc,bc | 47 km/h +- 1 |
|
| c | b | bc,bc | 47 km/h +- 1 |
|
||||||
|
|
||||||
@mokob @2162 @deleteme
|
|
||||||
Scenario: Car - Advisory speed overwrites backwards maxspeed
|
Scenario: Car - Advisory speed overwrites backwards maxspeed
|
||||||
Given the node map
|
Given the node map
|
||||||
| a | b | c | d |
|
| a | b | c | d |
|
||||||
@@ -65,7 +63,6 @@ OSRM will use 4/5 of the projected free-flow speed.
|
|||||||
| c | b | bc,bc | 47 km/h +- 1 |
|
| c | b | bc,bc | 47 km/h +- 1 |
|
||||||
| d | c | cd,cd | 47 km/h +- 1 |
|
| d | c | cd,cd | 47 km/h +- 1 |
|
||||||
|
|
||||||
@mokob @2162
|
|
||||||
Scenario: Car - Directional advisory speeds play nice with eachother
|
Scenario: Car - Directional advisory speeds play nice with eachother
|
||||||
Given the node map
|
Given the node map
|
||||||
| a | b | c |
|
| a | b | c |
|
||||||
|
|||||||
+13
-13
@@ -1,5 +1,5 @@
|
|||||||
@routing @car @bridge
|
@routing @car @bridge
|
||||||
Feature: Car - Handle movable bridge
|
Feature: Car - Handle driving
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the profile "car"
|
Given the profile "car"
|
||||||
@@ -18,14 +18,14 @@ Feature: Car - Handle movable bridge
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | modes |
|
| from | to | route | modes |
|
||||||
| a | g | abc,cde,efg,efg | driving,movable bridge,driving,driving |
|
| a | g | abc,cde,efg,efg | driving,driving,driving,driving |
|
||||||
| b | f | abc,cde,efg,efg | driving,movable bridge,driving,driving |
|
| b | f | abc,cde,efg,efg | driving,driving,driving,driving |
|
||||||
| e | c | cde,cde | movable bridge,movable bridge |
|
| e | c | cde,cde | driving,driving |
|
||||||
| e | b | cde,abc,abc | movable bridge,driving,driving |
|
| e | b | cde,abc,abc | driving,driving,driving |
|
||||||
| e | a | cde,abc,abc | movable bridge,driving,driving |
|
| e | a | cde,abc,abc | driving,driving,driving |
|
||||||
| c | e | cde,cde | movable bridge,movable bridge |
|
| c | e | cde,cde | driving,driving |
|
||||||
| c | f | cde,efg,efg | movable bridge,driving,driving |
|
| c | f | cde,efg,efg | driving,driving,driving |
|
||||||
| c | g | cde,efg,efg | movable bridge,driving,driving |
|
| c | g | cde,efg,efg | driving,driving,driving |
|
||||||
|
|
||||||
Scenario: Car - Properly handle durations
|
Scenario: Car - Properly handle durations
|
||||||
Given the node map
|
Given the node map
|
||||||
@@ -41,7 +41,7 @@ Feature: Car - Handle movable bridge
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | modes | speed |
|
| from | to | route | modes | speed |
|
||||||
| a | g | abc,cde,efg,efg | driving,movable bridge,driving,driving | 7 km/h |
|
| a | g | abc,cde,efg,efg | driving,driving,driving,driving | 7 km/h |
|
||||||
| b | f | abc,cde,efg,efg | driving,movable bridge,driving,driving | 5 km/h |
|
| b | f | abc,cde,efg,efg | driving,driving,driving,driving | 5 km/h |
|
||||||
| c | e | cde,cde | movable bridge,movable bridge | 2 km/h |
|
| c | e | cde,cde | driving,driving | 2 km/h |
|
||||||
| e | c | cde,cde | movable bridge,movable bridge | 2 km/h |
|
| e | c | cde,cde | driving,driving | 2 km/h |
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ Feature: End Of Road Instructions
|
|||||||
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
|
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
|
||||||
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
|
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
|
||||||
|
|
||||||
|
|
||||||
Scenario: End of Road with three streets
|
Scenario: End of Road with three streets
|
||||||
Given the node map
|
Given the node map
|
||||||
| | | c |
|
| | | c |
|
||||||
@@ -104,3 +103,21 @@ Feature: End Of Road Instructions
|
|||||||
| waypoints | route | turns |
|
| waypoints | route | turns |
|
||||||
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
|
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
|
||||||
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
|
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
|
||||||
|
|
||||||
|
Scenario: End of Road with two ramps - prefer ramp over end of road
|
||||||
|
Given the node map
|
||||||
|
| | | c |
|
||||||
|
| a | | b |
|
||||||
|
| | | d |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| ab | primary |
|
||||||
|
| bc | motorway_link |
|
||||||
|
| bd | motorway_link |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,c | ab,bc,bc | depart,ramp left,arrive |
|
||||||
|
| a,d | ab,bd,bd | depart,ramp right,arrive |
|
||||||
|
|
||||||
|
|||||||
@@ -211,3 +211,74 @@ Feature: Fork Instructions
|
|||||||
| a,c | ,, | depart,fork slight left,arrive |
|
| a,c | ,, | depart,fork slight left,arrive |
|
||||||
| a,d | ,, | depart,fork slight right,arrive |
|
| a,d | ,, | depart,fork slight right,arrive |
|
||||||
|
|
||||||
|
Scenario: Non-Fork on complex intersection - left
|
||||||
|
Given the node map
|
||||||
|
| | | | | c |
|
||||||
|
| a | | b | | |
|
||||||
|
| | e | | | d |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | secondary |
|
||||||
|
| bd | tertiary |
|
||||||
|
| eb | tertiary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,c | abc,abc | depart,arrive |
|
||||||
|
| a,d | abc,bd,bd | depart,turn slight right,arrive |
|
||||||
|
|
||||||
|
Scenario: Non-Fork on complex intersection - right
|
||||||
|
Given the node map
|
||||||
|
| | e | | | c |
|
||||||
|
| a | | b | | |
|
||||||
|
| | | | | d |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abd | secondary |
|
||||||
|
| bc | tertiary |
|
||||||
|
| eb | tertiary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,c | abd,bc,bc | depart,turn slight left,arrive |
|
||||||
|
| a,d | abd,abd | depart,arrive |
|
||||||
|
|
||||||
|
@pr2275 @bug
|
||||||
|
Scenario: Tripple fork
|
||||||
|
Given the node map
|
||||||
|
| | | | | | | | | c |
|
||||||
|
| a | | b | | d | | | | |
|
||||||
|
| | | | | | | | | e |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| ab | secondary |
|
||||||
|
| bc | secondary |
|
||||||
|
| bd | secondary |
|
||||||
|
| be | secondary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,c | ab,bc,bc | depart,fork slight left,arrive |
|
||||||
|
| a,d | ab,bd,bd | depart,fork straight,arrive |
|
||||||
|
| a,e | ab,be,be | depart,fork slight right,arrive |
|
||||||
|
|
||||||
|
Scenario: Tripple fork -- middle obvious
|
||||||
|
Given the node map
|
||||||
|
| | | | | c |
|
||||||
|
| a | | b | | d |
|
||||||
|
| | | | | e |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abd | secondary |
|
||||||
|
| bc | secondary |
|
||||||
|
| be | secondary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,c | abd,bc,bc | depart,turn slight left,arrive |
|
||||||
|
| a,d | abd,abd | depart,arrive |
|
||||||
|
| a,e | abd,be,be | depart,turn slight right,arrive |
|
||||||
|
|||||||
@@ -282,3 +282,532 @@ Feature: Simple Turns
|
|||||||
| h,c | first,second,second | depart,turn left,arrive |
|
| h,c | first,second,second | depart,turn left,arrive |
|
||||||
| h,i | first,first,first | depart,continue uturn,arrive |
|
| h,i | first,first,first | depart,continue uturn,arrive |
|
||||||
|
|
||||||
|
Scenario: Three Way Similar Sharp Turns
|
||||||
|
Given the node map
|
||||||
|
| a | | | | b |
|
||||||
|
| c | | | | |
|
||||||
|
| | d | | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| ab | primary |
|
||||||
|
| bc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,c | ab,bc,bc | depart,turn sharp right,arrive |
|
||||||
|
| a,d | ab,bd,bd | depart,turn sharp right,arrive |
|
||||||
|
| d,c | bd,bc,bc | depart,turn sharp left,arrive |
|
||||||
|
| d,a | bd,ab,ab | depart,turn sharp left,arrive |
|
||||||
|
|
||||||
|
Scenario: Left Turn Assignment (1)
|
||||||
|
Given the node map
|
||||||
|
| | | | | d |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | e | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn slight left,arrive |
|
||||||
|
|
||||||
|
Scenario: Left Turn Assignment (2)
|
||||||
|
Given the node map
|
||||||
|
| | | | | d |
|
||||||
|
| | | | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | e | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn left,arrive |
|
||||||
|
|
||||||
|
Scenario: Left Turn Assignment (3)
|
||||||
|
Given the node map
|
||||||
|
| | | | d | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | e | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn left,arrive |
|
||||||
|
|
||||||
|
Scenario: Left Turn Assignment (4)
|
||||||
|
Given the node map
|
||||||
|
| | | d | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | e | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn left,arrive |
|
||||||
|
|
||||||
|
Scenario: Left Turn Assignment (5)
|
||||||
|
Given the node map
|
||||||
|
| | d | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | e | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn left,arrive |
|
||||||
|
|
||||||
|
@bug @pr2275
|
||||||
|
Scenario: Left Turn Assignment (6)
|
||||||
|
Given the node map
|
||||||
|
| d | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | e | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn sharp left,arrive |
|
||||||
|
|
||||||
|
Scenario: Left Turn Assignment (7)
|
||||||
|
Given the node map
|
||||||
|
| d | | | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | e | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn sharp left,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment (1)
|
||||||
|
Given the node map
|
||||||
|
| | | e | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | | | d |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn slight right,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment (2)
|
||||||
|
Given the node map
|
||||||
|
| | | e | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | d |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn right,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment (3)
|
||||||
|
Given the node map
|
||||||
|
| | | e | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | d | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn right,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment (4)
|
||||||
|
Given the node map
|
||||||
|
| | | e | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | d | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn right,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment (5)
|
||||||
|
Given the node map
|
||||||
|
| | | e | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | d | | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn right,arrive |
|
||||||
|
|
||||||
|
@bug @pr2275
|
||||||
|
Scenario: Right Turn Assignment (6)
|
||||||
|
Given the node map
|
||||||
|
| | | e | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | | | |
|
||||||
|
| d | | | | |
|
||||||
|
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn sharp right,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment (7)
|
||||||
|
Given the node map
|
||||||
|
| | | e | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| d | | | | |
|
||||||
|
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn sharp right,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment Two Turns
|
||||||
|
Given the node map
|
||||||
|
| | | f | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | | | |
|
||||||
|
| d | e | | | |
|
||||||
|
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
| bf | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn sharp right,arrive |
|
||||||
|
| a,e | abc,be,be | depart,turn right,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment Two Turns (2)
|
||||||
|
Given the node map
|
||||||
|
| | | f | c | |
|
||||||
|
| a | | b | | |
|
||||||
|
| | | | | e |
|
||||||
|
| | | | d | |
|
||||||
|
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
| bf | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn right,arrive |
|
||||||
|
| a,e | abc,be,be | depart,turn slight right,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment Two Turns (3)
|
||||||
|
Given the node map
|
||||||
|
| | | f | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | | | e |
|
||||||
|
| | | | d | |
|
||||||
|
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
| bf | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn right,arrive |
|
||||||
|
| a,e | abc,be,be | depart,turn slight right,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment Two Turns (4)
|
||||||
|
Given the node map
|
||||||
|
| | | f | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | | | |
|
||||||
|
| | | d | | e |
|
||||||
|
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
| bf | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn right,arrive |
|
||||||
|
| a,e | abc,be,be | depart,turn slight right,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment Three Turns
|
||||||
|
Given the node map
|
||||||
|
| | | g | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | d | | f | |
|
||||||
|
| | | e | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
| bf | primary |
|
||||||
|
| bg | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn sharp right,arrive |
|
||||||
|
| a,e | abc,be,be | depart,turn right,arrive |
|
||||||
|
| a,f | abc,bf,bf | depart,turn slight right,arrive |
|
||||||
|
|
||||||
|
Scenario: Slight Turn involving Oneways
|
||||||
|
Given the node map
|
||||||
|
| | | a | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | b | | e |
|
||||||
|
| d | | | | |
|
||||||
|
| | | c | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | oneway |
|
||||||
|
| abc | primary | yes |
|
||||||
|
| dbe | primary | no |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,c | abc,abc | depart,arrive |
|
||||||
|
| d,e | dbe,dbe | depart,arrive |
|
||||||
|
| e,d | dbe,dbe | depart,arrive |
|
||||||
|
|
||||||
|
@bug @pr2275
|
||||||
|
Scenario: Slight Turn involving Oneways
|
||||||
|
Given the node map
|
||||||
|
| | | | a | |
|
||||||
|
| | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | b | | e |
|
||||||
|
| d | | | | |
|
||||||
|
| | | c | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | oneway |
|
||||||
|
| abc | primary | yes |
|
||||||
|
| dbe | primary | no |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,c | abc,abc | depart,arrive |
|
||||||
|
| d,e | dbe,dbe | depart,arrive |
|
||||||
|
| e,d | dbe,dbe | depart,arrive |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Slight Turn involving Oneways - Name Change
|
||||||
|
Given the node map
|
||||||
|
| | | a | | |
|
||||||
|
| | | | | |
|
||||||
|
| | | b | | e |
|
||||||
|
| d | | | | |
|
||||||
|
| | | c | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | oneway |
|
||||||
|
| abc | primary | yes |
|
||||||
|
| db | primary | no |
|
||||||
|
| be | primary | no |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,c | abc,abc | depart,arrive |
|
||||||
|
| d,e | db,be,be | depart,new name slight right,arrive |
|
||||||
|
| e,d | be,db,db | depart,new name slight left,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment Three Conflicting Turns with invalid - 1
|
||||||
|
Given the node map
|
||||||
|
| | | g | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | | | |
|
||||||
|
| | d | e | f | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | oneway |
|
||||||
|
| abc | primary | no |
|
||||||
|
| db | primary | yes |
|
||||||
|
| eb | primary | no |
|
||||||
|
| fb | primary | no |
|
||||||
|
| bg | primary | no |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,e | abc,eb,eb | depart,turn right,arrive |
|
||||||
|
| a,f | abc,fb,fb | depart,turn slight right,arrive |
|
||||||
|
|
||||||
|
@bug @pr2275
|
||||||
|
Scenario: Right Turn Assignment Three Conflicting Turns with invalid - 2
|
||||||
|
Given the node map
|
||||||
|
| | | g | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | | | |
|
||||||
|
| | d | e | f | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | oneway |
|
||||||
|
| abc | primary | no |
|
||||||
|
| db | primary | no |
|
||||||
|
| eb | primary | yes |
|
||||||
|
| fb | primary | no |
|
||||||
|
| bg | primary | no |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,db,db | depart,turn sharp right,arrive |
|
||||||
|
| a,f | abc,fb,fb | depart,turn right,arrive |
|
||||||
|
|
||||||
|
Scenario: Right Turn Assignment Three Conflicting Turns with invalid - 3
|
||||||
|
Given the node map
|
||||||
|
| | | g | | |
|
||||||
|
| a | | b | | c |
|
||||||
|
| | | | | |
|
||||||
|
| | d | e | f | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | oneway |
|
||||||
|
| abc | primary | no |
|
||||||
|
| db | primary | no |
|
||||||
|
| be | primary | no |
|
||||||
|
| fb | primary | yes |
|
||||||
|
| bg | primary | no |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,db,db | depart,turn sharp right,arrive |
|
||||||
|
| a,e | abc,be,be | depart,turn right,arrive |
|
||||||
|
|
||||||
|
Scenario: Conflicting Turns with well distinguished turn
|
||||||
|
Given the node map
|
||||||
|
| a | | | b | | | c |
|
||||||
|
| | | | | | | |
|
||||||
|
| f | | | | | | d |
|
||||||
|
| | | | | | | e |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
| bf | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn slight right,arrive |
|
||||||
|
| a,e | abc,be,be | depart,turn right,arrive |
|
||||||
|
| a,f | abc,bf,bf | depart,turn sharp right,arrive |
|
||||||
|
|
||||||
|
@bug @pr2275
|
||||||
|
Scenario: Conflicting Turns with well distinguished turn (back)
|
||||||
|
Given the node map
|
||||||
|
| a | | | b | | | c |
|
||||||
|
| | | | | | | |
|
||||||
|
| d | | | | | | f |
|
||||||
|
| | e | | | | | |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| bd | primary |
|
||||||
|
| be | primary |
|
||||||
|
| bf | primary |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns |
|
||||||
|
| a,d | abc,bd,bd | depart,turn sharp right,arrive |
|
||||||
|
| a,e | abc,be,be | depart,turn right,arrive |
|
||||||
|
| a,f | abc,bf,bf | depart,turn slight right,arrive |
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
@routing @continue_straight @via @testbot
|
||||||
|
Feature: U-turns at via points
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given the profile "testbot"
|
||||||
|
|
||||||
|
Scenario: Continue straight at waypoints enabled by default
|
||||||
|
Given the node map
|
||||||
|
| a | b | c | d |
|
||||||
|
| | e | f | g |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
| cd |
|
||||||
|
| be |
|
||||||
|
| dg |
|
||||||
|
| ef |
|
||||||
|
| fg |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route |
|
||||||
|
| a,e,c | ab,be,be,ef,fg,dg,cd,cd |
|
||||||
|
|
||||||
|
Scenario: Query parameter to disallow changing direction at all waypoints
|
||||||
|
Given the node map
|
||||||
|
| a | b | c | d |
|
||||||
|
| | e | f | g |
|
||||||
|
|
||||||
|
And the query options
|
||||||
|
| continue_straight | false |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
| cd |
|
||||||
|
| be |
|
||||||
|
| dg |
|
||||||
|
| ef |
|
||||||
|
| fg |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route |
|
||||||
|
| a,e,c | ab,be,be,be,bc,bc |
|
||||||
|
|
||||||
|
Scenario: Instructions at waypoints at u-turns
|
||||||
|
Given the node map
|
||||||
|
| a | b | c | d |
|
||||||
|
| | e | f | g |
|
||||||
|
|
||||||
|
And the query options
|
||||||
|
| continue_straight | false |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
| cd |
|
||||||
|
| be |
|
||||||
|
| dg |
|
||||||
|
| ef |
|
||||||
|
| fg |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route |
|
||||||
|
| a,e,c | ab,be,be,be,bc,bc |
|
||||||
|
|
||||||
|
Scenario: u-turn mixed with non-uturn vias
|
||||||
|
Given the node map
|
||||||
|
| a | 1 | b | 3 | c | 5 | d |
|
||||||
|
| | | 2 | | | | 4 |
|
||||||
|
| | | e | | f | | g |
|
||||||
|
|
||||||
|
And the query options
|
||||||
|
| continue_straight | false |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | oneway |
|
||||||
|
| ab | no |
|
||||||
|
| bc | no |
|
||||||
|
| cd | no |
|
||||||
|
| be | yes |
|
||||||
|
| dg | no |
|
||||||
|
| ef | no |
|
||||||
|
| fg | no |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route |
|
||||||
|
| 1,2,3,4,5 | ab,be,be,be,ef,fg,dg,cd,bc,bc,bc,cd,dg,dg,dg,cd,cd |
|
||||||
|
|
||||||
@@ -12,7 +12,6 @@ Feature: Testbot - Travel mode
|
|||||||
Background:
|
Background:
|
||||||
Given the profile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
@mokob @2166
|
|
||||||
Scenario: Testbot - Always announce mode change
|
Scenario: Testbot - Always announce mode change
|
||||||
Given the node map
|
Given the node map
|
||||||
| a | b | c | d |
|
| a | b | c | d |
|
||||||
@@ -28,7 +27,6 @@ Feature: Testbot - Travel mode
|
|||||||
| a | d | foo,foo,foo,foo | driving,river downstream,driving,driving |
|
| a | d | foo,foo,foo,foo | driving,river downstream,driving,driving |
|
||||||
| b | d | foo,foo,foo | river downstream,driving,driving |
|
| b | d | foo,foo,foo | river downstream,driving,driving |
|
||||||
|
|
||||||
@mokob @2166
|
|
||||||
Scenario: Testbot - Compressed Modes
|
Scenario: Testbot - Compressed Modes
|
||||||
Given the node map
|
Given the node map
|
||||||
| a | b | c | d | e | f | g |
|
| a | b | c | d | e | f | g |
|
||||||
@@ -44,7 +42,6 @@ Feature: Testbot - Travel mode
|
|||||||
| a | g | road,liquid,solid,solid | driving,river downstream,driving,driving |
|
| a | g | road,liquid,solid,solid | driving,river downstream,driving,driving |
|
||||||
| c | g | liquid,solid,solid | river downstream,driving,driving |
|
| c | g | liquid,solid,solid | river downstream,driving,driving |
|
||||||
|
|
||||||
@mokob @2166
|
|
||||||
Scenario: Testbot - Modes in each direction, different forward/backward speeds
|
Scenario: Testbot - Modes in each direction, different forward/backward speeds
|
||||||
Given the node map
|
Given the node map
|
||||||
| | 0 | 1 | |
|
| | 0 | 1 | |
|
||||||
@@ -79,7 +76,7 @@ Feature: Testbot - Travel mode
|
|||||||
| 0 | 1 | ab,ab | steps down,steps down | 60s +-1 |
|
| 0 | 1 | ab,ab | steps down,steps down | 60s +-1 |
|
||||||
| 1 | 0 | ab,ab | steps up,steps up | 60s +-1 |
|
| 1 | 0 | ab,ab | steps up,steps up | 60s +-1 |
|
||||||
|
|
||||||
@oneway @mokob @2166
|
@oneway
|
||||||
Scenario: Testbot - Modes for oneway, different forward/backward speeds
|
Scenario: Testbot - Modes for oneway, different forward/backward speeds
|
||||||
Given the node map
|
Given the node map
|
||||||
| a | b |
|
| a | b |
|
||||||
@@ -107,7 +104,7 @@ Feature: Testbot - Travel mode
|
|||||||
| a | b | ab,ab | steps down,steps down |
|
| a | b | ab,ab | steps down,steps down |
|
||||||
| b | a | | |
|
| b | a | | |
|
||||||
|
|
||||||
@oneway @mokob @2166
|
@oneway
|
||||||
Scenario: Testbot - Modes for reverse oneway, different forward/backward speeds
|
Scenario: Testbot - Modes for reverse oneway, different forward/backward speeds
|
||||||
Given the node map
|
Given the node map
|
||||||
| a | b |
|
| a | b |
|
||||||
@@ -135,7 +132,7 @@ Feature: Testbot - Travel mode
|
|||||||
| a | b | | |
|
| a | b | | |
|
||||||
| b | a | ab,ab | steps up,steps up |
|
| b | a | ab,ab | steps up,steps up |
|
||||||
|
|
||||||
@via @mokob @2166
|
@via
|
||||||
Scenario: Testbot - Mode should be set at via points
|
Scenario: Testbot - Mode should be set at via points
|
||||||
Given the node map
|
Given the node map
|
||||||
| a | 1 | b |
|
| a | 1 | b |
|
||||||
@@ -149,7 +146,6 @@ Feature: Testbot - Travel mode
|
|||||||
| a,1,b | ab,ab,ab,ab | river downstream,river downstream,river downstream,river downstream |
|
| a,1,b | ab,ab,ab,ab | river downstream,river downstream,river downstream,river downstream |
|
||||||
| b,1,a | ab,ab,ab,ab | river upstream,river upstream,river upstream,river upstream |
|
| b,1,a | ab,ab,ab,ab | river upstream,river upstream,river upstream,river upstream |
|
||||||
|
|
||||||
@mokob @2166
|
|
||||||
Scenario: Testbot - Starting at a tricky node
|
Scenario: Testbot - Starting at a tricky node
|
||||||
Given the node map
|
Given the node map
|
||||||
| | a | | | |
|
| | a | | | |
|
||||||
@@ -164,7 +160,6 @@ Feature: Testbot - Travel mode
|
|||||||
| from | to | route | modes |
|
| from | to | route | modes |
|
||||||
| b | a | ab,ab | river upstream,river upstream |
|
| b | a | ab,ab | river upstream,river upstream |
|
||||||
|
|
||||||
@mokob @2166
|
|
||||||
Scenario: Testbot - Mode changes on straight way without name change
|
Scenario: Testbot - Mode changes on straight way without name change
|
||||||
Given the node map
|
Given the node map
|
||||||
| a | 1 | b | 2 | c |
|
| a | 1 | b | 2 | c |
|
||||||
@@ -204,7 +199,6 @@ Feature: Testbot - Travel mode
|
|||||||
| b | d | bc,cd,cd | route,driving,driving |
|
| b | d | bc,cd,cd | route,driving,driving |
|
||||||
| a | f | ab,bc,cd,de,ef,ef | driving,route,driving,driving,driving,driving |
|
| a | f | ab,bc,cd,de,ef,ef | driving,route,driving,driving,driving,driving |
|
||||||
|
|
||||||
@mokob @2166
|
|
||||||
Scenario: Testbot - Modes, triangle map
|
Scenario: Testbot - Modes, triangle map
|
||||||
Given the node map
|
Given the node map
|
||||||
| | | | | | | d |
|
| | | | | | | d |
|
||||||
@@ -239,7 +233,6 @@ Feature: Testbot - Travel mode
|
|||||||
| a | d | abc,cd,cd | driving,driving,driving |
|
| a | d | abc,cd,cd | driving,driving,driving |
|
||||||
| d | a | de,ce,abc,abc | driving,river upstream,driving,driving |
|
| d | a | de,ce,abc,abc | driving,river upstream,driving,driving |
|
||||||
|
|
||||||
@mokob @2166
|
|
||||||
Scenario: Testbot - River in the middle
|
Scenario: Testbot - River in the middle
|
||||||
Given the node map
|
Given the node map
|
||||||
| a | b | c | | |
|
| a | b | c | | |
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ Feature: Via points
|
|||||||
| a,d,c | abc,bd,bd,bd,abc,abc |
|
| a,d,c | abc,bd,bd,bd,abc,abc |
|
||||||
| c,d,a | abc,bd,bd,bd,abc,abc |
|
| c,d,a | abc,bd,bd,bd,abc,abc |
|
||||||
|
|
||||||
@mokob
|
|
||||||
Scenario: Multiple via points
|
Scenario: Multiple via points
|
||||||
Given the node map
|
Given the node map
|
||||||
| a | | | | e | f | g | |
|
| a | | | | e | f | g | |
|
||||||
|
|||||||
@@ -48,13 +48,25 @@ template <typename ForwardIter> util::json::String makePolyline(ForwardIter begi
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ForwardIter>
|
template <typename ForwardIter>
|
||||||
util::json::Object makeGeoJSONLineString(ForwardIter begin, ForwardIter end)
|
util::json::Object makeGeoJSONGeometry(ForwardIter begin, ForwardIter end)
|
||||||
{
|
{
|
||||||
|
auto num_coordinates = std::distance(begin, end);
|
||||||
|
BOOST_ASSERT(num_coordinates != 0);
|
||||||
util::json::Object geojson;
|
util::json::Object geojson;
|
||||||
geojson.values["type"] = "LineString";
|
if (num_coordinates > 1)
|
||||||
util::json::Array coordinates;
|
{
|
||||||
std::transform(begin, end, std::back_inserter(coordinates.values), &detail::coordinateToLonLat);
|
geojson.values["type"] = "LineString";
|
||||||
geojson.values["coordinates"] = std::move(coordinates);
|
util::json::Array coordinates;
|
||||||
|
std::transform(begin, end, std::back_inserter(coordinates.values), &detail::coordinateToLonLat);
|
||||||
|
geojson.values["coordinates"] = std::move(coordinates);
|
||||||
|
}
|
||||||
|
else if (num_coordinates > 0)
|
||||||
|
{
|
||||||
|
geojson.values["type"] = "Point";
|
||||||
|
util::json::Array coordinates;
|
||||||
|
coordinates.values.push_back(detail::coordinateToLonLat(*begin));
|
||||||
|
geojson.values["coordinates"] = std::move(coordinates);
|
||||||
|
}
|
||||||
return geojson;
|
return geojson;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ class RouteAPI : public BaseAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(parameters.geometries == RouteParameters::GeometriesType::GeoJSON);
|
BOOST_ASSERT(parameters.geometries == RouteParameters::GeometriesType::GeoJSON);
|
||||||
return json::makeGeoJSONLineString(begin, end);
|
return json::makeGeoJSONGeometry(begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
util::json::Object MakeRoute(const std::vector<PhantomNodes> &segment_end_coordinates,
|
util::json::Object MakeRoute(const std::vector<PhantomNodes> &segment_end_coordinates,
|
||||||
@@ -93,8 +93,8 @@ class RouteAPI : public BaseAPI
|
|||||||
|
|
||||||
auto leg_geometry = guidance::assembleGeometry(
|
auto leg_geometry = guidance::assembleGeometry(
|
||||||
BaseAPI::facade, path_data, phantoms.source_phantom, phantoms.target_phantom);
|
BaseAPI::facade, path_data, phantoms.source_phantom, phantoms.target_phantom);
|
||||||
auto leg = guidance::assembleLeg(path_data, leg_geometry, phantoms.source_phantom,
|
auto leg = guidance::assembleLeg(facade, path_data, leg_geometry, phantoms.source_phantom,
|
||||||
phantoms.target_phantom, reversed_target);
|
phantoms.target_phantom, reversed_target, parameters.steps);
|
||||||
|
|
||||||
if (parameters.steps)
|
if (parameters.steps)
|
||||||
{
|
{
|
||||||
@@ -169,7 +169,7 @@ class RouteAPI : public BaseAPI
|
|||||||
leg_geometry.locations.begin() + step.geometry_end));
|
leg_geometry.locations.begin() + step.geometry_end));
|
||||||
}
|
}
|
||||||
BOOST_ASSERT(parameters.geometries == RouteParameters::GeometriesType::GeoJSON);
|
BOOST_ASSERT(parameters.geometries == RouteParameters::GeometriesType::GeoJSON);
|
||||||
return static_cast<util::json::Value>(json::makeGeoJSONLineString(
|
return static_cast<util::json::Value>(json::makeGeoJSONGeometry(
|
||||||
leg_geometry.locations.begin() + step.geometry_begin,
|
leg_geometry.locations.begin() + step.geometry_begin,
|
||||||
leg_geometry.locations.begin() + step.geometry_end));
|
leg_geometry.locations.begin() + step.geometry_end));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef ENGINE_GUIDANCE_ASSEMBLE_LEG_HPP_
|
#ifndef ENGINE_GUIDANCE_ASSEMBLE_LEG_HPP_
|
||||||
#define ENGINE_GUIDANCE_ASSEMBLE_LEG_HPP_
|
#define ENGINE_GUIDANCE_ASSEMBLE_LEG_HPP_
|
||||||
|
|
||||||
|
#include "engine/datafacade/datafacade_base.hpp"
|
||||||
#include "engine/guidance/leg_geometry.hpp"
|
#include "engine/guidance/leg_geometry.hpp"
|
||||||
#include "engine/guidance/route_leg.hpp"
|
#include "engine/guidance/route_leg.hpp"
|
||||||
#include "engine/guidance/route_step.hpp"
|
#include "engine/guidance/route_step.hpp"
|
||||||
@@ -22,12 +23,86 @@ namespace engine
|
|||||||
{
|
{
|
||||||
namespace guidance
|
namespace guidance
|
||||||
{
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
const constexpr std::size_t MAX_USED_SEGMENTS = 2;
|
||||||
|
struct NamedSegment
|
||||||
|
{
|
||||||
|
EdgeWeight duration;
|
||||||
|
std::uint32_t position;
|
||||||
|
std::uint32_t name_id;
|
||||||
|
};
|
||||||
|
|
||||||
inline RouteLeg assembleLeg(const std::vector<PathData> &route_data,
|
template <std::size_t SegmentNumber>
|
||||||
|
std::array<std::uint32_t, SegmentNumber> summarizeRoute(const std::vector<PathData> &route_data)
|
||||||
|
{
|
||||||
|
// merges segments with same name id
|
||||||
|
const auto collapse_segments = [](std::vector<NamedSegment> &segments)
|
||||||
|
{
|
||||||
|
auto out = segments.begin();
|
||||||
|
auto end = segments.end();
|
||||||
|
for (auto in = segments.begin(); in != end; ++in)
|
||||||
|
{
|
||||||
|
if (in->name_id == out->name_id)
|
||||||
|
{
|
||||||
|
out->duration += in->duration;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++out;
|
||||||
|
BOOST_ASSERT(out != end);
|
||||||
|
*out = *in;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<NamedSegment> segments(route_data.size());
|
||||||
|
std::uint32_t index = 0;
|
||||||
|
std::transform(
|
||||||
|
route_data.begin(), route_data.end(), segments.begin(), [&index](const PathData &point)
|
||||||
|
{
|
||||||
|
return NamedSegment{point.duration_until_turn, index++, point.name_id};
|
||||||
|
});
|
||||||
|
// this makes sure that the segment with the lowest position comes first
|
||||||
|
std::sort(segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs)
|
||||||
|
{
|
||||||
|
return lhs.name_id < rhs.name_id ||
|
||||||
|
(lhs.name_id == rhs.name_id && lhs.position < rhs.position);
|
||||||
|
});
|
||||||
|
auto new_end = collapse_segments(segments);
|
||||||
|
segments.resize(new_end - segments.begin());
|
||||||
|
// sort descending
|
||||||
|
std::sort(segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs)
|
||||||
|
{
|
||||||
|
return lhs.duration > rhs.duration;
|
||||||
|
});
|
||||||
|
|
||||||
|
// make sure the segments are sorted by position
|
||||||
|
segments.resize(std::min(segments.size(), SegmentNumber));
|
||||||
|
std::sort(segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs)
|
||||||
|
{
|
||||||
|
return lhs.position < rhs.position;
|
||||||
|
});
|
||||||
|
|
||||||
|
std::array<std::uint32_t, SegmentNumber> summary;
|
||||||
|
std::fill(summary.begin(), summary.end(), 0);
|
||||||
|
std::transform(segments.begin(), segments.end(), summary.begin(),
|
||||||
|
[](const NamedSegment &segment)
|
||||||
|
{
|
||||||
|
return segment.name_id;
|
||||||
|
});
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
||||||
|
const std::vector<PathData> &route_data,
|
||||||
const LegGeometry &leg_geometry,
|
const LegGeometry &leg_geometry,
|
||||||
const PhantomNode &source_node,
|
const PhantomNode &source_node,
|
||||||
const PhantomNode &target_node,
|
const PhantomNode &target_node,
|
||||||
const bool target_traversed_in_reverse)
|
const bool target_traversed_in_reverse,
|
||||||
|
const bool needs_summary)
|
||||||
{
|
{
|
||||||
const auto target_duration =
|
const auto target_duration =
|
||||||
(target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight) /
|
(target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight) /
|
||||||
@@ -70,7 +145,26 @@ inline RouteLeg assembleLeg(const std::vector<PathData> &route_data,
|
|||||||
10.0;
|
10.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RouteLeg{duration, distance, {}};
|
std::string summary;
|
||||||
|
if (needs_summary)
|
||||||
|
{
|
||||||
|
auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>(route_data);
|
||||||
|
|
||||||
|
BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0);
|
||||||
|
BOOST_ASSERT(summary_array.begin() != summary_array.end());
|
||||||
|
summary = std::accumulate(std::next(summary_array.begin()), summary_array.end(),
|
||||||
|
facade.GetNameForID(summary_array.front()),
|
||||||
|
[&facade](std::string previous, const std::uint32_t name_id)
|
||||||
|
{
|
||||||
|
if (name_id != 0)
|
||||||
|
{
|
||||||
|
previous += ", " + facade.GetNameForID(name_id);
|
||||||
|
}
|
||||||
|
return previous;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return RouteLeg{duration, distance, summary, {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace guidance
|
} // namespace guidance
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include "engine/guidance/route_step.hpp"
|
#include "engine/guidance/route_step.hpp"
|
||||||
|
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
@@ -16,6 +19,7 @@ struct RouteLeg
|
|||||||
{
|
{
|
||||||
double duration;
|
double duration;
|
||||||
double distance;
|
double distance;
|
||||||
|
std::string summary;
|
||||||
std::vector<RouteStep> steps;
|
std::vector<RouteStep> steps;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -373,8 +373,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
|||||||
// t: fwd_segment 3
|
// t: fwd_segment 3
|
||||||
// -> (U, v), (v, w), (w, x)
|
// -> (U, v), (v, w), (w, x)
|
||||||
// note that (x, t) is _not_ included but needs to be added later.
|
// note that (x, t) is _not_ included but needs to be added later.
|
||||||
BOOST_ASSERT(start_index <= end_index);
|
for (std::size_t i = start_index; i != end_index; (start_index < end_index ? ++i : --i))
|
||||||
for (std::size_t i = start_index; i != end_index; ++i)
|
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(i < id_vector.size());
|
BOOST_ASSERT(i < id_vector.size());
|
||||||
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0);
|
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0);
|
||||||
@@ -559,9 +558,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
|||||||
// make sure to correctly unpack loops
|
// make sure to correctly unpack loops
|
||||||
if (distance != forward_heap.GetKey(middle) + reverse_heap.GetKey(middle))
|
if (distance != forward_heap.GetKey(middle) + reverse_heap.GetKey(middle))
|
||||||
{
|
{
|
||||||
// self loop
|
// self loop makes up the full path
|
||||||
BOOST_ASSERT(forward_heap.GetData(middle).parent == middle &&
|
|
||||||
reverse_heap.GetData(middle).parent == middle);
|
|
||||||
packed_leg.push_back(middle);
|
packed_leg.push_back(middle);
|
||||||
packed_leg.push_back(middle);
|
packed_leg.push_back(middle);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ const constexpr osrm::extractor::TravelMode TRAVEL_MODE_WALKING = 3;
|
|||||||
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_FERRY = 4;
|
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_FERRY = 4;
|
||||||
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_TRAIN = 5;
|
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_TRAIN = 5;
|
||||||
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_PUSHING_BIKE = 6;
|
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_PUSHING_BIKE = 6;
|
||||||
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_MOVABLE_BRIDGE = 7;
|
|
||||||
// FIXME only for testbot.lua
|
// FIXME only for testbot.lua
|
||||||
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_STEPS_UP = 8;
|
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_STEPS_UP = 8;
|
||||||
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_STEPS_DOWN = 9;
|
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_STEPS_DOWN = 9;
|
||||||
|
|||||||
@@ -32,15 +32,11 @@ struct TableParametersGrammar final : public BaseParametersGrammar
|
|||||||
};
|
};
|
||||||
// TODO: ulonglong -> size_t not only on Windows but on all 32 bit platforms; unsupported anyway as of now
|
// TODO: ulonglong -> size_t not only on Windows but on all 32 bit platforms; unsupported anyway as of now
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
destinations_rule = (qi::lit("destinations=") > (qi::ulong_long % ";")[set_destiantions]) |
|
destinations_rule = qi::lit("destinations=all") | (qi::lit("destinations=") > (qi::ulong_long % ";")[set_destiantions]);
|
||||||
qi::lit("destinations=all");
|
sources_rule = qi::lit("sources=all") | (qi::lit("sources=") > (qi::ulong_long % ";")[set_sources]);
|
||||||
sources_rule =
|
|
||||||
(qi::lit("sources=") > (qi::ulong_long % ";")[set_sources]) | qi::lit("sources=all");
|
|
||||||
#else
|
#else
|
||||||
destinations_rule = (qi::lit("destinations=") > (qi::ulong_ % ";")[set_destiantions]) |
|
destinations_rule = qi::lit("destinations=all") | (qi::lit("destinations=") > (qi::ulong_ % ";")[set_destiantions]);
|
||||||
qi::lit("destinations=all");
|
sources_rule = qi::lit("sources=all") | (qi::lit("sources=") > (qi::ulong_ % ";")[set_sources]);
|
||||||
sources_rule =
|
|
||||||
(qi::lit("sources=") > (qi::ulong_ % ";")[set_sources]) | qi::lit("sources=all");
|
|
||||||
#endif
|
#endif
|
||||||
table_rule = destinations_rule | sources_rule;
|
table_rule = destinations_rule | sources_rule;
|
||||||
|
|
||||||
|
|||||||
@@ -441,6 +441,14 @@ class StaticRTree
|
|||||||
// inspecting an actual road segment
|
// inspecting an actual road segment
|
||||||
auto ¤t_candidate = current_query_node.node.template get<CandidateSegment>();
|
auto ¤t_candidate = current_query_node.node.template get<CandidateSegment>();
|
||||||
|
|
||||||
|
// to allow returns of no-results if too restrictive filtering, this needs to be done here
|
||||||
|
// even though performance would indicate that we want to stop after adding the first candidate
|
||||||
|
if (terminate(results.size(), current_candidate))
|
||||||
|
{
|
||||||
|
traversal_queue = std::priority_queue<QueryCandidate>{};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
auto use_segment = filter(current_candidate);
|
auto use_segment = filter(current_candidate);
|
||||||
if (!use_segment.first && !use_segment.second)
|
if (!use_segment.first && !use_segment.second)
|
||||||
{
|
{
|
||||||
@@ -451,12 +459,6 @@ class StaticRTree
|
|||||||
|
|
||||||
// store phantom node in result vector
|
// store phantom node in result vector
|
||||||
results.push_back(std::move(current_candidate.data));
|
results.push_back(std::move(current_candidate.data));
|
||||||
|
|
||||||
if (terminate(results.size(), current_candidate))
|
|
||||||
{
|
|
||||||
traversal_queue = std::priority_queue<QueryCandidate>{};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef OSRM_UTIL_VECTOR_TILE_HPP
|
||||||
|
#define OSRM_UTIL_VECTOR_TILE_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace osrm
|
||||||
|
{
|
||||||
|
namespace util
|
||||||
|
{
|
||||||
|
namespace vector_tile
|
||||||
|
{
|
||||||
|
|
||||||
|
const constexpr std::uint32_t LAYER_TAG = 3;
|
||||||
|
const constexpr std::uint32_t NAME_TAG = 1;
|
||||||
|
const constexpr std::uint32_t VERSION_TAG = 15;
|
||||||
|
const constexpr std::uint32_t EXTEND_TAG = 5;
|
||||||
|
const constexpr std::uint32_t FEATURE_TAG = 2;
|
||||||
|
const constexpr std::uint32_t GEOMETRY_TAG = 3;
|
||||||
|
const constexpr std::uint32_t VARIANT_TAG = 4;
|
||||||
|
const constexpr std::uint32_t KEY_TAG = 3;
|
||||||
|
const constexpr std::uint32_t ID_TAG = 1;
|
||||||
|
const constexpr std::uint32_t GEOMETRY_TYPE_LINE = 2;
|
||||||
|
const constexpr std::uint32_t FEATURE_ATTRIBUTES_TAG = 2;
|
||||||
|
const constexpr std::uint32_t FEATURE_GEOMETRIES_TAG = 4;
|
||||||
|
const constexpr std::uint32_t VARIANT_TYPE_UINT32 = 5;
|
||||||
|
const constexpr std::uint32_t VARIANT_TYPE_BOOL = 7;
|
||||||
|
const constexpr std::uint32_t VARIANT_TYPE_STRING = 1;
|
||||||
|
const constexpr std::uint32_t VARIANT_TYPE_DOUBLE = 3;
|
||||||
|
|
||||||
|
// Vector tiles are 4096 virtual pixels on each side
|
||||||
|
const constexpr double EXTENT = 4096.0;
|
||||||
|
const constexpr double BUFFER = 128.0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -234,8 +234,6 @@ function way_function (way, result)
|
|||||||
if duration and durationIsValid(duration) then
|
if duration and durationIsValid(duration) then
|
||||||
result.duration = math.max( parseDuration(duration), 1 )
|
result.duration = math.max( parseDuration(duration), 1 )
|
||||||
end
|
end
|
||||||
result.forward_mode = mode.movable_bridge
|
|
||||||
result.backward_mode = mode.movable_bridge
|
|
||||||
result.forward_speed = bridge_speed
|
result.forward_speed = bridge_speed
|
||||||
result.backward_speed = bridge_speed
|
result.backward_speed = bridge_speed
|
||||||
elseif route_speeds[route] then
|
elseif route_speeds[route] then
|
||||||
|
|||||||
@@ -270,8 +270,6 @@ function way_function (way, result)
|
|||||||
if duration and durationIsValid(duration) then
|
if duration and durationIsValid(duration) then
|
||||||
result.duration = max( parseDuration(duration), 1 )
|
result.duration = max( parseDuration(duration), 1 )
|
||||||
end
|
end
|
||||||
result.forward_mode = mode.movable_bridge
|
|
||||||
result.backward_mode = mode.movable_bridge
|
|
||||||
result.forward_speed = bridge_speed
|
result.forward_speed = bridge_speed
|
||||||
result.backward_speed = bridge_speed
|
result.backward_speed = bridge_speed
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -100,9 +100,6 @@ std::string modeToString(const extractor::TravelMode mode)
|
|||||||
case TRAVEL_MODE_PUSHING_BIKE:
|
case TRAVEL_MODE_PUSHING_BIKE:
|
||||||
token = "pushing bike";
|
token = "pushing bike";
|
||||||
break;
|
break;
|
||||||
case TRAVEL_MODE_MOVABLE_BRIDGE:
|
|
||||||
token = "movable bridge";
|
|
||||||
break;
|
|
||||||
case TRAVEL_MODE_STEPS_UP:
|
case TRAVEL_MODE_STEPS_UP:
|
||||||
token = "steps up";
|
token = "steps up";
|
||||||
break;
|
break;
|
||||||
@@ -197,6 +194,7 @@ util::json::Object makeRouteLeg(guidance::RouteLeg leg, util::json::Array steps)
|
|||||||
util::json::Object route_leg;
|
util::json::Object route_leg;
|
||||||
route_leg.values["distance"] = std::round(leg.distance * 10) / 10.;
|
route_leg.values["distance"] = std::round(leg.distance * 10) / 10.;
|
||||||
route_leg.values["duration"] = std::round(leg.duration * 10) / 10.;
|
route_leg.values["duration"] = std::round(leg.duration * 10) / 10.;
|
||||||
|
route_leg.values["summary"] = std::move(leg.summary);
|
||||||
route_leg.values["steps"] = std::move(steps);
|
route_leg.values["steps"] = std::move(steps);
|
||||||
return route_leg;
|
return route_leg;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -331,7 +331,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
|||||||
|
|
||||||
BOOST_ASSERT(geometry.locations.size() >= steps.size());
|
BOOST_ASSERT(geometry.locations.size() >= steps.size());
|
||||||
// Look for distances under 1m
|
// Look for distances under 1m
|
||||||
const bool zero_length_step = steps.front().distance <= 1;
|
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::haversineDistance(
|
||||||
geometry.locations[0], geometry.locations[1]) <= 1;
|
geometry.locations[0], geometry.locations[1]) <= 1;
|
||||||
if (zero_length_step || duplicated_coordinate)
|
if (zero_length_step || duplicated_coordinate)
|
||||||
|
|||||||
+34
-32
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "util/coordinate_calculation.hpp"
|
#include "util/coordinate_calculation.hpp"
|
||||||
#include "util/web_mercator.hpp"
|
#include "util/web_mercator.hpp"
|
||||||
|
#include "util/vector_tile.hpp"
|
||||||
|
|
||||||
#include <boost/geometry.hpp>
|
#include <boost/geometry.hpp>
|
||||||
#include <boost/geometry/geometries/point_xy.hpp>
|
#include <boost/geometry/geometries/point_xy.hpp>
|
||||||
@@ -27,10 +28,6 @@ namespace plugins
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
// Vector tiles are 4096 virtual pixels on each side
|
|
||||||
const constexpr double VECTOR_TILE_EXTENT = 4096.0;
|
|
||||||
const constexpr double VECTOR_TILE_BUFFER = 128.0;
|
|
||||||
|
|
||||||
// Simple container class for WGS84 coordinates
|
// Simple container class for WGS84 coordinates
|
||||||
template <typename T> struct Point final
|
template <typename T> struct Point final
|
||||||
{
|
{
|
||||||
@@ -78,9 +75,9 @@ typedef boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>
|
|||||||
typedef boost::geometry::model::linestring<point_t> linestring_t;
|
typedef boost::geometry::model::linestring<point_t> linestring_t;
|
||||||
typedef boost::geometry::model::box<point_t> box_t;
|
typedef boost::geometry::model::box<point_t> box_t;
|
||||||
typedef boost::geometry::model::multi_linestring<linestring_t> multi_linestring_t;
|
typedef boost::geometry::model::multi_linestring<linestring_t> multi_linestring_t;
|
||||||
const static box_t clip_box(point_t(-detail::VECTOR_TILE_BUFFER, -detail::VECTOR_TILE_BUFFER),
|
const static box_t clip_box(point_t(-util::vector_tile::BUFFER, -util::vector_tile::BUFFER),
|
||||||
point_t(detail::VECTOR_TILE_EXTENT + detail::VECTOR_TILE_BUFFER,
|
point_t(util::vector_tile::EXTENT + util::vector_tile::BUFFER,
|
||||||
detail::VECTOR_TILE_EXTENT + detail::VECTOR_TILE_BUFFER));
|
util::vector_tile::EXTENT + util::vector_tile::BUFFER));
|
||||||
|
|
||||||
// from mapnik-vector-tile
|
// from mapnik-vector-tile
|
||||||
// Encodes a linestring using protobuf zigzag encoding
|
// Encodes a linestring using protobuf zigzag encoding
|
||||||
@@ -136,10 +133,10 @@ FixedLine coordinatesToTileLine(const util::Coordinate start,
|
|||||||
// convert lon/lat to tile coordinates
|
// convert lon/lat to tile coordinates
|
||||||
const auto px = std::round(
|
const auto px = std::round(
|
||||||
((px_merc - tile_bbox.minx) * util::web_mercator::TILE_SIZE / tile_bbox.width()) *
|
((px_merc - tile_bbox.minx) * util::web_mercator::TILE_SIZE / tile_bbox.width()) *
|
||||||
detail::VECTOR_TILE_EXTENT / util::web_mercator::TILE_SIZE);
|
util::vector_tile::EXTENT / util::web_mercator::TILE_SIZE);
|
||||||
const auto py = std::round(
|
const auto py = std::round(
|
||||||
((tile_bbox.maxy - py_merc) * util::web_mercator::TILE_SIZE / tile_bbox.height()) *
|
((tile_bbox.maxy - py_merc) * util::web_mercator::TILE_SIZE / tile_bbox.height()) *
|
||||||
detail::VECTOR_TILE_EXTENT / util::web_mercator::TILE_SIZE);
|
util::vector_tile::EXTENT / util::web_mercator::TILE_SIZE);
|
||||||
|
|
||||||
boost::geometry::append(unclipped_line, point_t(px, py));
|
boost::geometry::append(unclipped_line, point_t(px, py));
|
||||||
}
|
}
|
||||||
@@ -254,15 +251,15 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
|
|||||||
protozero::pbf_writer tile_writer{pbf_buffer};
|
protozero::pbf_writer tile_writer{pbf_buffer};
|
||||||
{
|
{
|
||||||
// Add a layer object to the PBF stream. 3=='layer' from the vector tile spec (2.1)
|
// Add a layer object to the PBF stream. 3=='layer' from the vector tile spec (2.1)
|
||||||
protozero::pbf_writer layer_writer(tile_writer, 3);
|
protozero::pbf_writer layer_writer(tile_writer, util::vector_tile::LAYER_TAG);
|
||||||
// TODO: don't write a layer if there are no features
|
// TODO: don't write a layer if there are no features
|
||||||
|
|
||||||
layer_writer.add_uint32(15, 2); // version
|
layer_writer.add_uint32(util::vector_tile::VERSION_TAG, 2); // version
|
||||||
// Field 1 is the "layer name" field, it's a string
|
// Field 1 is the "layer name" field, it's a string
|
||||||
layer_writer.add_string(1, "speeds"); // name
|
layer_writer.add_string(util::vector_tile::NAME_TAG, "speeds"); // name
|
||||||
// Field 5 is the tile extent. It's a uint32 and should be set to 4096
|
// Field 5 is the tile extent. It's a uint32 and should be set to 4096
|
||||||
// for normal vector tiles.
|
// for normal vector tiles.
|
||||||
layer_writer.add_uint32(5, 4096); // extent
|
layer_writer.add_uint32(util::vector_tile::EXTEND_TAG, util::vector_tile::EXTENT); // extent
|
||||||
|
|
||||||
// Begin the layer features block
|
// Begin the layer features block
|
||||||
{
|
{
|
||||||
@@ -328,11 +325,13 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
|
|||||||
// is_small
|
// is_small
|
||||||
// boolean. We onl serve up speeds from 0-139, so all we do is save the
|
// boolean. We onl serve up speeds from 0-139, so all we do is save the
|
||||||
// first
|
// first
|
||||||
protozero::pbf_writer feature_writer(layer_writer, 2);
|
protozero::pbf_writer feature_writer(layer_writer,
|
||||||
|
util::vector_tile::FEATURE_TAG);
|
||||||
// Field 3 is the "geometry type" field. Value 2 is "line"
|
// Field 3 is the "geometry type" field. Value 2 is "line"
|
||||||
feature_writer.add_enum(3, 2); // geometry type
|
feature_writer.add_enum(util::vector_tile::GEOMETRY_TAG,
|
||||||
|
util::vector_tile::GEOMETRY_TYPE_LINE); // geometry type
|
||||||
// Field 1 for the feature is the "id" field.
|
// Field 1 for the feature is the "id" field.
|
||||||
feature_writer.add_uint64(1, id++); // id
|
feature_writer.add_uint64(util::vector_tile::ID_TAG, id++); // id
|
||||||
{
|
{
|
||||||
// When adding attributes to a feature, we have to write
|
// When adding attributes to a feature, we have to write
|
||||||
// pairs of numbers. The first value is the index in the
|
// pairs of numbers. The first value is the index in the
|
||||||
@@ -341,7 +340,8 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
|
|||||||
// not writing the actual speed or bool value here, we're saving
|
// not writing the actual speed or bool value here, we're saving
|
||||||
// an index into the "values" array. This means many features
|
// an index into the "values" array. This means many features
|
||||||
// can share the same value data, leading to smaller tiles.
|
// can share the same value data, leading to smaller tiles.
|
||||||
protozero::packed_field_uint32 field(feature_writer, 2);
|
protozero::packed_field_uint32 field(
|
||||||
|
feature_writer, util::vector_tile::FEATURE_ATTRIBUTES_TAG);
|
||||||
|
|
||||||
field.add_element(0); // "speed" tag key offset
|
field.add_element(0); // "speed" tag key offset
|
||||||
field.add_element(
|
field.add_element(
|
||||||
@@ -358,7 +358,8 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Encode the geometry for the feature
|
// Encode the geometry for the feature
|
||||||
protozero::packed_field_uint32 geometry(feature_writer, 4);
|
protozero::packed_field_uint32 geometry(
|
||||||
|
feature_writer, util::vector_tile::FEATURE_GEOMETRIES_TAG);
|
||||||
encodeLinestring(tile_line, geometry, start_x, start_y);
|
encodeLinestring(tile_line, geometry, start_x, start_y);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -405,10 +406,10 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
|
|||||||
// Field id 3 is the "keys" attribute
|
// Field id 3 is the "keys" attribute
|
||||||
// We need two "key" fields, these are referred to with 0 and 1 (their array indexes)
|
// We need two "key" fields, these are referred to with 0 and 1 (their array indexes)
|
||||||
// earlier
|
// earlier
|
||||||
layer_writer.add_string(3, "speed");
|
layer_writer.add_string(util::vector_tile::KEY_TAG, "speed");
|
||||||
layer_writer.add_string(3, "is_small");
|
layer_writer.add_string(util::vector_tile::KEY_TAG, "is_small");
|
||||||
layer_writer.add_string(3, "datasource");
|
layer_writer.add_string(util::vector_tile::KEY_TAG, "datasource");
|
||||||
layer_writer.add_string(3, "duration");
|
layer_writer.add_string(util::vector_tile::KEY_TAG, "duration");
|
||||||
|
|
||||||
// Now, we write out the possible speed value arrays and possible is_tiny
|
// Now, we write out the possible speed value arrays and possible is_tiny
|
||||||
// values. Field type 4 is the "values" field. It's a variable type field,
|
// values. Field type 4 is the "values" field. It's a variable type field,
|
||||||
@@ -416,35 +417,36 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
|
|||||||
for (std::size_t i = 0; i < 128; i++)
|
for (std::size_t i = 0; i < 128; i++)
|
||||||
{
|
{
|
||||||
// Writing field type 4 == variant type
|
// Writing field type 4 == variant type
|
||||||
protozero::pbf_writer values_writer(layer_writer, 4);
|
protozero::pbf_writer values_writer(layer_writer, util::vector_tile::VARIANT_TAG);
|
||||||
// Attribute value 5 == uin64 type
|
// Attribute value 5 == uin64 type
|
||||||
values_writer.add_uint64(5, i);
|
values_writer.add_uint64(util::vector_tile::VARIANT_TYPE_UINT32, i);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
protozero::pbf_writer values_writer(layer_writer, 4);
|
protozero::pbf_writer values_writer(layer_writer, util::vector_tile::VARIANT_TAG);
|
||||||
// Attribute value 7 == bool type
|
// Attribute value 7 == bool type
|
||||||
values_writer.add_bool(7, true);
|
values_writer.add_bool(util::vector_tile::VARIANT_TYPE_BOOL, true);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
protozero::pbf_writer values_writer(layer_writer, 4);
|
protozero::pbf_writer values_writer(layer_writer, util::vector_tile::VARIANT_TAG);
|
||||||
// Attribute value 7 == bool type
|
// Attribute value 7 == bool type
|
||||||
values_writer.add_bool(7, false);
|
values_writer.add_bool(util::vector_tile::VARIANT_TYPE_BOOL, false);
|
||||||
}
|
}
|
||||||
for (std::size_t i = 0; i <= max_datasource_id; i++)
|
for (std::size_t i = 0; i <= max_datasource_id; i++)
|
||||||
{
|
{
|
||||||
// Writing field type 4 == variant type
|
// Writing field type 4 == variant type
|
||||||
protozero::pbf_writer values_writer(layer_writer, 4);
|
protozero::pbf_writer values_writer(layer_writer, util::vector_tile::VARIANT_TAG);
|
||||||
// Attribute value 1 == string type
|
// Attribute value 1 == string type
|
||||||
values_writer.add_string(1, facade.GetDatasourceName(i));
|
values_writer.add_string(util::vector_tile::VARIANT_TYPE_STRING,
|
||||||
|
facade.GetDatasourceName(i));
|
||||||
}
|
}
|
||||||
for (auto weight : used_weights)
|
for (auto weight : used_weights)
|
||||||
{
|
{
|
||||||
// Writing field type 4 == variant type
|
// Writing field type 4 == variant type
|
||||||
protozero::pbf_writer values_writer(layer_writer, 4);
|
protozero::pbf_writer values_writer(layer_writer, util::vector_tile::VARIANT_TAG);
|
||||||
// Attribute value 2 == float type
|
// Attribute value 2 == float type
|
||||||
// Durations come out of OSRM in integer deciseconds, so we convert them
|
// Durations come out of OSRM in integer deciseconds, so we convert them
|
||||||
// to seconds with a simple /10 for display
|
// to seconds with a simple /10 for display
|
||||||
values_writer.add_double(3, weight / 10.);
|
values_writer.add_double(util::vector_tile::VARIANT_TYPE_DOUBLE, weight / 10.);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -555,6 +555,11 @@ void Extractor::BuildRTree(std::vector<EdgeBasedNode> node_based_edge_list,
|
|||||||
in_iter++;
|
in_iter++;
|
||||||
}
|
}
|
||||||
auto new_size = out_iter - node_based_edge_list.begin();
|
auto new_size = out_iter - node_based_edge_list.begin();
|
||||||
|
if (new_size == 0)
|
||||||
|
{
|
||||||
|
throw util::exception("There are no snappable edges left after processing. Are you "
|
||||||
|
"setting travel modes correctly in the profile? Cannot continue.");
|
||||||
|
}
|
||||||
node_based_edge_list.resize(new_size);
|
node_based_edge_list.resize(new_size);
|
||||||
|
|
||||||
TIMER_START(construction);
|
TIMER_START(construction);
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ void ScriptingEnvironment::InitContext(ScriptingEnvironment::Context &context)
|
|||||||
luabind::value("ferry", TRAVEL_MODE_FERRY),
|
luabind::value("ferry", TRAVEL_MODE_FERRY),
|
||||||
luabind::value("train", TRAVEL_MODE_TRAIN),
|
luabind::value("train", TRAVEL_MODE_TRAIN),
|
||||||
luabind::value("pushing_bike", TRAVEL_MODE_PUSHING_BIKE),
|
luabind::value("pushing_bike", TRAVEL_MODE_PUSHING_BIKE),
|
||||||
luabind::value("movable_bridge", TRAVEL_MODE_MOVABLE_BRIDGE),
|
|
||||||
luabind::value("steps_up", TRAVEL_MODE_STEPS_UP),
|
luabind::value("steps_up", TRAVEL_MODE_STEPS_UP),
|
||||||
luabind::value("steps_down", TRAVEL_MODE_STEPS_DOWN),
|
luabind::value("steps_down", TRAVEL_MODE_STEPS_DOWN),
|
||||||
luabind::value("river_up", TRAVEL_MODE_RIVER_UP),
|
luabind::value("river_up", TRAVEL_MODE_RIVER_UP),
|
||||||
|
|||||||
@@ -25,4 +25,11 @@ inline Locations get_locations_in_small_component()
|
|||||||
{Longitude{7.438190}, Latitude{43.747560}}};
|
{Longitude{7.438190}, Latitude{43.747560}}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Locations get_locations_in_big_component()
|
||||||
|
{
|
||||||
|
return {{Longitude{7.415800}, Latitude{43.734132}},
|
||||||
|
{Longitude{7.417710}, Latitude{43.736721}},
|
||||||
|
{Longitude{7.421315}, Latitude{43.738814}}};
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "args.hpp"
|
#include "args.hpp"
|
||||||
#include "fixture.hpp"
|
#include "fixture.hpp"
|
||||||
#include "coordinates.hpp"
|
#include "coordinates.hpp"
|
||||||
|
#include "waypoint_check.hpp"
|
||||||
|
|
||||||
#include "osrm/match_parameters.hpp"
|
#include "osrm/match_parameters.hpp"
|
||||||
|
|
||||||
@@ -46,12 +47,8 @@ BOOST_AUTO_TEST_CASE(test_match)
|
|||||||
{
|
{
|
||||||
if (waypoint.is<mapbox::util::recursive_wrapper<util::json::Object>>())
|
if (waypoint.is<mapbox::util::recursive_wrapper<util::json::Object>>())
|
||||||
{
|
{
|
||||||
|
BOOST_CHECK(waypoint_check(waypoint));
|
||||||
const auto &waypoint_object = waypoint.get<json::Object>();
|
const auto &waypoint_object = waypoint.get<json::Object>();
|
||||||
const auto &waypoint_object_location = waypoint_object.values.at("location").get<json::Array>().values;
|
|
||||||
util::FloatLongitude lon(waypoint_object_location[0].get<json::Number>().value);
|
|
||||||
util::FloatLatitude lat(waypoint_object_location[1].get<json::Number>().value);
|
|
||||||
util::Coordinate location_coordinate(lon, lat);
|
|
||||||
BOOST_CHECK(location_coordinate.IsValid());
|
|
||||||
const auto matchings_index = waypoint_object.values.at("matchings_index").get<json::Number>().value;
|
const auto matchings_index = waypoint_object.values.at("matchings_index").get<json::Number>().value;
|
||||||
const auto waypoint_index = waypoint_object.values.at("waypoint_index").get<json::Number>().value;
|
const auto waypoint_index = waypoint_object.values.at("waypoint_index").get<json::Number>().value;
|
||||||
const auto &route_legs = matchings[matchings_index].get<json::Object>().values.at("legs").get<json::Array>().values;
|
const auto &route_legs = matchings[matchings_index].get<json::Object>().values.at("legs").get<json::Array>().values;
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates_fixture)
|
|||||||
json::Array{{json::Object{
|
json::Array{{json::Object{
|
||||||
{{"distance", 0.},
|
{{"distance", 0.},
|
||||||
{"duration", 0.},
|
{"duration", 0.},
|
||||||
|
{"summary", ""},
|
||||||
{"steps", json::Array{{json::Object{{{"duration", 0.},
|
{"steps", json::Array{{json::Object{{{"duration", 0.},
|
||||||
{"distance", 0.},
|
{"distance", 0.},
|
||||||
{"geometry", "yw_jGupkl@??"},
|
{"geometry", "yw_jGupkl@??"},
|
||||||
@@ -153,6 +154,10 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates)
|
|||||||
const auto duration = leg_object.values.at("duration").get<json::Number>().value;
|
const auto duration = leg_object.values.at("duration").get<json::Number>().value;
|
||||||
BOOST_CHECK_EQUAL(duration, 0);
|
BOOST_CHECK_EQUAL(duration, 0);
|
||||||
|
|
||||||
|
// nothing can be said about summary, empty or contains human readable summary
|
||||||
|
const auto summary = leg_object.values.at("summary").get<json::String>().value;
|
||||||
|
BOOST_CHECK(((void)summary, true));
|
||||||
|
|
||||||
const auto &steps = leg_object.values.at("steps").get<json::Array>().values;
|
const auto &steps = leg_object.values.at("steps").get<json::Array>().values;
|
||||||
BOOST_CHECK(!steps.empty());
|
BOOST_CHECK(!steps.empty());
|
||||||
|
|
||||||
@@ -237,9 +242,80 @@ BOOST_AUTO_TEST_CASE(test_route_response_for_locations_in_small_component)
|
|||||||
const auto latitude = location[1].get<json::Number>().value;
|
const auto latitude = location[1].get<json::Number>().value;
|
||||||
BOOST_CHECK(longitude >= -180. && longitude <= 180.);
|
BOOST_CHECK(longitude >= -180. && longitude <= 180.);
|
||||||
BOOST_CHECK(latitude >= -90. && latitude <= 90.);
|
BOOST_CHECK(latitude >= -90. && latitude <= 90.);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(daniel-j-h): we could do a Nearest request for each waypoint, verifying
|
BOOST_AUTO_TEST_CASE(test_route_response_for_locations_in_big_component)
|
||||||
// that we did indeed not snap to the input locations inside the small component.
|
{
|
||||||
|
const auto args = get_args();
|
||||||
|
auto osrm = getOSRM(args.at(0));
|
||||||
|
|
||||||
|
using namespace osrm;
|
||||||
|
|
||||||
|
const auto locations = get_locations_in_big_component();
|
||||||
|
|
||||||
|
RouteParameters params;
|
||||||
|
params.coordinates.push_back(locations.at(0));
|
||||||
|
params.coordinates.push_back(locations.at(1));
|
||||||
|
params.coordinates.push_back(locations.at(2));
|
||||||
|
|
||||||
|
json::Object result;
|
||||||
|
const auto rc = osrm.Route(params, result);
|
||||||
|
BOOST_CHECK(rc == Status::Ok);
|
||||||
|
|
||||||
|
const auto code = result.values.at("code").get<json::String>().value;
|
||||||
|
BOOST_CHECK_EQUAL(code, "Ok");
|
||||||
|
|
||||||
|
const auto &waypoints = result.values.at("waypoints").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(waypoints.size(), params.coordinates.size());
|
||||||
|
|
||||||
|
for (const auto &waypoint : waypoints)
|
||||||
|
{
|
||||||
|
const auto &waypoint_object = waypoint.get<json::Object>();
|
||||||
|
|
||||||
|
const auto location = waypoint_object.values.at("location").get<json::Array>().values;
|
||||||
|
const auto longitude = location[0].get<json::Number>().value;
|
||||||
|
const auto latitude = location[1].get<json::Number>().value;
|
||||||
|
BOOST_CHECK(longitude >= -180. && longitude <= 180.);
|
||||||
|
BOOST_CHECK(latitude >= -90. && latitude <= 90.);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_route_response_for_locations_across_components)
|
||||||
|
{
|
||||||
|
const auto args = get_args();
|
||||||
|
auto osrm = getOSRM(args.at(0));
|
||||||
|
|
||||||
|
using namespace osrm;
|
||||||
|
|
||||||
|
const auto big_component = get_locations_in_big_component();
|
||||||
|
const auto small_component = get_locations_in_small_component();
|
||||||
|
|
||||||
|
RouteParameters params;
|
||||||
|
params.coordinates.push_back(small_component.at(0));
|
||||||
|
params.coordinates.push_back(big_component.at(0));
|
||||||
|
params.coordinates.push_back(small_component.at(1));
|
||||||
|
params.coordinates.push_back(big_component.at(1));
|
||||||
|
|
||||||
|
json::Object result;
|
||||||
|
const auto rc = osrm.Route(params, result);
|
||||||
|
BOOST_CHECK(rc == Status::Ok);
|
||||||
|
|
||||||
|
const auto code = result.values.at("code").get<json::String>().value;
|
||||||
|
BOOST_CHECK_EQUAL(code, "Ok");
|
||||||
|
|
||||||
|
const auto &waypoints = result.values.at("waypoints").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(waypoints.size(), params.coordinates.size());
|
||||||
|
|
||||||
|
for (const auto &waypoint : waypoints)
|
||||||
|
{
|
||||||
|
const auto &waypoint_object = waypoint.get<json::Object>();
|
||||||
|
|
||||||
|
const auto location = waypoint_object.values.at("location").get<json::Array>().values;
|
||||||
|
const auto longitude = location[0].get<json::Number>().value;
|
||||||
|
const auto latitude = location[1].get<json::Number>().value;
|
||||||
|
BOOST_CHECK(longitude >= -180. && longitude <= 180.);
|
||||||
|
BOOST_CHECK(latitude >= -90. && latitude <= 90.);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
#include <boost/test/test_case_template.hpp>
|
#include <boost/test/test_case_template.hpp>
|
||||||
|
|
||||||
#include "args.hpp"
|
#include "args.hpp"
|
||||||
|
#include "coordinates.hpp"
|
||||||
#include "fixture.hpp"
|
#include "fixture.hpp"
|
||||||
|
#include "waypoint_check.hpp"
|
||||||
|
|
||||||
#include "osrm/table_parameters.hpp"
|
#include "osrm/table_parameters.hpp"
|
||||||
|
|
||||||
@@ -14,7 +16,7 @@
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(table)
|
BOOST_AUTO_TEST_SUITE(table)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_table)
|
BOOST_AUTO_TEST_CASE(test_table_three_coords_one_source_one_dest_matrix)
|
||||||
{
|
{
|
||||||
const auto args = get_args();
|
const auto args = get_args();
|
||||||
BOOST_REQUIRE_EQUAL(args.size(), 1);
|
BOOST_REQUIRE_EQUAL(args.size(), 1);
|
||||||
@@ -23,15 +25,138 @@ BOOST_AUTO_TEST_CASE(test_table)
|
|||||||
|
|
||||||
auto osrm = getOSRM(args[0]);
|
auto osrm = getOSRM(args[0]);
|
||||||
|
|
||||||
/*
|
|
||||||
TableParameters params;
|
TableParameters params;
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
params.sources.push_back(0);
|
||||||
|
params.destinations.push_back(2);
|
||||||
|
|
||||||
json::Object result;
|
json::Object result;
|
||||||
|
|
||||||
const auto rc = osrm.Table(params, result);
|
const auto rc = osrm.Table(params, result);
|
||||||
|
|
||||||
BOOST_CHECK(rc == Status::Ok || rc == Status::Error);
|
BOOST_CHECK(rc == Status::Ok || rc == Status::Error);
|
||||||
*/
|
const auto code = result.values.at("code").get<json::String>().value;
|
||||||
|
BOOST_CHECK_EQUAL(code, "Ok");
|
||||||
|
|
||||||
|
// check that returned durations error is expected size and proportions
|
||||||
|
// this test expects a 1x1 matrix
|
||||||
|
const auto &durations_array = result.values.at("durations").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(durations_array.size(), params.sources.size());
|
||||||
|
for (unsigned int i = 0; i < durations_array.size(); i++)
|
||||||
|
{
|
||||||
|
const auto durations_matrix = durations_array[i].get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(durations_matrix.size(), params.sources.size()*params.destinations.size());
|
||||||
|
}
|
||||||
|
// check destinations array of waypoint objects
|
||||||
|
const auto &destinations_array = result.values.at("destinations").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(destinations_array.size(), params.destinations.size());
|
||||||
|
for (const auto &destination : destinations_array)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(waypoint_check(destination));
|
||||||
|
}
|
||||||
|
// check sources array of waypoint objects
|
||||||
|
const auto &sources_array = result.values.at("sources").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(sources_array.size(), params.sources.size());
|
||||||
|
for (const auto &source : sources_array)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(waypoint_check(source));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_table_three_coords_one_source_matrix)
|
||||||
|
{
|
||||||
|
const auto args = get_args();
|
||||||
|
BOOST_REQUIRE_EQUAL(args.size(), 1);
|
||||||
|
|
||||||
|
using namespace osrm;
|
||||||
|
|
||||||
|
auto osrm = getOSRM(args[0]);
|
||||||
|
|
||||||
|
TableParameters params;
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
params.sources.push_back(0);
|
||||||
|
|
||||||
|
json::Object result;
|
||||||
|
|
||||||
|
const auto rc = osrm.Table(params, result);
|
||||||
|
|
||||||
|
BOOST_CHECK(rc == Status::Ok || rc == Status::Error);
|
||||||
|
const auto code = result.values.at("code").get<json::String>().value;
|
||||||
|
BOOST_CHECK_EQUAL(code, "Ok");
|
||||||
|
|
||||||
|
// check that returned durations error is expected size and proportions
|
||||||
|
// this test expects a 1x3 matrix
|
||||||
|
const auto &durations_array = result.values.at("durations").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(durations_array.size(), params.sources.size());
|
||||||
|
for (unsigned int i = 0; i < durations_array.size(); i++)
|
||||||
|
{
|
||||||
|
const auto durations_matrix = durations_array[i].get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(durations_matrix[i].get<json::Number>().value, 0);
|
||||||
|
BOOST_CHECK_EQUAL(durations_matrix.size(), params.sources.size()*params.coordinates.size());
|
||||||
|
}
|
||||||
|
// check destinations array of waypoint objects
|
||||||
|
const auto &destinations_array = result.values.at("destinations").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(destinations_array.size(), params.coordinates.size());
|
||||||
|
for (const auto &destination : destinations_array)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(waypoint_check(destination));
|
||||||
|
}
|
||||||
|
// check sources array of waypoint objects
|
||||||
|
const auto &sources_array = result.values.at("sources").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(sources_array.size(), params.sources.size());
|
||||||
|
for (const auto &source : sources_array)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(waypoint_check(source));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_table_three_coordinates_matrix)
|
||||||
|
{
|
||||||
|
const auto args = get_args();
|
||||||
|
BOOST_REQUIRE_EQUAL(args.size(), 1);
|
||||||
|
|
||||||
|
using namespace osrm;
|
||||||
|
|
||||||
|
auto osrm = getOSRM(args[0]);
|
||||||
|
|
||||||
|
TableParameters params;
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
params.coordinates.push_back(get_dummy_location());
|
||||||
|
|
||||||
|
json::Object result;
|
||||||
|
|
||||||
|
const auto rc = osrm.Table(params, result);
|
||||||
|
|
||||||
|
BOOST_CHECK(rc == Status::Ok || rc == Status::Error);
|
||||||
|
const auto code = result.values.at("code").get<json::String>().value;
|
||||||
|
BOOST_CHECK_EQUAL(code, "Ok");
|
||||||
|
|
||||||
|
// check that returned durations error is expected size and proportions
|
||||||
|
// this test expects a 3x3 matrix
|
||||||
|
const auto &durations_array = result.values.at("durations").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(durations_array.size(), params.coordinates.size());
|
||||||
|
for (unsigned int i = 0; i < durations_array.size(); i++)
|
||||||
|
{
|
||||||
|
const auto durations_matrix = durations_array[i].get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(durations_matrix[i].get<json::Number>().value, 0);
|
||||||
|
BOOST_CHECK_EQUAL(durations_matrix.size(), params.coordinates.size());
|
||||||
|
}
|
||||||
|
const auto &destinations_array = result.values.at("destinations").get<json::Array>().values;
|
||||||
|
for (const auto &destination : destinations_array)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(waypoint_check(destination));
|
||||||
|
}
|
||||||
|
const auto &sources_array = result.values.at("sources").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(sources_array.size(), params.coordinates.size());
|
||||||
|
for (const auto &source : sources_array)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(waypoint_check(source));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|||||||
+105
-1
@@ -12,6 +12,10 @@
|
|||||||
#include "osrm/status.hpp"
|
#include "osrm/status.hpp"
|
||||||
#include "osrm/osrm.hpp"
|
#include "osrm/osrm.hpp"
|
||||||
|
|
||||||
|
#include "util/vector_tile.hpp"
|
||||||
|
|
||||||
|
#include <protozero/pbf_reader.hpp>
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(tile)
|
BOOST_AUTO_TEST_SUITE(tile)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_tile)
|
BOOST_AUTO_TEST_CASE(test_tile)
|
||||||
@@ -21,11 +25,111 @@ BOOST_AUTO_TEST_CASE(test_tile)
|
|||||||
|
|
||||||
using namespace osrm;
|
using namespace osrm;
|
||||||
|
|
||||||
TileParameters params{0, 0, 1};
|
// This tile should contain most of monaco
|
||||||
|
TileParameters params{17059, 11948, 15};
|
||||||
|
|
||||||
std::string result;
|
std::string result;
|
||||||
const auto rc = osrm.Tile(params, result);
|
const auto rc = osrm.Tile(params, result);
|
||||||
BOOST_CHECK(rc == Status::Ok);
|
BOOST_CHECK(rc == Status::Ok);
|
||||||
|
|
||||||
|
BOOST_CHECK_GT(result.size(), 128);
|
||||||
|
|
||||||
|
protozero::pbf_reader tile_message(result);
|
||||||
|
tile_message.next();
|
||||||
|
BOOST_CHECK_EQUAL(tile_message.tag(), util::vector_tile::LAYER_TAG); // must be a layer
|
||||||
|
protozero::pbf_reader layer_message = tile_message.get_message();
|
||||||
|
|
||||||
|
const auto check_feature = [](protozero::pbf_reader feature_message) {
|
||||||
|
protozero::pbf_reader::const_uint32_iterator value_begin;
|
||||||
|
protozero::pbf_reader::const_uint32_iterator value_end;
|
||||||
|
feature_message.next(); // advance parser to first entry
|
||||||
|
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::GEOMETRY_TAG);
|
||||||
|
BOOST_CHECK_EQUAL(feature_message.get_enum(), util::vector_tile::GEOMETRY_TYPE_LINE);
|
||||||
|
|
||||||
|
feature_message.next(); // advance to next entry
|
||||||
|
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::ID_TAG);
|
||||||
|
feature_message.get_uint64(); // id
|
||||||
|
|
||||||
|
feature_message.next(); // advance to next entry
|
||||||
|
BOOST_CHECK_EQUAL(feature_message.tag(), util::vector_tile::FEATURE_ATTRIBUTES_TAG);
|
||||||
|
// properties
|
||||||
|
std::tie(value_begin, value_end) = feature_message.get_packed_uint32();
|
||||||
|
BOOST_CHECK_EQUAL(std::distance(value_begin, value_end), 8);
|
||||||
|
auto iter = value_begin;
|
||||||
|
BOOST_CHECK_EQUAL(*iter++, 0); // speed key
|
||||||
|
BOOST_CHECK_LT(*iter++, 128); // speed value
|
||||||
|
BOOST_CHECK_EQUAL(*iter++, 1); // component key
|
||||||
|
// component value
|
||||||
|
BOOST_CHECK_GE(*iter, 128);
|
||||||
|
BOOST_CHECK_LE(*iter, 129);
|
||||||
|
iter++;
|
||||||
|
BOOST_CHECK_EQUAL(*iter++, 2); // data source key
|
||||||
|
*iter++; // skip value check, can be valud uint32
|
||||||
|
BOOST_CHECK_EQUAL(*iter++, 3); // duration key
|
||||||
|
BOOST_CHECK_GT(*iter++, 130); // duration value
|
||||||
|
BOOST_CHECK(iter == value_end);
|
||||||
|
// geometry
|
||||||
|
feature_message.next();
|
||||||
|
std::tie(value_begin, value_end) = feature_message.get_packed_uint32();
|
||||||
|
BOOST_CHECK_GT(std::distance(value_begin, value_end), 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto check_value = [](protozero::pbf_reader value) {
|
||||||
|
while (value.next())
|
||||||
|
{
|
||||||
|
switch(value.tag())
|
||||||
|
{
|
||||||
|
case util::vector_tile::VARIANT_TYPE_BOOL:
|
||||||
|
value.get_bool();
|
||||||
|
break;
|
||||||
|
case util::vector_tile::VARIANT_TYPE_DOUBLE:
|
||||||
|
value.get_double();
|
||||||
|
break;
|
||||||
|
case util::vector_tile::VARIANT_TYPE_STRING:
|
||||||
|
value.get_string();
|
||||||
|
break;
|
||||||
|
case util::vector_tile::VARIANT_TYPE_UINT32:
|
||||||
|
value.get_uint32();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto number_of_keys = 0u;
|
||||||
|
auto number_of_values = 0u;
|
||||||
|
|
||||||
|
while (layer_message.next())
|
||||||
|
{
|
||||||
|
switch(layer_message.tag())
|
||||||
|
{
|
||||||
|
case util::vector_tile::VERSION_TAG:
|
||||||
|
BOOST_CHECK_EQUAL(layer_message.get_uint32(), 2);
|
||||||
|
break;
|
||||||
|
case util::vector_tile::NAME_TAG:
|
||||||
|
BOOST_CHECK_EQUAL(layer_message.get_string(), "speeds");
|
||||||
|
break;
|
||||||
|
case util::vector_tile::EXTEND_TAG:
|
||||||
|
BOOST_CHECK_EQUAL(layer_message.get_uint32(), util::vector_tile::EXTENT);
|
||||||
|
break;
|
||||||
|
case util::vector_tile::FEATURE_TAG:
|
||||||
|
check_feature(layer_message.get_message());
|
||||||
|
break;
|
||||||
|
case util::vector_tile::KEY_TAG:
|
||||||
|
layer_message.get_string();
|
||||||
|
number_of_keys++;
|
||||||
|
break;
|
||||||
|
case util::vector_tile::VARIANT_TAG:
|
||||||
|
check_value(layer_message.get_message());
|
||||||
|
number_of_values++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BOOST_CHECK(false); // invalid tag
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(number_of_keys, 4);
|
||||||
|
BOOST_CHECK_GT(number_of_values, 128); // speed value resolution
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|||||||
+125
-9
@@ -1,7 +1,8 @@
|
|||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#include <boost/test/test_case_template.hpp>
|
#include <boost/test/test_case_template.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
#include "args.hpp"
|
#include "args.hpp"
|
||||||
|
#include "coordinates.hpp"
|
||||||
#include "fixture.hpp"
|
#include "fixture.hpp"
|
||||||
|
|
||||||
#include "osrm/trip_parameters.hpp"
|
#include "osrm/trip_parameters.hpp"
|
||||||
@@ -9,29 +10,144 @@
|
|||||||
#include "osrm/coordinate.hpp"
|
#include "osrm/coordinate.hpp"
|
||||||
#include "osrm/engine_config.hpp"
|
#include "osrm/engine_config.hpp"
|
||||||
#include "osrm/json_container.hpp"
|
#include "osrm/json_container.hpp"
|
||||||
#include "osrm/status.hpp"
|
|
||||||
#include "osrm/osrm.hpp"
|
#include "osrm/osrm.hpp"
|
||||||
|
#include "osrm/status.hpp"
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(trip)
|
BOOST_AUTO_TEST_SUITE(trip)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_trip)
|
BOOST_AUTO_TEST_CASE(test_trip_response_for_locations_in_small_component)
|
||||||
{
|
{
|
||||||
const auto args = get_args();
|
const auto args = get_args();
|
||||||
BOOST_REQUIRE_EQUAL(args.size(), 1);
|
auto osrm = getOSRM(args.at(0));
|
||||||
|
|
||||||
using namespace osrm;
|
using namespace osrm;
|
||||||
|
|
||||||
auto osrm = getOSRM(args[0]);
|
const auto locations = get_locations_in_small_component();
|
||||||
|
|
||||||
/*
|
|
||||||
TripParameters params;
|
TripParameters params;
|
||||||
|
params.coordinates.push_back(locations.at(0));
|
||||||
|
params.coordinates.push_back(locations.at(1));
|
||||||
|
params.coordinates.push_back(locations.at(2));
|
||||||
|
|
||||||
json::Object result;
|
json::Object result;
|
||||||
|
|
||||||
const auto rc = osrm.Trip(params, result);
|
const auto rc = osrm.Trip(params, result);
|
||||||
|
BOOST_CHECK(rc == Status::Ok);
|
||||||
|
|
||||||
BOOST_CHECK(rc == Status::Ok || rc == Status::Error);
|
const auto code = result.values.at("code").get<json::String>().value;
|
||||||
*/
|
BOOST_CHECK_EQUAL(code, "Ok");
|
||||||
|
|
||||||
|
const auto &waypoints = result.values.at("waypoints").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(waypoints.size(), params.coordinates.size());
|
||||||
|
|
||||||
|
const auto &trips = result.values.at("trips").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(trips.size(), 1);
|
||||||
|
|
||||||
|
for (const auto &waypoint : waypoints)
|
||||||
|
{
|
||||||
|
const auto &waypoint_object = waypoint.get<json::Object>();
|
||||||
|
|
||||||
|
const auto location = waypoint_object.values.at("location").get<json::Array>().values;
|
||||||
|
const auto longitude = location[0].get<json::Number>().value;
|
||||||
|
const auto latitude = location[1].get<json::Number>().value;
|
||||||
|
BOOST_CHECK(longitude >= -180. && longitude <= 180.);
|
||||||
|
BOOST_CHECK(latitude >= -90. && latitude <= 90.);
|
||||||
|
|
||||||
|
const auto trip = waypoint_object.values.at("trips_index").get<json::Number>().value;
|
||||||
|
const auto pos = waypoint_object.values.at("waypoint_index").get<json::Number>().value;
|
||||||
|
BOOST_CHECK(trip >= 0 && trip < trips.size());
|
||||||
|
BOOST_CHECK(pos >= 0 && pos < waypoints.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_trip_response_for_locations_in_big_component)
|
||||||
|
{
|
||||||
|
const auto args = get_args();
|
||||||
|
auto osrm = getOSRM(args.at(0));
|
||||||
|
|
||||||
|
using namespace osrm;
|
||||||
|
|
||||||
|
const auto locations = get_locations_in_big_component();
|
||||||
|
|
||||||
|
TripParameters params;
|
||||||
|
params.coordinates.push_back(locations.at(0));
|
||||||
|
params.coordinates.push_back(locations.at(1));
|
||||||
|
params.coordinates.push_back(locations.at(2));
|
||||||
|
|
||||||
|
json::Object result;
|
||||||
|
const auto rc = osrm.Trip(params, result);
|
||||||
|
BOOST_CHECK(rc == Status::Ok);
|
||||||
|
|
||||||
|
const auto code = result.values.at("code").get<json::String>().value;
|
||||||
|
BOOST_CHECK_EQUAL(code, "Ok");
|
||||||
|
|
||||||
|
const auto &waypoints = result.values.at("waypoints").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(waypoints.size(), params.coordinates.size());
|
||||||
|
|
||||||
|
const auto &trips = result.values.at("trips").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(trips.size(), 1);
|
||||||
|
|
||||||
|
for (const auto &waypoint : waypoints)
|
||||||
|
{
|
||||||
|
const auto &waypoint_object = waypoint.get<json::Object>();
|
||||||
|
|
||||||
|
const auto location = waypoint_object.values.at("location").get<json::Array>().values;
|
||||||
|
const auto longitude = location[0].get<json::Number>().value;
|
||||||
|
const auto latitude = location[1].get<json::Number>().value;
|
||||||
|
BOOST_CHECK(longitude >= -180. && longitude <= 180.);
|
||||||
|
BOOST_CHECK(latitude >= -90. && latitude <= 90.);
|
||||||
|
|
||||||
|
const auto trip = waypoint_object.values.at("trips_index").get<json::Number>().value;
|
||||||
|
const auto pos = waypoint_object.values.at("waypoint_index").get<json::Number>().value;
|
||||||
|
BOOST_CHECK(trip >= 0 && trip < trips.size());
|
||||||
|
BOOST_CHECK(pos >= 0 && pos < waypoints.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_trip_response_for_locations_across_components)
|
||||||
|
{
|
||||||
|
const auto args = get_args();
|
||||||
|
auto osrm = getOSRM(args.at(0));
|
||||||
|
|
||||||
|
using namespace osrm;
|
||||||
|
|
||||||
|
const auto small = get_locations_in_small_component();
|
||||||
|
const auto big = get_locations_in_big_component();
|
||||||
|
|
||||||
|
TripParameters params;
|
||||||
|
params.coordinates.push_back(small.at(0));
|
||||||
|
params.coordinates.push_back(big.at(0));
|
||||||
|
params.coordinates.push_back(small.at(1));
|
||||||
|
params.coordinates.push_back(big.at(1));
|
||||||
|
|
||||||
|
json::Object result;
|
||||||
|
const auto rc = osrm.Trip(params, result);
|
||||||
|
BOOST_CHECK(rc == Status::Ok);
|
||||||
|
|
||||||
|
const auto code = result.values.at("code").get<json::String>().value;
|
||||||
|
BOOST_CHECK_EQUAL(code, "Ok");
|
||||||
|
|
||||||
|
const auto &waypoints = result.values.at("waypoints").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(waypoints.size(), params.coordinates.size());
|
||||||
|
|
||||||
|
const auto &trips = result.values.at("trips").get<json::Array>().values;
|
||||||
|
BOOST_CHECK_EQUAL(trips.size(), 1);
|
||||||
|
// ^ First snapping, then SCC decomposition (see plugins/trip.cpp). Therefore only a single trip.
|
||||||
|
|
||||||
|
for (const auto &waypoint : waypoints)
|
||||||
|
{
|
||||||
|
const auto &waypoint_object = waypoint.get<json::Object>();
|
||||||
|
|
||||||
|
const auto location = waypoint_object.values.at("location").get<json::Array>().values;
|
||||||
|
const auto longitude = location[0].get<json::Number>().value;
|
||||||
|
const auto latitude = location[1].get<json::Number>().value;
|
||||||
|
BOOST_CHECK(longitude >= -180. && longitude <= 180.);
|
||||||
|
BOOST_CHECK(latitude >= -90. && latitude <= 90.);
|
||||||
|
|
||||||
|
const auto trip = waypoint_object.values.at("trips_index").get<json::Number>().value;
|
||||||
|
const auto pos = waypoint_object.values.at("waypoint_index").get<json::Number>().value;
|
||||||
|
BOOST_CHECK(trip >= 0 && trip < trips.size());
|
||||||
|
BOOST_CHECK(pos >= 0 && pos < waypoints.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef OSRM_UNIT_TEST_WAYPOINT_CHECK
|
||||||
|
#define OSRM_UNIT_TEST_WAYPOINT_CHECK
|
||||||
|
|
||||||
|
#include "osrm/coordinate.hpp"
|
||||||
|
#include "osrm/json_container.hpp"
|
||||||
|
#include "util/exception.hpp"
|
||||||
|
|
||||||
|
using namespace osrm;
|
||||||
|
|
||||||
|
inline bool waypoint_check(json::Value waypoint)
|
||||||
|
{
|
||||||
|
if (!waypoint.is<mapbox::util::recursive_wrapper<util::json::Object>>())
|
||||||
|
{
|
||||||
|
throw util::exception("Must pass in a waypoint object");
|
||||||
|
}
|
||||||
|
const auto waypoint_object = waypoint.get<json::Object>();
|
||||||
|
const auto waypoint_location = waypoint_object.values.at("location").get<json::Array>().values;
|
||||||
|
util::FloatLongitude lon(waypoint_location[0].get<json::Number>().value);
|
||||||
|
util::FloatLatitude lat(waypoint_location[1].get<json::Number>().value);
|
||||||
|
util::Coordinate location_coordinate(lon, lat);
|
||||||
|
return location_coordinate.IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#ifndef OSRM_TEST_SERVER_PARAMETERS_IO
|
||||||
|
#define OSRM_TEST_SERVER_PARAMETERS_IO
|
||||||
|
|
||||||
|
#include "engine/api/route_parameters.hpp"
|
||||||
|
#include "engine/bearing.hpp"
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace osrm
|
||||||
|
{
|
||||||
|
namespace engine
|
||||||
|
{
|
||||||
|
namespace api
|
||||||
|
{
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, api::RouteParameters::GeometriesType geometries)
|
||||||
|
{
|
||||||
|
switch (geometries)
|
||||||
|
{
|
||||||
|
case api::RouteParameters::GeometriesType::GeoJSON:
|
||||||
|
out << "GeoJSON";
|
||||||
|
break;
|
||||||
|
case api::RouteParameters::GeometriesType::Polyline:
|
||||||
|
out << "Polyline";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BOOST_ASSERT_MSG(false, "GeometriesType not fully captured");
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, api::RouteParameters::OverviewType overview)
|
||||||
|
{
|
||||||
|
switch (overview)
|
||||||
|
{
|
||||||
|
case api::RouteParameters::OverviewType::False:
|
||||||
|
out << "False";
|
||||||
|
break;
|
||||||
|
case api::RouteParameters::OverviewType::Full:
|
||||||
|
out << "Full";
|
||||||
|
break;
|
||||||
|
case api::RouteParameters::OverviewType::Simplified:
|
||||||
|
out << "Simplified";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BOOST_ASSERT_MSG(false, "OverviewType not fully captured");
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream &operator<<(std::ostream &out, Bearing bearing)
|
||||||
|
{
|
||||||
|
out << bearing.bearing << "," << bearing.range;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "server/api/parameters_parser.hpp"
|
#include "server/api/parameters_parser.hpp"
|
||||||
|
|
||||||
|
#include "parameters_io.hpp"
|
||||||
|
|
||||||
#include "engine/api/base_parameters.hpp"
|
#include "engine/api/base_parameters.hpp"
|
||||||
#include "engine/api/match_parameters.hpp"
|
#include "engine/api/match_parameters.hpp"
|
||||||
#include "engine/api/nearest_parameters.hpp"
|
#include "engine/api/nearest_parameters.hpp"
|
||||||
@@ -8,56 +10,6 @@
|
|||||||
#include "engine/api/tile_parameters.hpp"
|
#include "engine/api/tile_parameters.hpp"
|
||||||
#include "engine/api/trip_parameters.hpp"
|
#include "engine/api/trip_parameters.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
namespace osrm
|
|
||||||
{
|
|
||||||
namespace engine
|
|
||||||
{
|
|
||||||
namespace api
|
|
||||||
{
|
|
||||||
std::ostream &operator<<(std::ostream &out, api::RouteParameters::GeometriesType geometries)
|
|
||||||
{
|
|
||||||
switch (geometries)
|
|
||||||
{
|
|
||||||
case api::RouteParameters::GeometriesType::GeoJSON:
|
|
||||||
out << "GeoJSON";
|
|
||||||
break;
|
|
||||||
case api::RouteParameters::GeometriesType::Polyline:
|
|
||||||
out << "Polyline";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BOOST_ASSERT_MSG(false, "GeometriesType not fully captured");
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
std::ostream &operator<<(std::ostream &out, api::RouteParameters::OverviewType overview)
|
|
||||||
{
|
|
||||||
switch (overview)
|
|
||||||
{
|
|
||||||
case api::RouteParameters::OverviewType::False:
|
|
||||||
out << "False";
|
|
||||||
break;
|
|
||||||
case api::RouteParameters::OverviewType::Full:
|
|
||||||
out << "Full";
|
|
||||||
break;
|
|
||||||
case api::RouteParameters::OverviewType::Simplified:
|
|
||||||
out << "Simplified";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BOOST_ASSERT_MSG(false, "OverviewType not fully captured");
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::ostream &operator<<(std::ostream &out, Bearing bearing)
|
|
||||||
{
|
|
||||||
out << bearing.bearing << "," << bearing.range;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <boost/optional/optional_io.hpp>
|
#include <boost/optional/optional_io.hpp>
|
||||||
#include <boost/test/test_tools.hpp>
|
#include <boost/test/test_tools.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
@@ -69,55 +21,54 @@ BOOST_AUTO_TEST_SUITE(api_parameters_parser)
|
|||||||
|
|
||||||
using namespace osrm;
|
using namespace osrm;
|
||||||
using namespace osrm::server;
|
using namespace osrm::server;
|
||||||
|
using namespace osrm::server::api;
|
||||||
|
using namespace osrm::engine::api;
|
||||||
|
|
||||||
// returns distance to front
|
// returns distance to front
|
||||||
template <typename ParameterT> std::size_t testInvalidOptions(std::string options)
|
template <typename ParameterT> std::size_t testInvalidOptions(std::string options)
|
||||||
{
|
{
|
||||||
auto iter = options.begin();
|
auto iter = options.begin();
|
||||||
auto result = api::parseParameters<ParameterT>(iter, options.end());
|
auto result = parseParameters<ParameterT>(iter, options.end());
|
||||||
BOOST_CHECK(!result);
|
BOOST_CHECK(!result);
|
||||||
return std::distance(options.begin(), iter);
|
return std::distance(options.begin(), iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(invalid_route_urls)
|
BOOST_AUTO_TEST_CASE(invalid_route_urls)
|
||||||
{
|
{
|
||||||
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&bla=foo"), 22UL);
|
||||||
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&bearings=foo"),
|
||||||
|
32UL);
|
||||||
BOOST_CHECK_EQUAL(
|
BOOST_CHECK_EQUAL(
|
||||||
testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&bla=foo"), 22UL);
|
testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&continue_straight=foo"), 41UL);
|
||||||
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&radiuses=foo"),
|
||||||
|
32UL);
|
||||||
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&hints=foo"),
|
||||||
|
29UL);
|
||||||
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&geometries=foo"),
|
||||||
|
22UL);
|
||||||
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&overview=foo"),
|
||||||
|
22L);
|
||||||
BOOST_CHECK_EQUAL(
|
BOOST_CHECK_EQUAL(
|
||||||
testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&bearings=foo"),
|
testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&alternatives=foo"), 36UL);
|
||||||
32UL);
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(""), 0);
|
||||||
BOOST_CHECK_EQUAL(
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3.4.unsupported"), 7);
|
||||||
testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&continue_straight=foo"),
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4.json?nooptions"), 13);
|
||||||
41UL);
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4..json?nooptions"), 14);
|
||||||
BOOST_CHECK_EQUAL(
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4.0.json?nooptions"), 15);
|
||||||
testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&radiuses=foo"),
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(std::string{"1,2;3,4"} + '\0' + ".json"), 7);
|
||||||
32UL);
|
BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(std::string{"1,2;3,"} + '\0'), 6);
|
||||||
BOOST_CHECK_EQUAL(
|
|
||||||
testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&hints=foo"), 29UL);
|
//BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(), );
|
||||||
BOOST_CHECK_EQUAL(
|
|
||||||
testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&geometries=foo"),
|
|
||||||
22UL);
|
|
||||||
BOOST_CHECK_EQUAL(
|
|
||||||
testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&overview=foo"),
|
|
||||||
22L);
|
|
||||||
BOOST_CHECK_EQUAL(
|
|
||||||
testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&alternatives=foo"),
|
|
||||||
36UL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(invalid_table_urls)
|
BOOST_AUTO_TEST_CASE(invalid_table_urls)
|
||||||
{
|
{
|
||||||
BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("1,2;3,4?sources=1&bla=foo"),
|
BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?sources=1&bla=foo"), 17UL);
|
||||||
17UL);
|
BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?destinations=1&bla=foo"), 22UL);
|
||||||
BOOST_CHECK_EQUAL(
|
BOOST_CHECK_EQUAL(
|
||||||
testInvalidOptions<engine::api::TableParameters>("1,2;3,4?destinations=1&bla=foo"), 22UL);
|
testInvalidOptions<TableParameters>("1,2;3,4?sources=1&destinations=1&bla=foo"), 32UL);
|
||||||
BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>(
|
BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?sources=foo"), 16UL);
|
||||||
"1,2;3,4?sources=1&destinations=1&bla=foo"),
|
BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?destinations=foo"), 21UL);
|
||||||
32UL);
|
|
||||||
BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("1,2;3,4?sources=foo"),
|
|
||||||
16UL);
|
|
||||||
BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("1,2;3,4?destinations=foo"),
|
|
||||||
21UL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(valid_route_urls)
|
BOOST_AUTO_TEST_CASE(valid_route_urls)
|
||||||
@@ -125,9 +76,9 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
|
|||||||
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)},
|
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)},
|
||||||
{util::FloatLongitude(3), util::FloatLatitude(4)}};
|
{util::FloatLongitude(3), util::FloatLatitude(4)}};
|
||||||
|
|
||||||
engine::api::RouteParameters reference_1{};
|
RouteParameters reference_1{};
|
||||||
reference_1.coordinates = coords_1;
|
reference_1.coordinates = coords_1;
|
||||||
auto result_1 = api::parseParameters<engine::api::RouteParameters>("1,2;3,4");
|
auto result_1 = parseParameters<RouteParameters>("1,2;3,4");
|
||||||
BOOST_CHECK(result_1);
|
BOOST_CHECK(result_1);
|
||||||
BOOST_CHECK_EQUAL(reference_1.steps, result_1->steps);
|
BOOST_CHECK_EQUAL(reference_1.steps, result_1->steps);
|
||||||
BOOST_CHECK_EQUAL(reference_1.alternatives, result_1->alternatives);
|
BOOST_CHECK_EQUAL(reference_1.alternatives, result_1->alternatives);
|
||||||
@@ -138,11 +89,11 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
|
|||||||
CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
|
CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
|
||||||
CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
|
CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
|
||||||
|
|
||||||
engine::api::RouteParameters reference_2{};
|
RouteParameters reference_2{};
|
||||||
reference_2.alternatives = true;
|
reference_2.alternatives = true;
|
||||||
reference_2.steps = true;
|
reference_2.steps = true;
|
||||||
reference_2.coordinates = coords_1;
|
reference_2.coordinates = coords_1;
|
||||||
auto result_2 = api::parseParameters<engine::api::RouteParameters>(
|
auto result_2 = parseParameters<RouteParameters>(
|
||||||
"1,2;3,4?steps=true&alternatives=true&geometries=polyline&overview=simplified");
|
"1,2;3,4?steps=true&alternatives=true&geometries=polyline&overview=simplified");
|
||||||
BOOST_CHECK(result_2);
|
BOOST_CHECK(result_2);
|
||||||
BOOST_CHECK_EQUAL(reference_2.steps, result_2->steps);
|
BOOST_CHECK_EQUAL(reference_2.steps, result_2->steps);
|
||||||
@@ -154,12 +105,12 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
|
|||||||
CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
|
CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
|
||||||
CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
|
CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
|
||||||
|
|
||||||
engine::api::RouteParameters reference_3{
|
RouteParameters reference_3{false, false, RouteParameters::GeometriesType::GeoJSON,
|
||||||
false, false, engine::api::RouteParameters::GeometriesType::GeoJSON,
|
RouteParameters::OverviewType::False, true};
|
||||||
engine::api::RouteParameters::OverviewType::False, true};
|
|
||||||
reference_3.coordinates = coords_1;
|
reference_3.coordinates = coords_1;
|
||||||
auto result_3 = api::parseParameters<engine::api::RouteParameters>(
|
auto result_3 = api::parseParameters<engine::api::RouteParameters>(
|
||||||
"1,2;3,4?steps=false&alternatives=false&geometries=geojson&overview=false&continue_straight=true");
|
"1,2;3,4?steps=false&alternatives=false&geometries=geojson&overview=false&continue_"
|
||||||
|
"straight=true");
|
||||||
BOOST_CHECK(result_3);
|
BOOST_CHECK(result_3);
|
||||||
BOOST_CHECK_EQUAL(reference_3.steps, result_3->steps);
|
BOOST_CHECK_EQUAL(reference_3.steps, result_3->steps);
|
||||||
BOOST_CHECK_EQUAL(reference_3.alternatives, result_3->alternatives);
|
BOOST_CHECK_EQUAL(reference_3.alternatives, result_3->alternatives);
|
||||||
@@ -180,16 +131,16 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
|
|||||||
engine::Hint::FromBase64("3gAAgP___"
|
engine::Hint::FromBase64("3gAAgP___"
|
||||||
"39KAAAAHgAAACEAAAAAAAAAGAAAAE0BAABOAQAAGwAAAIAzcQBkUJsC1zNxAHBQmw"
|
"39KAAAAHgAAACEAAAAAAAAAGAAAAE0BAABOAQAAGwAAAIAzcQBkUJsC1zNxAHBQmw"
|
||||||
"IAAAEBl-Umfg==")};
|
"IAAAEBl-Umfg==")};
|
||||||
engine::api::RouteParameters reference_4{false,
|
RouteParameters reference_4{false,
|
||||||
false,
|
false,
|
||||||
engine::api::RouteParameters::GeometriesType::Polyline,
|
RouteParameters::GeometriesType::Polyline,
|
||||||
engine::api::RouteParameters::OverviewType::Simplified,
|
RouteParameters::OverviewType::Simplified,
|
||||||
boost::optional<bool>{},
|
boost::optional<bool>{},
|
||||||
coords_1,
|
coords_1,
|
||||||
hints_4,
|
hints_4,
|
||||||
std::vector<boost::optional<double>>{},
|
std::vector<boost::optional<double>>{},
|
||||||
std::vector<boost::optional<engine::Bearing>>{}};
|
std::vector<boost::optional<engine::Bearing>>{}};
|
||||||
auto result_4 = api::parseParameters<engine::api::RouteParameters>(
|
auto result_4 = parseParameters<RouteParameters>(
|
||||||
"1,2;3,4?steps=false&hints="
|
"1,2;3,4?steps=false&hints="
|
||||||
"DAIAgP___38AAAAAAAAAAAIAAAAAAAAAEAAAAOgDAAD0AwAAGwAAAOUacQBQP5sCshpxAB0_mwIAAAEBl-Umfg==;"
|
"DAIAgP___38AAAAAAAAAAAIAAAAAAAAAEAAAAOgDAAD0AwAAGwAAAOUacQBQP5sCshpxAB0_mwIAAAEBl-Umfg==;"
|
||||||
"cgAAgP___39jAAAADgAAACIAAABeAAAAkQAAANoDAABOAgAAGwAAAFVGcQCiRJsCR0VxAOZFmwIFAAEBl-Umfg==;"
|
"cgAAgP___39jAAAADgAAACIAAABeAAAAkQAAANoDAABOAgAAGwAAAFVGcQCiRJsCR0VxAOZFmwIFAAEBl-Umfg==;"
|
||||||
@@ -207,17 +158,16 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
|
|||||||
std::vector<boost::optional<engine::Bearing>> bearings_4 = {
|
std::vector<boost::optional<engine::Bearing>> bearings_4 = {
|
||||||
boost::none, engine::Bearing{200, 10}, engine::Bearing{100, 5},
|
boost::none, engine::Bearing{200, 10}, engine::Bearing{100, 5},
|
||||||
};
|
};
|
||||||
engine::api::RouteParameters reference_5{false,
|
RouteParameters reference_5{false,
|
||||||
false,
|
false,
|
||||||
engine::api::RouteParameters::GeometriesType::Polyline,
|
RouteParameters::GeometriesType::Polyline,
|
||||||
engine::api::RouteParameters::OverviewType::Simplified,
|
RouteParameters::OverviewType::Simplified,
|
||||||
boost::optional<bool>{},
|
boost::optional<bool>{},
|
||||||
coords_1,
|
coords_1,
|
||||||
std::vector<boost::optional<engine::Hint>>{},
|
std::vector<boost::optional<engine::Hint>>{},
|
||||||
std::vector<boost::optional<double>>{},
|
std::vector<boost::optional<double>>{},
|
||||||
bearings_4};
|
bearings_4};
|
||||||
auto result_5 = api::parseParameters<engine::api::RouteParameters>(
|
auto result_5 = parseParameters<RouteParameters>("1,2;3,4?steps=false&bearings=;200,10;100,5");
|
||||||
"1,2;3,4?steps=false&bearings=;200,10;100,5");
|
|
||||||
BOOST_CHECK(result_5);
|
BOOST_CHECK(result_5);
|
||||||
BOOST_CHECK_EQUAL(reference_5.steps, result_5->steps);
|
BOOST_CHECK_EQUAL(reference_5.steps, result_5->steps);
|
||||||
BOOST_CHECK_EQUAL(reference_5.alternatives, result_5->alternatives);
|
BOOST_CHECK_EQUAL(reference_5.alternatives, result_5->alternatives);
|
||||||
@@ -232,10 +182,9 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
|
|||||||
{util::FloatLongitude(2), util::FloatLatitude(3)},
|
{util::FloatLongitude(2), util::FloatLatitude(3)},
|
||||||
{util::FloatLongitude(4), util::FloatLatitude(5)}};
|
{util::FloatLongitude(4), util::FloatLatitude(5)}};
|
||||||
|
|
||||||
engine::api::RouteParameters reference_6{};
|
RouteParameters reference_6{};
|
||||||
reference_6.coordinates = coords_2;
|
reference_6.coordinates = coords_2;
|
||||||
auto result_6 =
|
auto result_6 = parseParameters<RouteParameters>("polyline(_ibE?_seK_seK_seK_seK)");
|
||||||
api::parseParameters<engine::api::RouteParameters>("polyline(_ibE?_seK_seK_seK_seK)");
|
|
||||||
BOOST_CHECK(result_6);
|
BOOST_CHECK(result_6);
|
||||||
BOOST_CHECK_EQUAL(reference_6.steps, result_6->steps);
|
BOOST_CHECK_EQUAL(reference_6.steps, result_6->steps);
|
||||||
BOOST_CHECK_EQUAL(reference_6.alternatives, result_6->alternatives);
|
BOOST_CHECK_EQUAL(reference_6.alternatives, result_6->alternatives);
|
||||||
@@ -245,6 +194,34 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
|
|||||||
CHECK_EQUAL_RANGE(reference_6.bearings, result_6->bearings);
|
CHECK_EQUAL_RANGE(reference_6.bearings, result_6->bearings);
|
||||||
CHECK_EQUAL_RANGE(reference_6.radiuses, result_6->radiuses);
|
CHECK_EQUAL_RANGE(reference_6.radiuses, result_6->radiuses);
|
||||||
CHECK_EQUAL_RANGE(reference_6.coordinates, result_6->coordinates);
|
CHECK_EQUAL_RANGE(reference_6.coordinates, result_6->coordinates);
|
||||||
|
|
||||||
|
auto result_7 = parseParameters<RouteParameters>("1,2;3,4?radiuses=;unlimited");
|
||||||
|
RouteParameters reference_7{};
|
||||||
|
reference_7.coordinates = coords_1;
|
||||||
|
reference_7.radiuses = {boost::none, boost::make_optional(std::numeric_limits<double>::infinity())};
|
||||||
|
BOOST_CHECK(result_7);
|
||||||
|
BOOST_CHECK_EQUAL(reference_7.steps, result_7->steps);
|
||||||
|
BOOST_CHECK_EQUAL(reference_7.alternatives, result_7->alternatives);
|
||||||
|
BOOST_CHECK_EQUAL(reference_7.geometries, result_7->geometries);
|
||||||
|
BOOST_CHECK_EQUAL(reference_7.overview, result_7->overview);
|
||||||
|
BOOST_CHECK_EQUAL(reference_7.continue_straight, result_7->continue_straight);
|
||||||
|
CHECK_EQUAL_RANGE(reference_7.bearings, result_7->bearings);
|
||||||
|
CHECK_EQUAL_RANGE(reference_7.radiuses, result_7->radiuses);
|
||||||
|
CHECK_EQUAL_RANGE(reference_7.coordinates, result_7->coordinates);
|
||||||
|
|
||||||
|
auto result_8 = parseParameters<RouteParameters>("1,2;3,4?radiuses=;");
|
||||||
|
RouteParameters reference_8{};
|
||||||
|
reference_8.coordinates = coords_1;
|
||||||
|
reference_8.radiuses = {boost::none, boost::none};
|
||||||
|
BOOST_CHECK(result_8);
|
||||||
|
CHECK_EQUAL_RANGE(reference_8.radiuses, result_8->radiuses);
|
||||||
|
|
||||||
|
auto result_9 = parseParameters<RouteParameters>("1,2?radiuses=");
|
||||||
|
RouteParameters reference_9{};
|
||||||
|
reference_9.coordinates = coords_1;
|
||||||
|
reference_9.radiuses = {boost::none};
|
||||||
|
BOOST_CHECK(result_9);
|
||||||
|
CHECK_EQUAL_RANGE(reference_9.radiuses, result_9->radiuses);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(valid_table_urls)
|
BOOST_AUTO_TEST_CASE(valid_table_urls)
|
||||||
@@ -252,9 +229,9 @@ BOOST_AUTO_TEST_CASE(valid_table_urls)
|
|||||||
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)},
|
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)},
|
||||||
{util::FloatLongitude(3), util::FloatLatitude(4)}};
|
{util::FloatLongitude(3), util::FloatLatitude(4)}};
|
||||||
|
|
||||||
engine::api::TableParameters reference_1{};
|
TableParameters reference_1{};
|
||||||
reference_1.coordinates = coords_1;
|
reference_1.coordinates = coords_1;
|
||||||
auto result_1 = api::parseParameters<engine::api::TableParameters>("1,2;3,4");
|
auto result_1 = parseParameters<TableParameters>("1,2;3,4");
|
||||||
BOOST_CHECK(result_1);
|
BOOST_CHECK(result_1);
|
||||||
CHECK_EQUAL_RANGE(reference_1.sources, result_1->sources);
|
CHECK_EQUAL_RANGE(reference_1.sources, result_1->sources);
|
||||||
CHECK_EQUAL_RANGE(reference_1.destinations, result_1->destinations);
|
CHECK_EQUAL_RANGE(reference_1.destinations, result_1->destinations);
|
||||||
@@ -264,16 +241,23 @@ BOOST_AUTO_TEST_CASE(valid_table_urls)
|
|||||||
|
|
||||||
std::vector<std::size_t> sources_2 = {1, 2, 3};
|
std::vector<std::size_t> sources_2 = {1, 2, 3};
|
||||||
std::vector<std::size_t> destinations_2 = {4, 5};
|
std::vector<std::size_t> destinations_2 = {4, 5};
|
||||||
engine::api::TableParameters reference_2{sources_2, destinations_2};
|
TableParameters reference_2{sources_2, destinations_2};
|
||||||
reference_2.coordinates = coords_1;
|
reference_2.coordinates = coords_1;
|
||||||
auto result_2 = api::parseParameters<engine::api::TableParameters>(
|
auto result_2 = parseParameters<TableParameters>("1,2;3,4?sources=1;2;3&destinations=4;5");
|
||||||
"1,2;3,4?sources=1;2;3&destinations=4;5");
|
|
||||||
BOOST_CHECK(result_2);
|
BOOST_CHECK(result_2);
|
||||||
CHECK_EQUAL_RANGE(reference_2.sources, result_2->sources);
|
CHECK_EQUAL_RANGE(reference_2.sources, result_2->sources);
|
||||||
CHECK_EQUAL_RANGE(reference_2.destinations, result_2->destinations);
|
CHECK_EQUAL_RANGE(reference_2.destinations, result_2->destinations);
|
||||||
CHECK_EQUAL_RANGE(reference_2.bearings, result_2->bearings);
|
CHECK_EQUAL_RANGE(reference_2.bearings, result_2->bearings);
|
||||||
CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
|
CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
|
||||||
CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
|
CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
|
||||||
|
|
||||||
|
auto result_3 = parseParameters<TableParameters>("1,2;3,4?sources=all&destinations=all");
|
||||||
|
BOOST_CHECK(result_3);
|
||||||
|
CHECK_EQUAL_RANGE(reference_1.sources, result_3->sources);
|
||||||
|
CHECK_EQUAL_RANGE(reference_1.destinations, result_3->destinations);
|
||||||
|
CHECK_EQUAL_RANGE(reference_1.bearings, result_3->bearings);
|
||||||
|
CHECK_EQUAL_RANGE(reference_1.radiuses, result_3->radiuses);
|
||||||
|
CHECK_EQUAL_RANGE(reference_1.coordinates, result_3->coordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(valid_match_urls)
|
BOOST_AUTO_TEST_CASE(valid_match_urls)
|
||||||
@@ -281,9 +265,9 @@ BOOST_AUTO_TEST_CASE(valid_match_urls)
|
|||||||
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)},
|
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)},
|
||||||
{util::FloatLongitude(3), util::FloatLatitude(4)}};
|
{util::FloatLongitude(3), util::FloatLatitude(4)}};
|
||||||
|
|
||||||
engine::api::MatchParameters reference_1{};
|
MatchParameters reference_1{};
|
||||||
reference_1.coordinates = coords_1;
|
reference_1.coordinates = coords_1;
|
||||||
auto result_1 = api::parseParameters<engine::api::MatchParameters>("1,2;3,4");
|
auto result_1 = parseParameters<MatchParameters>("1,2;3,4");
|
||||||
BOOST_CHECK(result_1);
|
BOOST_CHECK(result_1);
|
||||||
CHECK_EQUAL_RANGE(reference_1.timestamps, result_1->timestamps);
|
CHECK_EQUAL_RANGE(reference_1.timestamps, result_1->timestamps);
|
||||||
CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
|
CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
|
||||||
@@ -295,9 +279,9 @@ BOOST_AUTO_TEST_CASE(valid_nearest_urls)
|
|||||||
{
|
{
|
||||||
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)}};
|
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)}};
|
||||||
|
|
||||||
engine::api::NearestParameters reference_1{};
|
NearestParameters reference_1{};
|
||||||
reference_1.coordinates = coords_1;
|
reference_1.coordinates = coords_1;
|
||||||
auto result_1 = api::parseParameters<engine::api::NearestParameters>("1,2");
|
auto result_1 = parseParameters<NearestParameters>("1,2");
|
||||||
BOOST_CHECK(result_1);
|
BOOST_CHECK(result_1);
|
||||||
BOOST_CHECK_EQUAL(reference_1.number_of_results, result_1->number_of_results);
|
BOOST_CHECK_EQUAL(reference_1.number_of_results, result_1->number_of_results);
|
||||||
CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
|
CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
|
||||||
@@ -307,8 +291,8 @@ BOOST_AUTO_TEST_CASE(valid_nearest_urls)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(valid_tile_urls)
|
BOOST_AUTO_TEST_CASE(valid_tile_urls)
|
||||||
{
|
{
|
||||||
engine::api::TileParameters reference_1{1, 2, 3};
|
TileParameters reference_1{1, 2, 3};
|
||||||
auto result_1 = api::parseParameters<engine::api::TileParameters>("tile(1,2,3).mvt");
|
auto result_1 = parseParameters<TileParameters>("tile(1,2,3).mvt");
|
||||||
BOOST_CHECK(result_1);
|
BOOST_CHECK(result_1);
|
||||||
BOOST_CHECK_EQUAL(reference_1.x, result_1->x);
|
BOOST_CHECK_EQUAL(reference_1.x, result_1->x);
|
||||||
BOOST_CHECK_EQUAL(reference_1.y, result_1->y);
|
BOOST_CHECK_EQUAL(reference_1.y, result_1->y);
|
||||||
@@ -320,9 +304,9 @@ BOOST_AUTO_TEST_CASE(valid_trip_urls)
|
|||||||
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)},
|
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)},
|
||||||
{util::FloatLongitude(3), util::FloatLatitude(4)}};
|
{util::FloatLongitude(3), util::FloatLatitude(4)}};
|
||||||
|
|
||||||
engine::api::TripParameters reference_1{};
|
TripParameters reference_1{};
|
||||||
reference_1.coordinates = coords_1;
|
reference_1.coordinates = coords_1;
|
||||||
auto result_1 = api::parseParameters<engine::api::TripParameters>("1,2;3,4");
|
auto result_1 = parseParameters<TripParameters>("1,2;3,4");
|
||||||
BOOST_CHECK(result_1);
|
BOOST_CHECK(result_1);
|
||||||
CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
|
CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
|
||||||
CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
|
CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
|
||||||
|
|||||||
@@ -230,10 +230,10 @@ void sampling_verify_rtree(RTreeT &rtree,
|
|||||||
auto lsnn_u = result_lsnn.back().u;
|
auto lsnn_u = result_lsnn.back().u;
|
||||||
auto lsnn_v = result_lsnn.back().v;
|
auto lsnn_v = result_lsnn.back().v;
|
||||||
|
|
||||||
const double rtree_dist = coordinate_calculation::perpendicularDistance(
|
const double rtree_dist =
|
||||||
coords[rtree_u], coords[rtree_v], q);
|
coordinate_calculation::perpendicularDistance(coords[rtree_u], coords[rtree_v], q);
|
||||||
const double lsnn_dist = coordinate_calculation::perpendicularDistance(
|
const double lsnn_dist =
|
||||||
coords[lsnn_u], coords[lsnn_v], q);
|
coordinate_calculation::perpendicularDistance(coords[lsnn_u], coords[lsnn_v], q);
|
||||||
|
|
||||||
BOOST_CHECK_CLOSE(rtree_dist, lsnn_dist, 0.0001);
|
BOOST_CHECK_CLOSE(rtree_dist, lsnn_dist, 0.0001);
|
||||||
}
|
}
|
||||||
@@ -335,6 +335,34 @@ BOOST_AUTO_TEST_CASE(regression_test)
|
|||||||
BOOST_CHECK_EQUAL(result_ls.front().v, result_rtree.front().v);
|
BOOST_CHECK_EQUAL(result_ls.front().v, result_rtree.front().v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bug: If you querry a point with a narrow radius, no result should be returned
|
||||||
|
BOOST_AUTO_TEST_CASE(radius_regression_test)
|
||||||
|
{
|
||||||
|
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
||||||
|
using Edge = std::pair<unsigned, unsigned>;
|
||||||
|
GraphFixture fixture(
|
||||||
|
{
|
||||||
|
Coord(FloatLongitude(0.0), FloatLatitude(0.0)),
|
||||||
|
Coord(FloatLongitude(10.0), FloatLatitude(10.0)),
|
||||||
|
},
|
||||||
|
{Edge(0, 1), Edge(1, 0)});
|
||||||
|
|
||||||
|
std::string leaves_path;
|
||||||
|
std::string nodes_path;
|
||||||
|
build_rtree<GraphFixture, MiniStaticRTree>("test_angle", &fixture, leaves_path, nodes_path);
|
||||||
|
MiniStaticRTree rtree(nodes_path, leaves_path, fixture.coords);
|
||||||
|
MockDataFacade mockfacade;
|
||||||
|
engine::GeospatialQuery<MiniStaticRTree, MockDataFacade> query(rtree, fixture.coords,
|
||||||
|
mockfacade);
|
||||||
|
|
||||||
|
Coordinate input(FloatLongitude(5.2), FloatLatitude(5.0));
|
||||||
|
|
||||||
|
{
|
||||||
|
auto results = query.NearestPhantomNodesInRange(input, 0.01);
|
||||||
|
BOOST_CHECK_EQUAL(results.size(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(bearing_tests)
|
BOOST_AUTO_TEST_CASE(bearing_tests)
|
||||||
{
|
{
|
||||||
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
||||||
|
|||||||
Reference in New Issue
Block a user