Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Trip] Support more parameter combinations of fixed start/end when requesting roundtrips #3675

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 84 additions & 1 deletion features/testbot/trip.feature
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,64 @@ Feature: Basic trip planning
| waypoints | trips |
| a,b,c,d,e,f,g,h,i,j,k,l | alkjihgfedcba |

Scenario: Testbot - Roundtrip FS waypoints >10
Given the query options
| source | first |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move these to the "When I plan a trip I should get" portion of the test

Given the node map
"""
a b c d
l e
k f
j i h g
"""

And the ways
| nodes |
| ab |
| bc |
| de |
| ef |
| fg |
| gh |
| hi |
| ij |
| jk |
| kl |
| la |

When I plan a trip I should get
| waypoints | trips |
| a,b,c,d,e,f,g,h,i,j,k,l | alkjihgfedcba |

Scenario: Testbot - Roundtrip FE waypoints >10
Given the query options
| source | last |
Given the node map
"""
a b c d
l e
k f
j i h g
"""

And the ways
| nodes |
| ab |
| bc |
| de |
| ef |
| fg |
| gh |
| hi |
| ij |
| jk |
| kl |
| la |

When I plan a trip I should get
| waypoints | trips |
| a,b,c,d,e,f,g,h,i,j,k,l | lkjihgfedcbal |

Scenario: Testbot - Unroutable roundtrip with waypoints <10
Given the node map
"""
Expand Down Expand Up @@ -122,7 +180,6 @@ Feature: Basic trip planning
When I plan a trip I should get
| waypoints | source | destination | roundtrip | status | message |
| a,b,c,d | first | last | false | NoTrips | No trip visiting all destinations possible. |
| a,b,c,d | first | last | true | NotImplemented | This request is not implemented |

Scenario: Testbot - TFSE with waypoints <10
Given the node map
Expand Down Expand Up @@ -174,6 +231,32 @@ Feature: Basic trip planning
| waypoints | source | destination | roundtrip | trips | durations | distance |
| a,b,c,d,e,h,i,j,k,g,f | first | last | false | abcdeghijkf | 15 | 149.8 |

Scenario: Testbot - TFSE roundtrip with waypoints <10
Given the node map
"""
a b

c
e d
"""

And the ways
| nodes |
| ab |
| ac |
| ad |
| ae |
| bc |
| bd |
| be |
| cd |
| ce |
| de |

When I plan a trip I should get
| waypoints | source | destination | roundtrip | trips |
| a,b,d,e,c | first | last | true | abedca |


# Test single node in each component #1850
Scenario: Testbot - Trip planning with less than 10 nodes
Expand Down
2 changes: 2 additions & 0 deletions include/util/typedefs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ using NameID = std::uint32_t;
using EdgeWeight = std::int32_t;
using TurnPenalty = std::int16_t; // turn penalty in 100ms units

static const std::size_t INVALID_SIZE_T = std::numeric_limits<std::size_t>::max();

using LaneID = std::uint8_t;
static const LaneID INVALID_LANEID = std::numeric_limits<LaneID>::max();
using LaneDataID = std::uint16_t;
Expand Down
32 changes: 17 additions & 15 deletions src/engine/plugins/trip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ bool IsSupportedParameterCombination(const bool fixed_start,
{
return true;
}
else if (!fixed_start && !fixed_end && roundtrip)
else if (roundtrip)
{
return true;
}
Expand All @@ -51,6 +51,8 @@ bool IsSupportedParameterCombination(const bool fixed_start,
}
}

// given the node order in which to visit, compute the actual route (with geometry, travel time and
// so on) and return the result
InternalRouteResult
TripPlugin::ComputeRoute(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
const std::vector<PhantomNode> &snapped_phantoms,
Expand All @@ -60,27 +62,22 @@ TripPlugin::ComputeRoute(const std::shared_ptr<const datafacade::BaseDataFacade>
InternalRouteResult min_route;
// given the final trip, compute total duration and return the route and location permutation
PhantomNodes viapoint;
const auto start = std::begin(trip);
const auto end = std::end(trip);

// computes a roundtrip from the nodes in trip
for (auto it = start; it != end; ++it)
for (auto node = trip.begin(); node < trip.end() - 1; ++node)
{
const auto from_node = *it;

// if from_node is the last node and it is a fixed start and end trip,
// break out of this loop and return the route
if (!roundtrip && std::next(it) == end)
break;

// if from_node is the last node, compute the route from the last to the first location
const auto to_node = std::next(it) != end ? *std::next(it) : *start;
const auto from_node = *node;
const auto to_node = *std::next(node);

viapoint = PhantomNodes{snapped_phantoms[from_node], snapped_phantoms[to_node]};
min_route.segment_end_coordinates.emplace_back(viapoint);
}

// return back to the first node if it is a round trip
if (roundtrip)
{
viapoint = PhantomNodes{snapped_phantoms[trip.back()], snapped_phantoms[trip.front()]};
min_route.segment_end_coordinates.emplace_back(viapoint);
// trip comes out to be something like 0 1 4 3 2 0
BOOST_ASSERT(min_route.segment_end_coordinates.size() == trip.size());
}
Expand All @@ -91,7 +88,6 @@ TripPlugin::ComputeRoute(const std::shared_ptr<const datafacade::BaseDataFacade>
}

shortest_path(facade, min_route.segment_end_coordinates, {false}, min_route);

BOOST_ASSERT_MSG(min_route.shortest_path_length < INVALID_EDGE_WEIGHT, "unroutable route");
return min_route;
}
Expand Down Expand Up @@ -241,12 +237,18 @@ Status TripPlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
}

// rotate result such that roundtrip starts at node with index 0
if (parameters.roundtrip && !fixed_end)
if (!(fixed_end && !fixed_start_and_end))
{
auto desired_start_index = std::find(std::begin(trip), std::end(trip), 0);
BOOST_ASSERT(desired_start_index != std::end(trip));
std::rotate(std::begin(trip), desired_start_index, std::end(trip));
}
else if (fixed_end && !fixed_start_and_end && parameters.roundtrip)
{
auto desired_start_index = std::find(std::begin(trip), std::end(trip), destination_id);
BOOST_ASSERT(desired_start_index != std::end(trip));
std::rotate(std::begin(trip), desired_start_index, std::end(trip));
}

// get the route when visiting all destinations in optimized order
InternalRouteResult route = ComputeRoute(facade, snapped_phantoms, trip, parameters.roundtrip);
Expand Down
Loading