Skip to content

Commit

Permalink
Fix sliproad scenario with 4 roads in a target intersection, #4348/1
Browse files Browse the repository at this point in the history
  • Loading branch information
oxidase committed Aug 3, 2017
1 parent f2abc90 commit 5afe11e
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
6 changes: 3 additions & 3 deletions features/guidance/dedicated-turn-roads.feature
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,6 @@ Feature: Slipways and Dedicated Turn Lanes
| ec | primary_link | ec | yes |

When I route I should get
| waypoints | route | turns | locations |
| s,f | sabct,ae,dbef,dbef | depart,turn right,turn slight right,arrive | s,a,e,f |
| f,t | dbef,sabct,sabct | depart,turn right,arrive | f,e,t |
| waypoints | route | turns | locations |
| s,f | sabct,dbef,dbef | depart,turn right,arrive | s,a,f |
| f,t | dbef,sabct,sabct | depart,turn right,arrive | f,e,t |
50 changes: 48 additions & 2 deletions src/extractor/guidance/sliproad_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,9 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
if (!allSameMode(source_edge_id, sliproad.eid, find_valid(target_intersection)->eid))
continue;

// Constrain the Sliproad's target to sliproad, outgoing, incoming from main intersection
if (target_intersection.size() != 3)
// Constrain the sliproad's target intersection to 1 or 2 sliproads, outgoing road
// and incoming one from the main intersection
if (target_intersection.size() < 3 || target_intersection.size() > 4)
{
continue;
}
Expand All @@ -279,6 +280,51 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
continue;
}

if (target_intersection.size() == 4)
{
// Handle target intersections at `d` with 4 roads
//
// | `main_road_intersection` is intersection at `c`
// v
// a ... b .... c .... e <- fo
// ` . '
// ` . '
// ` . '
// d < `target_intersection` is intersection at `d`
// |
// Conditions for road `bd` to be a sliproad:
// - target_intersection at `d` has 4 roads
// - main_road_intersection at `c` has at least 3 roads
// - target nodes of `db` and `cd` roads is the same node `d`
// - target nodes of `ce` and `de` roads is the same node `e`
// - angle `bde` is sharp

// Check `c` has at least 3 roads at `c` and roads `bd` and `cd` share the node `d`
if (main_road_intersection->intersection.size() < 3 ||
sliproad_edge_target != node_based_graph.GetTarget(crossing_road.eid))
{
continue;
}

// Find a road at `d` that shares the same node `e` with `ce` and ∠ `bde` is sharp
auto next_to_crossing_idx =
is_left_sliproad_turn ? main_road_intersection->intersection.size() - 2 : 2;
auto next_to_crossing_road = main_road_intersection->intersection[next_to_crossing_idx];
auto next_to_crossing_node = node_based_graph.GetTarget(next_to_crossing_road.eid);
auto found_common_node = std::find_if(
begin(target_intersection), end(target_intersection), [&](const auto &road) {
if (next_to_crossing_node == node_based_graph.GetTarget(road.eid))
{
auto direction = getTurnDirection(road.angle);
return direction == DirectionModifier::SharpRight ||
direction == DirectionModifier::SharpLeft;
}
return false;
});
if (found_common_node == target_intersection.end())
continue;
}

// If the sliproad candidate is a through street, we cannot handle it as a sliproad.
if (isThroughStreet(sliproad_edge, target_intersection))
{
Expand Down

0 comments on commit 5afe11e

Please sign in to comment.