From 4698ebddc6d539b865f896ed4409f3d50c75c299 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 8 Feb 2017 19:12:05 +0100 Subject: [PATCH] [Trip] Change `source` and `destination` parameters for the trip plugin (#3674) * [Trip] Support more parameter combinations of fixed start/end when requesting roundtrips (#3675) --- CHANGELOG.md | 2 +- docs/http.md | 58 ++-- features/step_definitions/trip.js | 7 +- features/testbot/trip.feature | 108 +++++++- include/engine/trip/trip_brute_force.hpp | 1 + include/util/typedefs.hpp | 2 + src/engine/plugins/trip.cpp | 34 +-- unit_tests/library/trip.cpp | 321 ++++++++--------------- 8 files changed, 261 insertions(+), 272 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8f243246a1..cdb1a3b3103 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,7 @@ - Tools: - Added osrm-extract-conditionals tool for checking conditional values in OSM data - Trip Plugin - - Added a new feature that finds the optimal route given a list of waypoints, and a source and a destination. This does not return a roundtrip, but instead gives the optimal route given the fixed source and destination points. + - Added a new feature that finds the optimal route given a list of waypoints, a source and a destination. This does not return a roundtrip and instead returns a one way optimal route from the fixed source to the destination points. # 5.5.1 - Changes from 5.5.0 diff --git a/docs/http.md b/docs/http.md index 0d182c148f4..d8aacbd533e 100644 --- a/docs/http.md +++ b/docs/http.md @@ -312,49 +312,62 @@ All other properties might be undefined. ### Trip service The trip plugin solves the Traveling Salesman Problem using a greedy heuristic (farthest-insertion algorithm) for 10 or more waypoints and uses brute force for less than 10 waypoints. -The returned path does not have to be the fastest path, as TSP is NP-hard it is only an approximation. -Note that all input coordinates have to be connected. +The returned path does not have to be the fastest path. As TSP is NP-hard it only returns an approximation. +Note that all input coordinates have to be connected for the trip service to work. ```endpoint -GET /trip/v1/{profile}/{coordinates}?steps={true|false}&geometries={polyline|polyline6|geojson}&overview={simplified|full|false}&annotations={true|false}' +GET /trip/v1/{profile}/{coordinates}?roundtrip={true|false}&source{any|first}&destination{any|last}&steps={true|false}&geometries={polyline|polyline6|geojson}&overview={simplified|full|false}&annotations={true|false}' ``` +#### + In addition to the [general options](#general-options) the following options are supported for this service: |Option |Values |Description | |------------|------------------------------------------------|---------------------------------------------------------------------------| +|roundtrip |`true` (default), `false` |Return route is a roundtrip | +|source |`any` (default), `first` |Return route starts at `any` or `first` coordinate | +|destination |`any` (default), `last` |Return route ends at `any` or `last` coordinate | |steps |`true`, `false` (default) |Return route instructions for each trip | |annotations |`true`, `false` (default) |Returns additional metadata for each coordinate along the route geometry. | |geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) | |overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.| -A second feature of the trip plugin returns the route from a source to a destination while visiting all the other waypoints in the middle. -As with the roundtrip service, for fewer than 10 waypoints, the brute force algorithm is used, while for 10 or more waypoints the farthest insertion heuristic is used. +**Fixing Start and End Points** -|Option |Values |Description | -|------------|------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------| -|source |`{index of coordinate in coordinates provided}` |Will error if destination is not provided as well. Returns trip from source to destination routing through all other locations provided.| -|destination |`{index of coordinate in coordinates provided}` |Will error if source is not provided as well. Returns trip from source to destination routing through all other locations provided. | +It is possible to explicitely set the start or end point of the trip. Depending on whether `source` or `destination` is set to `any|first` or `any|last` the resulting output will start/end at the first/last coordinate. +However, if `source=any&destination=any` the returned round-trip will still start at the first coordinate by default. -```endpoint -GET /trip/v1/{profile}/{coordinates}?source={elem}&destination={elem}&steps={true|false}&geometries={polyline|polyline6|geojson}&overview={simplified|full|false}&annotations={true|false}' -``` +Currently, not all combinations of roundtrip, source and destination are supported. +Right now, the following combinations are possible: -**Example:** +| roundtrip | source | destination | supported | +| :-- | :-- | :-- | :-- | +| true | first | last | **yes** | +| true | first | any | **yes** | +| true | any | last | **yes** | +| true | any | any | **yes** | +| false | first | last | **yes** | +| false | first | any | no | +| false | any | last | no | +| false | any | any | no | -``` -source=0&destination=5 -``` +#### Example Requests -|Element |Values | -|------------|------------------------------| -|index |`0 <= integer < #coordinates` | +```curl +# Round trip in Berlin with three stops: +curl 'http://router.project-osrm.org/trip/v1/driving/13.388860,52.517037;13.397634,52.529407;13.428555,52.523219' +``` +```curl +# Round trip in Berlin with four stops, starting at the first stop, ending at the last: +curl 'http://router.project-osrm.org/trip/v1/driving/13.388860,52.517037;13.397634,52.529407;13.428555,52.523219;13.418555,52.523215?source=first&destination=last' +``` -**Response** +#### Response -- `code` if the request was successful `Ok` otherwise see the service dependent and general status codes. +- `code`: if the request was successful `Ok` otherwise see the service dependent and general status codes. - `waypoints`: Array of `Waypoint` objects representing all waypoints in input order. Each `Waypoint` object has the following additional properties: - `trips_index`: Index to `trips` of the sub-trip the point was matched to. - `waypoint_index`: Index of the point in the trip. @@ -364,7 +377,8 @@ In case of error the following `code`s are supported in addition to the general | Type | Description | |-------------------|---------------------| -| `NoTrips` | No trips found because input coordinates are not connected. | +| `NoTrips` | No trips found because input coordinates are not connected.| +| `NotImplemented` | This request is not supported | All other properties might be undefined. diff --git a/features/step_definitions/trip.js b/features/step_definitions/trip.js index df9afc02cc4..5a216acc64e 100644 --- a/features/step_definitions/trip.js +++ b/features/step_definitions/trip.js @@ -151,12 +151,15 @@ module.exports = function () { }); got = { waypoints: row.waypoints }; - if (row.source && row.destination) { + if (row.source) { params.source = got.source = row.source; + } + + if (row.destination) { params.destination = got.destination = row.destination; } - if (row.hasOwnProperty('roundtrip')) { + if (row.hasOwnProperty('roundtrip')) { //roundtrip is a boolean so row.roundtrip alone doesn't work as a check here params.roundtrip = got.roundtrip = row.roundtrip; } diff --git a/features/testbot/trip.feature b/features/testbot/trip.feature index 12ea55877c0..79255ba658a 100644 --- a/features/testbot/trip.feature +++ b/features/testbot/trip.feature @@ -5,7 +5,7 @@ Feature: Basic trip planning Given the profile "testbot" Given a grid size of 10 meters - Scenario: Testbot - Roundtrip with waypoints <10 + Scenario: Testbot - Trip: Roundtrip with waypoints <10 Given the node map """ a b @@ -24,7 +24,7 @@ Feature: Basic trip planning | a,b,c,d | abcda | 7.6 | | d,b,c,a | dbcad | 7.6 | - Scenario: Testbot - Roundtrip waypoints >10 + Scenario: Testbot - Trip: Roundtrip waypoints >10 Given the node map """ a b c d @@ -51,7 +51,63 @@ Feature: Basic trip planning | waypoints | trips | | a,b,c,d,e,f,g,h,i,j,k,l | alkjihgfedcba | - Scenario: Testbot - Unroutable roundtrip with waypoints <10 + Scenario: Testbot - Trip: Roundtrip FS waypoints >10 + Given the node map + """ + a b c d + l e + k f + j i h g + """ + + And the ways + | nodes | + | ab | + | bc | + | de | + | ef | + | fg | + | gh | + | hi | + | ij | + | jk | + | kl | + | la | + + When I plan a trip I should get + | waypoints | trips | source | + | a,b,c,d,e,f,g,h,i,j,k,l | alkjihgfedcba | first | + + Scenario: Testbot - Trip: Roundtrip FE waypoints >10 + Given the query options + | source | last | + Given the node map + """ + a b c d + l e + k f + j i h g + """ + + And the ways + | nodes | + | ab | + | bc | + | de | + | ef | + | fg | + | gh | + | hi | + | ij | + | jk | + | kl | + | la | + + When I plan a trip I should get + | waypoints | trips | + | a,b,c,d,e,f,g,h,i,j,k,l | lkjihgfedcbal | + + Scenario: Testbot - Trip: Unroutable roundtrip with waypoints <10 Given the node map """ a b @@ -69,7 +125,7 @@ Feature: Basic trip planning | a,b,c,d | NoTrips | No trip visiting all destinations possible. | - Scenario: Testbot - Unroutable roundtrip with waypoints >10 + Scenario: Testbot - Trip: Unroutable roundtrip with waypoints >10 Given the node map """ a b c d @@ -106,7 +162,7 @@ Feature: Basic trip planning | a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p | NoTrips | No trip visiting all destinations possible. | # Test TFSE - Scenario: Testbot - TFSE with errors + Scenario: Testbot - Trip: TFSE with errors Given the node map """ a b @@ -122,9 +178,8 @@ Feature: Basic trip planning When I plan a trip I should get | waypoints | source | destination | roundtrip | status | message | | a,b,c,d | first | last | false | NoTrips | No trip visiting all destinations possible. | - | a,b,c,d | first | last | true | NotImplemented | This request is not implemented | - Scenario: Testbot - TFSE with waypoints <10 + Scenario: Testbot - Trip: FSE with waypoints <10 Given the node map """ a b @@ -151,7 +206,7 @@ Feature: Basic trip planning | a,b,d,e,c | first | last | false | abedc | 8.200000000000001 | 81.6 | - Scenario: Testbot - TFSE with waypoints >10 + Scenario: Testbot - Trip: FSE with waypoints >10 Given the node map """ a b c d e f g h i j k @@ -174,9 +229,34 @@ Feature: Basic trip planning | waypoints | source | destination | roundtrip | trips | durations | distance | | a,b,c,d,e,h,i,j,k,g,f | first | last | false | abcdeghijkf | 15 | 149.8 | + Scenario: Testbot - Trip: FSE roundtrip with waypoints <10 + Given the node map + """ + a b + + c + e d + """ + + And the ways + | nodes | + | ab | + | ac | + | ad | + | ae | + | bc | + | bd | + | be | + | cd | + | ce | + | de | + + When I plan a trip I should get + | waypoints | source | destination | roundtrip | trips | + | a,b,d,e,c | first | last | true | abedca | + - # Test single node in each component #1850 - Scenario: Testbot - Trip planning with less than 10 nodes + Scenario: Testbot - Trip: midway points in isoldated roads should return no trips Given the node map """ a 1 b @@ -193,7 +273,7 @@ Feature: Basic trip planning | waypoints | trips | | 1,2 | | - Scenario: Testbot - Repeated Coordinate + Scenario: Testbot - Trip: Repeated Coordinate Given the node map """ a b @@ -208,7 +288,7 @@ Feature: Basic trip planning | a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a | | - Scenario: Testbot - Trip with geometry details of geojson + Scenario: Testbot - Trip: geometry details of geojson Given the query options | geometries | geojson | @@ -230,7 +310,7 @@ Feature: Basic trip planning | a,b,c,d | abcda | 7.6 | 1,1,1.00009,1,1,0.99991,1.00009,1,1,1,1.00009,0.99991,1,1 | | d,b,c,a | dbcad | 7.6 | 1.00009,0.99991,1,1,1.00009,1,1,0.99991,1.00009,1,1,1,1.00009,0.99991 | - Scenario: Testbot - Trip with geometry details of polyline + Scenario: Testbot - Trip: geometry details of polyline Given the query options | geometries | polyline | @@ -252,7 +332,7 @@ Feature: Basic trip planning | a,b,c,d | abcda | 7.6 | 1,1,1,1.00009,0.99991,1,1,1.00009,1,1,0.99991,1.00009,1,1 | | d,b,c,a | dbcad | 7.6 | 0.99991,1.00009,1,1,1,1.00009,0.99991,1,1,1.00009,1,1,0.99991,1.00009 | - Scenario: Testbot - Trip with geometry details of polyline6 + Scenario: Testbot - Trip: geometry details of polyline6 Given the query options | geometries | polyline6 | diff --git a/include/engine/trip/trip_brute_force.hpp b/include/engine/trip/trip_brute_force.hpp index 07891620214..ab29a24974a 100644 --- a/include/engine/trip/trip_brute_force.hpp +++ b/include/engine/trip/trip_brute_force.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/include/util/typedefs.hpp b/include/util/typedefs.hpp index 87c0f2d3ddb..a4b45db9105 100644 --- a/include/util/typedefs.hpp +++ b/include/util/typedefs.hpp @@ -60,6 +60,8 @@ using NameID = std::uint32_t; using EdgeWeight = std::int32_t; using TurnPenalty = std::int16_t; // turn penalty in 100ms units +static const std::size_t INVALID_SIZE_T = std::numeric_limits::max(); + using LaneID = std::uint8_t; static const LaneID INVALID_LANEID = std::numeric_limits::max(); using LaneDataID = std::uint16_t; diff --git a/src/engine/plugins/trip.cpp b/src/engine/plugins/trip.cpp index f1bd771e639..b1c88f0e374 100644 --- a/src/engine/plugins/trip.cpp +++ b/src/engine/plugins/trip.cpp @@ -41,7 +41,7 @@ bool IsSupportedParameterCombination(const bool fixed_start, { return true; } - else if (!fixed_start && !fixed_end && roundtrip) + else if (roundtrip) { return true; } @@ -51,6 +51,8 @@ bool IsSupportedParameterCombination(const bool fixed_start, } } +// given the node order in which to visit, compute the actual route (with geometry, travel time and +// so on) and return the result InternalRouteResult TripPlugin::ComputeRoute(const std::shared_ptr facade, const std::vector &snapped_phantoms, @@ -60,27 +62,22 @@ TripPlugin::ComputeRoute(const std::shared_ptr InternalRouteResult min_route; // given the final trip, compute total duration and return the route and location permutation PhantomNodes viapoint; - const auto start = std::begin(trip); - const auto end = std::end(trip); + // computes a roundtrip from the nodes in trip - for (auto it = start; it != end; ++it) + for (auto node = trip.begin(); node < trip.end() - 1; ++node) { - const auto from_node = *it; - - // if from_node is the last node and it is a fixed start and end trip, - // break out of this loop and return the route - if (!roundtrip && std::next(it) == end) - break; - - // if from_node is the last node, compute the route from the last to the first location - const auto to_node = std::next(it) != end ? *std::next(it) : *start; + const auto from_node = *node; + const auto to_node = *std::next(node); viapoint = PhantomNodes{snapped_phantoms[from_node], snapped_phantoms[to_node]}; min_route.segment_end_coordinates.emplace_back(viapoint); } + // return back to the first node if it is a round trip if (roundtrip) { + viapoint = PhantomNodes{snapped_phantoms[trip.back()], snapped_phantoms[trip.front()]}; + min_route.segment_end_coordinates.emplace_back(viapoint); // trip comes out to be something like 0 1 4 3 2 0 BOOST_ASSERT(min_route.segment_end_coordinates.size() == trip.size()); } @@ -91,7 +88,6 @@ TripPlugin::ComputeRoute(const std::shared_ptr } shortest_path(facade, min_route.segment_end_coordinates, {false}, min_route); - BOOST_ASSERT_MSG(min_route.shortest_path_length < INVALID_EDGE_WEIGHT, "unroutable route"); return min_route; } @@ -171,7 +167,7 @@ Status TripPlugin::HandleRequest(const std::shared_ptr().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); - - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); - params.source = TripParameters::SourceType::First; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; + BOOST_REQUIRE(rc == osrm::Status::Error); + auto code = result.values.at("code").get().value; BOOST_CHECK_EQUAL(code, "NotImplemented"); +} - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); - params.destination = TripParameters::DestinationType::Last; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); +void CheckOk(const osrm::OSRM &osrm, osrm::TripParameters ¶ms) +{ + osrm::json::Object result; + auto rc = osrm.Trip(params, result); + BOOST_REQUIRE(rc == osrm::Status::Ok); + auto code = result.values.at("code").get().value; + BOOST_CHECK_EQUAL(code, "Ok"); +} - // two parameters set - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); - params.source = TripParameters::SourceType::First; - params.destination = TripParameters::DestinationType::Any; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); +BOOST_AUTO_TEST_CASE(test_tfse_illegal_parameters) +{ + const auto args = get_args(); + auto osrm = getOSRM(args.at(0)); + using namespace osrm; - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); - params.source = TripParameters::SourceType::Any; - params.destination = TripParameters::DestinationType::Last; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); + const auto locations = get_locations_in_big_component(); + auto params = osrm::TripParameters(); - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); - params.source = TripParameters::SourceType::First; - params.destination = TripParameters::DestinationType::Last; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); + // one parameter set + ResetParams(locations, params); + params.roundtrip = false; + CheckNotImplemented(osrm, params); - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); + // two parameter set + ResetParams(locations, params); params.source = TripParameters::SourceType::Any; params.roundtrip = false; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); + CheckNotImplemented(osrm, params); - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); + ResetParams(locations, params); params.source = TripParameters::SourceType::First; params.roundtrip = false; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); + CheckNotImplemented(osrm, params); - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); - params.source = TripParameters::SourceType::First; - params.roundtrip = true; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); - - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); + ResetParams(locations, params); params.destination = TripParameters::DestinationType::Any; params.roundtrip = false; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); + CheckNotImplemented(osrm, params); - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); + ResetParams(locations, params); params.destination = TripParameters::DestinationType::Last; params.roundtrip = false; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); - - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); - params.destination = TripParameters::DestinationType::Last; - params.roundtrip = true; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); + CheckNotImplemented(osrm, params); // three parameters set params.source = TripParameters::SourceType::Any; params.destination = TripParameters::DestinationType::Any; params.roundtrip = false; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); + CheckNotImplemented(osrm, params); params.source = TripParameters::SourceType::Any; params.destination = TripParameters::DestinationType::Last; params.roundtrip = false; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); - - params.source = TripParameters::SourceType::Any; - params.destination = TripParameters::DestinationType::Last; - params.roundtrip = true; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); + CheckNotImplemented(osrm, params); params.source = TripParameters::SourceType::First; params.destination = TripParameters::DestinationType::Any; params.roundtrip = false; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); - - params.source = TripParameters::SourceType::First; - params.destination = TripParameters::DestinationType::Any; - params.roundtrip = true; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); - - params.source = TripParameters::SourceType::First; - params.destination = TripParameters::DestinationType::Last; - params.roundtrip = true; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Error); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "NotImplemented"); + CheckNotImplemented(osrm, params); } BOOST_AUTO_TEST_CASE(test_tfse_legal_parameters) @@ -448,95 +334,96 @@ BOOST_AUTO_TEST_CASE(test_tfse_legal_parameters) TripParameters params; // no parameter set - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); - auto rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Ok); - auto code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "Ok"); + ResetParams(locations, params); + CheckOk(osrm, params); // one parameter set - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); + ResetParams(locations, params); params.roundtrip = true; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Ok); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "Ok"); + CheckOk(osrm, params); - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); + ResetParams(locations, params); + params.source = TripParameters::SourceType::First; + CheckOk(osrm, params); + + ResetParams(locations, params); params.source = TripParameters::SourceType::Any; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Ok); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "Ok"); + CheckOk(osrm, params); - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); + ResetParams(locations, params); params.destination = TripParameters::DestinationType::Any; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Ok); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "Ok"); + CheckOk(osrm, params); + + ResetParams(locations, params); + params.destination = TripParameters::DestinationType::Last; + CheckOk(osrm, params); // two parameter set - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); + ResetParams(locations, params); + params.destination = TripParameters::DestinationType::Last; + params.roundtrip = true; + CheckOk(osrm, params); + + ResetParams(locations, params); + params.source = TripParameters::SourceType::First; + params.roundtrip = true; + CheckOk(osrm, params); + + ResetParams(locations, params); + params.source = TripParameters::SourceType::First; + params.destination = TripParameters::DestinationType::Any; + CheckOk(osrm, params); + + ResetParams(locations, params); + params.source = TripParameters::SourceType::Any; + params.destination = TripParameters::DestinationType::Last; + CheckOk(osrm, params); + + ResetParams(locations, params); + params.source = TripParameters::SourceType::First; + params.destination = TripParameters::DestinationType::Last; + CheckOk(osrm, params); + + ResetParams(locations, params); params.source = TripParameters::SourceType::Any; params.roundtrip = true; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Ok); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "Ok"); + CheckOk(osrm, params); - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); + ResetParams(locations, params); params.destination = TripParameters::DestinationType::Any; params.roundtrip = true; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Ok); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "Ok"); + CheckOk(osrm, params); - params = TripParameters(); - params.coordinates.push_back(locations.at(0)); - params.coordinates.push_back(locations.at(1)); - params.coordinates.push_back(locations.at(2)); + ResetParams(locations, params); params.source = TripParameters::SourceType::Any; params.destination = TripParameters::DestinationType::Any; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Ok); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "Ok"); + CheckOk(osrm, params); // three parameter set params.source = TripParameters::SourceType::Any; params.destination = TripParameters::DestinationType::Any; params.roundtrip = true; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Ok); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "Ok"); + CheckOk(osrm, params); params.source = TripParameters::SourceType::First; params.destination = TripParameters::DestinationType::Last; params.roundtrip = false; - rc = osrm.Trip(params, result); - BOOST_REQUIRE(rc == Status::Ok); - code = result.values.at("code").get().value; - BOOST_CHECK_EQUAL(code, "Ok"); + CheckOk(osrm, params); + + params.source = TripParameters::SourceType::Any; + params.destination = TripParameters::DestinationType::Last; + params.roundtrip = true; + CheckOk(osrm, params); + + params.source = TripParameters::SourceType::First; + params.destination = TripParameters::DestinationType::Any; + params.roundtrip = true; + CheckOk(osrm, params); + + params.source = TripParameters::SourceType::First; + params.destination = TripParameters::DestinationType::Last; + params.roundtrip = true; + CheckOk(osrm, params); } BOOST_AUTO_TEST_SUITE_END()