diff --git a/data_structures/route_parameters.cpp b/data_structures/route_parameters.cpp index e63ecab1c..f65d547b3 100644 --- a/data_structures/route_parameters.cpp +++ b/data_structures/route_parameters.cpp @@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. RouteParameters::RouteParameters() : 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) { } @@ -146,22 +146,28 @@ void RouteParameters::addCoordinate( coordinates.emplace_back( static_cast(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)), static_cast(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates))); + is_source.emplace_back(true); + is_destination.emplace_back(true); } void RouteParameters::addDestination( const boost::fusion::vector &received_coordinates) { - destinations.emplace_back( + coordinates.emplace_back( static_cast(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)), static_cast(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates))); + is_source.emplace_back(false); + is_destination.emplace_back(true); } void RouteParameters::addSource( const boost::fusion::vector &received_coordinates) { - sources.emplace_back( + coordinates.emplace_back( static_cast(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)), static_cast(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) @@ -170,4 +176,3 @@ void RouteParameters::getCoordinatesFromGeometry(const std::string &geometry_str coordinates = pc.decode_string(geometry_string); } -void RouteParameters::setMappedPointsFlag(const bool flag) { mapped_points = flag; } diff --git a/include/osrm/route_parameters.hpp b/include/osrm/route_parameters.hpp index a91a3d6fb..6d2dda719 100644 --- a/include/osrm/route_parameters.hpp +++ b/include/osrm/route_parameters.hpp @@ -88,8 +88,6 @@ struct RouteParameters void getCoordinatesFromGeometry(const std::string &geometry_string); - void setMappedPointsFlag(const bool flag); - short zoom_level; bool print_instructions; bool alternate_route; @@ -98,7 +96,6 @@ struct RouteParameters bool deprecatedAPI; bool uturn_default; bool classify; - bool mapped_points; double matching_beta; double gps_precision; unsigned check_sum; @@ -112,8 +109,8 @@ struct RouteParameters std::vector>> bearings; std::vector uturns; std::vector coordinates; - std::vector destinations; - std::vector sources; + std::vector is_destination; + std::vector is_source; }; #endif // ROUTE_PARAMETERS_HPP diff --git a/plugins/distance_table.hpp b/plugins/distance_table.hpp index c5d4a7f3b..f44c71fab 100644 --- a/plugins/distance_table.hpp +++ b/plugins/distance_table.hpp @@ -70,35 +70,49 @@ template class DistanceTablePlugin final : public BasePlugin int HandleRequest(const RouteParameters &route_parameters, osrm::json::Object &json_result) override final { - const bool useSameTgtSrc = route_parameters.coordinates.size() ? true : false; - 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))) + if (!check_all_coordinates(route_parameters.coordinates)) { + json_result.values["status_message"] = "Coordinates are invalid."; return 400; } 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 && nb_coordinates != input_bearings.size()) + if (input_bearings.size() > 0 && + 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; } const bool checksum_OK = (route_parameters.check_sum == facade->GetCheckSum()); - unsigned max_locations = useSameTgtSrc ? - std::min(static_cast(max_locations_distance_table), - static_cast(route_parameters.coordinates.size())) : - std::min(static_cast(max_locations_distance_table), - static_cast(route_parameters.destinations.size())); - PhantomNodeArray phantom_node_target_vector(max_locations); - for (const auto i : osrm::irange(0u, max_locations)) + PhantomNodeArray phantom_node_source_vector(number_of_sources); + 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(0u, route_parameters.coordinates.size())) { if (checksum_OK && i < route_parameters.hints.size() && !route_parameters.hints[i].empty()) @@ -107,92 +121,99 @@ template class DistanceTablePlugin final : public BasePlugin ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], current_phantom_node); 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; } } 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(useSameTgtSrc ? route_parameters.coordinates[i] : route_parameters.destinations[i], - phantom_node_target_vector[i], 1, bearing, range); - - 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(max_locations_distance_table), - static_cast(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()) + const int range = input_bearings.size() > 0 + ? (input_bearings[i].second ? *input_bearings[i].second : 10) + : 180; + if (route_parameters.is_source[i]) { - PhantomNode current_phantom_node; - ObjectEncoder::DecodeFromBase64(route_parameters.hints[i + shift_coordinates], current_phantom_node); - if (current_phantom_node.is_valid(facade->GetNumberOfNodes())) + facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates[i], + *phantom_node_source_out_iter, 1, + 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)); - continue; + *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]); + 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> result_table = - search_engine_ptr->distance_table(phantom_node_target_vector, phantom_node_source_vector); - // TIMER_STOP(distance_table); + std::shared_ptr> result_table = search_engine_ptr->distance_table( + phantom_node_source_vector, phantom_node_target_vector); if (!result_table) { + json_result.values["status_message"] = "No distance table found."; return 400; } 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(0, number_of_sources)) { osrm::json::Array json_row; - auto row_begin_iterator = result_table->begin() + (row * number_of_targets); - auto row_end_iterator = result_table->begin() + ((row + 1) * 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_destination); json_row.values.insert(json_row.values.end(), row_begin_iterator, row_end_iterator); 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 &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 &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::Array target_coord_json_array; + for (const std::vector &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); } - // 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 &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; } diff --git a/plugins/trip.hpp b/plugins/trip.hpp index 57631a6ac..b05b4cf62 100644 --- a/plugins/trip.hpp +++ b/plugins/trip.hpp @@ -256,7 +256,7 @@ template class RoundTripPlugin final : public BasePlugin // compute the distance table of all phantom nodes const auto result_table = DistTableWrapper( - *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) { diff --git a/routing_algorithms/many_to_many.hpp b/routing_algorithms/many_to_many.hpp index a2c4f8a10..343aafe76 100644 --- a/routing_algorithms/many_to_many.hpp +++ b/routing_algorithms/many_to_many.hpp @@ -67,10 +67,10 @@ class ManyToManyRouting final ~ManyToManyRouting() {} std::shared_ptr> - 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_sources = (phantom_sources_array.size()) ? phantom_sources_array.size() : number_of_targets; std::shared_ptr> result_table = std::make_shared>(number_of_targets * number_of_sources, std::numeric_limits::max()); @@ -114,7 +114,7 @@ class ManyToManyRouting final // for each source do forward search unsigned source_id = 0; - for (const std::vector &phantom_node_vector : (phantom_sources_array.size() ? phantom_sources_array : phantom_targets_array)) + for (const std::vector &phantom_node_vector : phantom_sources_array) { query_heap.Clear(); for (const PhantomNode &phantom_node : phantom_node_vector) @@ -148,7 +148,7 @@ class ManyToManyRouting final } void ForwardRoutingStep(const unsigned source_id, - const unsigned number_of_locations, + const unsigned number_of_targets, QueryHeap &query_heap, const SearchSpaceWithBuckets &search_space_with_buckets, std::shared_ptr> result_table) const @@ -168,12 +168,12 @@ class ManyToManyRouting final const unsigned target_id = current_bucket.target_id; const int target_distance = current_bucket.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 const EdgeWeight new_distance = source_distance + target_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); } } diff --git a/server/api_grammar.hpp b/server/api_grammar.hpp index 618dfb2b5..2e3afca7a 100644 --- a/server/api_grammar.hpp +++ b/server/api_grammar.hpp @@ -42,7 +42,7 @@ template struct APIGrammar : qi::grammar> -(uturns); query = ('?') >> (+(zoom | output | jsonp | checksum | location | destination | source | hint | timestamp | bearing | u | cmp | 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') >> '=' >> qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)]; @@ -93,8 +93,6 @@ template struct APIGrammar : qi::grammar> qi::lit("locs") >> '=' >> 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")); stringwithDot = +(qi::char_("a-zA-Z0-9_.-")); @@ -105,8 +103,8 @@ template struct APIGrammar : qi::grammar api_call, query; qi::rule service, zoom, output, string, jsonp, checksum, location, destination, source, - hint, timestamp, bearing, stringwithDot, stringwithPercent, language, instruction, geometry, cmp, alt_route, u, - uturns, old_API, num_results, matching_beta, gps_precision, classify, locs, mapped_points, stringforPolyline; + hint, timestamp, bearing, stringwithDot, stringwithPercent, language, geometry, cmp, alt_route, u, + uturns, old_API, num_results, matching_beta, gps_precision, classify, locs, instruction, stringforPolyline; HandlerT *handler; };