Integration #3149 and #3815

This commit is contained in:
Lev Dragunov 2017-03-14 14:35:09 +03:00 committed by Patrick Niklaus
parent bd9eb76a2d
commit e9c0987e8a
4 changed files with 57 additions and 13 deletions

View File

@ -274,7 +274,7 @@ In addition to the [general options](#general-options) the following options are
|Option |Values |Description | |Option |Values |Description |
|------------|------------------------------------------------|------------------------------------------------------------------------------------------| |------------|------------------------------------------------|------------------------------------------------------------------------------------------|
|steps |`true`, `false` (default) |Return route steps for each route | |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) | |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. | |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.| |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 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. 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 ```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}' 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** **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. 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. 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 | | roundtrip | source | destination | supported |
| :-- | :-- | :-- | :-- | | :-- | :-- | :-- | :-- |
| true | first | last | **yes** | | true | first | last | **yes** |
| true | first | any | **yes** | | true | first | any | **yes** |
| true | any | last | **yes** | | true | any | last | **yes** |
| true | any | any | **yes** | | true | any | any | **yes** |

View File

@ -50,24 +50,31 @@ namespace api
*/ */
struct MatchParameters : public RouteParameters struct MatchParameters : public RouteParameters
{ {
enum class PreprocessingType
{
False,
Simple,
Full
};
MatchParameters() MatchParameters()
: RouteParameters(false, : RouteParameters(false,
false, false,
false, false,
RouteParameters::GeometriesType::Polyline, RouteParameters::GeometriesType::Polyline,
RouteParameters::OverviewType::Simplified, RouteParameters::OverviewType::Simplified,
{}), use_tidying(true) {}), track_preprocessing(PreprocessingType::Simple)
{ {
} }
template <typename... Args> template <typename... Args>
MatchParameters(std::vector<unsigned> timestamps_, bool use_tidying_, Args... args_) MatchParameters(std::vector<unsigned> timestamps_, PreprocessingType track_preprocessing_, Args... args_)
: RouteParameters{std::forward<Args>(args_)...}, timestamps{std::move(timestamps_)}, use_tidying(use_tidying_) : RouteParameters{std::forward<Args>(args_)...}, timestamps{std::move(timestamps_)}, track_preprocessing(track_preprocessing_)
{ {
} }
std::vector<unsigned> timestamps; std::vector<unsigned> timestamps;
bool use_tidying; PreprocessingType track_preprocessing;
bool IsValid() const bool IsValid() const
{ {

View File

@ -33,15 +33,22 @@ struct MatchParametersGrammar final : public RouteParametersGrammar<Iterator, Si
(qi::uint_ % (qi::uint_ %
';')[ph::bind(&engine::api::MatchParameters::timestamps, qi::_r1) = qi::_1]; ';')[ph::bind(&engine::api::MatchParameters::timestamps, qi::_r1) = qi::_1];
preprocessing_type.add("simple", engine::api::MatchParameters::PreprocessingType::Simple)(
"full", engine::api::MatchParameters::PreprocessingType::Full)(
"false", engine::api::MatchParameters::PreprocessingType::False);
root_rule = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") > root_rule = BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") >
-('?' > (timestamps_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1) | ( -('?' > (timestamps_rule(qi::_r1) | BaseGrammar::base_rule(qi::_r1) | (
qi::lit("tidying=") > qi::bool_[ph::bind(&engine::api::MatchParameters::use_tidying, qi::lit("preprocess=") > preprocessing_type[ph::bind(&engine::api::MatchParameters::track_preprocessing, qi::_r1) = qi::_1])
qi::_r1) = qi::_1])) % '&'); ) % '&');
} }
private: private:
qi::rule<Iterator, Signature> root_rule; qi::rule<Iterator, Signature> root_rule;
qi::rule<Iterator, Signature> timestamps_rule; qi::rule<Iterator, Signature> timestamps_rule;
qi::symbols<char, engine::api::MatchParameters::PreprocessingType> preprocessing_type;
}; };
} }
} }

View File

@ -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. // Transparently tidy match parameters, do map matching on tidied parameters.
// Then use the mapping to restore the original <-> tidied relationship. // Then use the mapping to restore the original <-> tidied relationship.
auto tidied = api::tidy::tidy(parameters); auto tidied = api::tidy::tidy(parameters);
// TODO is search radiuses still actual
auto candidates_lists = GetPhantomNodesInRange(facade, tidied.parameters, search_radiuses); auto candidates_lists = GetPhantomNodesInRange(facade, tidied.parameters, search_radiuses);
filterCandidates(tidied.parameters.coordinates, candidates_lists); filterCandidates(tidied.parameters.coordinates, candidates_lists);
@ -193,12 +197,38 @@ Status MatchPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData
} }
// call the actual map matching // call the actual map matching
SubMatchingList sub_matchings = algorithms.MapMatching( sub_matchings = algorithms.MapMatching(
candidates_lists, candidates_lists,
tidied.parameters.coordinates, tidied.parameters.coordinates,
tidied.parameters.timestamps, tidied.parameters.timestamps,
tidied.parameters.radiuses, 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<PhantomNodeWithDistance> &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) 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); 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}; api::MatchAPI match_api{facade, parameters};
match_api.MakeResponse(sub_matchings, sub_routes, json_result); match_api.MakeResponse(sub_matchings, sub_routes, json_result);