Support snapping to multiple ways at an input location (#5953)
This PR improves routing results by adding support for snapping to multiple ways at input locations. This means all edges at the snapped location can act as source/target candidates for routing search, ensuring we always find the best route, and not the one dependent on the edge selected.
This commit is contained in:
@@ -9,9 +9,12 @@
|
||||
#include "engine/hint.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/range/adaptor/transformed.hpp>
|
||||
#include <boost/range/algorithm/transform.hpp>
|
||||
|
||||
#include <boost/range/adaptor/filtered.hpp>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@@ -22,6 +25,8 @@ namespace engine
|
||||
namespace api
|
||||
{
|
||||
|
||||
static const constexpr char *INTERSECTION_DELIMITER = " / ";
|
||||
|
||||
class BaseAPI
|
||||
{
|
||||
public:
|
||||
@@ -30,92 +35,129 @@ class BaseAPI
|
||||
{
|
||||
}
|
||||
|
||||
util::json::Array MakeWaypoints(const std::vector<PhantomNodes> &segment_end_coordinates) const
|
||||
util::json::Array
|
||||
MakeWaypoints(const std::vector<PhantomNodeCandidates> &waypoint_candidates) const
|
||||
{
|
||||
BOOST_ASSERT(parameters.coordinates.size() > 0);
|
||||
BOOST_ASSERT(parameters.coordinates.size() == segment_end_coordinates.size() + 1);
|
||||
BOOST_ASSERT(parameters.coordinates.size() == waypoint_candidates.size());
|
||||
|
||||
util::json::Array waypoints;
|
||||
waypoints.values.resize(parameters.coordinates.size());
|
||||
waypoints.values[0] = MakeWaypoint(segment_end_coordinates.front().source_phantom);
|
||||
|
||||
auto out_iter = std::next(waypoints.values.begin());
|
||||
boost::range::transform(
|
||||
segment_end_coordinates, out_iter, [this](const PhantomNodes &phantom_pair) {
|
||||
return MakeWaypoint(phantom_pair.target_phantom);
|
||||
});
|
||||
waypoint_candidates,
|
||||
waypoints.values.begin(),
|
||||
[this](const PhantomNodeCandidates &candidates) { return MakeWaypoint(candidates); });
|
||||
return waypoints;
|
||||
}
|
||||
|
||||
// FIXME: gcc 4.9 does not like MakeWaypoints to be protected
|
||||
// protected:
|
||||
util::json::Object MakeWaypoint(const PhantomNode &phantom) const
|
||||
util::json::Object MakeWaypoint(const PhantomNodeCandidates &candidates) const
|
||||
{
|
||||
// TODO: check forward/reverse
|
||||
const auto toName = [this](const auto &phantom) {
|
||||
return facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id))
|
||||
.to_string();
|
||||
};
|
||||
const auto noEmpty = [](const auto &name) { return !name.empty(); };
|
||||
|
||||
// At an intersection we may have multiple phantom node candidates.
|
||||
// Combine them to represent the waypoint name.
|
||||
std::string waypoint_name = boost::algorithm::join(
|
||||
candidates | boost::adaptors::transformed(toName) | boost::adaptors::filtered(noEmpty),
|
||||
INTERSECTION_DELIMITER);
|
||||
|
||||
const auto &snapped_location = candidatesSnappedLocation(candidates);
|
||||
const auto &input_location = candidatesInputLocation(candidates);
|
||||
if (parameters.generate_hints)
|
||||
{
|
||||
// TODO: check forward/reverse
|
||||
std::vector<SegmentHint> seg_hints(candidates.size());
|
||||
std::transform(candidates.begin(),
|
||||
candidates.end(),
|
||||
seg_hints.begin(),
|
||||
[this](const auto &phantom) {
|
||||
return SegmentHint{phantom, facade.GetCheckSum()};
|
||||
});
|
||||
|
||||
return json::makeWaypoint(
|
||||
phantom.location,
|
||||
util::coordinate_calculation::greatCircleDistance(phantom.location,
|
||||
phantom.input_location),
|
||||
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)).to_string(),
|
||||
Hint{phantom, facade.GetCheckSum()});
|
||||
snapped_location,
|
||||
util::coordinate_calculation::greatCircleDistance(snapped_location, input_location),
|
||||
waypoint_name,
|
||||
{std::move(seg_hints)});
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: check forward/reverse
|
||||
return json::makeWaypoint(
|
||||
phantom.location,
|
||||
util::coordinate_calculation::greatCircleDistance(phantom.location,
|
||||
phantom.input_location),
|
||||
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id))
|
||||
.to_string());
|
||||
snapped_location,
|
||||
util::coordinate_calculation::greatCircleDistance(snapped_location, input_location),
|
||||
waypoint_name);
|
||||
}
|
||||
}
|
||||
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>>
|
||||
MakeWaypoints(flatbuffers::FlatBufferBuilder *builder,
|
||||
const std::vector<PhantomNodes> &segment_end_coordinates) const
|
||||
const std::vector<PhantomNodeCandidates> &waypoint_candidates) const
|
||||
{
|
||||
BOOST_ASSERT(parameters.coordinates.size() > 0);
|
||||
BOOST_ASSERT(parameters.coordinates.size() == segment_end_coordinates.size() + 1);
|
||||
BOOST_ASSERT(parameters.coordinates.size() == waypoint_candidates.size());
|
||||
|
||||
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
|
||||
waypoints.resize(parameters.coordinates.size());
|
||||
waypoints[0] =
|
||||
MakeWaypoint(builder, segment_end_coordinates.front().source_phantom)->Finish();
|
||||
|
||||
std::transform(segment_end_coordinates.begin(),
|
||||
segment_end_coordinates.end(),
|
||||
std::next(waypoints.begin()),
|
||||
[this, builder](const PhantomNodes &phantom_pair) {
|
||||
return MakeWaypoint(builder, phantom_pair.target_phantom)->Finish();
|
||||
std::transform(waypoint_candidates.begin(),
|
||||
waypoint_candidates.end(),
|
||||
waypoints.begin(),
|
||||
[this, builder](const PhantomNodeCandidates &candidates) {
|
||||
return MakeWaypoint(builder, candidates)->Finish();
|
||||
});
|
||||
return builder->CreateVector(waypoints);
|
||||
}
|
||||
|
||||
// FIXME: gcc 4.9 does not like MakeWaypoints to be protected
|
||||
// protected:
|
||||
std::unique_ptr<fbresult::WaypointBuilder> MakeWaypoint(flatbuffers::FlatBufferBuilder *builder,
|
||||
const PhantomNode &phantom) const
|
||||
std::unique_ptr<fbresult::WaypointBuilder>
|
||||
MakeWaypoint(flatbuffers::FlatBufferBuilder *builder,
|
||||
const PhantomNodeCandidates &candidates) const
|
||||
{
|
||||
|
||||
const auto &snapped_location = candidatesSnappedLocation(candidates);
|
||||
const auto &input_location = candidatesInputLocation(candidates);
|
||||
auto location =
|
||||
fbresult::Position(static_cast<double>(util::toFloating(phantom.location.lon)),
|
||||
static_cast<double>(util::toFloating(phantom.location.lat)));
|
||||
auto name_string = builder->CreateString(
|
||||
facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)).to_string());
|
||||
fbresult::Position(static_cast<double>(util::toFloating(snapped_location.lon)),
|
||||
static_cast<double>(util::toFloating(snapped_location.lat)));
|
||||
|
||||
const auto toName = [this](const auto &phantom) {
|
||||
return facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id))
|
||||
.to_string();
|
||||
};
|
||||
const auto noEmpty = [](const auto &name) { return !name.empty(); };
|
||||
|
||||
// At an intersection we may have multiple phantom node candidates.
|
||||
// Combine them to represent the waypoint name.
|
||||
std::string waypoint_name = boost::algorithm::join(
|
||||
candidates | boost::adaptors::transformed(toName) | boost::adaptors::filtered(noEmpty),
|
||||
INTERSECTION_DELIMITER);
|
||||
auto name_string = builder->CreateString(waypoint_name);
|
||||
|
||||
flatbuffers::Offset<flatbuffers::String> hint_string;
|
||||
if (parameters.generate_hints)
|
||||
{
|
||||
hint_string = builder->CreateString(Hint{phantom, facade.GetCheckSum()}.ToBase64());
|
||||
std::vector<SegmentHint> seg_hints(candidates.size());
|
||||
std::transform(candidates.begin(),
|
||||
candidates.end(),
|
||||
seg_hints.begin(),
|
||||
[this](const auto &phantom) {
|
||||
return SegmentHint{phantom, facade.GetCheckSum()};
|
||||
});
|
||||
Hint hint{std::move(seg_hints)};
|
||||
hint_string = builder->CreateString(hint.ToBase64());
|
||||
}
|
||||
|
||||
auto waypoint = std::make_unique<fbresult::WaypointBuilder>(*builder);
|
||||
waypoint->add_location(&location);
|
||||
waypoint->add_distance(util::coordinate_calculation::greatCircleDistance(
|
||||
phantom.location, phantom.input_location));
|
||||
waypoint->add_distance(
|
||||
util::coordinate_calculation::greatCircleDistance(snapped_location, input_location));
|
||||
waypoint->add_name(name_string);
|
||||
if (parameters.generate_hints)
|
||||
{
|
||||
|
||||
@@ -51,14 +51,14 @@ namespace api
|
||||
* Holds member attributes:
|
||||
* - coordinates: for specifying location(s) to services
|
||||
* - hints: hint for the service to derive the position(s) in the road network more efficiently,
|
||||
* optional per coordinate
|
||||
* optional per coordinate. Multiple hints can be provided for a coordinate.
|
||||
* - radiuses: limits the search for segments in the road network to given radius(es) in meter,
|
||||
* optional per coordinate
|
||||
* - bearings: limits the search for segments in the road network to given bearing(s) in degree
|
||||
* towards true north in clockwise direction, optional per coordinate
|
||||
* - approaches: force the phantom node to start towards the node with the road country side.
|
||||
*
|
||||
* \see OSRM, Coordinate, Hint, Bearing, RouteParame, RouteParameters, TableParameters,
|
||||
* \see OSRM, Coordinate, Hint, Bearing, RouteParameters, TableParameters,
|
||||
* NearestParameters, TripParameters, MatchParameters and TileParameters
|
||||
*/
|
||||
struct BaseParameters
|
||||
|
||||
@@ -76,7 +76,7 @@ class MatchAPI final : public RouteAPI
|
||||
routes.values.reserve(number_of_routes);
|
||||
for (auto index : util::irange<std::size_t>(0UL, sub_matchings.size()))
|
||||
{
|
||||
auto route = MakeRoute(sub_routes[index].segment_end_coordinates,
|
||||
auto route = MakeRoute(sub_routes[index].leg_endpoints,
|
||||
sub_routes[index].unpacked_path_segments,
|
||||
sub_routes[index].source_traversed_in_reverse,
|
||||
sub_routes[index].target_traversed_in_reverse);
|
||||
@@ -146,7 +146,7 @@ class MatchAPI final : public RouteAPI
|
||||
}
|
||||
const auto &phantom =
|
||||
sub_matchings[matching_index.sub_matching_index].nodes[matching_index.point_index];
|
||||
auto waypoint = BaseAPI::MakeWaypoint(&fb_result, phantom);
|
||||
auto waypoint = BaseAPI::MakeWaypoint(&fb_result, {phantom});
|
||||
waypoint->add_matchings_index(matching_index.sub_matching_index);
|
||||
waypoint->add_alternatives_count(sub_matchings[matching_index.sub_matching_index]
|
||||
.alternatives_count[matching_index.point_index]);
|
||||
@@ -200,7 +200,7 @@ class MatchAPI final : public RouteAPI
|
||||
}
|
||||
const auto &phantom =
|
||||
sub_matchings[matching_index.sub_matching_index].nodes[matching_index.point_index];
|
||||
auto waypoint = BaseAPI::MakeWaypoint(phantom);
|
||||
auto waypoint = BaseAPI::MakeWaypoint({phantom});
|
||||
waypoint.values["matchings_index"] = matching_index.sub_matching_index;
|
||||
waypoint.values["waypoint_index"] = matching_index.point_index;
|
||||
waypoint.values["alternatives_count"] =
|
||||
|
||||
@@ -71,7 +71,7 @@ class NearestAPI final : public BaseAPI
|
||||
auto node_values = MakeNodes(phantom_node);
|
||||
fbresult::Uint64Pair nodes{node_values.first, node_values.second};
|
||||
|
||||
auto waypoint = MakeWaypoint(&fb_result, phantom_node);
|
||||
auto waypoint = MakeWaypoint(&fb_result, {phantom_node});
|
||||
waypoint->add_nodes(&nodes);
|
||||
return waypoint->Finish();
|
||||
});
|
||||
@@ -100,7 +100,7 @@ class NearestAPI final : public BaseAPI
|
||||
waypoints.values.begin(),
|
||||
[this](const PhantomNodeWithDistance &phantom_with_distance) {
|
||||
auto &phantom_node = phantom_with_distance.phantom_node;
|
||||
auto waypoint = MakeWaypoint(phantom_node);
|
||||
auto waypoint = MakeWaypoint({phantom_node});
|
||||
|
||||
util::json::Array nodes;
|
||||
|
||||
|
||||
@@ -47,8 +47,8 @@ class RouteAPI : public BaseAPI
|
||||
|
||||
void
|
||||
MakeResponse(const InternalManyRoutesResult &raw_routes,
|
||||
const std::vector<PhantomNodes>
|
||||
&all_start_end_points, // all used coordinates, ignoring waypoints= parameter
|
||||
const std::vector<PhantomNodeCandidates>
|
||||
&waypoint_candidates, // all used coordinates, ignoring waypoints= parameter
|
||||
osrm::engine::api::ResultT &response) const
|
||||
{
|
||||
BOOST_ASSERT(!raw_routes.routes.empty());
|
||||
@@ -56,19 +56,19 @@ class RouteAPI : public BaseAPI
|
||||
if (response.is<flatbuffers::FlatBufferBuilder>())
|
||||
{
|
||||
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
|
||||
MakeResponse(raw_routes, all_start_end_points, fb_result);
|
||||
MakeResponse(raw_routes, waypoint_candidates, fb_result);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto &json_result = response.get<util::json::Object>();
|
||||
MakeResponse(raw_routes, all_start_end_points, json_result);
|
||||
MakeResponse(raw_routes, waypoint_candidates, json_result);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MakeResponse(const InternalManyRoutesResult &raw_routes,
|
||||
const std::vector<PhantomNodes>
|
||||
&all_start_end_points, // all used coordinates, ignoring waypoints= parameter
|
||||
const std::vector<PhantomNodeCandidates>
|
||||
&waypoint_candidates, // all used coordinates, ignoring waypoints= parameter
|
||||
flatbuffers::FlatBufferBuilder &fb_result) const
|
||||
{
|
||||
|
||||
@@ -80,8 +80,8 @@ class RouteAPI : public BaseAPI
|
||||
}
|
||||
|
||||
auto response =
|
||||
MakeFBResponse(raw_routes, fb_result, [this, &all_start_end_points, &fb_result]() {
|
||||
return BaseAPI::MakeWaypoints(&fb_result, all_start_end_points);
|
||||
MakeFBResponse(raw_routes, fb_result, [this, &waypoint_candidates, &fb_result]() {
|
||||
return BaseAPI::MakeWaypoints(&fb_result, waypoint_candidates);
|
||||
});
|
||||
|
||||
if (!data_timestamp.empty())
|
||||
@@ -93,8 +93,8 @@ class RouteAPI : public BaseAPI
|
||||
|
||||
void
|
||||
MakeResponse(const InternalManyRoutesResult &raw_routes,
|
||||
const std::vector<PhantomNodes>
|
||||
&all_start_end_points, // all used coordinates, ignoring waypoints= parameter
|
||||
const std::vector<PhantomNodeCandidates>
|
||||
&waypoint_candidates, // all used coordinates, ignoring waypoints= parameter
|
||||
util::json::Object &response) const
|
||||
{
|
||||
util::json::Array jsRoutes;
|
||||
@@ -104,7 +104,7 @@ class RouteAPI : public BaseAPI
|
||||
if (!route.is_valid())
|
||||
continue;
|
||||
|
||||
jsRoutes.values.push_back(MakeRoute(route.segment_end_coordinates,
|
||||
jsRoutes.values.push_back(MakeRoute(route.leg_endpoints,
|
||||
route.unpacked_path_segments,
|
||||
route.source_traversed_in_reverse,
|
||||
route.target_traversed_in_reverse));
|
||||
@@ -112,7 +112,7 @@ class RouteAPI : public BaseAPI
|
||||
|
||||
if (!parameters.skip_waypoints)
|
||||
{
|
||||
response.values["waypoints"] = BaseAPI::MakeWaypoints(all_start_end_points);
|
||||
response.values["waypoints"] = BaseAPI::MakeWaypoints(waypoint_candidates);
|
||||
}
|
||||
response.values["routes"] = std::move(jsRoutes);
|
||||
response.values["code"] = "Ok";
|
||||
@@ -138,7 +138,7 @@ class RouteAPI : public BaseAPI
|
||||
continue;
|
||||
|
||||
routes.push_back(MakeRoute(fb_result,
|
||||
raw_route.segment_end_coordinates,
|
||||
raw_route.leg_endpoints,
|
||||
raw_route.unpacked_path_segments,
|
||||
raw_route.source_traversed_in_reverse,
|
||||
raw_route.target_traversed_in_reverse));
|
||||
@@ -328,12 +328,12 @@ class RouteAPI : public BaseAPI
|
||||
|
||||
flatbuffers::Offset<fbresult::RouteObject>
|
||||
MakeRoute(flatbuffers::FlatBufferBuilder &fb_result,
|
||||
const std::vector<PhantomNodes> &segment_end_coordinates,
|
||||
const std::vector<PhantomEndpoints> &leg_endpoints,
|
||||
const std::vector<std::vector<PathData>> &unpacked_path_segments,
|
||||
const std::vector<bool> &source_traversed_in_reverse,
|
||||
const std::vector<bool> &target_traversed_in_reverse) const
|
||||
{
|
||||
auto legs_info = MakeLegs(segment_end_coordinates,
|
||||
auto legs_info = MakeLegs(leg_endpoints,
|
||||
unpacked_path_segments,
|
||||
source_traversed_in_reverse,
|
||||
target_traversed_in_reverse);
|
||||
@@ -705,12 +705,12 @@ class RouteAPI : public BaseAPI
|
||||
return fb_result.CreateVector(intersections);
|
||||
}
|
||||
|
||||
util::json::Object MakeRoute(const std::vector<PhantomNodes> &segment_end_coordinates,
|
||||
util::json::Object MakeRoute(const std::vector<PhantomEndpoints> &leg_endpoints,
|
||||
const std::vector<std::vector<PathData>> &unpacked_path_segments,
|
||||
const std::vector<bool> &source_traversed_in_reverse,
|
||||
const std::vector<bool> &target_traversed_in_reverse) const
|
||||
{
|
||||
auto legs_info = MakeLegs(segment_end_coordinates,
|
||||
auto legs_info = MakeLegs(leg_endpoints,
|
||||
unpacked_path_segments,
|
||||
source_traversed_in_reverse,
|
||||
target_traversed_in_reverse);
|
||||
@@ -868,7 +868,7 @@ class RouteAPI : public BaseAPI
|
||||
const RouteParameters ¶meters;
|
||||
|
||||
std::pair<std::vector<guidance::RouteLeg>, std::vector<guidance::LegGeometry>>
|
||||
MakeLegs(const std::vector<PhantomNodes> &segment_end_coordinates,
|
||||
MakeLegs(const std::vector<PhantomEndpoints> &leg_endpoints,
|
||||
const std::vector<std::vector<PathData>> &unpacked_path_segments,
|
||||
const std::vector<bool> &source_traversed_in_reverse,
|
||||
const std::vector<bool> &target_traversed_in_reverse) const
|
||||
@@ -877,13 +877,13 @@ class RouteAPI : public BaseAPI
|
||||
std::make_pair(std::vector<guidance::RouteLeg>(), std::vector<guidance::LegGeometry>());
|
||||
auto &legs = result.first;
|
||||
auto &leg_geometries = result.second;
|
||||
auto number_of_legs = segment_end_coordinates.size();
|
||||
auto number_of_legs = leg_endpoints.size();
|
||||
legs.reserve(number_of_legs);
|
||||
leg_geometries.reserve(number_of_legs);
|
||||
|
||||
for (auto idx : util::irange<std::size_t>(0UL, number_of_legs))
|
||||
{
|
||||
const auto &phantoms = segment_end_coordinates[idx];
|
||||
const auto &phantoms = leg_endpoints[idx];
|
||||
const auto &path_data = unpacked_path_segments[idx];
|
||||
|
||||
const bool reversed_source = source_traversed_in_reverse[idx];
|
||||
|
||||
@@ -48,25 +48,25 @@ class TableAPI final : public BaseAPI
|
||||
|
||||
virtual void
|
||||
MakeResponse(const std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> &tables,
|
||||
const std::vector<PhantomNode> &phantoms,
|
||||
const std::vector<PhantomNodeCandidates> &candidates,
|
||||
const std::vector<TableCellRef> &fallback_speed_cells,
|
||||
osrm::engine::api::ResultT &response) const
|
||||
{
|
||||
if (response.is<flatbuffers::FlatBufferBuilder>())
|
||||
{
|
||||
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
|
||||
MakeResponse(tables, phantoms, fallback_speed_cells, fb_result);
|
||||
MakeResponse(tables, candidates, fallback_speed_cells, fb_result);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto &json_result = response.get<util::json::Object>();
|
||||
MakeResponse(tables, phantoms, fallback_speed_cells, json_result);
|
||||
MakeResponse(tables, candidates, fallback_speed_cells, json_result);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void
|
||||
MakeResponse(const std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> &tables,
|
||||
const std::vector<PhantomNode> &phantoms,
|
||||
const std::vector<PhantomNodeCandidates> &candidates,
|
||||
const std::vector<TableCellRef> &fallback_speed_cells,
|
||||
flatbuffers::FlatBufferBuilder &fb_result) const
|
||||
{
|
||||
@@ -86,15 +86,15 @@ class TableAPI final : public BaseAPI
|
||||
{
|
||||
if (!parameters.skip_waypoints)
|
||||
{
|
||||
sources = MakeWaypoints(fb_result, phantoms);
|
||||
sources = MakeWaypoints(fb_result, candidates);
|
||||
}
|
||||
number_of_sources = phantoms.size();
|
||||
number_of_sources = candidates.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!parameters.skip_waypoints)
|
||||
{
|
||||
sources = MakeWaypoints(fb_result, phantoms, parameters.sources);
|
||||
sources = MakeWaypoints(fb_result, candidates, parameters.sources);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,15 +104,15 @@ class TableAPI final : public BaseAPI
|
||||
{
|
||||
if (!parameters.skip_waypoints)
|
||||
{
|
||||
destinations = MakeWaypoints(fb_result, phantoms);
|
||||
destinations = MakeWaypoints(fb_result, candidates);
|
||||
}
|
||||
number_of_destinations = phantoms.size();
|
||||
number_of_destinations = candidates.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!parameters.skip_waypoints)
|
||||
{
|
||||
destinations = MakeWaypoints(fb_result, phantoms, parameters.destinations);
|
||||
destinations = MakeWaypoints(fb_result, candidates, parameters.destinations);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ class TableAPI final : public BaseAPI
|
||||
|
||||
virtual void
|
||||
MakeResponse(const std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> &tables,
|
||||
const std::vector<PhantomNode> &phantoms,
|
||||
const std::vector<PhantomNodeCandidates> &candidates,
|
||||
const std::vector<TableCellRef> &fallback_speed_cells,
|
||||
util::json::Object &response) const
|
||||
{
|
||||
@@ -180,15 +180,15 @@ class TableAPI final : public BaseAPI
|
||||
{
|
||||
if (!parameters.skip_waypoints)
|
||||
{
|
||||
response.values["sources"] = MakeWaypoints(phantoms);
|
||||
response.values["sources"] = MakeWaypoints(candidates);
|
||||
}
|
||||
number_of_sources = phantoms.size();
|
||||
number_of_sources = candidates.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!parameters.skip_waypoints)
|
||||
{
|
||||
response.values["sources"] = MakeWaypoints(phantoms, parameters.sources);
|
||||
response.values["sources"] = MakeWaypoints(candidates, parameters.sources);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,15 +196,16 @@ class TableAPI final : public BaseAPI
|
||||
{
|
||||
if (!parameters.skip_waypoints)
|
||||
{
|
||||
response.values["destinations"] = MakeWaypoints(phantoms);
|
||||
response.values["destinations"] = MakeWaypoints(candidates);
|
||||
}
|
||||
number_of_destinations = phantoms.size();
|
||||
number_of_destinations = candidates.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!parameters.skip_waypoints)
|
||||
{
|
||||
response.values["destinations"] = MakeWaypoints(phantoms, parameters.destinations);
|
||||
response.values["destinations"] =
|
||||
MakeWaypoints(candidates, parameters.destinations);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,32 +237,34 @@ class TableAPI final : public BaseAPI
|
||||
protected:
|
||||
virtual flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>>
|
||||
MakeWaypoints(flatbuffers::FlatBufferBuilder &builder,
|
||||
const std::vector<PhantomNode> &phantoms) const
|
||||
const std::vector<PhantomNodeCandidates> &candidates) const
|
||||
{
|
||||
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
|
||||
waypoints.reserve(phantoms.size());
|
||||
BOOST_ASSERT(phantoms.size() == parameters.coordinates.size());
|
||||
waypoints.reserve(candidates.size());
|
||||
BOOST_ASSERT(candidates.size() == parameters.coordinates.size());
|
||||
|
||||
boost::range::transform(
|
||||
phantoms, std::back_inserter(waypoints), [this, &builder](const PhantomNode &phantom) {
|
||||
return BaseAPI::MakeWaypoint(&builder, phantom)->Finish();
|
||||
});
|
||||
boost::range::transform(candidates,
|
||||
std::back_inserter(waypoints),
|
||||
[this, &builder](const PhantomNodeCandidates &candidates) {
|
||||
return BaseAPI::MakeWaypoint(&builder, candidates)->Finish();
|
||||
});
|
||||
return builder.CreateVector(waypoints);
|
||||
}
|
||||
|
||||
virtual flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>>
|
||||
MakeWaypoints(flatbuffers::FlatBufferBuilder &builder,
|
||||
const std::vector<PhantomNode> &phantoms,
|
||||
const std::vector<PhantomNodeCandidates> &candidates,
|
||||
const std::vector<std::size_t> &indices) const
|
||||
{
|
||||
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
|
||||
waypoints.reserve(indices.size());
|
||||
boost::range::transform(indices,
|
||||
std::back_inserter(waypoints),
|
||||
[this, &builder, phantoms](const std::size_t idx) {
|
||||
BOOST_ASSERT(idx < phantoms.size());
|
||||
return BaseAPI::MakeWaypoint(&builder, phantoms[idx])->Finish();
|
||||
});
|
||||
boost::range::transform(
|
||||
indices,
|
||||
std::back_inserter(waypoints),
|
||||
[this, &builder, &candidates](const std::size_t idx) {
|
||||
BOOST_ASSERT(idx < candidates.size());
|
||||
return BaseAPI::MakeWaypoint(&builder, candidates[idx])->Finish();
|
||||
});
|
||||
return builder.CreateVector(waypoints);
|
||||
}
|
||||
|
||||
@@ -313,29 +316,31 @@ class TableAPI final : public BaseAPI
|
||||
return builder.CreateVector(fb_table);
|
||||
}
|
||||
|
||||
virtual util::json::Array MakeWaypoints(const std::vector<PhantomNode> &phantoms) const
|
||||
virtual util::json::Array
|
||||
MakeWaypoints(const std::vector<PhantomNodeCandidates> &candidates) const
|
||||
{
|
||||
util::json::Array json_waypoints;
|
||||
json_waypoints.values.reserve(phantoms.size());
|
||||
BOOST_ASSERT(phantoms.size() == parameters.coordinates.size());
|
||||
json_waypoints.values.reserve(candidates.size());
|
||||
BOOST_ASSERT(candidates.size() == parameters.coordinates.size());
|
||||
|
||||
boost::range::transform(
|
||||
phantoms,
|
||||
std::back_inserter(json_waypoints.values),
|
||||
[this](const PhantomNode &phantom) { return BaseAPI::MakeWaypoint(phantom); });
|
||||
boost::range::transform(candidates,
|
||||
std::back_inserter(json_waypoints.values),
|
||||
[this](const PhantomNodeCandidates &candidates) {
|
||||
return BaseAPI::MakeWaypoint(candidates);
|
||||
});
|
||||
return json_waypoints;
|
||||
}
|
||||
|
||||
virtual util::json::Array MakeWaypoints(const std::vector<PhantomNode> &phantoms,
|
||||
virtual util::json::Array MakeWaypoints(const std::vector<PhantomNodeCandidates> &candidates,
|
||||
const std::vector<std::size_t> &indices) const
|
||||
{
|
||||
util::json::Array json_waypoints;
|
||||
json_waypoints.values.reserve(indices.size());
|
||||
boost::range::transform(indices,
|
||||
std::back_inserter(json_waypoints.values),
|
||||
[this, phantoms](const std::size_t idx) {
|
||||
BOOST_ASSERT(idx < phantoms.size());
|
||||
return BaseAPI::MakeWaypoint(phantoms[idx]);
|
||||
[this, &candidates](const std::size_t idx) {
|
||||
BOOST_ASSERT(idx < candidates.size());
|
||||
return BaseAPI::MakeWaypoint(candidates[idx]);
|
||||
});
|
||||
return json_waypoints;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ class TripAPI final : public RouteAPI
|
||||
}
|
||||
void MakeResponse(const std::vector<std::vector<NodeID>> &sub_trips,
|
||||
const std::vector<InternalRouteResult> &sub_routes,
|
||||
const std::vector<PhantomNode> &phantoms,
|
||||
const std::vector<PhantomNodeCandidates> &candidates,
|
||||
osrm::engine::api::ResultT &response) const
|
||||
{
|
||||
BOOST_ASSERT(sub_trips.size() == sub_routes.size());
|
||||
@@ -34,17 +34,17 @@ class TripAPI final : public RouteAPI
|
||||
if (response.is<flatbuffers::FlatBufferBuilder>())
|
||||
{
|
||||
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
|
||||
MakeResponse(sub_trips, sub_routes, phantoms, fb_result);
|
||||
MakeResponse(sub_trips, sub_routes, candidates, fb_result);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto &json_result = response.get<util::json::Object>();
|
||||
MakeResponse(sub_trips, sub_routes, phantoms, json_result);
|
||||
MakeResponse(sub_trips, sub_routes, candidates, json_result);
|
||||
}
|
||||
}
|
||||
void MakeResponse(const std::vector<std::vector<NodeID>> &sub_trips,
|
||||
const std::vector<InternalRouteResult> &sub_routes,
|
||||
const std::vector<PhantomNode> &phantoms,
|
||||
const std::vector<PhantomNodeCandidates> &candidates,
|
||||
flatbuffers::FlatBufferBuilder &fb_result) const
|
||||
{
|
||||
auto data_timestamp = facade.GetTimestamp();
|
||||
@@ -55,8 +55,8 @@ class TripAPI final : public RouteAPI
|
||||
}
|
||||
|
||||
auto response =
|
||||
MakeFBResponse(sub_routes, fb_result, [this, &fb_result, &sub_trips, &phantoms]() {
|
||||
return MakeWaypoints(fb_result, sub_trips, phantoms);
|
||||
MakeFBResponse(sub_routes, fb_result, [this, &fb_result, &sub_trips, &candidates]() {
|
||||
return MakeWaypoints(fb_result, sub_trips, candidates);
|
||||
});
|
||||
|
||||
if (!data_timestamp.empty())
|
||||
@@ -67,7 +67,7 @@ class TripAPI final : public RouteAPI
|
||||
}
|
||||
void MakeResponse(const std::vector<std::vector<NodeID>> &sub_trips,
|
||||
const std::vector<InternalRouteResult> &sub_routes,
|
||||
const std::vector<PhantomNode> &phantoms,
|
||||
const std::vector<PhantomNodeCandidates> &candidates,
|
||||
util::json::Object &response) const
|
||||
{
|
||||
auto number_of_routes = sub_trips.size();
|
||||
@@ -75,7 +75,7 @@ class TripAPI final : public RouteAPI
|
||||
routes.values.reserve(number_of_routes);
|
||||
for (auto index : util::irange<std::size_t>(0UL, sub_trips.size()))
|
||||
{
|
||||
auto route = MakeRoute(sub_routes[index].segment_end_coordinates,
|
||||
auto route = MakeRoute(sub_routes[index].leg_endpoints,
|
||||
sub_routes[index].unpacked_path_segments,
|
||||
sub_routes[index].source_traversed_in_reverse,
|
||||
sub_routes[index].target_traversed_in_reverse);
|
||||
@@ -83,7 +83,7 @@ class TripAPI final : public RouteAPI
|
||||
}
|
||||
if (!parameters.skip_waypoints)
|
||||
{
|
||||
response.values["waypoints"] = MakeWaypoints(sub_trips, phantoms);
|
||||
response.values["waypoints"] = MakeWaypoints(sub_trips, candidates);
|
||||
}
|
||||
response.values["trips"] = std::move(routes);
|
||||
response.values["code"] = "Ok";
|
||||
@@ -120,7 +120,7 @@ class TripAPI final : public RouteAPI
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<fbresult::Waypoint>>>
|
||||
MakeWaypoints(flatbuffers::FlatBufferBuilder &fb_result,
|
||||
const std::vector<std::vector<NodeID>> &sub_trips,
|
||||
const std::vector<PhantomNode> &phantoms) const
|
||||
const std::vector<PhantomNodeCandidates> &candidates) const
|
||||
{
|
||||
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
|
||||
waypoints.reserve(parameters.coordinates.size());
|
||||
@@ -132,7 +132,7 @@ class TripAPI final : public RouteAPI
|
||||
auto trip_index = input_idx_to_trip_idx[input_index];
|
||||
BOOST_ASSERT(!trip_index.NotUsed());
|
||||
|
||||
auto waypoint = BaseAPI::MakeWaypoint(&fb_result, phantoms[input_index]);
|
||||
auto waypoint = BaseAPI::MakeWaypoint(&fb_result, candidates[input_index]);
|
||||
waypoint->add_waypoint_index(trip_index.point_index);
|
||||
waypoint->add_trips_index(trip_index.sub_trip_index);
|
||||
waypoints.push_back(waypoint->Finish());
|
||||
@@ -142,7 +142,7 @@ class TripAPI final : public RouteAPI
|
||||
}
|
||||
|
||||
util::json::Array MakeWaypoints(const std::vector<std::vector<NodeID>> &sub_trips,
|
||||
const std::vector<PhantomNode> &phantoms) const
|
||||
const std::vector<PhantomNodeCandidates> &candidates) const
|
||||
{
|
||||
util::json::Array waypoints;
|
||||
waypoints.values.reserve(parameters.coordinates.size());
|
||||
@@ -154,7 +154,7 @@ class TripAPI final : public RouteAPI
|
||||
auto trip_index = input_idx_to_trip_idx[input_index];
|
||||
BOOST_ASSERT(!trip_index.NotUsed());
|
||||
|
||||
auto waypoint = BaseAPI::MakeWaypoint(phantoms[input_index]);
|
||||
auto waypoint = BaseAPI::MakeWaypoint(candidates[input_index]);
|
||||
waypoint.values["trips_index"] = trip_index.sub_trip_index;
|
||||
waypoint.values["waypoint_index"] = trip_index.point_index;
|
||||
waypoints.values.push_back(std::move(waypoint));
|
||||
|
||||
Reference in New Issue
Block a user