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.|

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);