Support rectangular matrix with less sources than targets

This commit is contained in:
Fabien Girard
2015-11-05 18:28:00 +01:00
committed by Patrick Niklaus
parent 4253ebf243
commit 478d4a571a
8 changed files with 128 additions and 29 deletions
+67 -14
View File
@@ -70,13 +70,14 @@ template <class DataFacadeT> class DistanceTablePlugin final : public BasePlugin
int HandleRequest(const RouteParameters &route_parameters,
osrm::json::Object &json_result) override final
{
if (!check_all_coordinates(route_parameters.coordinates))
if (!check_all_coordinates(route_parameters.coordinates) ||
(route_parameters.sources.size() && !check_all_coordinates(route_parameters.sources, 1)))
{
return 400;
}
const auto &input_bearings = route_parameters.bearings;
if (input_bearings.size() > 0 && route_parameters.coordinates.size() != input_bearings.size())
if (input_bearings.size() > 0 && route_parameters.coordinates.size() + route_parameters.sources.size() != input_bearings.size())
{
json_result.values["status"] = "Number of bearings does not match number of coordinates .";
return 400;
@@ -87,7 +88,7 @@ template <class DataFacadeT> class DistanceTablePlugin final : public BasePlugin
std::min(static_cast<unsigned>(max_locations_distance_table),
static_cast<unsigned>(route_parameters.coordinates.size()));
PhantomNodeArray phantom_node_vector(max_locations);
PhantomNodeArray phantom_node_target_vector(max_locations);
for (const auto i : osrm::irange(0u, max_locations))
{
if (checksum_OK && i < route_parameters.hints.size() &&
@@ -97,21 +98,49 @@ template <class DataFacadeT> class DistanceTablePlugin final : public BasePlugin
ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], current_phantom_node);
if (current_phantom_node.is_valid(facade->GetNumberOfNodes()))
{
phantom_node_vector[i].emplace_back(std::move(current_phantom_node));
phantom_node_target_vector[i].emplace_back(std::move(current_phantom_node));
continue;
}
}
const int bearing = input_bearings.size() > 0 ? input_bearings[i].first : 0;
const int range = input_bearings.size() > 0 ? (input_bearings[i].second?*input_bearings[i].second:10) : 180;
facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates[i],
phantom_node_vector[i], 1, bearing, range);
phantom_node_target_vector[i], 1, bearing, range);
BOOST_ASSERT(phantom_node_vector[i].front().is_valid(facade->GetNumberOfNodes()));
BOOST_ASSERT(phantom_node_target_vector[i].front().is_valid(facade->GetNumberOfNodes()));
}
unsigned nb_coordinates = route_parameters.coordinates.size();
max_locations = 0;
if (route_parameters.sources.size())
{
max_locations = std::min(static_cast<unsigned>(max_locations_distance_table),
static_cast<unsigned>(route_parameters.sources.size()));
}
PhantomNodeArray phantom_node_source_vector(max_locations);
for (const auto i : osrm::irange(0u, max_locations))
{
if (checksum_OK && i < route_parameters.hints.size() - route_parameters.coordinates.size() &&
!route_parameters.hints[i+route_parameters.coordinates.size()].empty())
{
PhantomNode current_phantom_node;
ObjectEncoder::DecodeFromBase64(route_parameters.hints[i+route_parameters.coordinates.size()], current_phantom_node);
if (current_phantom_node.is_valid(facade->GetNumberOfNodes()))
{
phantom_node_source_vector[i].emplace_back(std::move(current_phantom_node));
continue;
}
}
const int bearing = input_bearings.size() > 0 ? input_bearings[nb_coordinates + i].first : 0;
const int range = input_bearings.size() > 0 ? (input_bearings[nb_coordinates + i].second?*input_bearings[nb_coordinates + i].second:10) : 180;
facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.sources[i],
phantom_node_source_vector[i], 1, bearing, range);
BOOST_ASSERT(phantom_node_source_vector[i].front().is_valid(facade->GetNumberOfNodes()));
}
// TIMER_START(distance_table);
std::shared_ptr<std::vector<EdgeWeight>> result_table =
search_engine_ptr->distance_table(phantom_node_vector);
search_engine_ptr->distance_table(phantom_node_target_vector, phantom_node_source_vector);
// TIMER_STOP(distance_table);
if (!result_table)
@@ -119,17 +148,41 @@ template <class DataFacadeT> class DistanceTablePlugin final : public BasePlugin
return 400;
}
osrm::json::Array json_array;
const auto number_of_locations = phantom_node_vector.size();
for (const auto row : osrm::irange<std::size_t>(0, number_of_locations))
osrm::json::Array matrix_json_array;
const auto number_of_targets = phantom_node_target_vector.size();
const auto number_of_sources = (phantom_node_source_vector.size()) ? phantom_node_source_vector.size() : number_of_targets;
for (const auto row : osrm::irange<std::size_t>(0, number_of_sources))
{
osrm::json::Array json_row;
auto row_begin_iterator = result_table->begin() + (row * number_of_locations);
auto row_end_iterator = result_table->begin() + ((row + 1) * number_of_locations);
auto row_begin_iterator = result_table->begin() + (row * number_of_targets);
auto row_end_iterator = result_table->begin() + ((row + 1) * number_of_targets);
json_row.values.insert(json_row.values.end(), row_begin_iterator, row_end_iterator);
json_array.values.push_back(json_row);
matrix_json_array.values.push_back(json_row);
}
json_result.values["distance_table"] = matrix_json_array;
if (route_parameters.mapped_points) {
osrm::json::Array target_coord_json_array;
for (const std::vector<PhantomNode> &phantom_node_vector : phantom_node_target_vector)
{
osrm::json::Array json_coord;
FixedPointCoordinate coord = phantom_node_vector[0].location;
json_coord.values.push_back(coord.lat / COORDINATE_PRECISION);
json_coord.values.push_back(coord.lon / COORDINATE_PRECISION);
target_coord_json_array.values.push_back(json_coord);
}
json_result.values["target_mapped_coordinates"] = target_coord_json_array;
osrm::json::Array source_coord_json_array;
for (const std::vector<PhantomNode> &phantom_node_vector : phantom_node_source_vector)
{
osrm::json::Array json_coord;
FixedPointCoordinate coord = phantom_node_vector[0].location;
json_coord.values.push_back(coord.lat / COORDINATE_PRECISION);
json_coord.values.push_back(coord.lon / COORDINATE_PRECISION);
source_coord_json_array.values.push_back(json_coord);
}
if (source_coord_json_array.values.size())
json_result.values["source_mapped_coordinates"] = source_coord_json_array;
}
json_result.values["distance_table"] = json_array;
// osrm::json::render(reply.content, json_object);
return 200;
}
+2 -2
View File
@@ -45,9 +45,9 @@ class BasePlugin
virtual const std::string GetDescriptor() const = 0;
virtual int HandleRequest(const RouteParameters &, osrm::json::Object &) = 0;
virtual bool
check_all_coordinates(const std::vector<FixedPointCoordinate> &coordinates) const final
check_all_coordinates(const std::vector<FixedPointCoordinate> &coordinates, const unsigned min = 2) const final
{
if (2 > coordinates.size() || std::any_of(std::begin(coordinates), std::end(coordinates),
if (min > coordinates.size() || std::any_of(std::begin(coordinates), std::end(coordinates),
[](const FixedPointCoordinate &coordinate)
{
return !coordinate.is_valid();