Finish the nearest plugin
This commit is contained in:
parent
81319228bd
commit
14c36bc405
55
include/engine/api/nearest_api.hpp
Normal file
55
include/engine/api/nearest_api.hpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef ENGINE_API_NEAREST_API_HPP
|
||||||
|
#define ENGINE_API_NEAREST_API_HPP
|
||||||
|
|
||||||
|
#include "engine/api/base_api.hpp"
|
||||||
|
#include "engine/api/nearest_parameters.hpp"
|
||||||
|
|
||||||
|
#include "engine/api/json_factory.hpp"
|
||||||
|
#include "engine/phantom_node.hpp"
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace osrm
|
||||||
|
{
|
||||||
|
namespace engine
|
||||||
|
{
|
||||||
|
namespace api
|
||||||
|
{
|
||||||
|
|
||||||
|
class NearestAPI final : public BaseAPI
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NearestAPI(const datafacade::BaseDataFacade &facade_, const NearestParameters ¶meters_)
|
||||||
|
: BaseAPI(facade_, parameters_), parameters(parameters_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakeResponse(const std::vector<std::vector<PhantomNodeWithDistance>> &phantom_nodes, util::json::Object& response) const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(phantom_nodes.size() == 1);
|
||||||
|
BOOST_ASSERT(parameters.coordinates.size() == 1);
|
||||||
|
|
||||||
|
util::json::Array waypoints;
|
||||||
|
waypoints.values.resize(phantom_nodes.front().size());
|
||||||
|
std::transform(phantom_nodes.front().begin(),
|
||||||
|
phantom_nodes.front().end(), waypoints.values.begin(), [this](const PhantomNodeWithDistance& phantom_with_distance)
|
||||||
|
{
|
||||||
|
auto waypoint = MakeWaypoint(parameters.coordinates.front(), phantom_with_distance.phantom_node);
|
||||||
|
waypoint.values["distance"] = phantom_with_distance.distance;
|
||||||
|
return waypoint;
|
||||||
|
});
|
||||||
|
|
||||||
|
response.values["code"] = "ok";
|
||||||
|
response.values["waypoints"] = std::move(waypoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
const NearestParameters ¶meters;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // ns api
|
||||||
|
} // ns engine
|
||||||
|
} // ns osrm
|
||||||
|
|
||||||
|
#endif
|
@ -88,7 +88,6 @@ class BaseDataFacade
|
|||||||
const float max_distance,
|
const float max_distance,
|
||||||
const int bearing,
|
const int bearing,
|
||||||
const int bearing_range) = 0;
|
const int bearing_range) = 0;
|
||||||
|
|
||||||
virtual std::vector<PhantomNodeWithDistance>
|
virtual std::vector<PhantomNodeWithDistance>
|
||||||
NearestPhantomNodesInRange(const util::FixedPointCoordinate input_coordinate,
|
NearestPhantomNodesInRange(const util::FixedPointCoordinate input_coordinate,
|
||||||
const float max_distance) = 0;
|
const float max_distance) = 0;
|
||||||
@ -96,21 +95,30 @@ class BaseDataFacade
|
|||||||
virtual std::vector<PhantomNodeWithDistance>
|
virtual std::vector<PhantomNodeWithDistance>
|
||||||
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
const unsigned max_results,
|
const unsigned max_results,
|
||||||
const int bearing = 0,
|
const double max_distance,
|
||||||
const int bearing_range = 180) = 0;
|
const int bearing,
|
||||||
|
const int bearing_range) = 0;
|
||||||
|
virtual std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
|
const unsigned max_results,
|
||||||
|
const int bearing,
|
||||||
|
const int bearing_range) = 0;
|
||||||
|
virtual std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
|
const unsigned max_results) = 0;
|
||||||
|
virtual std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
|
const unsigned max_results, const double max_distance) = 0;
|
||||||
|
|
||||||
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
const util::FixedPointCoordinate input_coordinate) = 0;
|
const util::FixedPointCoordinate input_coordinate) = 0;
|
||||||
|
|
||||||
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
const util::FixedPointCoordinate input_coordinate, const double max_distance) = 0;
|
const util::FixedPointCoordinate input_coordinate, const double max_distance) = 0;
|
||||||
|
|
||||||
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
const util::FixedPointCoordinate input_coordinate,
|
const util::FixedPointCoordinate input_coordinate,
|
||||||
const double max_distance,
|
const double max_distance,
|
||||||
const int bearing,
|
const int bearing,
|
||||||
const int bearing_range) = 0;
|
const int bearing_range) = 0;
|
||||||
|
|
||||||
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
virtual std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
const util::FixedPointCoordinate input_coordinate,
|
const util::FixedPointCoordinate input_coordinate,
|
||||||
const int bearing,
|
const int bearing,
|
||||||
|
@ -383,11 +383,38 @@ class InternalDataFacade final : public BaseDataFacade
|
|||||||
bearing, bearing_range);
|
bearing, bearing_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
|
const unsigned max_results) override final
|
||||||
|
{
|
||||||
|
if (!m_static_rtree.get())
|
||||||
|
{
|
||||||
|
LoadRTree();
|
||||||
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<PhantomNodeWithDistance>
|
std::vector<PhantomNodeWithDistance>
|
||||||
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
const unsigned max_results,
|
const unsigned max_results,
|
||||||
const int bearing = 0,
|
const double max_distance) override final
|
||||||
const int bearing_range = 180) override final
|
{
|
||||||
|
if (!m_static_rtree.get())
|
||||||
|
{
|
||||||
|
LoadRTree();
|
||||||
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
|
const unsigned max_results,
|
||||||
|
const int bearing,
|
||||||
|
const int bearing_range) override final
|
||||||
{
|
{
|
||||||
if (!m_static_rtree.get())
|
if (!m_static_rtree.get())
|
||||||
{
|
{
|
||||||
@ -399,6 +426,23 @@ class InternalDataFacade final : public BaseDataFacade
|
|||||||
bearing_range);
|
bearing_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
|
const unsigned max_results,
|
||||||
|
const double max_distance,
|
||||||
|
const int bearing,
|
||||||
|
const int bearing_range) override final
|
||||||
|
{
|
||||||
|
if (!m_static_rtree.get())
|
||||||
|
{
|
||||||
|
LoadRTree();
|
||||||
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance,
|
||||||
|
bearing, bearing_range);
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
const util::FixedPointCoordinate input_coordinate, const double max_distance) override final
|
const util::FixedPointCoordinate input_coordinate, const double max_distance) override final
|
||||||
{
|
{
|
||||||
|
@ -235,7 +235,8 @@ class SharedDataFacade final : public BaseDataFacade
|
|||||||
}
|
}
|
||||||
data_timestamp_ptr = static_cast<storage::SharedDataTimestamp *>(
|
data_timestamp_ptr = static_cast<storage::SharedDataTimestamp *>(
|
||||||
storage::makeSharedMemory(storage::CURRENT_REGIONS,
|
storage::makeSharedMemory(storage::CURRENT_REGIONS,
|
||||||
sizeof(storage::SharedDataTimestamp), false, false)->Ptr());
|
sizeof(storage::SharedDataTimestamp), false, false)
|
||||||
|
->Ptr());
|
||||||
CURRENT_LAYOUT = storage::LAYOUT_NONE;
|
CURRENT_LAYOUT = storage::LAYOUT_NONE;
|
||||||
CURRENT_DATA = storage::DATA_NONE;
|
CURRENT_DATA = storage::DATA_NONE;
|
||||||
CURRENT_TIMESTAMP = 0;
|
CURRENT_TIMESTAMP = 0;
|
||||||
@ -306,8 +307,8 @@ class SharedDataFacade final : public BaseDataFacade
|
|||||||
LoadNames();
|
LoadNames();
|
||||||
LoadCoreInformation();
|
LoadCoreInformation();
|
||||||
|
|
||||||
util::SimpleLogger().Write()
|
util::SimpleLogger().Write() << "number of geometries: "
|
||||||
<< "number of geometries: " << m_coordinate_list->size();
|
<< m_coordinate_list->size();
|
||||||
for (unsigned i = 0; i < m_coordinate_list->size(); ++i)
|
for (unsigned i = 0; i < m_coordinate_list->size(); ++i)
|
||||||
{
|
{
|
||||||
if (!GetCoordinateOfNode(i).IsValid())
|
if (!GetCoordinateOfNode(i).IsValid())
|
||||||
@ -450,11 +451,38 @@ class SharedDataFacade final : public BaseDataFacade
|
|||||||
bearing, bearing_range);
|
bearing, bearing_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
|
const unsigned max_results) override final
|
||||||
|
{
|
||||||
|
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
|
||||||
|
{
|
||||||
|
LoadRTree();
|
||||||
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<PhantomNodeWithDistance>
|
std::vector<PhantomNodeWithDistance>
|
||||||
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
const unsigned max_results,
|
const unsigned max_results,
|
||||||
const int bearing = 0,
|
const double max_distance) override final
|
||||||
const int bearing_range = 180) override final
|
{
|
||||||
|
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
|
||||||
|
{
|
||||||
|
LoadRTree();
|
||||||
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
|
const unsigned max_results,
|
||||||
|
const int bearing,
|
||||||
|
const int bearing_range) override final
|
||||||
{
|
{
|
||||||
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
|
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
|
||||||
{
|
{
|
||||||
@ -466,6 +494,23 @@ class SharedDataFacade final : public BaseDataFacade
|
|||||||
bearing_range);
|
bearing_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
|
const unsigned max_results,
|
||||||
|
const double max_distance,
|
||||||
|
const int bearing,
|
||||||
|
const int bearing_range) override final
|
||||||
|
{
|
||||||
|
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
|
||||||
|
{
|
||||||
|
LoadRTree();
|
||||||
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance,
|
||||||
|
bearing, bearing_range);
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
const util::FixedPointCoordinate input_coordinate) override final
|
const util::FixedPointCoordinate input_coordinate) override final
|
||||||
{
|
{
|
||||||
@ -523,7 +568,6 @@ class SharedDataFacade final : public BaseDataFacade
|
|||||||
input_coordinate, bearing, bearing_range);
|
input_coordinate, bearing, bearing_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned GetCheckSum() const override final { return m_check_sum; }
|
unsigned GetCheckSum() const override final { return m_check_sum; }
|
||||||
|
|
||||||
unsigned GetNameIndexFromEdgeID(const unsigned id) const override final
|
unsigned GetNameIndexFromEdgeID(const unsigned id) const override final
|
||||||
|
@ -82,8 +82,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
std::vector<PhantomNodeWithDistance>
|
std::vector<PhantomNodeWithDistance>
|
||||||
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
const unsigned max_results,
|
const unsigned max_results,
|
||||||
const int bearing = 0,
|
const int bearing,
|
||||||
const int bearing_range = 180)
|
const int bearing_range)
|
||||||
{
|
{
|
||||||
auto results = rtree.Nearest(input_coordinate,
|
auto results = rtree.Nearest(input_coordinate,
|
||||||
[this, bearing, bearing_range](const EdgeData &data)
|
[this, bearing, bearing_range](const EdgeData &data)
|
||||||
@ -98,6 +98,67 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
return MakePhantomNodes(input_coordinate, results);
|
return MakePhantomNodes(input_coordinate, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns max_results nearest PhantomNodes in the given bearing range within the maximum distance.
|
||||||
|
// Does not filter by small/big component!
|
||||||
|
std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
|
const unsigned max_results,
|
||||||
|
const double max_distance,
|
||||||
|
const int bearing,
|
||||||
|
const int bearing_range)
|
||||||
|
{
|
||||||
|
auto results = rtree.Nearest(input_coordinate,
|
||||||
|
[this, bearing, bearing_range](const EdgeData &data)
|
||||||
|
{
|
||||||
|
return checkSegmentBearing(data, bearing, bearing_range);
|
||||||
|
},
|
||||||
|
[max_results, max_distance](const std::size_t num_results, const double min_dist)
|
||||||
|
{
|
||||||
|
return num_results >= max_results || min_dist > max_distance;
|
||||||
|
});
|
||||||
|
|
||||||
|
return MakePhantomNodes(input_coordinate, results);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns max_results nearest PhantomNodes.
|
||||||
|
// Does not filter by small/big component!
|
||||||
|
std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
|
const unsigned max_results)
|
||||||
|
{
|
||||||
|
auto results = rtree.Nearest(input_coordinate,
|
||||||
|
[](const EdgeData &)
|
||||||
|
{
|
||||||
|
return std::make_pair(true, true);
|
||||||
|
},
|
||||||
|
[max_results](const std::size_t num_results, const double)
|
||||||
|
{
|
||||||
|
return num_results >= max_results;
|
||||||
|
});
|
||||||
|
|
||||||
|
return MakePhantomNodes(input_coordinate, results);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns max_results nearest PhantomNodes in the given max distance.
|
||||||
|
// Does not filter by small/big component!
|
||||||
|
std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::FixedPointCoordinate input_coordinate,
|
||||||
|
const unsigned max_results,
|
||||||
|
const double max_distance)
|
||||||
|
{
|
||||||
|
auto results = rtree.Nearest(input_coordinate,
|
||||||
|
[](const EdgeData &)
|
||||||
|
{
|
||||||
|
return std::make_pair(true, true);
|
||||||
|
},
|
||||||
|
[max_results, max_distance](const std::size_t num_results, const double min_dist)
|
||||||
|
{
|
||||||
|
return num_results >= max_results || min_dist > max_distance;
|
||||||
|
});
|
||||||
|
|
||||||
|
return MakePhantomNodes(input_coordinate, results);
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the nearest phantom node. If this phantom node is not from a big component
|
// Returns the nearest phantom node. If this phantom node is not from a big component
|
||||||
// a second phantom node is return that is the nearest coordinate in a big component.
|
// a second phantom node is return that is the nearest coordinate in a big component.
|
||||||
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
|
||||||
|
@ -150,6 +150,70 @@ class BasePlugin
|
|||||||
return phantom_nodes;
|
return phantom_nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::vector<PhantomNodeWithDistance>> GetPhantomNodes(const api::BaseParameters ¶meters, unsigned number_of_results)
|
||||||
|
{
|
||||||
|
std::vector<std::vector<PhantomNodeWithDistance>> phantom_nodes(parameters.coordinates.size());
|
||||||
|
|
||||||
|
const bool use_hints = !parameters.hints.empty();
|
||||||
|
const bool use_bearings = !parameters.bearings.empty();
|
||||||
|
const bool use_radiuses = !parameters.radiuses.empty();
|
||||||
|
|
||||||
|
BOOST_ASSERT(parameters.IsValid());
|
||||||
|
for (const auto i : util::irange<std::size_t>(0, parameters.coordinates.size()))
|
||||||
|
{
|
||||||
|
if (use_hints && parameters.hints[i] &&
|
||||||
|
parameters.hints[i]->IsValid(parameters.coordinates[i], facade))
|
||||||
|
{
|
||||||
|
phantom_nodes[i].push_back(PhantomNodeWithDistance{
|
||||||
|
parameters.hints[i]->phantom,
|
||||||
|
util::coordinate_calculation::haversineDistance(
|
||||||
|
parameters.coordinates[i], parameters.hints[i]->phantom.location),
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_bearings && parameters.bearings[i])
|
||||||
|
{
|
||||||
|
if (use_radiuses && parameters.radiuses[i])
|
||||||
|
{
|
||||||
|
phantom_nodes[i] =
|
||||||
|
facade.NearestPhantomNodes(
|
||||||
|
parameters.coordinates[i], number_of_results, *parameters.radiuses[i],
|
||||||
|
parameters.bearings[i]->bearing, parameters.bearings[i]->range);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
phantom_nodes[i] =
|
||||||
|
facade.NearestPhantomNodes(
|
||||||
|
parameters.coordinates[i], number_of_results, parameters.bearings[i]->bearing,
|
||||||
|
parameters.bearings[i]->range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (use_radiuses && parameters.radiuses[i])
|
||||||
|
{
|
||||||
|
phantom_nodes[i] =
|
||||||
|
facade.NearestPhantomNodes(
|
||||||
|
parameters.coordinates[i], number_of_results, *parameters.radiuses[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
phantom_nodes[i] =
|
||||||
|
facade.NearestPhantomNodes(
|
||||||
|
parameters.coordinates[i], number_of_results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we didn't found a fitting node, return error
|
||||||
|
if (phantom_nodes[i].empty())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return phantom_nodes;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<PhantomNodePair> GetPhantomNodes(const api::BaseParameters ¶meters)
|
std::vector<PhantomNodePair> GetPhantomNodes(const api::BaseParameters ¶meters)
|
||||||
{
|
{
|
||||||
std::vector<PhantomNodePair> phantom_node_pairs(parameters.coordinates.size());
|
std::vector<PhantomNodePair> phantom_node_pairs(parameters.coordinates.size());
|
||||||
|
@ -26,7 +26,12 @@ struct NearestParametersGrammar final : public BaseParametersGrammar
|
|||||||
|
|
||||||
NearestParametersGrammar() : BaseParametersGrammar(root_rule, parameters)
|
NearestParametersGrammar() : BaseParametersGrammar(root_rule, parameters)
|
||||||
{
|
{
|
||||||
root_rule = "TODO(daniel-j-h)";
|
const auto set_number = [this](const unsigned number)
|
||||||
|
{
|
||||||
|
parameters.number_of_results = number;
|
||||||
|
};
|
||||||
|
nearest_rule = (qi::lit("number=") >> qi::uint_)[set_number];
|
||||||
|
root_rule = *(base_rule | nearest_rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
engine::api::NearestParameters parameters;
|
engine::api::NearestParameters parameters;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "engine/plugins/nearest.hpp"
|
#include "engine/plugins/nearest.hpp"
|
||||||
|
#include "engine/api/nearest_parameters.hpp"
|
||||||
|
#include "engine/api/nearest_api.hpp"
|
||||||
#include "engine/phantom_node.hpp"
|
#include "engine/phantom_node.hpp"
|
||||||
#include "util/integer_range.hpp"
|
#include "util/integer_range.hpp"
|
||||||
|
|
||||||
@ -17,69 +19,29 @@ namespace plugins
|
|||||||
NearestPlugin::NearestPlugin(datafacade::BaseDataFacade &facade) : BasePlugin{facade} {}
|
NearestPlugin::NearestPlugin(datafacade::BaseDataFacade &facade) : BasePlugin{facade} {}
|
||||||
|
|
||||||
Status NearestPlugin::HandleRequest(const api::NearestParameters ¶ms,
|
Status NearestPlugin::HandleRequest(const api::NearestParameters ¶ms,
|
||||||
util::json::Object &result)
|
util::json::Object &json_result)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(params.IsValid());
|
BOOST_ASSERT(params.IsValid());
|
||||||
|
|
||||||
if (!CheckAllCoordinates(params.coordinates))
|
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())
|
if (params.coordinates.size() != 1)
|
||||||
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())
|
|
||||||
{
|
{
|
||||||
result.values["status_message"] =
|
return Error("TooBig", "Only one input coordinate is supported", json_result);
|
||||||
std::string("Could not find a matching segments for coordinate");
|
|
||||||
return Status::NoSegment;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
result.values["status_message"] = "Found nearest edge";
|
|
||||||
if (number_of_results > 1)
|
|
||||||
{
|
|
||||||
util::json::Array results;
|
|
||||||
|
|
||||||
auto vector_length = phantom_node_vector.size();
|
auto phantom_nodes = GetPhantomNodes(params, params.number_of_results);
|
||||||
for (const auto i :
|
|
||||||
util::irange<std::size_t>(0, std::min(number_of_results, vector_length)))
|
if (phantom_nodes.front().size() == 0)
|
||||||
{
|
{
|
||||||
const auto &node = phantom_node_vector[i].phantom_node;
|
return Error("NoSegment", "Could not find a matching segments for coordinate", json_result);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
BOOST_ASSERT(phantom_nodes.front().size() > 0);
|
||||||
|
|
||||||
|
api::NearestAPI nearest_api(facade, params);
|
||||||
|
nearest_api.MakeResponse(phantom_nodes, json_result);
|
||||||
|
|
||||||
return Status::Ok;
|
return Status::Ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "server/service/nearest_service.hpp"
|
#include "server/service/nearest_service.hpp"
|
||||||
|
#include "server/service/utils.hpp"
|
||||||
|
|
||||||
#include "engine/api/nearest_parameters.hpp"
|
#include "engine/api/nearest_parameters.hpp"
|
||||||
#include "server/api/parameters_parser.hpp"
|
#include "server/api/parameters_parser.hpp"
|
||||||
@ -14,11 +15,58 @@ namespace server
|
|||||||
namespace service
|
namespace service
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
std::string getWrongOptionHelp(const engine::api::NearestParameters ¶meters)
|
||||||
|
{
|
||||||
|
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,
|
engine::Status NearestService::RunQuery(std::vector<util::FixedPointCoordinate> coordinates,
|
||||||
std::string &options,
|
std::string &options,
|
||||||
util::json::Object &result)
|
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;
|
return Status::Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user