Support snapping to multiple ways at an input location (#5953)

This PR improves routing results by adding support for snapping to
multiple ways at input locations.

This means all edges at the snapped location can act as source/target
candidates for routing search, ensuring we always find the best route,
and not the one dependent on the edge selected.
This commit is contained in:
Michael Bell
2022-08-27 11:36:20 +01:00
committed by GitHub
parent bb18a2b428
commit d74e7b66bd
59 changed files with 2820 additions and 1964 deletions
+39 -20
View File
@@ -19,6 +19,20 @@
#define CHECK_EQUAL_RANGE(R1, R2) \
BOOST_CHECK_EQUAL_COLLECTIONS((R1).begin(), (R1).end(), (R2).begin(), (R2).end());
#define CHECK_EQUAL_RANGE_OF_HINTS(R1, R2) \
BOOST_REQUIRE_EQUAL((R1).size(), (R2).size()); \
for (const auto i : util::irange<std::size_t>(0UL, (R1).size())) \
{ \
BOOST_REQUIRE(((R1)[i] && (R2)[i]) || !((R1)[i] || (R2)[i])); \
if ((R1)[i]) \
{ \
BOOST_CHECK_EQUAL_COLLECTIONS((R1)[i]->segment_hints.begin(), \
(R1)[i]->segment_hints.end(), \
(R2)[i]->segment_hints.begin(), \
(R2)[i]->segment_hints.end()); \
} \
}
BOOST_AUTO_TEST_SUITE(api_parameters_parser)
using namespace osrm;
@@ -117,15 +131,16 @@ BOOST_AUTO_TEST_CASE(invalid_table_urls)
// BOOST_CHECK_EQUAL(testInvalidOptions<TableParameters>("1,2;3,4?destinations=2"), 7UL);
}
BOOST_AUTO_TEST_CASE(valid_route_hint)
BOOST_AUTO_TEST_CASE(valid_route_segment_hint)
{
engine::PhantomNode reference_node;
reference_node.input_location =
util::Coordinate(util::FloatLongitude{7.432251}, util::FloatLatitude{43.745995});
engine::Hint reference_hint{reference_node, 0x1337};
auto encoded_hint = reference_hint.ToBase64();
auto hint = engine::Hint::FromBase64(encoded_hint);
BOOST_CHECK_EQUAL(hint.phantom.input_location, reference_hint.phantom.input_location);
engine::SegmentHint reference_segment_hint{reference_node, 0x1337};
auto encoded_hint = reference_segment_hint.ToBase64();
auto seg_hint = engine::SegmentHint::FromBase64(encoded_hint);
BOOST_CHECK_EQUAL(seg_hint.phantom.input_location,
reference_segment_hint.phantom.input_location);
}
BOOST_AUTO_TEST_CASE(valid_route_urls)
@@ -147,7 +162,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
CHECK_EQUAL_RANGE(reference_1.approaches, result_1->approaches);
CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
CHECK_EQUAL_RANGE(reference_1.hints, result_1->hints);
CHECK_EQUAL_RANGE_OF_HINTS(reference_1.hints, result_1->hints);
RouteParameters reference_2{};
reference_2.alternatives = true;
@@ -170,7 +185,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
CHECK_EQUAL_RANGE(reference_2.approaches, result_2->approaches);
CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
CHECK_EQUAL_RANGE(reference_2.hints, result_2->hints);
CHECK_EQUAL_RANGE_OF_HINTS(reference_2.hints, result_2->hints);
BOOST_CHECK_EQUAL(result_2->annotations_type == RouteParameters::AnnotationsType::All, true);
RouteParameters reference_3{false,
@@ -195,14 +210,15 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_3.radiuses, result_3->radiuses);
CHECK_EQUAL_RANGE(reference_3.approaches, result_3->approaches);
CHECK_EQUAL_RANGE(reference_3.coordinates, result_3->coordinates);
CHECK_EQUAL_RANGE(reference_3.hints, result_3->hints);
CHECK_EQUAL_RANGE_OF_HINTS(reference_3.hints, result_3->hints);
engine::PhantomNode phantom_1;
phantom_1.input_location = coords_1[0];
engine::PhantomNode phantom_2;
phantom_2.input_location = coords_1[1];
std::vector<boost::optional<engine::Hint>> hints_4 = {engine::Hint{phantom_1, 0x1337},
engine::Hint{phantom_2, 0x1337}};
std::vector<boost::optional<engine::Hint>> hints_4 = {
engine::Hint{{engine::SegmentHint{phantom_1, 0x1337}}},
engine::Hint{{engine::SegmentHint{phantom_2, 0x1337}}}};
RouteParameters reference_4{false,
false,
false,
@@ -226,7 +242,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_4.radiuses, result_4->radiuses);
CHECK_EQUAL_RANGE(reference_4.approaches, result_4->approaches);
CHECK_EQUAL_RANGE(reference_4.coordinates, result_4->coordinates);
CHECK_EQUAL_RANGE(reference_4.hints, result_4->hints);
CHECK_EQUAL_RANGE_OF_HINTS(reference_4.hints, result_4->hints);
std::vector<boost::optional<engine::Bearing>> bearings_4 = {
boost::none,
@@ -255,7 +271,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_5.radiuses, result_5->radiuses);
CHECK_EQUAL_RANGE(reference_5.approaches, result_5->approaches);
CHECK_EQUAL_RANGE(reference_5.coordinates, result_5->coordinates);
CHECK_EQUAL_RANGE(reference_5.hints, result_5->hints);
CHECK_EQUAL_RANGE_OF_HINTS(reference_5.hints, result_5->hints);
std::vector<util::Coordinate> coords_2 = {{util::FloatLongitude{0}, util::FloatLatitude{1}},
{util::FloatLongitude{2}, util::FloatLatitude{3}},
@@ -275,7 +291,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_6.radiuses, result_6->radiuses);
CHECK_EQUAL_RANGE(reference_6.approaches, result_6->approaches);
CHECK_EQUAL_RANGE(reference_6.coordinates, result_6->coordinates);
CHECK_EQUAL_RANGE(reference_6.hints, result_6->hints);
CHECK_EQUAL_RANGE_OF_HINTS(reference_6.hints, result_6->hints);
auto result_7 = parseParameters<RouteParameters>("1,2;3,4?radiuses=;unlimited");
RouteParameters reference_7{};
@@ -293,7 +309,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_7.radiuses, result_7->radiuses);
CHECK_EQUAL_RANGE(reference_7.approaches, result_7->approaches);
CHECK_EQUAL_RANGE(reference_7.coordinates, result_7->coordinates);
CHECK_EQUAL_RANGE(reference_7.hints, result_7->hints);
CHECK_EQUAL_RANGE_OF_HINTS(reference_7.hints, result_7->hints);
auto result_8 = parseParameters<RouteParameters>("1,2;3,4?radiuses=;");
RouteParameters reference_8{};
@@ -320,7 +336,10 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
engine::PhantomNode phantom_4;
phantom_4.input_location = coords_3[2];
std::vector<boost::optional<engine::Hint>> hints_10 = {
engine::Hint{phantom_3, 0x1337}, boost::none, engine::Hint{phantom_4, 0x1337}, boost::none};
engine::Hint{{engine::SegmentHint{phantom_3, 0x1337}}},
{},
engine::Hint{{engine::SegmentHint{phantom_4, 0x1337}}},
{}};
RouteParameters reference_10{false,
false,
@@ -346,7 +365,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_10.radiuses, result_10->radiuses);
CHECK_EQUAL_RANGE(reference_10.approaches, result_10->approaches);
CHECK_EQUAL_RANGE(reference_10.coordinates, result_10->coordinates);
CHECK_EQUAL_RANGE(reference_10.hints, result_10->hints);
CHECK_EQUAL_RANGE_OF_HINTS(reference_10.hints, result_10->hints);
// Do not generate Hints when they are explicitly disabled
auto result_11 = parseParameters<RouteParameters>("1,2;3,4?generate_hints=false");
@@ -459,7 +478,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_18.radiuses, result_18->radiuses);
CHECK_EQUAL_RANGE(reference_18.approaches, result_18->approaches);
CHECK_EQUAL_RANGE(reference_18.coordinates, result_18->coordinates);
CHECK_EQUAL_RANGE(reference_18.hints, result_18->hints);
CHECK_EQUAL_RANGE_OF_HINTS(reference_18.hints, result_18->hints);
RouteParameters reference_19{};
reference_19.alternatives = true;
@@ -478,7 +497,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_19.radiuses, result_19->radiuses);
CHECK_EQUAL_RANGE(reference_19.approaches, result_19->approaches);
CHECK_EQUAL_RANGE(reference_19.coordinates, result_19->coordinates);
CHECK_EQUAL_RANGE(reference_19.hints, result_19->hints);
CHECK_EQUAL_RANGE_OF_HINTS(reference_19.hints, result_19->hints);
RouteParameters reference_20{};
reference_20.alternatives = false;
@@ -497,7 +516,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_20.radiuses, result_20->radiuses);
CHECK_EQUAL_RANGE(reference_20.approaches, result_20->approaches);
CHECK_EQUAL_RANGE(reference_20.coordinates, result_20->coordinates);
CHECK_EQUAL_RANGE(reference_20.hints, result_20->hints);
CHECK_EQUAL_RANGE_OF_HINTS(reference_20.hints, result_20->hints);
// exclude flags
RouteParameters reference_21{};
@@ -516,7 +535,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_21.radiuses, result_21->radiuses);
CHECK_EQUAL_RANGE(reference_21.approaches, result_21->approaches);
CHECK_EQUAL_RANGE(reference_21.coordinates, result_21->coordinates);
CHECK_EQUAL_RANGE(reference_21.hints, result_21->hints);
CHECK_EQUAL_RANGE_OF_HINTS(reference_21.hints, result_21->hints);
CHECK_EQUAL_RANGE(reference_21.exclude, result_21->exclude);
}