From 71bdfd2c6e94842956dd0b7686157f63d098de24 Mon Sep 17 00:00:00 2001 From: Daniel Patterson Date: Wed, 31 Oct 2018 22:02:54 -0700 Subject: [PATCH] Add feature to fill null matrix entries with straight-line estimates. --- features/testbot/distance_matrix.feature | 24 ++++++++++++++++ features/testbot/duration_matrix.feature | 23 +++++++++++++++ include/engine/api/table_parameters.hpp | 8 ++++-- include/nodejs/node_osrm_support.hpp | 13 +++++++++ .../server/api/table_parameter_grammar.hpp | 11 ++++++-- src/engine/plugins/table.cpp | 28 +++++++++++++++++++ 6 files changed, 103 insertions(+), 4 deletions(-) diff --git a/features/testbot/distance_matrix.feature b/features/testbot/distance_matrix.feature index 0b9e7c733..8cacb0a77 100644 --- a/features/testbot/distance_matrix.feature +++ b/features/testbot/distance_matrix.feature @@ -595,3 +595,27 @@ Feature: Basic Distance Matrix | d | 1478.9 | 1579 | 1779.1 | 0 | 1280.1 | 882.5 | | e | 198.8 | 298.9 | 499 | 710.3 | 0 | 1592.8 | | f | 596.4 | 696.5 | 896.6 | 1107.9 | 397.6 | 0 | + + + Scenario: Testbot - Filling in noroutes with estimates + Given a grid size of 300 meters + Given the extract extra arguments "--small-component-size 4" + Given the query options + | noroute_estimate | 5 | + Given the node map + """ + a b f h + d e g i + """ + + And the ways + | nodes | + | abeda | + | fhigf | + + When I request a travel distance matrix I should get + | | a | b | f | h | + | a | 0 | 300.2 | 900.7 | 1200.9 | + | b | 300.2 | 0 | 600.5 | 900.7 | + | f | 900.7 | 600.5 | 0 | 302.2 | + | h | 1200.9 | 900.7 | 300.2 | 0 | \ No newline at end of file diff --git a/features/testbot/duration_matrix.feature b/features/testbot/duration_matrix.feature index c6977dfab..61330051c 100644 --- a/features/testbot/duration_matrix.feature +++ b/features/testbot/duration_matrix.feature @@ -510,3 +510,26 @@ Feature: Basic Duration Matrix | | a | | a | 0 | | b | 24.1 | + + Scenario: Testbot - Filling in noroutes with estimates + Given a grid size of 300 meters + Given the extract extra arguments "--small-component-size 4" + Given the query options + | noroute_estimate | 5 | + Given the node map + """ + a b f h + d e g i + """ + + And the ways + | nodes | + | abeda | + | fhigf | + + When I request a travel time matrix I should get + | | a | b | f | h | + | a | 0 | 30 | 18 | 24 | + | b | 30 | 0 | 12 | 18 | + | f | 18 | 12 | 0 | 30 | + | h | 24 | 18 | 30 | 0 | \ No newline at end of file diff --git a/include/engine/api/table_parameters.hpp b/include/engine/api/table_parameters.hpp index 4f1a496bd..722b2cd85 100644 --- a/include/engine/api/table_parameters.hpp +++ b/include/engine/api/table_parameters.hpp @@ -59,6 +59,7 @@ struct TableParameters : public BaseParameters { std::vector sources; std::vector destinations; + std::size_t noroute_estimate = 0; enum class AnnotationsType { @@ -74,19 +75,22 @@ struct TableParameters : public BaseParameters template TableParameters(std::vector sources_, std::vector destinations_, + std::size_t noroute_estimate_, Args... args_) : BaseParameters{std::forward(args_)...}, sources{std::move(sources_)}, - destinations{std::move(destinations_)} + destinations{std::move(destinations_)}, noroute_estimate{noroute_estimate_} { } template TableParameters(std::vector sources_, std::vector destinations_, + std::size_t noroute_estimate_, const AnnotationsType annotations_, Args... args_) : BaseParameters{std::forward(args_)...}, sources{std::move(sources_)}, - destinations{std::move(destinations_)}, annotations{annotations_} + destinations{std::move(destinations_)}, noroute_estimate{noroute_estimate_}, + annotations{annotations_} { } diff --git a/include/nodejs/node_osrm_support.hpp b/include/nodejs/node_osrm_support.hpp index 27752e431..5b621dac7 100644 --- a/include/nodejs/node_osrm_support.hpp +++ b/include/nodejs/node_osrm_support.hpp @@ -1183,6 +1183,19 @@ argumentsToTableParameter(const Nan::FunctionCallbackInfo &args, } } + if (obj->Has(Nan::New("noroute_estimate").ToLocalChecked())) + { + auto noroute_estimate = obj->Get(Nan::New("noroute_estimate").ToLocalChecked()); + + if (!noroute_estimate->IsNumber() && !noroute_estimate->IsUint32()) + { + Nan::ThrowError("noroute_estimate must be an integral number"); + return table_parameters_ptr(); + } + + params->noroute_estimate = static_cast(noroute_estimate->NumberValue()); + } + return params; } diff --git a/include/server/api/table_parameter_grammar.hpp b/include/server/api/table_parameter_grammar.hpp index 5be793645..fccf87ea8 100644 --- a/include/server/api/table_parameter_grammar.hpp +++ b/include/server/api/table_parameter_grammar.hpp @@ -48,10 +48,16 @@ struct TableParametersGrammar : public BaseParametersGrammar - -('?' > (table_rule(qi::_r1) | base_rule(qi::_r1)) % '&'); + root_rule = + BaseGrammar::query_rule(qi::_r1) > -qi::lit(".json") > + -('?' > + (table_rule(qi::_r1) | base_rule(qi::_r1) | noroute_estimate_rule(qi::_r1)) % '&'); } TableParametersGrammar(qi::rule &root_rule_) : BaseGrammar(root_rule_) @@ -77,6 +83,7 @@ struct TableParametersGrammar : public BaseParametersGrammar table_rule; qi::rule sources_rule; qi::rule destinations_rule; + qi::rule noroute_estimate_rule; qi::rule size_t_; qi::symbols annotations; qi::rule annotations_list; diff --git a/src/engine/plugins/table.cpp b/src/engine/plugins/table.cpp index 3d89bc25a..0bdd79e9c 100644 --- a/src/engine/plugins/table.cpp +++ b/src/engine/plugins/table.cpp @@ -4,6 +4,7 @@ #include "engine/api/table_parameters.hpp" #include "engine/routing_algorithms/many_to_many.hpp" #include "engine/search_engine_data.hpp" +#include "util/coordinate_calculation.hpp" #include "util/json_container.hpp" #include "util/string_util.hpp" @@ -94,6 +95,33 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, return Error("NoTable", "No table found", result); } + // Scan table for null results - if any exist, replace with distance estimates + if (params.noroute_estimate > 0) + { + for (std::size_t row = 0; row < num_sources; row++) + { + for (std::size_t column = 0; column < num_destinations; column++) + { + if (result_tables_pair.first[row * num_sources + column] == MAXIMAL_EDGE_DURATION) + { + auto distance_estimate = util::coordinate_calculation::fccApproximateDistance( + snapped_phantoms[params.sources.empty() ? row : params.sources[row]] + .location, + snapped_phantoms[params.destinations.empty() ? column + : params.destinations[column]] + .location); + + result_tables_pair.first[row * num_sources + column] = + distance_estimate / (double)params.noroute_estimate; + if (!result_tables_pair.second.empty()) + { + result_tables_pair.second[row * num_sources + column] = distance_estimate; + } + } + } + } + } + api::TableAPI table_api{facade, params}; table_api.MakeResponse(result_tables_pair, snapped_phantoms, result);