Added flatbuffers output support to the 'Nearest' service.

This commit is contained in:
Denis Chaplygin 2019-08-06 15:31:39 +03:00
parent acd3e81ab4
commit 9d7a74445d
7 changed files with 147 additions and 59 deletions

View File

@ -74,7 +74,7 @@ class BaseAPI
// FIXME: gcc 4.9 does not like MakeWaypoints to be protected
// protected:
flatbuffers::Offset<fbresult::Waypoint> MakeWaypoint(flatbuffers::FlatBufferBuilder& builder, const PhantomNode &phantom) const
fbresult::WaypointBuilder MakeWaypoint(flatbuffers::FlatBufferBuilder& builder, const PhantomNode &phantom) const
{
auto location = fbresult::Position(static_cast<double>(util::toFloating(phantom.location.lon)), static_cast<double>(util::toFloating(phantom.location.lat)));
@ -82,12 +82,14 @@ class BaseAPI
waypoint.add_location(&location);
waypoint.add_distance(util::coordinate_calculation::fccApproximateDistance(phantom.location,
phantom.input_location));
waypoint.add_name(builder.CreateString(facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)).to_string()));
auto name_string = builder.CreateString(facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)).to_string());
waypoint.add_name(name_string);
if (parameters.generate_hints)
{
waypoint.add_hint(builder.CreateString(Hint{phantom, facade.GetCheckSum()}.ToBase64()));
auto hint_string = builder.CreateString(Hint{phantom, facade.GetCheckSum()}.ToBase64());
waypoint.add_hint(hint_string);
}
return waypoint.Finish();
return waypoint;
}
const datafacade::BaseDataFacade &facade;

View File

@ -13,6 +13,8 @@ namespace fbresult {
struct Position;
struct Uint64Pair;
struct Waypoint;
struct WaypointT;
@ -434,13 +436,35 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Position FLATBUFFERS_FINAL_CLASS {
};
FLATBUFFERS_STRUCT_END(Position, 16);
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Uint64Pair FLATBUFFERS_FINAL_CLASS {
private:
uint64_t first_;
uint64_t second_;
public:
Uint64Pair() {
memset(static_cast<void *>(this), 0, sizeof(Uint64Pair));
}
Uint64Pair(uint64_t _first, uint64_t _second)
: first_(flatbuffers::EndianScalar(_first)),
second_(flatbuffers::EndianScalar(_second)) {
}
uint64_t first() const {
return flatbuffers::EndianScalar(first_);
}
uint64_t second() const {
return flatbuffers::EndianScalar(second_);
}
};
FLATBUFFERS_STRUCT_END(Uint64Pair, 16);
struct WaypointT : public flatbuffers::NativeTable {
typedef Waypoint TableType;
std::string hint;
double distance;
std::string name;
std::unique_ptr<osrm::engine::api::fbresult::Position> location;
std::vector<double> nodes;
std::unique_ptr<osrm::engine::api::fbresult::Uint64Pair> nodes;
uint32_t matchings_index;
uint32_t waypoint_index;
uint32_t alternatives_count;
@ -479,8 +503,8 @@ struct Waypoint FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const osrm::engine::api::fbresult::Position *location() const {
return GetStruct<const osrm::engine::api::fbresult::Position *>(VT_LOCATION);
}
const flatbuffers::Vector<double> *nodes() const {
return GetPointer<const flatbuffers::Vector<double> *>(VT_NODES);
const osrm::engine::api::fbresult::Uint64Pair *nodes() const {
return GetStruct<const osrm::engine::api::fbresult::Uint64Pair *>(VT_NODES);
}
uint32_t matchings_index() const {
return GetField<uint32_t>(VT_MATCHINGS_INDEX, 0);
@ -502,8 +526,7 @@ struct Waypoint FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyOffset(verifier, VT_NAME) &&
verifier.VerifyString(name()) &&
VerifyField<osrm::engine::api::fbresult::Position>(verifier, VT_LOCATION) &&
VerifyOffset(verifier, VT_NODES) &&
verifier.VerifyVector(nodes()) &&
VerifyField<osrm::engine::api::fbresult::Uint64Pair>(verifier, VT_NODES) &&
VerifyField<uint32_t>(verifier, VT_MATCHINGS_INDEX) &&
VerifyField<uint32_t>(verifier, VT_WAYPOINT_INDEX) &&
VerifyField<uint32_t>(verifier, VT_ALTERNATIVES_COUNT) &&
@ -530,8 +553,8 @@ struct WaypointBuilder {
void add_location(const osrm::engine::api::fbresult::Position *location) {
fbb_.AddStruct(Waypoint::VT_LOCATION, location);
}
void add_nodes(flatbuffers::Offset<flatbuffers::Vector<double>> nodes) {
fbb_.AddOffset(Waypoint::VT_NODES, nodes);
void add_nodes(const osrm::engine::api::fbresult::Uint64Pair *nodes) {
fbb_.AddStruct(Waypoint::VT_NODES, nodes);
}
void add_matchings_index(uint32_t matchings_index) {
fbb_.AddElement<uint32_t>(Waypoint::VT_MATCHINGS_INDEX, matchings_index, 0);
@ -563,7 +586,7 @@ inline flatbuffers::Offset<Waypoint> CreateWaypoint(
double distance = 0.0,
flatbuffers::Offset<flatbuffers::String> name = 0,
const osrm::engine::api::fbresult::Position *location = 0,
flatbuffers::Offset<flatbuffers::Vector<double>> nodes = 0,
const osrm::engine::api::fbresult::Uint64Pair *nodes = 0,
uint32_t matchings_index = 0,
uint32_t waypoint_index = 0,
uint32_t alternatives_count = 0,
@ -587,21 +610,20 @@ inline flatbuffers::Offset<Waypoint> CreateWaypointDirect(
double distance = 0.0,
const char *name = nullptr,
const osrm::engine::api::fbresult::Position *location = 0,
const std::vector<double> *nodes = nullptr,
const osrm::engine::api::fbresult::Uint64Pair *nodes = 0,
uint32_t matchings_index = 0,
uint32_t waypoint_index = 0,
uint32_t alternatives_count = 0,
uint32_t trips_index = 0) {
auto hint__ = hint ? _fbb.CreateString(hint) : 0;
auto name__ = name ? _fbb.CreateString(name) : 0;
auto nodes__ = nodes ? _fbb.CreateVector<double>(*nodes) : 0;
return osrm::engine::api::fbresult::CreateWaypoint(
_fbb,
hint__,
distance,
name__,
location,
nodes__,
nodes,
matchings_index,
waypoint_index,
alternatives_count,
@ -2423,7 +2445,7 @@ inline void Waypoint::UnPackTo(WaypointT *_o, const flatbuffers::resolver_functi
{ auto _e = distance(); _o->distance = _e; };
{ auto _e = name(); if (_e) _o->name = _e->str(); };
{ auto _e = location(); if (_e) _o->location = std::unique_ptr<osrm::engine::api::fbresult::Position>(new osrm::engine::api::fbresult::Position(*_e)); };
{ auto _e = nodes(); if (_e) { _o->nodes.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->nodes[_i] = _e->Get(_i); } } };
{ auto _e = nodes(); if (_e) _o->nodes = std::unique_ptr<osrm::engine::api::fbresult::Uint64Pair>(new osrm::engine::api::fbresult::Uint64Pair(*_e)); };
{ auto _e = matchings_index(); _o->matchings_index = _e; };
{ auto _e = waypoint_index(); _o->waypoint_index = _e; };
{ auto _e = alternatives_count(); _o->alternatives_count = _e; };
@ -2442,7 +2464,7 @@ inline flatbuffers::Offset<Waypoint> CreateWaypoint(flatbuffers::FlatBufferBuild
auto _distance = _o->distance;
auto _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name);
auto _location = _o->location ? _o->location.get() : 0;
auto _nodes = _o->nodes.size() ? _fbb.CreateVector(_o->nodes) : 0;
auto _nodes = _o->nodes ? _o->nodes.get() : 0;
auto _matchings_index = _o->matchings_index;
auto _waypoint_index = _o->waypoint_index;
auto _alternatives_count = _o->alternatives_count;

View File

@ -1,12 +1,17 @@
include "position.fbs";
namespace osrm.engine.api.fbresult;
struct Uint64Pair {
first: uint64;
second: uint64;
}
table Waypoint {
hint: string;
distance: double;
name: string;
location: Position;
nodes: [double]; //Used only by 'Nearest' service
nodes: Uint64Pair; //Used only by 'Nearest' service
matchings_index: uint; //Used only by 'Match' service
waypoint_index: uint; //Used by 'Match' and 'Trip' services
alternatives_count: uint; //Used only by 'Match' service

View File

@ -27,11 +27,56 @@ class NearestAPI final : public BaseAPI
}
void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes,
util::json::Object &response) const
{
osrm::engine::api::ResultT &response) const {
BOOST_ASSERT(phantom_nodes.size() == 1);
BOOST_ASSERT(parameters.coordinates.size() == 1);
if(response.is<flatbuffers::FlatBufferBuilder>())
{
auto& fb_result = response.get<flatbuffers::FlatBufferBuilder>();
MakeResponse(phantom_nodes, fb_result);
}
else
{
auto& json_result = response.get<util::json::Object>();
MakeResponse(phantom_nodes, json_result);
}
}
void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes,
flatbuffers::FlatBufferBuilder &fb_result) const
{
fbresult::FBResultBuilder response(fb_result);
response.add_code(fb_result.CreateString("Ok"));
response.add_response_type(osrm::engine::api::fbresult::ServiceResponse::ServiceResponse_nearest);
fbresult::NearestBuilder nearest(fb_result);
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
waypoints.resize(phantom_nodes.front().size());
std::transform(
phantom_nodes.front().begin(),
phantom_nodes.front().end(),
waypoints.begin(),
[this, &fb_result](const PhantomNodeWithDistance &phantom_with_distance) {
auto &phantom_node = phantom_with_distance.phantom_node;
auto node_values = MakeNodes(phantom_node);
fbresult::Uint64Pair nodes{node_values.first, node_values.second};
auto waypoint = MakeWaypoint(fb_result,phantom_node);
waypoint.add_nodes(&nodes);
return waypoint.Finish();
});
auto waypoints_vector = fb_result.CreateVector(waypoints);
nearest.add_waypoints(waypoints_vector);
fb_result.Finish(response.Finish());
}
void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes,
util::json::Object &response) const
{
util::json::Array waypoints;
waypoints.values.resize(phantom_nodes.front().size());
std::transform(
@ -44,40 +89,10 @@ class NearestAPI final : public BaseAPI
util::json::Array nodes;
std::uint64_t from_node = 0;
std::uint64_t to_node = 0;
auto node_values = MakeNodes(phantom_node);
datafacade::BaseDataFacade::NodeForwardRange forward_geometry;
if (phantom_node.forward_segment_id.enabled)
{
auto segment_id = phantom_node.forward_segment_id.id;
const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
forward_geometry = facade.GetUncompressedForwardGeometry(geometry_id);
auto osm_node_id = facade.GetOSMNodeIDOfNode(
forward_geometry(phantom_node.fwd_segment_position));
to_node = static_cast<std::uint64_t>(osm_node_id);
}
if (phantom_node.reverse_segment_id.enabled)
{
auto segment_id = phantom_node.reverse_segment_id.id;
const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
const auto geometry = facade.GetUncompressedForwardGeometry(geometry_id);
auto osm_node_id =
facade.GetOSMNodeIDOfNode(geometry(phantom_node.fwd_segment_position + 1));
from_node = static_cast<std::uint64_t>(osm_node_id);
}
else if (phantom_node.forward_segment_id.enabled &&
phantom_node.fwd_segment_position > 0)
{
// In the case of one way, rely on forward segment only
auto osm_node_id = facade.GetOSMNodeIDOfNode(
forward_geometry(phantom_node.fwd_segment_position - 1));
from_node = static_cast<std::uint64_t>(osm_node_id);
}
nodes.values.push_back(from_node);
nodes.values.push_back(to_node);
nodes.values.push_back(node_values.first);
nodes.values.push_back(node_values.second);
waypoint.values["nodes"] = std::move(nodes);
return waypoint;
@ -88,6 +103,44 @@ class NearestAPI final : public BaseAPI
}
const NearestParameters &parameters;
protected:
std::pair<uint64_t, uint64_t> MakeNodes(const PhantomNode& phantom_node) const {
std::uint64_t from_node = 0;
std::uint64_t to_node = 0;
datafacade::BaseDataFacade::NodeForwardRange forward_geometry;
if (phantom_node.forward_segment_id.enabled)
{
auto segment_id = phantom_node.forward_segment_id.id;
const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
forward_geometry = facade.GetUncompressedForwardGeometry(geometry_id);
auto osm_node_id = facade.GetOSMNodeIDOfNode(
forward_geometry(phantom_node.fwd_segment_position));
to_node = static_cast<std::uint64_t>(osm_node_id);
}
if (phantom_node.reverse_segment_id.enabled)
{
auto segment_id = phantom_node.reverse_segment_id.id;
const auto geometry_id = facade.GetGeometryIndex(segment_id).id;
const auto geometry = facade.GetUncompressedForwardGeometry(geometry_id);
auto osm_node_id =
facade.GetOSMNodeIDOfNode(geometry(phantom_node.fwd_segment_position + 1));
from_node = static_cast<std::uint64_t>(osm_node_id);
}
else if (phantom_node.forward_segment_id.enabled &&
phantom_node.fwd_segment_position > 0)
{
// In the case of one way, rely on forward segment only
auto osm_node_id = facade.GetOSMNodeIDOfNode(
forward_geometry(phantom_node.fwd_segment_position - 1));
from_node = static_cast<std::uint64_t>(osm_node_id);
}
return std::make_pair(from_node, to_node);
}
};
} // ns api

View File

@ -54,11 +54,12 @@ class TableAPI final : public BaseAPI
if(response.is<flatbuffers::FlatBufferBuilder>()) {
auto& fb_result = response.get<flatbuffers::FlatBufferBuilder>();
MakeResponse(tables, phantoms, fallback_speed_cells, fb_result);
} else {
}
else
{
auto& json_result = response.get<util::json::Object>();
MakeResponse(tables, phantoms, fallback_speed_cells, json_result);
}
}
virtual void
@ -177,7 +178,7 @@ class TableAPI final : public BaseAPI
boost::range::transform(
phantoms,
std::back_inserter(waypoints),
[this, &builder](const PhantomNode &phantom) { return BaseAPI::MakeWaypoint(builder, phantom); });
[this, &builder](const PhantomNode &phantom) { return BaseAPI::MakeWaypoint(builder, phantom).Finish(); });
return builder.CreateVector(waypoints);
}
@ -192,7 +193,7 @@ class TableAPI final : public BaseAPI
std::back_inserter(waypoints),
[this, &builder, phantoms](const std::size_t idx) {
BOOST_ASSERT(idx < phantoms.size());
return BaseAPI::MakeWaypoint(builder, phantoms[idx]);
return BaseAPI::MakeWaypoint(builder, phantoms[idx]).Finish();
});
return builder.CreateVector(waypoints);
}

View File

@ -25,7 +25,6 @@ Status NearestPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms
{
BOOST_ASSERT(params.IsValid());
auto& json_result = result.get<util::json::Object>();
if (!CheckAlgorithms(params, algorithms, result))
return Status::Error;
@ -57,7 +56,7 @@ Status NearestPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms
BOOST_ASSERT(phantom_nodes.front().size() > 0);
api::NearestAPI nearest_api(facade, params);
nearest_api.MakeResponse(phantom_nodes, json_result);
nearest_api.MakeResponse(phantom_nodes, result);
return Status::Ok;
}

View File

@ -62,6 +62,12 @@ NearestService::RunQuery(std::size_t prefix_length, std::string &query, osrm::en
}
BOOST_ASSERT(parameters->IsValid());
if (parameters->format)
{
if (parameters->format == engine::api::BaseParameters::OutputFormatType::FLATBUFFERS) {
result = flatbuffers::FlatBufferBuilder();
}
}
return BaseService::routing_machine.Nearest(*parameters, result);
}
}