From e9c0987e8a2fdd01291bba148b83264ceec0b91f Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Tue, 14 Mar 2017 14:35:09 +0300 Subject: [PATCH] Integration #3149 and #3815 --- docs/http.md | 8 ++--- include/engine/api/match_parameters.hpp | 15 +++++--- .../server/api/match_parameter_grammar.hpp | 11 ++++-- src/engine/plugins/match.cpp | 36 +++++++++++++++++-- 4 files changed, 57 insertions(+), 13 deletions(-) diff --git a/docs/http.md b/docs/http.md index fe7d81fb1..6ea272443 100644 --- a/docs/http.md +++ b/docs/http.md @@ -274,7 +274,7 @@ In addition to the [general options](#general-options) the following options are |Option |Values |Description | |------------|------------------------------------------------|------------------------------------------------------------------------------------------| |steps |`true`, `false` (default) |Return route steps for each route | -|tidying |`true` (default), `false` |Allows the input track modification to obtain better matching quality for noisy tracks. | +|preprocess |`full`, `simple` (default), `false` |Allows the input track modification to obtain better matching quality for noisy tracks. | |geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) | |annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. | |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.| @@ -315,7 +315,7 @@ All other properties might be undefined. 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 only returns an approximation. -Note that all input coordinates have to be connected for the trip service to work. +Note that all input coordinates have to be connected for the trip service to work. ```endpoint 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}' @@ -335,7 +335,7 @@ In addition to the [general options](#general-options) the following options are **Fixing Start and End Points** -It is possible to explicitely set the start or end coordinate of the trip. +It is possible to explicitely set the start or end coordinate of the trip. When source is set to `first`, the first coordinate is used as start coordinate of the trip in the output. When destination is set to `last`, the last coordinate will be used as destination of the trip in the returned output. If you specify `any`, any of the coordinates can be used as the first or last coordinate in the output. However, if `source=any&destination=any` the returned round-trip will still start at the first input coordinate by default. @@ -345,7 +345,7 @@ Right now, the following combinations are possible: | roundtrip | source | destination | supported | | :-- | :-- | :-- | :-- | -| true | first | last | **yes** | +| true | first | last | **yes** | | true | first | any | **yes** | | true | any | last | **yes** | | true | any | any | **yes** | diff --git a/include/engine/api/match_parameters.hpp b/include/engine/api/match_parameters.hpp index 06e556be0..f27fe7829 100644 --- a/include/engine/api/match_parameters.hpp +++ b/include/engine/api/match_parameters.hpp @@ -50,24 +50,31 @@ namespace api */ struct MatchParameters : public RouteParameters { + enum class PreprocessingType + { + False, + Simple, + Full + }; + MatchParameters() : RouteParameters(false, false, false, RouteParameters::GeometriesType::Polyline, RouteParameters::OverviewType::Simplified, - {}), use_tidying(true) + {}), track_preprocessing(PreprocessingType::Simple) { } template - MatchParameters(std::vector timestamps_, bool use_tidying_, Args... args_) - : RouteParameters{std::forward(args_)...}, timestamps{std::move(timestamps_)}, use_tidying(use_tidying_) + MatchParameters(std::vector timestamps_, PreprocessingType track_preprocessing_, Args... args_) + : RouteParameters{std::forward(args_)...}, timestamps{std::move(timestamps_)}, track_preprocessing(track_preprocessing_) { } std::vector timestamps; - bool use_tidying; + PreprocessingType track_preprocessing; bool IsValid() const { diff --git a/include/server/api/match_parameter_grammar.hpp b/include/server/api/match_parameter_grammar.hpp index 56db73c3d..672d8bddb 100644 --- a/include/server/api/match_parameter_grammar.hpp +++ b/include/server/api/match_parameter_grammar.hpp @@ -33,15 +33,22 @@ struct MatchParametersGrammar final : public RouteParametersGrammar -qi::lit(".json") > -('?' > (timestamps_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1) | ( - qi::lit("tidying=") > qi::bool_[ph::bind(&engine::api::MatchParameters::use_tidying, - qi::_r1) = qi::_1])) % '&'); + qi::lit("preprocess=") > preprocessing_type[ph::bind(&engine::api::MatchParameters::track_preprocessing, qi::_r1) = qi::_1]) + ) % '&'); } private: qi::rule root_rule; qi::rule timestamps_rule; + + qi::symbols preprocessing_type; }; } } diff --git a/src/engine/plugins/match.cpp b/src/engine/plugins/match.cpp index 97b83d559..264cfb67c 100644 --- a/src/engine/plugins/match.cpp +++ b/src/engine/plugins/match.cpp @@ -174,10 +174,14 @@ Status MatchPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData }); } + SubMatchingList sub_matchings; + if (parameters.track_preprocessing == api::MatchParameters::PreprocessingType::Full) + { // Transparently tidy match parameters, do map matching on tidied parameters. // Then use the mapping to restore the original <-> tidied relationship. auto tidied = api::tidy::tidy(parameters); + // TODO is search radiuses still actual auto candidates_lists = GetPhantomNodesInRange(facade, tidied.parameters, search_radiuses); filterCandidates(tidied.parameters.coordinates, candidates_lists); @@ -193,12 +197,38 @@ Status MatchPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData } // call the actual map matching - SubMatchingList sub_matchings = algorithms.MapMatching( + sub_matchings = algorithms.MapMatching( candidates_lists, tidied.parameters.coordinates, tidied.parameters.timestamps, tidied.parameters.radiuses, - parameters.use_tidying); + !(parameters.track_preprocessing == api::MatchParameters::PreprocessingType::False)); + } + else + { + + auto candidates_lists = GetPhantomNodesInRange(facade, parameters, search_radiuses); + + filterCandidates(parameters.coordinates, candidates_lists); + if (std::all_of(candidates_lists.begin(), + candidates_lists.end(), + [](const std::vector &candidates) { + return candidates.empty(); + })) + { + return Error("NoSegment", + std::string("Could not find a matching segment for any coordinate."), + json_result); + } + + // call the actual map matching + sub_matchings = algorithms.MapMatching( + candidates_lists, + parameters.coordinates, + parameters.timestamps, + parameters.radiuses, + !(parameters.track_preprocessing == api::MatchParameters::PreprocessingType::False)); + } if (sub_matchings.size() == 0) { @@ -229,7 +259,7 @@ Status MatchPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData BOOST_ASSERT(sub_routes[index].shortest_path_length != INVALID_EDGE_WEIGHT); } - // TODO: restore original coordinates + // TODO: restore original coordinates for tidyied parameters api::MatchAPI match_api{facade, parameters}; match_api.MakeResponse(sub_matchings, sub_routes, json_result);