[osrm] 04/22: Imported Upstream version 5.0.0+ds
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Fri Apr 29 22:44:13 UTC 2016
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository osrm.
commit f42bc40499a2591351d12e73ffd9a40844c188f5
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Fri Apr 29 23:13:17 2016 +0200
Imported Upstream version 5.0.0+ds
---
CHANGELOG.md | 46 +++
appveyor-build.bat | 13 +-
features/bicycle/bridge.feature | 26 +-
features/car/bridge.feature | 26 +-
features/guidance/end-of-road.feature | 19 +-
features/guidance/fork.feature | 71 ++++
features/guidance/turn.feature | 529 +++++++++++++++++++++++++
features/testbot/continue_straight.feature | 92 +++++
include/engine/api/json_factory.hpp | 22 +-
include/engine/api/route_api.hpp | 8 +-
include/engine/guidance/assemble_leg.hpp | 100 ++++-
include/engine/guidance/route_leg.hpp | 4 +
include/extractor/travel_mode.hpp | 1 -
include/server/api/table_parameter_grammar.hpp | 12 +-
include/util/static_rtree.hpp | 14 +-
include/util/vector_tile.hpp | 37 ++
profiles/bicycle.lua | 2 -
profiles/car.lua | 2 -
src/engine/api/json_factory.cpp | 4 +-
src/engine/plugins/tile.cpp | 66 +--
src/extractor/extractor.cpp | 5 +
src/extractor/scripting_environment.cpp | 1 -
unit_tests/library/coordinates.hpp | 7 +
unit_tests/library/match.cpp | 7 +-
unit_tests/library/route.cpp | 80 +++-
unit_tests/library/table.cpp | 131 +++++-
unit_tests/library/tile.cpp | 106 ++++-
unit_tests/library/trip.cpp | 132 +++++-
unit_tests/library/waypoint_check.hpp | 24 ++
unit_tests/server/parameters_io.hpp | 59 +++
unit_tests/server/parameters_parser.cpp | 236 +++++------
unit_tests/util/static_rtree.cpp | 36 +-
32 files changed, 1670 insertions(+), 248 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4430ff0..b324d15 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,49 @@
+# 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
- Profiles:
- `properties.allow_uturns_at_via` -> `properties.continue_straight_at_waypoint` (value is inverted!)
diff --git a/appveyor-build.bat b/appveyor-build.bat
index 5dbdfa2..3ef305d 100644
--- a/appveyor-build.bat
+++ b/appveyor-build.bat
@@ -116,14 +116,17 @@ IF %ERRORLEVEL% NEQ 0 GOTO ERROR
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 ...
-%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
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 NOT "%APPVEYOR_REPO_BRANCH%"=="develop" GOTO DONE
diff --git a/features/bicycle/bridge.feature b/features/bicycle/bridge.feature
index e691ae1..9e3873f 100644
--- a/features/bicycle/bridge.feature
+++ b/features/bicycle/bridge.feature
@@ -1,5 +1,5 @@
@routing @bicycle @bridge
-Feature: Bicycle - Handle movable bridge
+Feature: Bicycle - Handle cycling
Background:
Given the profile "bicycle"
@@ -18,14 +18,14 @@ Feature: Bicycle - Handle movable bridge
When I route I should get
| from | to | route | modes |
- | a | g | abc,cde,efg,efg | cycling,movable bridge,cycling,cycling |
- | b | f | abc,cde,efg,efg | cycling,movable bridge,cycling,cycling |
- | e | c | cde,cde | movable bridge,movable bridge |
- | e | b | cde,abc,abc | movable bridge,cycling,cycling |
- | e | a | cde,abc,abc | movable bridge,cycling,cycling |
- | c | e | cde,cde | movable bridge,movable bridge |
- | c | f | cde,efg,efg | movable bridge,cycling,cycling |
- | c | g | cde,efg,efg | movable bridge,cycling,cycling |
+ | a | g | abc,cde,efg,efg | cycling,cycling,cycling,cycling |
+ | b | f | abc,cde,efg,efg | cycling,cycling,cycling,cycling |
+ | e | c | cde,cde | cycling,cycling |
+ | e | b | cde,abc,abc | cycling,cycling,cycling |
+ | e | a | cde,abc,abc | cycling,cycling,cycling |
+ | c | e | cde,cde | cycling,cycling |
+ | c | f | cde,efg,efg | cycling,cycling,cycling |
+ | c | g | cde,efg,efg | cycling,cycling,cycling |
Scenario: Bicycle - Properly handle durations
Given the node map
@@ -41,7 +41,7 @@ Feature: Bicycle - Handle movable bridge
When I route I should get
| from | to | route | modes | speed |
- | a | g | abc,cde,efg,efg | cycling,movable bridge,cycling,cycling | 5 km/h |
- | b | f | abc,cde,efg,efg | cycling,movable bridge,cycling,cycling | 4 km/h |
- | c | e | cde,cde | movable bridge,movable bridge | 2 km/h |
- | e | c | cde,cde | movable bridge,movable bridge | 2 km/h |
+ | a | g | abc,cde,efg,efg | cycling,cycling,cycling,cycling | 5 km/h |
+ | b | f | abc,cde,efg,efg | cycling,cycling,cycling,cycling | 4 km/h |
+ | c | e | cde,cde | cycling,cycling | 2 km/h |
+ | e | c | cde,cde | cycling,cycling | 2 km/h |
diff --git a/features/car/bridge.feature b/features/car/bridge.feature
index 931f1d9..c1cb506 100644
--- a/features/car/bridge.feature
+++ b/features/car/bridge.feature
@@ -1,5 +1,5 @@
@routing @car @bridge
-Feature: Car - Handle movable bridge
+Feature: Car - Handle driving
Background:
Given the profile "car"
@@ -18,14 +18,14 @@ Feature: Car - Handle movable bridge
When I route I should get
| from | to | route | modes |
- | a | g | abc,cde,efg,efg | driving,movable bridge,driving,driving |
- | b | f | abc,cde,efg,efg | driving,movable bridge,driving,driving |
- | e | c | cde,cde | movable bridge,movable bridge |
- | e | b | cde,abc,abc | movable bridge,driving,driving |
- | e | a | cde,abc,abc | movable bridge,driving,driving |
- | c | e | cde,cde | movable bridge,movable bridge |
- | c | f | cde,efg,efg | movable bridge,driving,driving |
- | c | g | cde,efg,efg | movable bridge,driving,driving |
+ | a | g | abc,cde,efg,efg | driving,driving,driving,driving |
+ | b | f | abc,cde,efg,efg | driving,driving,driving,driving |
+ | e | c | cde,cde | driving,driving |
+ | e | b | cde,abc,abc | driving,driving,driving |
+ | e | a | cde,abc,abc | driving,driving,driving |
+ | c | e | cde,cde | driving,driving |
+ | c | f | cde,efg,efg | driving,driving,driving |
+ | c | g | cde,efg,efg | driving,driving,driving |
Scenario: Car - Properly handle durations
Given the node map
@@ -41,7 +41,7 @@ Feature: Car - Handle movable bridge
When I route I should get
| from | to | route | modes | speed |
- | a | g | abc,cde,efg,efg | driving,movable bridge,driving,driving | 7 km/h |
- | b | f | abc,cde,efg,efg | driving,movable bridge,driving,driving | 5 km/h |
- | c | e | cde,cde | movable bridge,movable bridge | 2 km/h |
- | e | c | cde,cde | movable bridge,movable bridge | 2 km/h |
+ | a | g | abc,cde,efg,efg | driving,driving,driving,driving | 7 km/h |
+ | b | f | abc,cde,efg,efg | driving,driving,driving,driving | 5 km/h |
+ | c | e | cde,cde | driving,driving | 2 km/h |
+ | e | c | cde,cde | driving,driving | 2 km/h |
diff --git a/features/guidance/end-of-road.feature b/features/guidance/end-of-road.feature
index 7f8231b..323f5df 100644
--- a/features/guidance/end-of-road.feature
+++ b/features/guidance/end-of-road.feature
@@ -21,7 +21,6 @@ Feature: End Of Road Instructions
| a,c | ab,cbd,cbd | depart,end of road left,arrive |
| a,d | ab,cbd,cbd | depart,end of road right,arrive |
-
Scenario: End of Road with three streets
Given the node map
| | | c |
@@ -104,3 +103,21 @@ Feature: End Of Road Instructions
| waypoints | route | turns |
| a,c | ab,cbd,cbd | depart,end of road left,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 |
+
diff --git a/features/guidance/fork.feature b/features/guidance/fork.feature
index 7b78a28..916799e 100644
--- a/features/guidance/fork.feature
+++ b/features/guidance/fork.feature
@@ -211,3 +211,74 @@ Feature: Fork Instructions
| a,c | ,, | depart,fork slight left,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 |
diff --git a/features/guidance/turn.feature b/features/guidance/turn.feature
index 3eb5fc3..20f4226 100644
--- a/features/guidance/turn.feature
+++ b/features/guidance/turn.feature
@@ -282,3 +282,532 @@ Feature: Simple Turns
| h,c | first,second,second | depart,turn left,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 |
+
diff --git a/features/testbot/continue_straight.feature b/features/testbot/continue_straight.feature
new file mode 100644
index 0000000..40fcbb4
--- /dev/null
+++ b/features/testbot/continue_straight.feature
@@ -0,0 +1,92 @@
+ at 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 |
+
diff --git a/include/engine/api/json_factory.hpp b/include/engine/api/json_factory.hpp
index 0b1e5f3..398fb68 100644
--- a/include/engine/api/json_factory.hpp
+++ b/include/engine/api/json_factory.hpp
@@ -48,13 +48,25 @@ template <typename ForwardIter> util::json::String makePolyline(ForwardIter begi
}
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;
- geojson.values["type"] = "LineString";
- util::json::Array coordinates;
- std::transform(begin, end, std::back_inserter(coordinates.values), &detail::coordinateToLonLat);
- geojson.values["coordinates"] = std::move(coordinates);
+ if (num_coordinates > 1)
+ {
+ geojson.values["type"] = "LineString";
+ 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;
}
diff --git a/include/engine/api/route_api.hpp b/include/engine/api/route_api.hpp
index f2b7a73..1907bee 100644
--- a/include/engine/api/route_api.hpp
+++ b/include/engine/api/route_api.hpp
@@ -69,7 +69,7 @@ class RouteAPI : public BaseAPI
}
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,
@@ -93,8 +93,8 @@ class RouteAPI : public BaseAPI
auto leg_geometry = guidance::assembleGeometry(
BaseAPI::facade, path_data, phantoms.source_phantom, phantoms.target_phantom);
- auto leg = guidance::assembleLeg(path_data, leg_geometry, phantoms.source_phantom,
- phantoms.target_phantom, reversed_target);
+ auto leg = guidance::assembleLeg(facade, path_data, leg_geometry, phantoms.source_phantom,
+ phantoms.target_phantom, reversed_target, parameters.steps);
if (parameters.steps)
{
@@ -169,7 +169,7 @@ class RouteAPI : public BaseAPI
leg_geometry.locations.begin() + step.geometry_end));
}
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_end));
});
diff --git a/include/engine/guidance/assemble_leg.hpp b/include/engine/guidance/assemble_leg.hpp
index b8d3dfe..6f8e6cb 100644
--- a/include/engine/guidance/assemble_leg.hpp
+++ b/include/engine/guidance/assemble_leg.hpp
@@ -1,6 +1,7 @@
#ifndef 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/route_leg.hpp"
#include "engine/guidance/route_step.hpp"
@@ -22,12 +23,86 @@ namespace engine
{
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;
+};
+
+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;
+ });
-inline RouteLeg assembleLeg(const std::vector<PathData> &route_data,
+ 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 PhantomNode &source_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 =
(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;
}
- 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
diff --git a/include/engine/guidance/route_leg.hpp b/include/engine/guidance/route_leg.hpp
index f3b8de1..5ecca4f 100644
--- a/include/engine/guidance/route_leg.hpp
+++ b/include/engine/guidance/route_leg.hpp
@@ -3,6 +3,9 @@
#include "engine/guidance/route_step.hpp"
+#include <boost/optional.hpp>
+
+#include <string>
#include <vector>
namespace osrm
@@ -16,6 +19,7 @@ struct RouteLeg
{
double duration;
double distance;
+ std::string summary;
std::vector<RouteStep> steps;
};
}
diff --git a/include/extractor/travel_mode.hpp b/include/extractor/travel_mode.hpp
index 7ec7bec..fa75c37 100644
--- a/include/extractor/travel_mode.hpp
+++ b/include/extractor/travel_mode.hpp
@@ -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_TRAIN = 5;
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
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_STEPS_UP = 8;
const constexpr osrm::extractor::TravelMode TRAVEL_MODE_STEPS_DOWN = 9;
diff --git a/include/server/api/table_parameter_grammar.hpp b/include/server/api/table_parameter_grammar.hpp
index 00fe703..b95b1b8 100644
--- a/include/server/api/table_parameter_grammar.hpp
+++ b/include/server/api/table_parameter_grammar.hpp
@@ -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
#ifdef WIN32
- destinations_rule = (qi::lit("destinations=") > (qi::ulong_long % ";")[set_destiantions]) |
- qi::lit("destinations=all");
- sources_rule =
- (qi::lit("sources=") > (qi::ulong_long % ";")[set_sources]) | qi::lit("sources=all");
+ destinations_rule = qi::lit("destinations=all") | (qi::lit("destinations=") > (qi::ulong_long % ";")[set_destiantions]);
+ sources_rule = qi::lit("sources=all") | (qi::lit("sources=") > (qi::ulong_long % ";")[set_sources]);
#else
- destinations_rule = (qi::lit("destinations=") > (qi::ulong_ % ";")[set_destiantions]) |
- qi::lit("destinations=all");
- sources_rule =
- (qi::lit("sources=") > (qi::ulong_ % ";")[set_sources]) | qi::lit("sources=all");
+ destinations_rule = qi::lit("destinations=all") | (qi::lit("destinations=") > (qi::ulong_ % ";")[set_destiantions]);
+ sources_rule = qi::lit("sources=all") | (qi::lit("sources=") > (qi::ulong_ % ";")[set_sources]);
#endif
table_rule = destinations_rule | sources_rule;
diff --git a/include/util/static_rtree.hpp b/include/util/static_rtree.hpp
index 32bd60b..2e5a988 100644
--- a/include/util/static_rtree.hpp
+++ b/include/util/static_rtree.hpp
@@ -441,6 +441,14 @@ class StaticRTree
// inspecting an actual road segment
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);
if (!use_segment.first && !use_segment.second)
{
@@ -451,12 +459,6 @@ class StaticRTree
// store phantom node in result vector
results.push_back(std::move(current_candidate.data));
-
- if (terminate(results.size(), current_candidate))
- {
- traversal_queue = std::priority_queue<QueryCandidate>{};
- break;
- }
}
}
diff --git a/include/util/vector_tile.hpp b/include/util/vector_tile.hpp
new file mode 100644
index 0000000..8d816da
--- /dev/null
+++ b/include/util/vector_tile.hpp
@@ -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
diff --git a/profiles/bicycle.lua b/profiles/bicycle.lua
index 84e02d8..644a254 100644
--- a/profiles/bicycle.lua
+++ b/profiles/bicycle.lua
@@ -234,8 +234,6 @@ function way_function (way, result)
if duration and durationIsValid(duration) then
result.duration = math.max( parseDuration(duration), 1 )
end
- result.forward_mode = mode.movable_bridge
- result.backward_mode = mode.movable_bridge
result.forward_speed = bridge_speed
result.backward_speed = bridge_speed
elseif route_speeds[route] then
diff --git a/profiles/car.lua b/profiles/car.lua
index 4033f31..ffe62ca 100644
--- a/profiles/car.lua
+++ b/profiles/car.lua
@@ -270,8 +270,6 @@ function way_function (way, result)
if duration and durationIsValid(duration) then
result.duration = max( parseDuration(duration), 1 )
end
- result.forward_mode = mode.movable_bridge
- result.backward_mode = mode.movable_bridge
result.forward_speed = bridge_speed
result.backward_speed = bridge_speed
end
diff --git a/src/engine/api/json_factory.cpp b/src/engine/api/json_factory.cpp
index b1f5da5..4d5ff9b 100644
--- a/src/engine/api/json_factory.cpp
+++ b/src/engine/api/json_factory.cpp
@@ -100,9 +100,6 @@ std::string modeToString(const extractor::TravelMode mode)
case TRAVEL_MODE_PUSHING_BIKE:
token = "pushing bike";
break;
- case TRAVEL_MODE_MOVABLE_BRIDGE:
- token = "movable bridge";
- break;
case TRAVEL_MODE_STEPS_UP:
token = "steps up";
break;
@@ -197,6 +194,7 @@ util::json::Object makeRouteLeg(guidance::RouteLeg leg, util::json::Array steps)
util::json::Object route_leg;
route_leg.values["distance"] = std::round(leg.distance * 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);
return route_leg;
}
diff --git a/src/engine/plugins/tile.cpp b/src/engine/plugins/tile.cpp
index 87586ea..6ce85c7 100644
--- a/src/engine/plugins/tile.cpp
+++ b/src/engine/plugins/tile.cpp
@@ -3,6 +3,7 @@
#include "util/coordinate_calculation.hpp"
#include "util/web_mercator.hpp"
+#include "util/vector_tile.hpp"
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
@@ -27,10 +28,6 @@ namespace plugins
{
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
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::box<point_t> box_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),
- point_t(detail::VECTOR_TILE_EXTENT + detail::VECTOR_TILE_BUFFER,
- detail::VECTOR_TILE_EXTENT + detail::VECTOR_TILE_BUFFER));
+const static box_t clip_box(point_t(-util::vector_tile::BUFFER, -util::vector_tile::BUFFER),
+ point_t(util::vector_tile::EXTENT + util::vector_tile::BUFFER,
+ util::vector_tile::EXTENT + util::vector_tile::BUFFER));
// from mapnik-vector-tile
// Encodes a linestring using protobuf zigzag encoding
@@ -136,10 +133,10 @@ FixedLine coordinatesToTileLine(const util::Coordinate start,
// convert lon/lat to tile coordinates
const auto px = std::round(
((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(
((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));
}
@@ -254,15 +251,15 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
protozero::pbf_writer tile_writer{pbf_buffer};
{
// 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
- 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
- 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
// 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
{
@@ -328,11 +325,13 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
// is_small
// boolean. We onl serve up speeds from 0-139, so all we do is save the
// 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"
- 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.
- 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
// 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
// an index into the "values" array. This means many features
// 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(
@@ -358,7 +358,8 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
{
// 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);
}
};
@@ -405,10 +406,10 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
// Field id 3 is the "keys" attribute
// We need two "key" fields, these are referred to with 0 and 1 (their array indexes)
// earlier
- layer_writer.add_string(3, "speed");
- layer_writer.add_string(3, "is_small");
- layer_writer.add_string(3, "datasource");
- layer_writer.add_string(3, "duration");
+ layer_writer.add_string(util::vector_tile::KEY_TAG, "speed");
+ layer_writer.add_string(util::vector_tile::KEY_TAG, "is_small");
+ layer_writer.add_string(util::vector_tile::KEY_TAG, "datasource");
+ layer_writer.add_string(util::vector_tile::KEY_TAG, "duration");
// 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,
@@ -416,35 +417,36 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
for (std::size_t i = 0; i < 128; i++)
{
// 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
- 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
- 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
- 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++)
{
// 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
- 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)
{
// 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
// Durations come out of OSRM in integer deciseconds, so we convert them
// 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.);
}
}
diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp
index 99f25ae..977a59c 100644
--- a/src/extractor/extractor.cpp
+++ b/src/extractor/extractor.cpp
@@ -555,6 +555,11 @@ void Extractor::BuildRTree(std::vector<EdgeBasedNode> node_based_edge_list,
in_iter++;
}
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);
TIMER_START(construction);
diff --git a/src/extractor/scripting_environment.cpp b/src/extractor/scripting_environment.cpp
index e3f9b6e..0840f7d 100644
--- a/src/extractor/scripting_environment.cpp
+++ b/src/extractor/scripting_environment.cpp
@@ -80,7 +80,6 @@ void ScriptingEnvironment::InitContext(ScriptingEnvironment::Context &context)
luabind::value("ferry", TRAVEL_MODE_FERRY),
luabind::value("train", TRAVEL_MODE_TRAIN),
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_down", TRAVEL_MODE_STEPS_DOWN),
luabind::value("river_up", TRAVEL_MODE_RIVER_UP),
diff --git a/unit_tests/library/coordinates.hpp b/unit_tests/library/coordinates.hpp
index 2ccc689..e2cb7e8 100644
--- a/unit_tests/library/coordinates.hpp
+++ b/unit_tests/library/coordinates.hpp
@@ -25,4 +25,11 @@ inline Locations get_locations_in_small_component()
{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
diff --git a/unit_tests/library/match.cpp b/unit_tests/library/match.cpp
index 37d36c2..b6b01ab 100644
--- a/unit_tests/library/match.cpp
+++ b/unit_tests/library/match.cpp
@@ -4,6 +4,7 @@
#include "args.hpp"
#include "fixture.hpp"
#include "coordinates.hpp"
+#include "waypoint_check.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>>())
{
+ BOOST_CHECK(waypoint_check(waypoint));
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 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;
diff --git a/unit_tests/library/route.cpp b/unit_tests/library/route.cpp
index f9aaae9..a090208 100644
--- a/unit_tests/library/route.cpp
+++ b/unit_tests/library/route.cpp
@@ -55,6 +55,7 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates_fixture)
json::Array{{json::Object{
{{"distance", 0.},
{"duration", 0.},
+ {"summary", ""},
{"steps", json::Array{{json::Object{{{"duration", 0.},
{"distance", 0.},
{"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;
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;
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;
BOOST_CHECK(longitude >= -180. && longitude <= 180.);
BOOST_CHECK(latitude >= -90. && latitude <= 90.);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_route_response_for_locations_in_big_component)
+{
+ const auto args = get_args();
+ auto osrm = getOSRM(args.at(0));
+
+ using namespace osrm;
- // TODO(daniel-j-h): we could do a Nearest request for each waypoint, verifying
- // that we did indeed not snap to the input locations inside the small component.
+ 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.);
}
}
diff --git a/unit_tests/library/table.cpp b/unit_tests/library/table.cpp
index bab5312..43b44a8 100644
--- a/unit_tests/library/table.cpp
+++ b/unit_tests/library/table.cpp
@@ -2,7 +2,9 @@
#include <boost/test/test_case_template.hpp>
#include "args.hpp"
+#include "coordinates.hpp"
#include "fixture.hpp"
+#include "waypoint_check.hpp"
#include "osrm/table_parameters.hpp"
@@ -14,7 +16,7 @@
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();
BOOST_REQUIRE_EQUAL(args.size(), 1);
@@ -23,15 +25,138 @@ BOOST_AUTO_TEST_CASE(test_table)
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);
+ params.destinations.push_back(2);
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 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()
diff --git a/unit_tests/library/tile.cpp b/unit_tests/library/tile.cpp
index 2ca674b..6cacc30 100644
--- a/unit_tests/library/tile.cpp
+++ b/unit_tests/library/tile.cpp
@@ -12,6 +12,10 @@
#include "osrm/status.hpp"
#include "osrm/osrm.hpp"
+#include "util/vector_tile.hpp"
+
+#include <protozero/pbf_reader.hpp>
+
BOOST_AUTO_TEST_SUITE(tile)
BOOST_AUTO_TEST_CASE(test_tile)
@@ -21,11 +25,111 @@ BOOST_AUTO_TEST_CASE(test_tile)
using namespace osrm;
- TileParameters params{0, 0, 1};
+ // This tile should contain most of monaco
+ TileParameters params{17059, 11948, 15};
std::string result;
const auto rc = osrm.Tile(params, result);
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()
diff --git a/unit_tests/library/trip.cpp b/unit_tests/library/trip.cpp
index 7bfd1c2..e630706 100644
--- a/unit_tests/library/trip.cpp
+++ b/unit_tests/library/trip.cpp
@@ -1,7 +1,8 @@
-#include <boost/test/unit_test.hpp>
#include <boost/test/test_case_template.hpp>
+#include <boost/test/unit_test.hpp>
#include "args.hpp"
+#include "coordinates.hpp"
#include "fixture.hpp"
#include "osrm/trip_parameters.hpp"
@@ -9,29 +10,144 @@
#include "osrm/coordinate.hpp"
#include "osrm/engine_config.hpp"
#include "osrm/json_container.hpp"
-#include "osrm/status.hpp"
#include "osrm/osrm.hpp"
+#include "osrm/status.hpp"
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();
+ auto osrm = getOSRM(args.at(0));
+
+ using namespace osrm;
+
+ const auto locations = get_locations_in_small_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_in_big_component)
{
const auto args = get_args();
- BOOST_REQUIRE_EQUAL(args.size(), 1);
+ auto osrm = getOSRM(args.at(0));
using namespace osrm;
- auto osrm = getOSRM(args[0]);
+ 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.);
- BOOST_CHECK(rc == Status::Ok || rc == Status::Error);
- */
+ 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()
diff --git a/unit_tests/library/waypoint_check.hpp b/unit_tests/library/waypoint_check.hpp
new file mode 100644
index 0000000..7bf1797
--- /dev/null
+++ b/unit_tests/library/waypoint_check.hpp
@@ -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
diff --git a/unit_tests/server/parameters_io.hpp b/unit_tests/server/parameters_io.hpp
new file mode 100644
index 0000000..dd2bd6c
--- /dev/null
+++ b/unit_tests/server/parameters_io.hpp
@@ -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
diff --git a/unit_tests/server/parameters_parser.cpp b/unit_tests/server/parameters_parser.cpp
index 1b5161f..ecf98f2 100644
--- a/unit_tests/server/parameters_parser.cpp
+++ b/unit_tests/server/parameters_parser.cpp
@@ -1,5 +1,7 @@
#include "server/api/parameters_parser.hpp"
+#include "parameters_io.hpp"
+
#include "engine/api/base_parameters.hpp"
#include "engine/api/match_parameters.hpp"
#include "engine/api/nearest_parameters.hpp"
@@ -8,56 +10,6 @@
#include "engine/api/tile_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/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
@@ -69,55 +21,54 @@ BOOST_AUTO_TEST_SUITE(api_parameters_parser)
using namespace osrm;
using namespace osrm::server;
+using namespace osrm::server::api;
+using namespace osrm::engine::api;
// returns distance to front
template <typename ParameterT> std::size_t testInvalidOptions(std::string options)
{
auto iter = options.begin();
- auto result = api::parseParameters<ParameterT>(iter, options.end());
+ auto result = parseParameters<ParameterT>(iter, options.end());
BOOST_CHECK(!result);
return std::distance(options.begin(), iter);
}
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(
- testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&bla=foo"), 22UL);
- BOOST_CHECK_EQUAL(
- testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&bearings=foo"),
- 32UL);
- BOOST_CHECK_EQUAL(
- testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&continue_straight=foo"),
- 41UL);
- BOOST_CHECK_EQUAL(
- testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&radiuses=foo"),
- 32UL);
- BOOST_CHECK_EQUAL(
- testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&hints=foo"), 29UL);
- 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);
+ 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(
- testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&alternatives=foo"),
- 36UL);
+ testInvalidOptions<RouteParameters>("1,2;3,4?overview=false&alternatives=foo"), 36UL);
+ BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(""), 0);
+ BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3.4.unsupported"), 7);
+ BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4.json?nooptions"), 13);
+ BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4..json?nooptions"), 14);
+ BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>("1,2;3,4.0.json?nooptions"), 15);
+ BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(std::string{"1,2;3,4"} + '\0' + ".json"), 7);
+ BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(std::string{"1,2;3,"} + '\0'), 6);
+
+ //BOOST_CHECK_EQUAL(testInvalidOptions<RouteParameters>(), );
}
BOOST_AUTO_TEST_CASE(invalid_table_urls)
{
- BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("1,2;3,4?sources=1&bla=foo"),
- 17UL);
+ BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?sources=1&bla=foo"), 17UL);
+ BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?destinations=1&bla=foo"), 22UL);
BOOST_CHECK_EQUAL(
- testInvalidOptions<engine::api::TableParameters>("1,2;3,4?destinations=1&bla=foo"), 22UL);
- BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>(
- "1,2;3,4?sources=1&destinations=1&bla=foo"),
- 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);
+ testInvalidOptions<TableParameters>("1,2;3,4?sources=1&destinations=1&bla=foo"), 32UL);
+ BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?sources=foo"), 16UL);
+ BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?destinations=foo"), 21UL);
}
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)},
{util::FloatLongitude(3), util::FloatLatitude(4)}};
- engine::api::RouteParameters reference_1{};
+ RouteParameters reference_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_EQUAL(reference_1.steps, result_1->steps);
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.coordinates, result_1->coordinates);
- engine::api::RouteParameters reference_2{};
+ RouteParameters reference_2{};
reference_2.alternatives = true;
reference_2.steps = true;
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");
BOOST_CHECK(result_2);
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.coordinates, result_2->coordinates);
- engine::api::RouteParameters reference_3{
- false, false, engine::api::RouteParameters::GeometriesType::GeoJSON,
- engine::api::RouteParameters::OverviewType::False, true};
+ RouteParameters reference_3{false, false, RouteParameters::GeometriesType::GeoJSON,
+ RouteParameters::OverviewType::False, true};
reference_3.coordinates = coords_1;
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_EQUAL(reference_3.steps, result_3->steps);
BOOST_CHECK_EQUAL(reference_3.alternatives, result_3->alternatives);
@@ -180,16 +131,16 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
engine::Hint::FromBase64("3gAAgP___"
"39KAAAAHgAAACEAAAAAAAAAGAAAAE0BAABOAQAAGwAAAIAzcQBkUJsC1zNxAHBQmw"
"IAAAEBl-Umfg==")};
- engine::api::RouteParameters reference_4{false,
- false,
- engine::api::RouteParameters::GeometriesType::Polyline,
- engine::api::RouteParameters::OverviewType::Simplified,
- boost::optional<bool>{},
- coords_1,
- hints_4,
- std::vector<boost::optional<double>>{},
- std::vector<boost::optional<engine::Bearing>>{}};
- auto result_4 = api::parseParameters<engine::api::RouteParameters>(
+ RouteParameters reference_4{false,
+ false,
+ RouteParameters::GeometriesType::Polyline,
+ RouteParameters::OverviewType::Simplified,
+ boost::optional<bool>{},
+ coords_1,
+ hints_4,
+ std::vector<boost::optional<double>>{},
+ std::vector<boost::optional<engine::Bearing>>{}};
+ auto result_4 = parseParameters<RouteParameters>(
"1,2;3,4?steps=false&hints="
"DAIAgP___38AAAAAAAAAAAIAAAAAAAAAEAAAAOgDAAD0AwAAGwAAAOUacQBQP5sCshpxAB0_mwIAAAEBl-Umfg==;"
"cgAAgP___39jAAAADgAAACIAAABeAAAAkQAAANoDAABOAgAAGwAAAFVGcQCiRJsCR0VxAOZFmwIFAAEBl-Umfg==;"
@@ -207,17 +158,16 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
std::vector<boost::optional<engine::Bearing>> bearings_4 = {
boost::none, engine::Bearing{200, 10}, engine::Bearing{100, 5},
};
- engine::api::RouteParameters reference_5{false,
- false,
- engine::api::RouteParameters::GeometriesType::Polyline,
- engine::api::RouteParameters::OverviewType::Simplified,
- boost::optional<bool>{},
- coords_1,
- std::vector<boost::optional<engine::Hint>>{},
- std::vector<boost::optional<double>>{},
- bearings_4};
- auto result_5 = api::parseParameters<engine::api::RouteParameters>(
- "1,2;3,4?steps=false&bearings=;200,10;100,5");
+ RouteParameters reference_5{false,
+ false,
+ RouteParameters::GeometriesType::Polyline,
+ RouteParameters::OverviewType::Simplified,
+ boost::optional<bool>{},
+ coords_1,
+ std::vector<boost::optional<engine::Hint>>{},
+ std::vector<boost::optional<double>>{},
+ bearings_4};
+ auto result_5 = parseParameters<RouteParameters>("1,2;3,4?steps=false&bearings=;200,10;100,5");
BOOST_CHECK(result_5);
BOOST_CHECK_EQUAL(reference_5.steps, result_5->steps);
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(4), util::FloatLatitude(5)}};
- engine::api::RouteParameters reference_6{};
+ RouteParameters reference_6{};
reference_6.coordinates = coords_2;
- auto result_6 =
- api::parseParameters<engine::api::RouteParameters>("polyline(_ibE?_seK_seK_seK_seK)");
+ auto result_6 = parseParameters<RouteParameters>("polyline(_ibE?_seK_seK_seK_seK)");
BOOST_CHECK(result_6);
BOOST_CHECK_EQUAL(reference_6.steps, result_6->steps);
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.radiuses, result_6->radiuses);
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)
@@ -252,9 +229,9 @@ BOOST_AUTO_TEST_CASE(valid_table_urls)
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)},
{util::FloatLongitude(3), util::FloatLatitude(4)}};
- engine::api::TableParameters reference_1{};
+ TableParameters reference_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);
CHECK_EQUAL_RANGE(reference_1.sources, result_1->sources);
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> 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;
- auto result_2 = api::parseParameters<engine::api::TableParameters>(
- "1,2;3,4?sources=1;2;3&destinations=4;5");
+ auto result_2 = parseParameters<TableParameters>("1,2;3,4?sources=1;2;3&destinations=4;5");
BOOST_CHECK(result_2);
CHECK_EQUAL_RANGE(reference_2.sources, result_2->sources);
CHECK_EQUAL_RANGE(reference_2.destinations, result_2->destinations);
CHECK_EQUAL_RANGE(reference_2.bearings, result_2->bearings);
CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
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)
@@ -281,9 +265,9 @@ BOOST_AUTO_TEST_CASE(valid_match_urls)
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)},
{util::FloatLongitude(3), util::FloatLatitude(4)}};
- engine::api::MatchParameters reference_1{};
+ MatchParameters reference_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);
CHECK_EQUAL_RANGE(reference_1.timestamps, result_1->timestamps);
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)}};
- engine::api::NearestParameters reference_1{};
+ NearestParameters reference_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_EQUAL(reference_1.number_of_results, result_1->number_of_results);
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)
{
- engine::api::TileParameters reference_1{1, 2, 3};
- auto result_1 = api::parseParameters<engine::api::TileParameters>("tile(1,2,3).mvt");
+ TileParameters reference_1{1, 2, 3};
+ auto result_1 = parseParameters<TileParameters>("tile(1,2,3).mvt");
BOOST_CHECK(result_1);
BOOST_CHECK_EQUAL(reference_1.x, result_1->x);
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)},
{util::FloatLongitude(3), util::FloatLatitude(4)}};
- engine::api::TripParameters reference_1{};
+ TripParameters reference_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);
CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
diff --git a/unit_tests/util/static_rtree.cpp b/unit_tests/util/static_rtree.cpp
index b3c2c9e..f8be130 100644
--- a/unit_tests/util/static_rtree.cpp
+++ b/unit_tests/util/static_rtree.cpp
@@ -230,10 +230,10 @@ void sampling_verify_rtree(RTreeT &rtree,
auto lsnn_u = result_lsnn.back().u;
auto lsnn_v = result_lsnn.back().v;
- const double rtree_dist = coordinate_calculation::perpendicularDistance(
- coords[rtree_u], coords[rtree_v], q);
- const double lsnn_dist = coordinate_calculation::perpendicularDistance(
- coords[lsnn_u], coords[lsnn_v], q);
+ const double rtree_dist =
+ coordinate_calculation::perpendicularDistance(coords[rtree_u], coords[rtree_v], q);
+ const double lsnn_dist =
+ coordinate_calculation::perpendicularDistance(coords[lsnn_u], coords[lsnn_v], q);
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);
}
+// 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)
{
using Coord = std::pair<FloatLongitude, FloatLatitude>;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/osrm.git
More information about the Pkg-grass-devel
mailing list