Finish the nearest plugin

This commit is contained in:
Patrick Niklaus
2016-02-23 00:44:35 +01:00
parent 81319228bd
commit 14c36bc405
9 changed files with 363 additions and 72 deletions
+16 -54
View File
@@ -1,4 +1,6 @@
#include "engine/plugins/nearest.hpp"
#include "engine/api/nearest_parameters.hpp"
#include "engine/api/nearest_api.hpp"
#include "engine/phantom_node.hpp"
#include "util/integer_range.hpp"
@@ -17,69 +19,29 @@ namespace plugins
NearestPlugin::NearestPlugin(datafacade::BaseDataFacade &facade) : BasePlugin{facade} {}
Status NearestPlugin::HandleRequest(const api::NearestParameters &params,
util::json::Object &result)
util::json::Object &json_result)
{
BOOST_ASSERT(params.IsValid());
if (!CheckAllCoordinates(params.coordinates))
return Error("invalid-options", "Coordinates are invalid", result);
return Error("InvalidOptions", "Coordinates are invalid", json_result);
if (params.bearings.size() > 0 && params.coordinates.size() != params.bearings.size())
return Error("invalid-options", "Number of bearings does not match number of coordinates",
result);
const auto &input_bearings = params.bearings;
auto number_of_results = static_cast<std::size_t>(params.number_of_results);
/* TODO(daniel-j-h): bearing range?
const int bearing = input_bearings.size() > 0 ? input_bearings.front().first : 0;
const int range = input_bearings.size() > 0
? (input_bearings.front().second ? *input_bearings.front().second : 10)
: 180;
auto phantom_node_vector =
facade.NearestPhantomNodes(params.coordinates.front(), number_of_results, bearing, range);
if (phantom_node_vector.empty())
if (params.coordinates.size() != 1)
{
result.values["status_message"] =
std::string("Could not find a matching segments for coordinate");
return Status::NoSegment;
return Error("TooBig", "Only one input coordinate is supported", json_result);
}
else
{
result.values["status_message"] = "Found nearest edge";
if (number_of_results > 1)
{
util::json::Array results;
auto vector_length = phantom_node_vector.size();
for (const auto i :
util::irange<std::size_t>(0, std::min(number_of_results, vector_length)))
{
const auto &node = phantom_node_vector[i].phantom_node;
util::json::Array json_coordinate;
util::json::Object result;
json_coordinate.values.push_back(node.location.lat / COORDINATE_PRECISION);
json_coordinate.values.push_back(node.location.lon / COORDINATE_PRECISION);
result.values["mapped coordinate"] = json_coordinate;
result.values["name"] = facade.get_name_for_id(node.name_id);
results.values.push_back(result);
}
result.values["results"] = results;
}
else
{
util::json::Array json_coordinate;
json_coordinate.values.push_back(phantom_node_vector.front().phantom_node.location.lat /
COORDINATE_PRECISION);
json_coordinate.values.push_back(phantom_node_vector.front().phantom_node.location.lon /
COORDINATE_PRECISION);
result.values["mapped_coordinate"] = json_coordinate;
result.values["name"] =
facade.get_name_for_id(phantom_node_vector.front().phantom_node.name_id);
}
auto phantom_nodes = GetPhantomNodes(params, params.number_of_results);
if (phantom_nodes.front().size() == 0)
{
return Error("NoSegment", "Could not find a matching segments for coordinate", json_result);
}
*/
BOOST_ASSERT(phantom_nodes.front().size() > 0);
api::NearestAPI nearest_api(facade, params);
nearest_api.MakeResponse(phantom_nodes, json_result);
return Status::Ok;
}
}
+49 -1
View File
@@ -1,4 +1,5 @@
#include "server/service/nearest_service.hpp"
#include "server/service/utils.hpp"
#include "engine/api/nearest_parameters.hpp"
#include "server/api/parameters_parser.hpp"
@@ -14,11 +15,58 @@ namespace server
namespace service
{
namespace
{
std::string getWrongOptionHelp(const engine::api::NearestParameters &parameters)
{
std::string help;
const auto coord_size = parameters.coordinates.size();
const bool param_size_mismatch = constrainParamSize(PARAMETER_SIZE_MISMATCH_MSG, "hints",
parameters.hints, coord_size, help) ||
constrainParamSize(PARAMETER_SIZE_MISMATCH_MSG, "bearings",
parameters.bearings, coord_size, help) ||
constrainParamSize(PARAMETER_SIZE_MISMATCH_MSG, "radiuses",
parameters.radiuses, coord_size, help);
if (!param_size_mismatch && parameters.coordinates.size() < 2)
{
help = "Number of coordinates needs to be at least two.";
}
return help;
}
} // anon. ns
engine::Status NearestService::RunQuery(std::vector<util::FixedPointCoordinate> coordinates,
std::string &options,
util::json::Object &result)
{
// TODO(daniel-j-h)
auto options_iterator = options.begin();
auto parameters =
api::parseParameters<engine::api::NearestParameters>(options_iterator, options.end());
if (!parameters || options_iterator != options.end())
{
const auto position = std::distance(options.begin(), options_iterator);
result.values["code"] = "invalid-options";
result.values["message"] =
"Options string malformed close to position " + std::to_string(position);
return engine::Status::Error;
}
BOOST_ASSERT(parameters);
parameters->coordinates = std::move(coordinates);
if (!parameters->IsValid())
{
result.values["code"] = "invalid-options";
result.values["message"] = getWrongOptionHelp(*parameters);
return engine::Status::Error;
}
BOOST_ASSERT(parameters->IsValid());
return BaseService::routing_machine.Nearest(*parameters, result);
return Status::Error;
}
}