From 0affec8f1732e9d3cb56bff4f4d08da42f250943 Mon Sep 17 00:00:00 2001 From: Moritz Kobitzsch Date: Tue, 25 Jul 2017 17:19:33 +0200 Subject: [PATCH] handle throughabouts -- do not announce going through --- CHANGELOG.md | 1 + features/guidance/roundabout-turn.feature | 4 +-- features/guidance/roundabout.feature | 8 ++--- src/extractor/guidance/roundabout_handler.cpp | 33 +++++++++++++++---- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cfdff82a..f01f631f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Pass functions instead of strings to `WayHandlers.run()`, so it's possible to mix in your own functions. - Reorders arguments to `WayHandlers` functions to match `process_way()`. - Profiles must return a hash of profile functions. This makes it easier for profiles to include each other. + - Guidance: add support for throughabouts # 5.9.2 - API: diff --git a/features/guidance/roundabout-turn.feature b/features/guidance/roundabout-turn.feature index 13c1e44bd..b940c76d1 100644 --- a/features/guidance/roundabout-turn.feature +++ b/features/guidance/roundabout-turn.feature @@ -567,5 +567,5 @@ Feature: Basic Roundabout | ab | residential | in | | | When I route I should get - | waypoints | turns | route | - | a,f | depart,turn right,roundabout turn straight exit-1,arrive | in,through,through,through | + | waypoints | turns | route | + | a,f | depart,turn right,arrive | in,through,through | diff --git a/features/guidance/roundabout.feature b/features/guidance/roundabout.feature index 844900ac9..474e8041a 100644 --- a/features/guidance/roundabout.feature +++ b/features/guidance/roundabout.feature @@ -763,7 +763,7 @@ Feature: Basic Roundabout When I route I should get | waypoints | bearings | route | turns | - | e,f | 90 90 | edf,edf,edf | depart,roundabout-exit-1,arrive | + | e,f | 90 90 | edf,edf | depart,arrive | | e,h | 90 135 | edf,gch,gch | depart,roundabout-exit-2,arrive | | g,f | 45 90 | gch,edf,edf | depart,roundabout-exit-2,arrive | | g,h | 45 135 | gch,gch,gch | depart,roundabout-exit-1,arrive | @@ -843,6 +843,6 @@ Feature: Basic Roundabout When I route I should get - | from | to | route | turns | distance | - | e | k | ebds,ebds,ds,ufghl,jhik,jhik | depart,rotary-exit-1,rotary-exit-1,rstur-exit-2,turn right,arrive | 189.1m | - | 1 | k | ebds,ds,ufghl,jhik,jhik | depart,rotary-exit-1,rstur-exit-2,turn right,arrive | 159.1m | + | from | to | route | turns | distance | + | e | k | ebds,ufghl,jhik,jhik | depart,rstur-exit-2,turn right,arrive | 189.1m | + | 1 | k | ebds,ufghl,jhik,jhik | depart,rstur-exit-2,turn right,arrive | 159.1m | diff --git a/src/extractor/guidance/roundabout_handler.cpp b/src/extractor/guidance/roundabout_handler.cpp index ea0883ff7..954d2b602 100644 --- a/src/extractor/guidance/roundabout_handler.cpp +++ b/src/extractor/guidance/roundabout_handler.cpp @@ -504,15 +504,23 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou } else { + bool crossing_roundabout = false; for (std::size_t cnt = 0, idx = lhs ? intersection.size() - 1 : 0; cnt < intersection.size(); ++cnt, idx += step) { - auto &road = intersection[idx]; - if (!road.entry_allowed) - continue; - auto &turn = road; + auto &turn = intersection[idx]; const auto &out_data = node_based_graph.GetEdgeData(turn.eid); + + // A roundabout consists of exactly two roads at an intersection. by toggeling this + // flag, we can switch between roads crossing the roundabout and roads that are on the + // same side as via_eid. + if (out_data.roundabout || out_data.circular) + crossing_roundabout = !crossing_roundabout; + + if (!turn.entry_allowed) + continue; + if (out_data.roundabout || out_data.circular) { if (can_exit_roundabout_separately) @@ -524,8 +532,21 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou } else { - turn.instruction = TurnInstruction::ENTER_AND_EXIT_ROUNDABOUT( - roundabout_type, getTurnDirection(turn.angle)); + // Distinguish between throughabouts and entering a roundabout to directly exit: In + // case of a throughabout, both enter and exit do not show roundabout tags (as we + // already have checked, when arriving here) and the enter/exit are nearly straight + // and on different sides of the roundabouts + if (util::angularDeviation(turn.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE && + crossing_roundabout) + { + turn.instruction = getInstructionForObvious( + intersection.size(), via_eid, isThroughStreet(idx, intersection), turn); + } + else + { + turn.instruction = TurnInstruction::ENTER_AND_EXIT_ROUNDABOUT( + roundabout_type, getTurnDirection(turn.angle)); + } } } }