Skip to content

Commit

Permalink
handle waypoints while tidying traces
Browse files Browse the repository at this point in the history
  • Loading branch information
karenzshea committed Dec 12, 2017
1 parent ea432ae commit d3e3d52
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 18 deletions.
48 changes: 48 additions & 0 deletions features/testbot/matching.feature
Original file line number Diff line number Diff line change
Expand Up @@ -480,3 +480,51 @@ Feature: Basic Map Matching
| trace | a:nodes |
| 12 | 1:2:3:4:5:6 |
| 21 | 6:5:4:3:2:1 |

Scenario: Testbot - Map matching with trace tidying and waypoints param
Given a grid size of 8 meters

Given the query options
| tidy | true |
| waypoints | 0,2,3,5 |

Given the node map
"""
a b c d
e
g
"""

And the ways
| nodes | oneway |
| abcd | no |
| ceg | no |

When I match I should get
| trace | matchings |
| abcceg | |


Scenario: Matching with waypoints param that were tidied away
Given the node map
"""
a - b - c - e
|
f
|
g
"""
And the ways
| nodes | oneway |
| abce | no |
| cfg | no |

Given the query options
| tidy | true |
| waypoints | 0;2;5 |

When I match I should get
| trace | code | matchings |
| abccfg | Ok | |
28 changes: 27 additions & 1 deletion include/engine/api/match_parameters_tidy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,21 @@ struct Result
Mask can_be_removed;
// Maps the MatchParameter's original items to items which should not be removed.
Mapping tidied_to_original;
// Masking the MatchParameter coordinates for items whose indices were present in the
// `waypoints` parameter.
Mask was_waypoint;
};

inline Result keep_all(const MatchParameters &params)
{
Result result;

result.can_be_removed.resize(params.coordinates.size(), false);
result.was_waypoint.resize(params.coordinates.size(), false);
for (const auto p : params.waypoints)
{
result.was_waypoint.set(p, true);
}
result.tidied_to_original.reserve(params.coordinates.size());
for (std::size_t current = 0; current < params.coordinates.size(); ++current)
{
Expand All @@ -61,6 +69,8 @@ inline Result keep_all(const MatchParameters &params)
{
result.parameters.coordinates.push_back(params.coordinates[i]);

if (result.was_waypoint[i])
result.parameters.waypoints.push_back(result.parameters.coordinates.size() - 1);
if (!params.hints.empty())
result.parameters.hints.push_back(params.hints[i]);

Expand All @@ -85,6 +95,11 @@ inline Result tidy(const MatchParameters &params, Thresholds cfg = {15., 5})
Result result;

result.can_be_removed.resize(params.coordinates.size(), false);
result.was_waypoint.resize(params.coordinates.size(), false);
for (const auto p : params.waypoints)
{
result.was_waypoint.set(p, true);
}

result.tidied_to_original.push_back(0);

Expand Down Expand Up @@ -138,13 +153,14 @@ inline Result tidy(const MatchParameters &params, Thresholds cfg = {15., 5})

// We have to filter parallel arrays that may be empty or the exact same size.
// result.parameters contains an empty MatchParameters at this point: conditionally fill.

for (std::size_t i = 0; i < result.can_be_removed.size(); ++i)
{
if (!result.can_be_removed[i])
{
result.parameters.coordinates.push_back(params.coordinates[i]);

if (result.was_waypoint[i])
result.parameters.waypoints.push_back(result.parameters.coordinates.size() - 1);
if (!params.hints.empty())
result.parameters.hints.push_back(params.hints[i]);

Expand All @@ -157,7 +173,17 @@ inline Result tidy(const MatchParameters &params, Thresholds cfg = {15., 5})
if (!params.timestamps.empty())
result.parameters.timestamps.push_back(params.timestamps[i]);
}
else
{
// one of the coordinates meant to be used as a waypoint was marked for removal
// update the original waypoint index to the new representative coordinate
if (result.was_waypoint[i] &&
(result.parameters.waypoints.back() != result.parameters.coordinates.size() - 1))
// check if thecurrent size is the last one in the waypoints array
result.parameters.waypoints.push_back(result.parameters.coordinates.size() - 1);
}
}
BOOST_ASSERT(result.parameters.waypoints.size() == params.waypoints.size());
BOOST_ASSERT(result.tidied_to_original.size() == result.parameters.coordinates.size());

return result;
Expand Down
9 changes: 6 additions & 3 deletions include/engine/internal_route_result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ inline InternalRouteResult CollapseInternalRouteResult(const InternalRouteResult
const std::vector<bool> &is_waypoint)
{
BOOST_ASSERT(leggy_result.is_valid());
BOOST_ASSERT(is_waypoint[0]);
BOOST_ASSERT(is_waypoint[0]); // first and last coords
BOOST_ASSERT(is_waypoint.back()); // should always be waypoints
// Nothing to collapse! return result as is
if (leggy_result.unpacked_path_segments.size() == 1)
return leggy_result;
Expand All @@ -135,8 +136,10 @@ inline InternalRouteResult CollapseInternalRouteResult(const InternalRouteResult
// no new leg, collapse the next segment into the last leg
{
auto &last_segment = collapsed.unpacked_path_segments.back();
// deduplicate last segment
last_segment.pop_back();
// deduplicate last segment (needs to be checked for empty for the same node query edge
// case)
if (!last_segment.empty())
last_segment.pop_back();
// update target phantom node of leg
collapsed.segment_end_coordinates.back().target_phantom =
leggy_result.segment_end_coordinates[i].target_phantom;
Expand Down
3 changes: 1 addition & 2 deletions include/server/api/match_parameter_grammar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ struct MatchParametersGrammar final : public RouteParametersGrammar<Iterator, Si

waypoints_rule =
qi::lit("waypoints=") >
(size_t_ %
';')[ph::bind(&engine::api::MatchParameters::waypoints, qi::_r1) = qi::_1];
(size_t_ % ';')[ph::bind(&engine::api::MatchParameters::waypoints, qi::_r1) = qi::_1];

gaps_type.add("split", engine::api::MatchParameters::GapsType::Split)(
"ignore", engine::api::MatchParameters::GapsType::Ignore);
Expand Down
4 changes: 2 additions & 2 deletions src/engine/plugins/match.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,12 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
{
std::vector<bool> waypoint_legs;
waypoint_legs.reserve(sub_matchings[index].nodes.size());
for (unsigned i = 0; i < sub_matchings[index].nodes.size() - 1; ++i)
for (unsigned i = 0; i < sub_matchings[index].nodes.size(); ++i)
{
auto is_waypoint = std::find(parameters.waypoints.begin(),
parameters.waypoints.end(),
sub_matchings[index].indices[i]);
waypoint_legs[i] = is_waypoint != parameters.waypoints.end();
waypoint_legs.push_back(is_waypoint != parameters.waypoints.end());
}
sub_routes[index] = CollapseInternalRouteResult(sub_routes[index], waypoint_legs);
}
Expand Down
35 changes: 25 additions & 10 deletions unit_tests/engine/collapse_internal_route_result.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@ BOOST_AUTO_TEST_CASE(unchanged_collapse_route_result)
target.forward_segment_id = {6, true};
PathData pathy{2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false};
PathData kathy{1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false};
InternalRouteResult one_leg_result{std::vector<std::vector<PathData>>{std::vector<PathData>{pathy, kathy}},
InternalRouteResult one_leg_result{
std::vector<std::vector<PathData>>{std::vector<PathData>{pathy, kathy}},
std::vector<PhantomNodes>{PhantomNodes{source, target}},
std::vector<bool>{true},
std::vector<bool>{true},
50};

auto collapsed = CollapseInternalRouteResult(one_leg_result, {true, true});
BOOST_CHECK_EQUAL(one_leg_result.unpacked_path_segments[0].front().turn_via_node, collapsed.unpacked_path_segments[0].front().turn_via_node);
BOOST_CHECK_EQUAL(one_leg_result.unpacked_path_segments[0].back().turn_via_node, collapsed.unpacked_path_segments[0].back().turn_via_node);
BOOST_CHECK_EQUAL(one_leg_result.unpacked_path_segments[0].front().turn_via_node,
collapsed.unpacked_path_segments[0].front().turn_via_node);
BOOST_CHECK_EQUAL(one_leg_result.unpacked_path_segments[0].back().turn_via_node,
collapsed.unpacked_path_segments[0].back().turn_via_node);
}

BOOST_AUTO_TEST_CASE(two_legs_to_one_leg)
Expand All @@ -44,7 +47,9 @@ BOOST_AUTO_TEST_CASE(two_legs_to_one_leg)
node_1.forward_segment_id = {1, true};
node_2.forward_segment_id = {6, true};
node_3.forward_segment_id = {12, true};
InternalRouteResult three_leg_result{std::vector<std::vector<PathData>>{std::vector<PathData>{pathy, kathy}, std::vector<PathData>{kathy, cathy}},
InternalRouteResult three_leg_result{
std::vector<std::vector<PathData>>{std::vector<PathData>{pathy, kathy},
std::vector<PathData>{kathy, cathy}},
std::vector<PhantomNodes>{PhantomNodes{node_1, node_2}, PhantomNodes{node_2, node_3}},
std::vector<bool>{true, false},
std::vector<bool>{true, false},
Expand All @@ -53,7 +58,8 @@ BOOST_AUTO_TEST_CASE(two_legs_to_one_leg)
auto collapsed = CollapseInternalRouteResult(three_leg_result, {true, false, true, true});
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments.size(), 1);
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates.size(), 1);
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[0].target_phantom.forward_segment_id.id, 12);
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[0].target_phantom.forward_segment_id.id,
12);
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[0].source_phantom.forward_segment_id.id, 1);
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0].size(), 3);
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][0].turn_via_node, 2);
Expand All @@ -76,8 +82,13 @@ BOOST_AUTO_TEST_CASE(three_legs_to_two_legs)
node_2.forward_segment_id = {6, true};
node_3.forward_segment_id = {12, true};
node_4.forward_segment_id = {18, true};
InternalRouteResult three_leg_result{std::vector<std::vector<PathData>>{std::vector<PathData>{pathy, kathy}, std::vector<PathData>{kathy, qathy, cathy}, std::vector<PathData>{cathy, mathy}},
std::vector<PhantomNodes>{PhantomNodes{node_1, node_2}, PhantomNodes{node_2, node_3}, PhantomNodes{node_3, node_4}},
InternalRouteResult three_leg_result{
std::vector<std::vector<PathData>>{std::vector<PathData>{pathy, kathy},
std::vector<PathData>{kathy, qathy, cathy},
std::vector<PathData>{cathy, mathy}},
std::vector<PhantomNodes>{PhantomNodes{node_1, node_2},
PhantomNodes{node_2, node_3},
PhantomNodes{node_3, node_4}},
std::vector<bool>{true, false, true},
std::vector<bool>{true, false, true},
140};
Expand All @@ -88,7 +99,8 @@ BOOST_AUTO_TEST_CASE(three_legs_to_two_legs)
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[0].source_phantom.forward_segment_id.id, 1);
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[0].target_phantom.forward_segment_id.id, 6);
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[1].source_phantom.forward_segment_id.id, 6);
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[1].target_phantom.forward_segment_id.id, 18);
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[1].target_phantom.forward_segment_id.id,
18);
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0].size(), 2);
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1].size(), 4);
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][0].turn_via_node, 2);
Expand All @@ -110,7 +122,9 @@ BOOST_AUTO_TEST_CASE(two_legs_to_two_legs)
node_1.forward_segment_id = {1, true};
node_2.forward_segment_id = {6, true};
node_3.forward_segment_id = {12, true};
InternalRouteResult three_leg_result{std::vector<std::vector<PathData>>{std::vector<PathData>{pathy, kathy}, std::vector<PathData>{kathy, cathy}},
InternalRouteResult three_leg_result{
std::vector<std::vector<PathData>>{std::vector<PathData>{pathy, kathy},
std::vector<PathData>{kathy, cathy}},
std::vector<PhantomNodes>{PhantomNodes{node_1, node_2}, PhantomNodes{node_2, node_3}},
std::vector<bool>{true, false},
std::vector<bool>{true, false},
Expand All @@ -122,7 +136,8 @@ BOOST_AUTO_TEST_CASE(two_legs_to_two_legs)
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[0].source_phantom.forward_segment_id.id, 1);
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[0].target_phantom.forward_segment_id.id, 6);
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[1].source_phantom.forward_segment_id.id, 6);
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[1].target_phantom.forward_segment_id.id, 12);
BOOST_CHECK_EQUAL(collapsed.segment_end_coordinates[1].target_phantom.forward_segment_id.id,
12);
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0].size(), 2);
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[1].size(), 2);
BOOST_CHECK_EQUAL(collapsed.unpacked_path_segments[0][0].turn_via_node, 2);
Expand Down

0 comments on commit d3e3d52

Please sign in to comment.