Skip to content

Commit 0a6ef58

Browse files
committed
Enforce constraints and add tests.
1 parent 6783e71 commit 0a6ef58

File tree

6 files changed

+113
-10
lines changed

6 files changed

+113
-10
lines changed

include/engine/bearing.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ struct Bearing
3838
short bearing;
3939
short range;
4040

41-
bool IsValid() const { return bearing >= 0 && bearing <= 360 && range >= 0 && range <= 180; }
41+
bool IsValid() const { return bearing >= 0 && bearing <= 360 && range > 0 && range <= 180; }
4242
};
4343

4444
inline bool operator==(const Bearing lhs, const Bearing rhs)

include/engine/geospatial_query.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
7171
const int bearing,
7272
const int bearing_range) const
7373
{
74+
if (bearing_range == 0) return {};
7475
auto results = rtree.Nearest(
7576
input_coordinate,
7677
[this, bearing, bearing_range, max_distance](const CandidateSegment &segment) {
@@ -93,6 +94,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
9394
const int bearing,
9495
const int bearing_range) const
9596
{
97+
if (bearing_range == 0) return {};
9698
auto results = rtree.Nearest(
9799
input_coordinate,
98100
[this, bearing, bearing_range](const CandidateSegment &segment) {
@@ -116,6 +118,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
116118
const int bearing,
117119
const int bearing_range) const
118120
{
121+
if (bearing_range == 0) return {};
119122
auto results = rtree.Nearest(
120123
input_coordinate,
121124
[this, bearing, bearing_range](const CandidateSegment &segment) {
@@ -136,6 +139,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
136139
std::vector<PhantomNodeWithDistance>
137140
NearestPhantomNodes(const util::Coordinate input_coordinate, const unsigned max_results) const
138141
{
142+
if (max_results == 0) return {};
139143
auto results =
140144
rtree.Nearest(input_coordinate,
141145
[this](const CandidateSegment &segment) { return HasValidEdge(segment); },
@@ -153,6 +157,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
153157
const unsigned max_results,
154158
const double max_distance) const
155159
{
160+
if (max_results == 0) return {};
156161
auto results =
157162
rtree.Nearest(input_coordinate,
158163
[this](const CandidateSegment &segment) { return HasValidEdge(segment); },
@@ -251,6 +256,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
251256
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
252257
const util::Coordinate input_coordinate, const int bearing, const int bearing_range) const
253258
{
259+
if (bearing_range == 0) return {};
254260
bool has_small_component = false;
255261
bool has_big_component = false;
256262
auto results = rtree.Nearest(
@@ -298,6 +304,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
298304
const int bearing,
299305
const int bearing_range) const
300306
{
307+
if (bearing_range == 0) return {};
301308
bool has_small_component = false;
302309
bool has_big_component = false;
303310
auto results = rtree.Nearest(

src/engine/plugins/nearest.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,22 @@ Status NearestPlugin::HandleRequest(const api::NearestParameters &params,
4444
// We want to keep the user-interface as is, so make a copy. Should be cheap.
4545
auto constraint_params = params;
4646

47-
const auto max_radius_m = static_cast<double>(max_radius);
47+
if (max_radius != -1)
48+
{
49+
const auto max_radius_m = static_cast<double>(max_radius);
50+
51+
if (constraint_params.radiuses.empty())
52+
constraint_params.radiuses.push_back(boost::make_optional(max_radius_m));
53+
else if (constraint_params.radiuses[0])
54+
boost::algorithm::clamp(*constraint_params.radiuses[0], 0., max_radius_m);
55+
}
4856

49-
if (constraint_params.radiuses.empty())
50-
constraint_params.radiuses.push_back(boost::make_optional(max_radius_m));
51-
else if (constraint_params.radiuses[0])
52-
boost::algorithm::clamp(*constraint_params.radiuses[0], 0., max_radius_m);
57+
if (max_results != -1)
58+
{
59+
constraint_params.number_of_results = boost::algorithm::clamp(params.number_of_results, 0, max_results);
60+
}
5361

54-
auto phantom_nodes = GetPhantomNodes(constraint_params, params.number_of_results);
62+
auto phantom_nodes = GetPhantomNodes(constraint_params, constraint_params.number_of_results);
5563

5664
if (phantom_nodes.front().size() == 0)
5765
{

unit_tests/library/fixture.hpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,20 @@
88

99
// I couldn't get Boost.UnitTest to provide a test suite level fixture with custom
1010
// arguments per test suite (osrm base path from argv), so this has to suffice.
11-
12-
inline osrm::OSRM getOSRM(const std::string &base_path)
11+
inline osrm::OSRM getOSRM(const std::string &base_path, osrm::EngineConfig &config)
1312
{
14-
osrm::EngineConfig config;
1513
config.storage_config = {base_path};
1614
config.use_shared_memory = false;
1715

1816
return osrm::OSRM{config};
1917
}
2018

19+
inline osrm::OSRM getOSRM(const std::string &base_path)
20+
{
21+
osrm::EngineConfig config;
22+
23+
return getOSRM(base_path, config);
24+
}
25+
26+
2127
#endif

unit_tests/library/nearest.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,67 @@ BOOST_AUTO_TEST_CASE(test_nearest_response)
4343
}
4444
}
4545

46+
BOOST_AUTO_TEST_CASE(test_nearest_response_max_results)
47+
{
48+
const auto args = get_args();
49+
osrm::EngineConfig config;
50+
config.max_results_nearest = 2;
51+
// Default radius is unlimited
52+
auto osrm = getOSRM(args.at(0), config);
53+
54+
using namespace osrm;
55+
56+
NearestParameters params;
57+
params.number_of_results = 10;
58+
params.coordinates.push_back(get_dummy_location());
59+
60+
json::Object result;
61+
const auto rc = osrm.Nearest(params, result);
62+
BOOST_REQUIRE(rc == Status::Ok);
63+
64+
const auto code = result.values.at("code").get<json::String>().value;
65+
BOOST_CHECK_EQUAL(code, "Ok");
66+
67+
const auto &waypoints = result.values.at("waypoints").get<json::Array>().values;
68+
BOOST_CHECK(waypoints.size() == 2); // make sure our results were capped at max_results_nearest
69+
70+
// Test that we get nothing when we restrict to no matches
71+
config.max_results_nearest = 0;
72+
osrm = getOSRM(args.at(0), config);
73+
74+
json::Object result2;
75+
const auto rc2 = osrm.Nearest(params, result2);
76+
BOOST_REQUIRE(rc2 == Status::Error);
77+
const auto code2 = result2.values.at("code").get<json::String>().value;
78+
BOOST_CHECK_EQUAL(code2, "NoSegment");
79+
}
80+
81+
BOOST_AUTO_TEST_CASE(test_nearest_response_max_radius)
82+
{
83+
const auto args = get_args();
84+
osrm::EngineConfig config;
85+
config.max_radius_nearest = 1;
86+
auto osrm = getOSRM(args.at(0), config);
87+
88+
using namespace osrm;
89+
90+
NearestParameters params;
91+
params.number_of_results = 10;
92+
params.coordinates.push_back(get_dummy_location());
93+
94+
json::Object result;
95+
const auto rc = osrm.Nearest(params, result);
96+
BOOST_REQUIRE(rc == Status::Ok);
97+
98+
const auto code = result.values.at("code").get<json::String>().value;
99+
BOOST_CHECK_EQUAL(code, "Ok");
100+
101+
const auto &waypoints = result.values.at("waypoints").get<json::Array>().values;
102+
BOOST_CHECK(waypoints.size() == 1); // Check that we only got 1 match within 1m, even though
103+
// we asked for 10 results.
104+
}
105+
106+
46107
BOOST_AUTO_TEST_CASE(test_nearest_response_no_coordinates)
47108
{
48109
const auto args = get_args();

unit_tests/util/static_rtree.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,11 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
394394
BOOST_CHECK_EQUAL(results.back().phantom_node.reverse_segment_id.id, 1);
395395
}
396396

397+
{
398+
auto results = query.NearestPhantomNodes(input, 0);
399+
BOOST_CHECK_EQUAL(results.size(), 0);
400+
}
401+
397402
{
398403
auto results = query.NearestPhantomNodes(input, 5, 270, 10);
399404
BOOST_CHECK_EQUAL(results.size(), 0);
@@ -412,6 +417,16 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
412417
BOOST_CHECK_EQUAL(results[1].phantom_node.reverse_segment_id.id, 1);
413418
}
414419

420+
{
421+
auto results = query.NearestPhantomNodes(input, 0, 45, 10);
422+
BOOST_CHECK_EQUAL(results.size(), 0);
423+
}
424+
425+
{
426+
auto results = query.NearestPhantomNodes(input, 5, 45, 0);
427+
BOOST_CHECK_EQUAL(results.size(), 0);
428+
}
429+
415430
{
416431
auto results = query.NearestPhantomNodesInRange(input, 11000);
417432
BOOST_CHECK_EQUAL(results.size(), 2);
@@ -434,6 +449,12 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
434449
BOOST_CHECK(results[1].phantom_node.reverse_segment_id.enabled);
435450
BOOST_CHECK_EQUAL(results[1].phantom_node.reverse_segment_id.id, 1);
436451
}
452+
453+
{
454+
auto results = query.NearestPhantomNodesInRange(input, 11000, 45, 0);
455+
BOOST_CHECK_EQUAL(results.size(), 0);
456+
}
457+
437458
}
438459

439460
BOOST_AUTO_TEST_CASE(bbox_search_tests)

0 commit comments

Comments
 (0)