Return an array with meta-data for each coordinate.

Currently supports duration and distance for each coordinate.

This is particularly useful in map-matching, comparing how
a trip progresses compared to a real GPS trace that is
map-matched.
This commit is contained in:
Daniel Patterson
2016-05-08 22:58:13 -07:00
committed by Patrick Niklaus
parent 0f2bb5dde5
commit fa525ad610
13 changed files with 121 additions and 10 deletions
+1
View File
@@ -52,6 +52,7 @@ struct MatchParameters : public RouteParameters
{
MatchParameters()
: RouteParameters(false,
false,
false,
RouteParameters::GeometriesType::Polyline,
RouteParameters::OverviewType::Simplified,
+25 -1
View File
@@ -176,9 +176,33 @@ class RouteAPI : public BaseAPI
});
}
return json::makeRoute(route,
auto result = json::makeRoute(route,
json::makeRouteLegs(std::move(legs), std::move(step_geometries)),
std::move(json_overview));
if (parameters.annotation)
{
util::json::Array durations;
util::json::Array distances;
for (const auto idx : util::irange<std::size_t>(0UL, leg_geometries.size()))
{
auto &leg_geometry = leg_geometries[idx];
std::for_each(leg_geometry.annotations.begin(),
leg_geometry.annotations.end(),
[this, &durations, &distances](const guidance::LegGeometry::Annotation &step) {
durations.values.push_back(step.duration);
distances.values.push_back(step.distance);
});
}
util::json::Object details;
details.values["distance"] = std::move(distances);
details.values["duration"] = std::move(durations);
result.values["annotation"] = std::move(details);
}
return result;
}
const RouteParameters &parameters;
+4 -1
View File
@@ -72,17 +72,20 @@ struct RouteParameters : public BaseParameters
template <typename... Args>
RouteParameters(const bool steps_,
const bool alternatives_,
const bool annotation_,
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
geometries{geometries_}, overview{overview_}, continue_straight{continue_straight_}
annotation{annotation_}, geometries{geometries_}, overview{overview_},
continue_straight{continue_straight_}
{
}
bool steps = false;
bool alternatives = false;
bool annotation = false;
GeometriesType geometries = GeometriesType::Polyline;
OverviewType overview = OverviewType::Simplified;
boost::optional<bool> continue_straight;
+11 -5
View File
@@ -43,34 +43,40 @@ LegGeometry assembleGeometry(const DataFacadeT &facade,
geometry.segment_offsets.push_back(0);
geometry.locations.push_back(source_node.location);
auto cumulative_distance = 0.;
auto current_distance = 0.;
auto prev_coordinate = geometry.locations.front();
for (const auto &path_point : leg_data)
{
auto coordinate = facade.GetCoordinateOfNode(path_point.turn_via_node);
current_distance +=
current_distance =
util::coordinate_calculation::haversineDistance(prev_coordinate, coordinate);
cumulative_distance += current_distance;
// all changes to this check have to be matched with assemble_steps
if (path_point.turn_instruction.type != extractor::guidance::TurnType::NoTurn)
{
geometry.segment_distances.push_back(current_distance);
geometry.segment_distances.push_back(cumulative_distance);
geometry.segment_offsets.push_back(geometry.locations.size());
current_distance = 0.;
cumulative_distance = 0.;
}
prev_coordinate = coordinate;
geometry.annotations.emplace_back(LegGeometry::Annotation{current_distance, path_point.duration_until_turn / 10.});
geometry.locations.push_back(std::move(coordinate));
}
current_distance +=
current_distance =
util::coordinate_calculation::haversineDistance(prev_coordinate, target_node.location);
cumulative_distance += current_distance;
// segment leading to the target node
geometry.segment_distances.push_back(current_distance);
geometry.segment_distances.push_back(cumulative_distance);
geometry.annotations.emplace_back(LegGeometry::Annotation{current_distance, target_node.forward_weight / 10.});
geometry.segment_offsets.push_back(geometry.locations.size());
geometry.locations.push_back(target_node.location);
BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1);
BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size());
BOOST_ASSERT(geometry.annotations.size() == geometry.locations.size() - 1);
return geometry;
}
+7
View File
@@ -31,6 +31,13 @@ struct LegGeometry
// length of the segment in meters
std::vector<double> segment_distances;
// Per-coordinate metadata
struct Annotation {
double distance;
double duration;
};
std::vector<Annotation> annotations;
std::size_t FrontIndex(std::size_t segment_index) const
{
return segment_offsets[segment_index];
@@ -57,6 +57,7 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
base_rule =
BaseGrammar::base_rule(qi::_r1)
| (qi::lit("steps=") > qi::bool_[ph::bind(&engine::api::RouteParameters::steps, qi::_r1) = qi::_1])
| (qi::lit("annotate=") > qi::bool_[ph::bind(&engine::api::RouteParameters::annotation, qi::_r1) = qi::_1])
| (qi::lit("geometries=") > geometries_type[ph::bind(&engine::api::RouteParameters::geometries, qi::_r1) = qi::_1])
| (qi::lit("overview=") > overview_type[ph::bind(&engine::api::RouteParameters::overview, qi::_r1) = qi::_1])
;