2016-01-28 10:28:44 -05:00
|
|
|
#ifndef ENGINE_API_ROUTE_HPP
|
|
|
|
#define ENGINE_API_ROUTE_HPP
|
|
|
|
|
2018-02-09 13:32:09 -05:00
|
|
|
#include "extractor/maneuver_override.hpp"
|
2016-01-28 10:28:44 -05:00
|
|
|
#include "engine/api/base_api.hpp"
|
|
|
|
#include "engine/api/json_factory.hpp"
|
2016-04-06 03:47:17 -04:00
|
|
|
#include "engine/api/route_parameters.hpp"
|
2016-01-28 10:28:44 -05:00
|
|
|
|
|
|
|
#include "engine/datafacade/datafacade_base.hpp"
|
|
|
|
|
|
|
|
#include "engine/guidance/assemble_geometry.hpp"
|
2016-04-06 03:47:17 -04:00
|
|
|
#include "engine/guidance/assemble_leg.hpp"
|
2016-01-28 10:28:44 -05:00
|
|
|
#include "engine/guidance/assemble_overview.hpp"
|
2016-04-06 03:47:17 -04:00
|
|
|
#include "engine/guidance/assemble_route.hpp"
|
2016-01-28 10:28:44 -05:00
|
|
|
#include "engine/guidance/assemble_steps.hpp"
|
2017-02-15 09:12:24 -05:00
|
|
|
#include "engine/guidance/collapse_turns.hpp"
|
2016-06-15 08:38:24 -04:00
|
|
|
#include "engine/guidance/lane_processing.hpp"
|
2016-02-24 04:29:23 -05:00
|
|
|
#include "engine/guidance/post_processing.hpp"
|
2017-02-15 09:12:24 -05:00
|
|
|
#include "engine/guidance/verbosity_reduction.hpp"
|
2016-01-28 10:28:44 -05:00
|
|
|
|
|
|
|
#include "engine/internal_route_result.hpp"
|
|
|
|
|
2018-02-09 13:32:09 -05:00
|
|
|
#include "guidance/turn_instruction.hpp"
|
|
|
|
|
2016-02-25 04:01:16 -05:00
|
|
|
#include "util/coordinate.hpp"
|
2016-01-28 10:28:44 -05:00
|
|
|
#include "util/integer_range.hpp"
|
2017-02-22 08:29:17 -05:00
|
|
|
#include "util/json_util.hpp"
|
2016-01-28 10:28:44 -05:00
|
|
|
|
2016-04-12 09:00:08 -04:00
|
|
|
#include <iterator>
|
2016-02-25 04:01:16 -05:00
|
|
|
#include <vector>
|
|
|
|
|
2016-01-28 10:28:44 -05:00
|
|
|
namespace osrm
|
|
|
|
{
|
|
|
|
namespace engine
|
|
|
|
{
|
|
|
|
namespace api
|
|
|
|
{
|
|
|
|
|
2016-02-20 22:27:26 -05:00
|
|
|
class RouteAPI : public BaseAPI
|
2016-01-28 10:28:44 -05:00
|
|
|
{
|
|
|
|
public:
|
2016-02-17 19:41:50 -05:00
|
|
|
RouteAPI(const datafacade::BaseDataFacade &facade_, const RouteParameters ¶meters_)
|
|
|
|
: BaseAPI(facade_, parameters_), parameters(parameters_)
|
2016-01-28 10:28:44 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-01-24 19:19:59 -05:00
|
|
|
void
|
|
|
|
MakeResponse(const InternalManyRoutesResult &raw_routes,
|
|
|
|
const std::vector<PhantomNodes>
|
|
|
|
&all_start_end_points, // all used coordinates, ignoring waypoints= parameter
|
|
|
|
util::json::Object &response) const
|
2016-01-28 10:28:44 -05:00
|
|
|
{
|
2017-05-11 12:44:48 -04:00
|
|
|
BOOST_ASSERT(!raw_routes.routes.empty());
|
|
|
|
|
|
|
|
util::json::Array jsRoutes;
|
|
|
|
|
|
|
|
for (const auto &route : raw_routes.routes)
|
2016-01-28 10:28:44 -05:00
|
|
|
{
|
2017-05-11 12:44:48 -04:00
|
|
|
if (!route.is_valid())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
jsRoutes.values.push_back(MakeRoute(route.segment_end_coordinates,
|
|
|
|
route.unpacked_path_segments,
|
|
|
|
route.source_traversed_in_reverse,
|
|
|
|
route.target_traversed_in_reverse));
|
2016-01-28 10:28:44 -05:00
|
|
|
}
|
2017-05-11 12:44:48 -04:00
|
|
|
|
2019-01-24 19:19:59 -05:00
|
|
|
response.values["waypoints"] = BaseAPI::MakeWaypoints(all_start_end_points);
|
2017-05-11 12:44:48 -04:00
|
|
|
response.values["routes"] = std::move(jsRoutes);
|
2016-04-04 08:05:38 -04:00
|
|
|
response.values["code"] = "Ok";
|
2016-01-28 10:28:44 -05:00
|
|
|
}
|
|
|
|
|
2016-12-15 09:28:54 -05:00
|
|
|
protected:
|
2016-01-28 10:28:44 -05:00
|
|
|
template <typename ForwardIter>
|
|
|
|
util::json::Value MakeGeometry(ForwardIter begin, ForwardIter end) const
|
|
|
|
{
|
|
|
|
if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
|
|
|
|
{
|
2016-11-07 15:11:21 -05:00
|
|
|
return json::makePolyline<100000>(begin, end);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parameters.geometries == RouteParameters::GeometriesType::Polyline6)
|
|
|
|
{
|
|
|
|
return json::makePolyline<1000000>(begin, end);
|
2016-01-28 10:28:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_ASSERT(parameters.geometries == RouteParameters::GeometriesType::GeoJSON);
|
2016-04-20 14:49:54 -04:00
|
|
|
return json::makeGeoJSONGeometry(begin, end);
|
2016-01-28 10:28:44 -05:00
|
|
|
}
|
|
|
|
|
2017-02-01 09:33:43 -05:00
|
|
|
template <typename GetFn>
|
|
|
|
util::json::Array GetAnnotations(const guidance::LegGeometry &leg, GetFn Get) const
|
|
|
|
{
|
|
|
|
util::json::Array annotations_store;
|
|
|
|
annotations_store.values.reserve(leg.annotations.size());
|
2018-01-18 06:08:16 -05:00
|
|
|
|
2018-01-19 06:38:14 -05:00
|
|
|
for (const auto &step : leg.annotations)
|
2018-01-18 06:08:16 -05:00
|
|
|
{
|
2018-01-19 06:38:14 -05:00
|
|
|
annotations_store.values.push_back(Get(step));
|
2018-01-18 06:08:16 -05:00
|
|
|
}
|
|
|
|
|
2017-02-01 09:33:43 -05:00
|
|
|
return annotations_store;
|
|
|
|
}
|
|
|
|
|
2016-02-20 22:27:26 -05:00
|
|
|
util::json::Object MakeRoute(const std::vector<PhantomNodes> &segment_end_coordinates,
|
2016-03-21 13:07:28 -04:00
|
|
|
const std::vector<std::vector<PathData>> &unpacked_path_segments,
|
2016-02-20 22:27:26 -05:00
|
|
|
const std::vector<bool> &source_traversed_in_reverse,
|
2016-03-07 12:59:39 -05:00
|
|
|
const std::vector<bool> &target_traversed_in_reverse) const
|
2016-01-28 10:28:44 -05:00
|
|
|
{
|
|
|
|
std::vector<guidance::RouteLeg> legs;
|
|
|
|
std::vector<guidance::LegGeometry> leg_geometries;
|
|
|
|
auto number_of_legs = segment_end_coordinates.size();
|
|
|
|
legs.reserve(number_of_legs);
|
|
|
|
leg_geometries.reserve(number_of_legs);
|
2016-02-24 04:29:23 -05:00
|
|
|
|
2016-04-12 06:42:16 -04:00
|
|
|
for (auto idx : util::irange<std::size_t>(0UL, number_of_legs))
|
2016-01-28 10:28:44 -05:00
|
|
|
{
|
|
|
|
const auto &phantoms = segment_end_coordinates[idx];
|
|
|
|
const auto &path_data = unpacked_path_segments[idx];
|
2016-02-24 04:29:23 -05:00
|
|
|
|
2016-01-28 10:28:44 -05:00
|
|
|
const bool reversed_source = source_traversed_in_reverse[idx];
|
|
|
|
const bool reversed_target = target_traversed_in_reverse[idx];
|
|
|
|
|
2016-10-24 22:15:45 -04:00
|
|
|
auto leg_geometry = guidance::assembleGeometry(BaseAPI::facade,
|
|
|
|
path_data,
|
|
|
|
phantoms.source_phantom,
|
|
|
|
phantoms.target_phantom,
|
|
|
|
reversed_source,
|
|
|
|
reversed_target);
|
2016-05-27 15:05:04 -04:00
|
|
|
auto leg = guidance::assembleLeg(facade,
|
|
|
|
path_data,
|
|
|
|
leg_geometry,
|
|
|
|
phantoms.source_phantom,
|
|
|
|
phantoms.target_phantom,
|
|
|
|
reversed_target,
|
|
|
|
parameters.steps);
|
2016-01-28 10:28:44 -05:00
|
|
|
|
2018-02-09 13:32:09 -05:00
|
|
|
util::Log(logDEBUG) << "Assembling steps " << std::endl;
|
2016-01-28 10:28:44 -05:00
|
|
|
if (parameters.steps)
|
|
|
|
{
|
2016-05-27 15:05:04 -04:00
|
|
|
auto steps = guidance::assembleSteps(BaseAPI::facade,
|
|
|
|
path_data,
|
|
|
|
leg_geometry,
|
|
|
|
phantoms.source_phantom,
|
|
|
|
phantoms.target_phantom,
|
|
|
|
reversed_source,
|
|
|
|
reversed_target);
|
2016-03-21 13:07:28 -04:00
|
|
|
|
2018-02-09 13:32:09 -05:00
|
|
|
// Apply maneuver overrides before any other post
|
|
|
|
// processing is performed
|
|
|
|
guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry);
|
|
|
|
|
2018-03-30 07:43:56 -04:00
|
|
|
// Collapse segregated steps before others
|
|
|
|
steps = guidance::collapseSegregatedTurnInstructions(std::move(steps));
|
|
|
|
|
2016-03-21 13:07:28 -04:00
|
|
|
/* Perform step-based post-processing.
|
|
|
|
*
|
|
|
|
* Using post-processing on basis of route-steps for a single leg at a time
|
|
|
|
* comes at the cost that we cannot count the correct exit for roundabouts.
|
|
|
|
* We can only emit the exit nr/intersections up to/starting at a part of the leg.
|
2016-03-29 07:45:48 -04:00
|
|
|
* If a roundabout is not terminated in a leg, we will end up with a
|
|
|
|
*enter-roundabout
|
2016-03-21 13:07:28 -04:00
|
|
|
* and exit-roundabout-nr where the exit nr is out of sync with the previous enter.
|
|
|
|
*
|
|
|
|
* | S |
|
|
|
|
* * *
|
|
|
|
* ----* * ----
|
|
|
|
* T
|
|
|
|
* ----* * ----
|
|
|
|
* V * *
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
*
|
2016-03-29 07:45:48 -04:00
|
|
|
* Coming from S via V to T, we end up with the legs S->V and V->T. V-T will say to
|
|
|
|
*take
|
2016-03-21 13:07:28 -04:00
|
|
|
* the second exit, even though counting from S it would be the third.
|
2016-03-29 07:45:48 -04:00
|
|
|
* For S, we only emit `roundabout` without an exit number, showing that we enter a
|
|
|
|
*roundabout
|
2016-03-21 13:07:28 -04:00
|
|
|
* to find a via point.
|
|
|
|
* The same exit will be emitted, though, if we should start routing at S, making
|
|
|
|
* the overall response consistent.
|
2017-06-01 05:00:54 -04:00
|
|
|
*
|
|
|
|
* ⚠ CAUTION: order of post-processing steps is important
|
2017-09-05 15:30:34 -04:00
|
|
|
* - handleRoundabouts must be called before collapseTurnInstructions that
|
|
|
|
* expects post-processed roundabouts
|
2016-03-21 13:07:28 -04:00
|
|
|
*/
|
|
|
|
|
2016-03-30 03:53:17 -04:00
|
|
|
guidance::trimShortSegments(steps, leg_geometry);
|
2017-09-05 15:30:34 -04:00
|
|
|
leg.steps = guidance::handleRoundabouts(std::move(steps));
|
2017-11-30 07:10:46 -05:00
|
|
|
leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps));
|
2017-07-10 06:46:18 -04:00
|
|
|
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
|
2016-05-30 11:42:28 -04:00
|
|
|
leg.steps = guidance::buildIntersections(std::move(leg.steps));
|
2017-02-15 09:12:24 -05:00
|
|
|
leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps));
|
2016-05-27 15:05:04 -04:00
|
|
|
leg.steps = guidance::assignRelativeLocations(std::move(leg.steps),
|
|
|
|
leg_geometry,
|
2016-03-29 07:45:48 -04:00
|
|
|
phantoms.source_phantom,
|
|
|
|
phantoms.target_phantom);
|
|
|
|
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps);
|
2016-01-28 10:28:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
leg_geometries.push_back(std::move(leg_geometry));
|
|
|
|
legs.push_back(std::move(leg));
|
|
|
|
}
|
2016-03-21 13:07:28 -04:00
|
|
|
|
2016-01-28 10:28:44 -05:00
|
|
|
auto route = guidance::assembleRoute(legs);
|
|
|
|
boost::optional<util::json::Value> json_overview;
|
|
|
|
if (parameters.overview != RouteParameters::OverviewType::False)
|
|
|
|
{
|
|
|
|
const auto use_simplification =
|
|
|
|
parameters.overview == RouteParameters::OverviewType::Simplified;
|
|
|
|
BOOST_ASSERT(use_simplification ||
|
|
|
|
parameters.overview == RouteParameters::OverviewType::Full);
|
|
|
|
|
|
|
|
auto overview = guidance::assembleOverview(leg_geometries, use_simplification);
|
|
|
|
json_overview = MakeGeometry(overview.begin(), overview.end());
|
|
|
|
}
|
|
|
|
|
2016-02-25 11:55:52 -05:00
|
|
|
std::vector<util::json::Value> step_geometries;
|
2018-03-06 01:45:23 -05:00
|
|
|
const auto total_step_count =
|
|
|
|
std::accumulate(legs.begin(), legs.end(), 0, [](const auto &v, const auto &leg) {
|
|
|
|
return v + leg.steps.size();
|
|
|
|
});
|
|
|
|
step_geometries.reserve(total_step_count);
|
|
|
|
|
2016-04-12 06:42:16 -04:00
|
|
|
for (const auto idx : util::irange<std::size_t>(0UL, legs.size()))
|
2016-02-25 11:55:52 -05:00
|
|
|
{
|
|
|
|
auto &leg_geometry = leg_geometries[idx];
|
2016-06-08 05:28:32 -04:00
|
|
|
|
2016-02-25 11:55:52 -05:00
|
|
|
std::transform(
|
2016-05-27 15:05:04 -04:00
|
|
|
legs[idx].steps.begin(),
|
|
|
|
legs[idx].steps.end(),
|
|
|
|
std::back_inserter(step_geometries),
|
2016-04-06 03:47:17 -04:00
|
|
|
[this, &leg_geometry](const guidance::RouteStep &step) {
|
2016-02-25 11:55:52 -05:00
|
|
|
if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
|
|
|
|
{
|
2016-11-11 08:09:04 -05:00
|
|
|
return static_cast<util::json::Value>(json::makePolyline<100000>(
|
|
|
|
leg_geometry.locations.begin() + step.geometry_begin,
|
|
|
|
leg_geometry.locations.begin() + step.geometry_end));
|
2016-02-25 11:55:52 -05:00
|
|
|
}
|
2016-11-07 15:11:21 -05:00
|
|
|
|
|
|
|
if (parameters.geometries == RouteParameters::GeometriesType::Polyline6)
|
|
|
|
{
|
2016-11-11 08:09:04 -05:00
|
|
|
return static_cast<util::json::Value>(json::makePolyline<1000000>(
|
|
|
|
leg_geometry.locations.begin() + step.geometry_begin,
|
|
|
|
leg_geometry.locations.begin() + step.geometry_end));
|
2016-11-07 15:11:21 -05:00
|
|
|
}
|
|
|
|
|
2016-02-25 11:55:52 -05:00
|
|
|
BOOST_ASSERT(parameters.geometries == RouteParameters::GeometriesType::GeoJSON);
|
2016-04-20 14:49:54 -04:00
|
|
|
return static_cast<util::json::Value>(json::makeGeoJSONGeometry(
|
2016-02-25 11:55:52 -05:00
|
|
|
leg_geometry.locations.begin() + step.geometry_begin,
|
|
|
|
leg_geometry.locations.begin() + step.geometry_end));
|
|
|
|
});
|
|
|
|
}
|
2016-03-01 16:30:31 -05:00
|
|
|
|
2016-05-26 18:39:46 -04:00
|
|
|
std::vector<util::json::Object> annotations;
|
2016-05-09 01:58:13 -04:00
|
|
|
|
2017-02-13 06:53:05 -05:00
|
|
|
// To maintain support for uses of the old default constructors, we check
|
|
|
|
// if annotations property was set manually after default construction
|
|
|
|
auto requested_annotations = parameters.annotations_type;
|
|
|
|
if ((parameters.annotations == true) &&
|
|
|
|
(parameters.annotations_type == RouteParameters::AnnotationsType::None))
|
2016-05-09 01:58:13 -04:00
|
|
|
{
|
2017-02-13 06:53:05 -05:00
|
|
|
requested_annotations = RouteParameters::AnnotationsType::All;
|
|
|
|
}
|
2017-02-10 11:26:27 -05:00
|
|
|
|
2017-02-13 06:53:05 -05:00
|
|
|
if (requested_annotations != RouteParameters::AnnotationsType::None)
|
|
|
|
{
|
2016-05-09 01:58:13 -04:00
|
|
|
for (const auto idx : util::irange<std::size_t>(0UL, leg_geometries.size()))
|
|
|
|
{
|
|
|
|
auto &leg_geometry = leg_geometries[idx];
|
2016-05-26 18:39:46 -04:00
|
|
|
util::json::Object annotation;
|
2017-02-01 09:33:43 -05:00
|
|
|
|
2017-02-13 06:53:05 -05:00
|
|
|
// AnnotationsType uses bit flags, & operator checks if a property is set
|
2017-02-09 13:37:56 -05:00
|
|
|
if (parameters.annotations_type & RouteParameters::AnnotationsType::Speed)
|
|
|
|
{
|
2018-01-18 06:08:16 -05:00
|
|
|
double prev_speed = 0;
|
2017-02-09 13:37:56 -05:00
|
|
|
annotation.values["speed"] = GetAnnotations(
|
2018-01-18 06:08:16 -05:00
|
|
|
leg_geometry, [&prev_speed](const guidance::LegGeometry::Annotation &anno) {
|
|
|
|
if (anno.duration < std::numeric_limits<double>::min())
|
|
|
|
{
|
|
|
|
return prev_speed;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto speed = std::round(anno.distance / anno.duration * 10.) / 10.;
|
|
|
|
prev_speed = speed;
|
|
|
|
return util::json::clamp_float(speed);
|
|
|
|
}
|
2017-02-09 13:37:56 -05:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-02-13 06:53:05 -05:00
|
|
|
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
|
2017-01-30 06:30:31 -05:00
|
|
|
{
|
2017-02-02 10:36:35 -05:00
|
|
|
annotation.values["duration"] = GetAnnotations(
|
|
|
|
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
|
|
|
return anno.duration;
|
|
|
|
});
|
2017-01-30 06:30:31 -05:00
|
|
|
}
|
2017-02-10 11:26:27 -05:00
|
|
|
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
|
2017-01-30 06:30:31 -05:00
|
|
|
{
|
2017-02-02 10:36:35 -05:00
|
|
|
annotation.values["distance"] = GetAnnotations(
|
|
|
|
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
|
|
|
return anno.distance;
|
|
|
|
});
|
2017-01-30 06:30:31 -05:00
|
|
|
}
|
2017-02-10 11:26:27 -05:00
|
|
|
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
|
2017-01-30 06:30:31 -05:00
|
|
|
{
|
2017-02-02 10:36:35 -05:00
|
|
|
annotation.values["weight"] = GetAnnotations(
|
|
|
|
leg_geometry,
|
|
|
|
[](const guidance::LegGeometry::Annotation &anno) { return anno.weight; });
|
2017-01-30 06:30:31 -05:00
|
|
|
}
|
2017-02-10 11:26:27 -05:00
|
|
|
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
|
2017-01-30 06:30:31 -05:00
|
|
|
{
|
2017-02-02 10:36:35 -05:00
|
|
|
annotation.values["datasources"] = GetAnnotations(
|
|
|
|
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
|
|
|
return anno.datasource;
|
|
|
|
});
|
2017-01-30 06:30:31 -05:00
|
|
|
}
|
2017-02-10 11:26:27 -05:00
|
|
|
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
|
2017-01-30 06:30:31 -05:00
|
|
|
{
|
|
|
|
util::json::Array nodes;
|
|
|
|
nodes.values.reserve(leg_geometry.osm_node_ids.size());
|
2018-01-18 06:08:16 -05:00
|
|
|
for (const auto node_id : leg_geometry.osm_node_ids)
|
|
|
|
{
|
2018-01-19 06:38:14 -05:00
|
|
|
nodes.values.push_back(static_cast<std::uint64_t>(node_id));
|
2018-01-18 06:08:16 -05:00
|
|
|
}
|
2017-01-30 06:30:31 -05:00
|
|
|
annotation.values["nodes"] = std::move(nodes);
|
|
|
|
}
|
2018-04-03 18:13:25 -04:00
|
|
|
// Add any supporting metadata, if needed
|
|
|
|
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
|
|
|
|
{
|
|
|
|
const auto MAX_DATASOURCE_ID = 255u;
|
|
|
|
util::json::Object metadata;
|
|
|
|
util::json::Array datasource_names;
|
|
|
|
for (auto i = 0u; i < MAX_DATASOURCE_ID; i++)
|
|
|
|
{
|
|
|
|
const auto name = facade.GetDatasourceName(i);
|
|
|
|
// Length of 0 indicates the first empty name, so we can stop here
|
|
|
|
if (name.size() == 0)
|
|
|
|
break;
|
|
|
|
datasource_names.values.push_back(std::string(facade.GetDatasourceName(i)));
|
|
|
|
}
|
|
|
|
metadata.values["datasource_names"] = datasource_names;
|
|
|
|
annotation.values["metadata"] = metadata;
|
|
|
|
}
|
2017-01-30 06:30:31 -05:00
|
|
|
|
2016-05-26 18:39:46 -04:00
|
|
|
annotations.push_back(std::move(annotation));
|
2016-05-09 01:58:13 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-26 18:39:46 -04:00
|
|
|
auto result = json::makeRoute(route,
|
2016-05-27 15:05:04 -04:00
|
|
|
json::makeRouteLegs(std::move(legs),
|
|
|
|
std::move(step_geometries),
|
|
|
|
std::move(annotations)),
|
2016-05-12 12:50:10 -04:00
|
|
|
std::move(json_overview),
|
|
|
|
facade.GetWeightName());
|
2016-05-26 18:39:46 -04:00
|
|
|
|
2016-05-09 01:58:13 -04:00
|
|
|
return result;
|
2016-01-28 10:28:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
const RouteParameters ¶meters;
|
|
|
|
};
|
|
|
|
|
2016-02-17 19:41:50 -05:00
|
|
|
} // ns api
|
|
|
|
} // ns engine
|
|
|
|
} // ns osrm
|
2016-01-28 10:28:44 -05:00
|
|
|
|
|
|
|
#endif
|