Address PR comments

This commit is contained in:
Patrick Niklaus 2015-12-08 03:16:07 +01:00
parent f2ee0aad20
commit 20c45be3b3
6 changed files with 120 additions and 99 deletions

View File

@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
RouteParameters::RouteParameters() RouteParameters::RouteParameters()
: zoom_level(18), print_instructions(false), alternate_route(true), geometry(true), : zoom_level(18), print_instructions(false), alternate_route(true), geometry(true),
compression(true), deprecatedAPI(false), uturn_default(false), classify(false), mapped_points(true), compression(true), deprecatedAPI(false), uturn_default(false), classify(false),
matching_beta(5), gps_precision(5), check_sum(-1), num_results(1) matching_beta(5), gps_precision(5), check_sum(-1), num_results(1)
{ {
} }
@ -146,22 +146,28 @@ void RouteParameters::addCoordinate(
coordinates.emplace_back( coordinates.emplace_back(
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)), static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates))); static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
is_source.emplace_back(true);
is_destination.emplace_back(true);
} }
void RouteParameters::addDestination( void RouteParameters::addDestination(
const boost::fusion::vector<double, double> &received_coordinates) const boost::fusion::vector<double, double> &received_coordinates)
{ {
destinations.emplace_back( coordinates.emplace_back(
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)), static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates))); static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
is_source.emplace_back(false);
is_destination.emplace_back(true);
} }
void RouteParameters::addSource( void RouteParameters::addSource(
const boost::fusion::vector<double, double> &received_coordinates) const boost::fusion::vector<double, double> &received_coordinates)
{ {
sources.emplace_back( coordinates.emplace_back(
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)), static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates))); static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
is_source.emplace_back(true);
is_destination.emplace_back(false);
} }
void RouteParameters::getCoordinatesFromGeometry(const std::string &geometry_string) void RouteParameters::getCoordinatesFromGeometry(const std::string &geometry_string)
@ -170,4 +176,3 @@ void RouteParameters::getCoordinatesFromGeometry(const std::string &geometry_str
coordinates = pc.decode_string(geometry_string); coordinates = pc.decode_string(geometry_string);
} }
void RouteParameters::setMappedPointsFlag(const bool flag) { mapped_points = flag; }

View File

@ -88,8 +88,6 @@ struct RouteParameters
void getCoordinatesFromGeometry(const std::string &geometry_string); void getCoordinatesFromGeometry(const std::string &geometry_string);
void setMappedPointsFlag(const bool flag);
short zoom_level; short zoom_level;
bool print_instructions; bool print_instructions;
bool alternate_route; bool alternate_route;
@ -98,7 +96,6 @@ struct RouteParameters
bool deprecatedAPI; bool deprecatedAPI;
bool uturn_default; bool uturn_default;
bool classify; bool classify;
bool mapped_points;
double matching_beta; double matching_beta;
double gps_precision; double gps_precision;
unsigned check_sum; unsigned check_sum;
@ -112,8 +109,8 @@ struct RouteParameters
std::vector<std::pair<const int,const boost::optional<int>>> bearings; std::vector<std::pair<const int,const boost::optional<int>>> bearings;
std::vector<bool> uturns; std::vector<bool> uturns;
std::vector<FixedPointCoordinate> coordinates; std::vector<FixedPointCoordinate> coordinates;
std::vector<FixedPointCoordinate> destinations; std::vector<bool> is_destination;
std::vector<FixedPointCoordinate> sources; std::vector<bool> is_source;
}; };
#endif // ROUTE_PARAMETERS_HPP #endif // ROUTE_PARAMETERS_HPP

View File

@ -70,35 +70,49 @@ template <class DataFacadeT> class DistanceTablePlugin final : public BasePlugin
int HandleRequest(const RouteParameters &route_parameters, int HandleRequest(const RouteParameters &route_parameters,
osrm::json::Object &json_result) override final osrm::json::Object &json_result) override final
{ {
const bool useSameTgtSrc = route_parameters.coordinates.size() ? true : false; if (!check_all_coordinates(route_parameters.coordinates))
if ((useSameTgtSrc && route_parameters.destinations.size()) || (useSameTgtSrc && route_parameters.sources.size()))
{
return 400;
}
if ((useSameTgtSrc && !check_all_coordinates(route_parameters.coordinates)) ||
(!useSameTgtSrc && !check_all_coordinates(route_parameters.destinations, 2) && !check_all_coordinates(route_parameters.sources, 1)))
{ {
json_result.values["status_message"] = "Coordinates are invalid.";
return 400; return 400;
} }
const auto &input_bearings = route_parameters.bearings; const auto &input_bearings = route_parameters.bearings;
unsigned nb_coordinates = useSameTgtSrc ? route_parameters.coordinates.size() : (route_parameters.destinations.size() + route_parameters.sources.size()); if (input_bearings.size() > 0 &&
if (input_bearings.size() > 0 && nb_coordinates != input_bearings.size()) route_parameters.coordinates.size() != input_bearings.size())
{ {
json_result.values["status"] = "Number of bearings does not match number of coordinates ."; json_result.values["status_message"] =
"Number of bearings does not match number of coordinates.";
return 400;
}
auto number_of_sources =
std::count_if(route_parameters.is_source.begin(), route_parameters.is_source.end(),
[](const bool is_source)
{
return is_source;
});
auto number_of_destination =
std::count_if(route_parameters.is_destination.begin(),
route_parameters.is_destination.end(), [](const bool is_destination)
{
return is_destination;
});
if (number_of_sources * number_of_destination >
max_locations_distance_table * max_locations_distance_table)
{
json_result.values["status_message"] =
"Number of bearings does not match number of coordinates.";
return 400; return 400;
} }
const bool checksum_OK = (route_parameters.check_sum == facade->GetCheckSum()); const bool checksum_OK = (route_parameters.check_sum == facade->GetCheckSum());
unsigned max_locations = useSameTgtSrc ?
std::min(static_cast<unsigned>(max_locations_distance_table),
static_cast<unsigned>(route_parameters.coordinates.size())) :
std::min(static_cast<unsigned>(max_locations_distance_table),
static_cast<unsigned>(route_parameters.destinations.size()));
PhantomNodeArray phantom_node_target_vector(max_locations); PhantomNodeArray phantom_node_source_vector(number_of_sources);
for (const auto i : osrm::irange(0u, max_locations)) PhantomNodeArray phantom_node_target_vector(number_of_destination);
auto phantom_node_source_out_iter = phantom_node_source_vector.begin();
auto phantom_node_target_out_iter = phantom_node_target_vector.begin();
for (const auto i : osrm::irange<std::size_t>(0u, route_parameters.coordinates.size()))
{ {
if (checksum_OK && i < route_parameters.hints.size() && if (checksum_OK && i < route_parameters.hints.size() &&
!route_parameters.hints[i].empty()) !route_parameters.hints[i].empty())
@ -107,92 +121,99 @@ template <class DataFacadeT> class DistanceTablePlugin final : public BasePlugin
ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], current_phantom_node); ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], current_phantom_node);
if (current_phantom_node.is_valid(facade->GetNumberOfNodes())) if (current_phantom_node.is_valid(facade->GetNumberOfNodes()))
{ {
phantom_node_target_vector[i].emplace_back(std::move(current_phantom_node)); if (route_parameters.is_source[i])
{
phantom_node_source_out_iter->emplace_back(std::move(current_phantom_node));
if (route_parameters.is_destination[i])
{
*phantom_node_target_out_iter = *phantom_node_source_out_iter;
phantom_node_target_out_iter++;
}
phantom_node_source_out_iter++;
}
else
{
BOOST_ASSERT(route_parameters.is_destination[i] && !route_parameters.is_source[i]);
phantom_node_target_out_iter->emplace_back(std::move(current_phantom_node));
phantom_node_target_out_iter++;
}
continue; continue;
} }
} }
const int bearing = input_bearings.size() > 0 ? input_bearings[i].first : 0; 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; const int range = input_bearings.size() > 0
facade->IncrementalFindPhantomNodeForCoordinate(useSameTgtSrc ? route_parameters.coordinates[i] : route_parameters.destinations[i], ? (input_bearings[i].second ? *input_bearings[i].second : 10)
phantom_node_target_vector[i], 1, bearing, range); : 180;
if (route_parameters.is_source[i])
BOOST_ASSERT(phantom_node_target_vector[i].front().is_valid(facade->GetNumberOfNodes()));
}
unsigned shift_coordinates = (useSameTgtSrc) ? 0 : route_parameters.destinations.size();
max_locations = 0;
if (!useSameTgtSrc)
{
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() - shift_coordinates &&
!route_parameters.hints[i + shift_coordinates].empty())
{ {
PhantomNode current_phantom_node; facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates[i],
ObjectEncoder::DecodeFromBase64(route_parameters.hints[i + shift_coordinates], current_phantom_node); *phantom_node_source_out_iter, 1,
if (current_phantom_node.is_valid(facade->GetNumberOfNodes())) bearing, range);
BOOST_ASSERT(
phantom_node_source_out_iter->front().is_valid(facade->GetNumberOfNodes()));
if (route_parameters.is_destination[i])
{ {
phantom_node_source_vector[i].emplace_back(std::move(current_phantom_node)); *phantom_node_target_out_iter = *phantom_node_source_out_iter;
continue; phantom_node_target_out_iter++;
} }
phantom_node_source_out_iter++;
}
else
{
BOOST_ASSERT(route_parameters.is_destination[i] && !route_parameters.is_source[i]);
facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates[i],
*phantom_node_target_out_iter, 1,
bearing, range);
BOOST_ASSERT(
phantom_node_target_out_iter->front().is_valid(facade->GetNumberOfNodes()));
phantom_node_target_out_iter++;
} }
const int bearing = input_bearings.size() > 0 ? input_bearings[i + shift_coordinates].first : 0;
const int range = input_bearings.size() > 0 ? (input_bearings[i + shift_coordinates].second?*input_bearings[i + shift_coordinates].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()));
} }
BOOST_ASSERT((phantom_node_source_out_iter - phantom_node_source_vector.begin()) ==
number_of_sources);
BOOST_ASSERT((phantom_node_target_out_iter - phantom_node_target_vector.begin()) ==
number_of_destination);
// TIMER_START(distance_table); std::shared_ptr<std::vector<EdgeWeight>> result_table = search_engine_ptr->distance_table(
std::shared_ptr<std::vector<EdgeWeight>> result_table = phantom_node_source_vector, phantom_node_target_vector);
search_engine_ptr->distance_table(phantom_node_target_vector, phantom_node_source_vector);
// TIMER_STOP(distance_table);
if (!result_table) if (!result_table)
{ {
json_result.values["status_message"] = "No distance table found.";
return 400; return 400;
} }
osrm::json::Array matrix_json_array; 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)) for (const auto row : osrm::irange<std::size_t>(0, number_of_sources))
{ {
osrm::json::Array json_row; osrm::json::Array json_row;
auto row_begin_iterator = result_table->begin() + (row * number_of_targets); auto row_begin_iterator = result_table->begin() + (row * number_of_destination);
auto row_end_iterator = result_table->begin() + ((row + 1) * number_of_targets); auto row_end_iterator = result_table->begin() + ((row + 1) * number_of_destination);
json_row.values.insert(json_row.values.end(), row_begin_iterator, row_end_iterator); json_row.values.insert(json_row.values.end(), row_begin_iterator, row_end_iterator);
matrix_json_array.values.push_back(json_row); matrix_json_array.values.push_back(json_row);
} }
json_result.values["distance_table"] = matrix_json_array; json_result.values["distance_table"] = matrix_json_array;
if (route_parameters.mapped_points) { osrm::json::Array target_coord_json_array;
osrm::json::Array target_coord_json_array; for (const std::vector<PhantomNode> &phantom_node_vector : phantom_node_target_vector)
for (const std::vector<PhantomNode> &phantom_node_vector : phantom_node_target_vector) {
{ osrm::json::Array json_coord;
osrm::json::Array json_coord; FixedPointCoordinate coord = phantom_node_vector[0].location;
FixedPointCoordinate coord = phantom_node_vector[0].location; json_coord.values.push_back(coord.lat / COORDINATE_PRECISION);
json_coord.values.push_back(coord.lat / COORDINATE_PRECISION); json_coord.values.push_back(coord.lon / COORDINATE_PRECISION);
json_coord.values.push_back(coord.lon / COORDINATE_PRECISION); target_coord_json_array.values.push_back(json_coord);
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;
} }
// osrm::json::render(reply.content, json_object); json_result.values["destination_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);
}
json_result.values["source_coordinates"] = source_coord_json_array;
return 200; return 200;
} }

View File

@ -256,7 +256,7 @@ template <class DataFacadeT> class RoundTripPlugin final : public BasePlugin
// compute the distance table of all phantom nodes // compute the distance table of all phantom nodes
const auto result_table = DistTableWrapper<EdgeWeight>( const auto result_table = DistTableWrapper<EdgeWeight>(
*search_engine_ptr->distance_table(phantom_node_vector), number_of_locations); *search_engine_ptr->distance_table(phantom_node_vector, phantom_node_vector), number_of_locations);
if (result_table.size() == 0) if (result_table.size() == 0)
{ {

View File

@ -67,10 +67,10 @@ class ManyToManyRouting final
~ManyToManyRouting() {} ~ManyToManyRouting() {}
std::shared_ptr<std::vector<EdgeWeight>> std::shared_ptr<std::vector<EdgeWeight>>
operator()(const PhantomNodeArray &phantom_targets_array, const PhantomNodeArray &phantom_sources_array = PhantomNodeArray(0)) const operator()(const PhantomNodeArray &phantom_sources_array, const PhantomNodeArray &phantom_targets_array) const
{ {
const auto number_of_sources = phantom_sources_array.size();
const auto number_of_targets = phantom_targets_array.size(); const auto number_of_targets = phantom_targets_array.size();
const auto number_of_sources = (phantom_sources_array.size()) ? phantom_sources_array.size() : number_of_targets;
std::shared_ptr<std::vector<EdgeWeight>> result_table = std::shared_ptr<std::vector<EdgeWeight>> result_table =
std::make_shared<std::vector<EdgeWeight>>(number_of_targets * number_of_sources, std::make_shared<std::vector<EdgeWeight>>(number_of_targets * number_of_sources,
std::numeric_limits<EdgeWeight>::max()); std::numeric_limits<EdgeWeight>::max());
@ -114,7 +114,7 @@ class ManyToManyRouting final
// for each source do forward search // for each source do forward search
unsigned source_id = 0; unsigned source_id = 0;
for (const std::vector<PhantomNode> &phantom_node_vector : (phantom_sources_array.size() ? phantom_sources_array : phantom_targets_array)) for (const std::vector<PhantomNode> &phantom_node_vector : phantom_sources_array)
{ {
query_heap.Clear(); query_heap.Clear();
for (const PhantomNode &phantom_node : phantom_node_vector) for (const PhantomNode &phantom_node : phantom_node_vector)
@ -148,7 +148,7 @@ class ManyToManyRouting final
} }
void ForwardRoutingStep(const unsigned source_id, void ForwardRoutingStep(const unsigned source_id,
const unsigned number_of_locations, const unsigned number_of_targets,
QueryHeap &query_heap, QueryHeap &query_heap,
const SearchSpaceWithBuckets &search_space_with_buckets, const SearchSpaceWithBuckets &search_space_with_buckets,
std::shared_ptr<std::vector<EdgeWeight>> result_table) const std::shared_ptr<std::vector<EdgeWeight>> result_table) const
@ -168,12 +168,12 @@ class ManyToManyRouting final
const unsigned target_id = current_bucket.target_id; const unsigned target_id = current_bucket.target_id;
const int target_distance = current_bucket.distance; const int target_distance = current_bucket.distance;
const EdgeWeight current_distance = const EdgeWeight current_distance =
(*result_table)[source_id * number_of_locations + target_id]; (*result_table)[source_id * number_of_targets + target_id];
// check if new distance is better // check if new distance is better
const EdgeWeight new_distance = source_distance + target_distance; const EdgeWeight new_distance = source_distance + target_distance;
if (new_distance >= 0 && new_distance < current_distance) if (new_distance >= 0 && new_distance < current_distance)
{ {
(*result_table)[source_id * number_of_locations + target_id] = (*result_table)[source_id * number_of_targets + target_id] =
(source_distance + target_distance); (source_distance + target_distance);
} }
} }

View File

@ -42,7 +42,7 @@ template <typename Iterator, class HandlerT> struct APIGrammar : qi::grammar<Ite
*(query) >> -(uturns); *(query) >> -(uturns);
query = ('?') >> (+(zoom | output | jsonp | checksum | location | destination | source | hint | timestamp | bearing | u | cmp | query = ('?') >> (+(zoom | output | jsonp | checksum | location | destination | source | hint | timestamp | bearing | u | cmp |
language | instruction | geometry | alt_route | old_API | num_results | language | instruction | geometry | alt_route | old_API | num_results |
matching_beta | gps_precision | classify | locs | mapped_points)); matching_beta | gps_precision | classify | locs));
zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >> zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >>
qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)]; qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)];
@ -93,8 +93,6 @@ template <typename Iterator, class HandlerT> struct APIGrammar : qi::grammar<Ite
qi::bool_[boost::bind(&HandlerT::setClassify, handler, ::_1)]; qi::bool_[boost::bind(&HandlerT::setClassify, handler, ::_1)];
locs = (-qi::lit('&')) >> qi::lit("locs") >> '=' >> locs = (-qi::lit('&')) >> qi::lit("locs") >> '=' >>
stringforPolyline[boost::bind(&HandlerT::getCoordinatesFromGeometry, handler, ::_1)]; stringforPolyline[boost::bind(&HandlerT::getCoordinatesFromGeometry, handler, ::_1)];
mapped_points = (-qi::lit('&')) >> qi::lit("mapped_points") >> '=' >>
qi::bool_[boost::bind(&HandlerT::setMappedPointsFlag, handler, ::_1)];
string = +(qi::char_("a-zA-Z")); string = +(qi::char_("a-zA-Z"));
stringwithDot = +(qi::char_("a-zA-Z0-9_.-")); stringwithDot = +(qi::char_("a-zA-Z0-9_.-"));
@ -105,8 +103,8 @@ template <typename Iterator, class HandlerT> struct APIGrammar : qi::grammar<Ite
qi::rule<Iterator> api_call, query; qi::rule<Iterator> api_call, query;
qi::rule<Iterator, std::string()> service, zoom, output, string, jsonp, checksum, location, destination, source, qi::rule<Iterator, std::string()> service, zoom, output, string, jsonp, checksum, location, destination, source,
hint, timestamp, bearing, stringwithDot, stringwithPercent, language, instruction, geometry, cmp, alt_route, u, hint, timestamp, bearing, stringwithDot, stringwithPercent, language, geometry, cmp, alt_route, u,
uturns, old_API, num_results, matching_beta, gps_precision, classify, locs, mapped_points, stringforPolyline; uturns, old_API, num_results, matching_beta, gps_precision, classify, locs, instruction, stringforPolyline;
HandlerT *handler; HandlerT *handler;
}; };