diff --git a/CHANGELOG.md b/CHANGELOG.md index 677ca7f21..ea1cb5970 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 5.2.4 + - Bugfixes: + - Fixed in issue that arised on roundabouts in combination with intermediate intersections and sliproads + # 5.2.3 - Bugfixes: - Fixed an issue with name changes in roundabouts that could result in crashes diff --git a/features/guidance/intersections.feature b/features/guidance/intersections.feature index b25667a09..22ccac63d 100644 --- a/features/guidance/intersections.feature +++ b/features/guidance/intersections.feature @@ -144,10 +144,10 @@ Feature: Intersections Data | hd | | When I route I should get - | waypoints | route | turns | intersections | - | e,f | ea,fb,fb | depart,abcda-exit-1,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 | - | e,g | ea,gc,gc | depart,abcda-exit-2,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0| + | waypoints | route | turns | intersections | + | e,f | ea,fb,fb | depart,abcda-exit-1,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 | + | e,g | ea,gc,gc | depart,abcda-exit-2,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0 | | e,h | ea,hd,hd | depart,abcda-exit-3,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330,true:90 false:210 true:330;true:270 | - | e,2 | ea,abcda,abcda | depart,abcda-exit-undefined,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1| - | 1,g | abcda,gc,gc | depart,abcda-exit-2,arrive | true:214;true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:0| - | 1,3 | abcda,abcda | depart,arrive | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214| + | e,2 | ea,abcda,abcda | depart,abcda-exit-undefined,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1 | + | 1,g | abcda,gc,gc | depart,abcda-exit-2,arrive | true:214;false:30 true:150 true:270,true:30 true:180 false:330;true:0 | + | 1,3 | abcda,abcda | depart,arrive | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214 | diff --git a/features/guidance/roundabout.feature b/features/guidance/roundabout.feature index 6d262bae8..9b622f658 100644 --- a/features/guidance/roundabout.feature +++ b/features/guidance/roundabout.feature @@ -363,38 +363,77 @@ Feature: Basic Roundabout Scenario: Motorway Roundabout #See 39.933742 -75.082345 - Given the node map - | | | | | l | | | | a | | i | - | | | | | | | | | | | | - | | | | | | | | | | | | - | | | | | | | b | | | | | - | | | | c | | | | | | | | - | | | | | | | | | | | | - | | | | | | | | | h | | | - | n | | | | | | | | | | | - | | | | | | | | | | | | - | | | d | | | | | | | | j | - | | | | | | | | | | | | - | | | | | m | | | g | | | | - | | | | | | | | | | | | - | | | | | | | | | | | | - | | | e | | f | | | | | | | + Given the node map + | | | | | l | | | | a | | i | + | | | | | | | | | | | | + | | | | | | | | | | | | + | | | | | | | b | | | | | + | | | | c | | | | | | | | + | | | | | | | | | | | | + | | | | | | | | | h | | | + | n | | | | | | | | | | | + | | | | | | | | | | | | + | | | d | | | | | | | | j | + | | | | | | | | | | | | + | | | | | m | | | g | | | | + | | | | | | | | | | | | + | | | | | | | | | | | | + | | | e | | f | | | | | | | - And the ways - | nodes | junction | name | highway | oneway | ref | - | ab | | crescent | trunk | yes | US 130 | - | bcd | roundabout | crescent | trunk | yes | US 130 | - | de | | crescent | trunk | yes | US 130 | - | fg | | crescent | trunk | yes | US 130 | - | gh | roundabout | crescent | trunk | yes | US 130 | - | hi | | crescent | trunk | yes | US 130 | - | jh | | | trunk_link | yes | NJ 38 | - | hb | roundabout | | trunk_link | yes | NJ 38 | - | bl | | | trunk_link | yes | NJ 38 | - | cnd | | kaighns | trunk_link | yes | | - | dmg | roundabout | | trunk_link | yes | | + And the ways + | nodes | junction | name | highway | oneway | ref | + | ab | | crescent | trunk | yes | US 130 | + | bcd | roundabout | crescent | trunk | yes | US 130 | + | de | | crescent | trunk | yes | US 130 | + | fg | | crescent | trunk | yes | US 130 | + | gh | roundabout | crescent | trunk | yes | US 130 | + | hi | | crescent | trunk | yes | US 130 | + | jh | | | trunk_link | yes | NJ 38 | + | hb | roundabout | | trunk_link | yes | NJ 38 | + | bl | | | trunk_link | yes | NJ 38 | + | cnd | | kaighns | trunk_link | yes | | + | dmg | roundabout | | trunk_link | yes | | - When I route I should get - | waypoints | route | turns | - | a,e | crescent (US 130),crescent (US 130),crescent (US 130) | depart,roundabout-exit-3,arrive | - | j,l | NJ 38,NJ 38,NJ 38 | depart,roundabout-exit-2,arrive | + When I route I should get + | waypoints | route | turns | + | a,e | crescent (US 130),crescent (US 130),crescent (US 130) | depart,roundabout-exit-3,arrive | + | j,l | NJ 38,NJ 38,NJ 38 | depart,roundabout-exit-2,arrive | + + Scenario: Double Roundabout with through-lane + #http://map.project-osrm.org/?z=18¢er=38.911752%2C-77.048667&loc=38.912003%2C-77.050831&loc=38.909277%2C-77.042516&hl=en&alt=0 + Given the node map + | | | | | o | | | | | | | | | | | | n | | | | | + | | | | | e | | | | | | | | | | | | j | | | | | + | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | q | | | | | | | | | | | | | | | + | a | | b | | | | | | s | | f | | | | g | | | | i | | k | + | | | | | | | r | | | | | | | | | | | p | | | | + | | | | | | | | | | | t | | | | | | | | | | | + | | | | | c | | d | | | | | | | | | | h | | | | | + | | | | | l | | | | | | | | | | | | m | | | | | + + And the nodes + | node | highway | + | i | traffic_signals | + + And the ways + | nodes | junction | name | oneway | + | bcdrqeb | roundabout | sheridan circle | yes | + | ghi | roundabout | dupont circle | yes | + | ijg | roundabout | dupont circle | yes | + | ab | | massachusetts | no | + | sfgpik | | massachusetts | no | + | cl | | 23rd street | no | + | oe | | r street | no | + | jn | | new hampshire | no | + | mh | | new hampshire | yes | + | rsq | | massachusetts | yes | + | ft | | suppressed | no | + + And the relations + | type | way:from | way:to | node:via | restriction | + | restriction | sfgpik | ijg | i | no_left_turn | + + When I route I should get + | waypoints | route | turns | + | a,k | massachusetts,massachusetts,massachusetts,massachusetts | depart,sheridan circle-exit-2,dupont circle-exit-1,arrive | diff --git a/include/extractor/guidance/toolkit.hpp b/include/extractor/guidance/toolkit.hpp index bd21137cd..5eb3fa864 100644 --- a/include/extractor/guidance/toolkit.hpp +++ b/include/extractor/guidance/toolkit.hpp @@ -456,6 +456,26 @@ inline ConnectedRoad mirror(ConnectedRoad road) return road; } +inline bool hasRoundaboutType(const TurnInstruction instruction) +{ + using namespace extractor::guidance::TurnType; + const constexpr TurnType::Enum valid_types[] = {TurnType::EnterRoundabout, + TurnType::EnterAndExitRoundabout, + TurnType::EnterRotary, + TurnType::EnterAndExitRotary, + TurnType::EnterRoundaboutIntersection, + TurnType::EnterAndExitRoundaboutIntersection, + TurnType::EnterRoundaboutAtExit, + TurnType::ExitRoundabout, + TurnType::EnterRotaryAtExit, + TurnType::ExitRotary, + TurnType::EnterRoundaboutIntersectionAtExit, + TurnType::ExitRoundaboutIntersection, + TurnType::StayOnRoundabout}; + const auto valid_end = valid_types + 13; + return std::find(valid_types, valid_end, instruction.type) != valid_end; +}; + } // namespace guidance } // namespace extractor } // namespace osrm diff --git a/src/engine/guidance/post_processing.cpp b/src/engine/guidance/post_processing.cpp index dfad1e028..83ca5b6ee 100644 --- a/src/engine/guidance/post_processing.cpp +++ b/src/engine/guidance/post_processing.cpp @@ -120,7 +120,7 @@ RouteStep forwardInto(RouteStep destination, const RouteStep &source) // Overwrites turn instruction and increases exit NR destination.duration += source.duration; destination.distance += source.distance; - + destination.maneuver.exit = source.maneuver.exit; if (destination.geometry_begin < source.geometry_begin) { destination.intersections.insert(destination.intersections.end(), @@ -136,8 +136,6 @@ RouteStep forwardInto(RouteStep destination, const RouteStep &source) destination.geometry_begin = std::min(destination.geometry_begin, source.geometry_begin); destination.geometry_end = std::max(destination.geometry_end, source.geometry_end); - destination.maneuver.exit = destination.intersections.size() - 1; - return destination; } @@ -150,7 +148,6 @@ void fixFinalRoundabout(std::vector &steps) if (entersRoundabout(propagation_step.maneuver.instruction)) { propagation_step.maneuver.exit = 0; - propagation_step.geometry_end = steps.back().geometry_begin; // remember the current name as rotary name in tha case we end in a rotary if (propagation_step.maneuver.instruction.type == TurnType::EnterRotary || @@ -235,7 +232,12 @@ void closeOffRoundabout(const bool on_roundabout, steps[1].maneuver.instruction.type == TurnType::Suppressed || steps[1].maneuver.instruction.type == TurnType::NoTurn); steps[0].geometry_end = 1; + steps[1].geometry_begin = 0; steps[1] = forwardInto(steps[1], steps[0]); + steps[1].intersections.erase(steps[1].intersections.begin()); // otherwise we copy the + // source + if (leavesRoundabout(steps[1].maneuver.instruction)) + steps[1].maneuver.exit = 1; steps[0].duration = 0; steps[0].distance = 0; const auto exitToEnter = [](const TurnType::Enum type) { @@ -273,7 +275,6 @@ void closeOffRoundabout(const bool on_roundabout, if (entersRoundabout(propagation_step.maneuver.instruction)) { propagation_step.maneuver.exit = step.maneuver.exit; - propagation_step.geometry_end = step.geometry_end; const auto entry_intersection = propagation_step.intersections.front(); // remember rotary name @@ -303,8 +304,10 @@ void closeOffRoundabout(const bool on_roundabout, } else { - BOOST_ASSERT(propagation_step.maneuver.instruction.type = - TurnType::StayOnRoundabout); + BOOST_ASSERT(propagation_step.maneuver.instruction.type == + TurnType::StayOnRoundabout || + propagation_step.maneuver.instruction.type == TurnType::Suppressed || + propagation_step.maneuver.instruction.type == TurnType::NoTurn); propagation_step.maneuver.instruction = TurnInstruction::NO_TURN(); // mark intermediate instructions invalid } @@ -441,7 +444,6 @@ void collapseTurnAt(std::vector &steps, current_step.intersections.front() .bearings[current_step.intersections.front().out]) && compatible(one_back_step, current_step)) - { BOOST_ASSERT(two_back_index < steps.size()); // the simple case is a u-turn that changes directly into the in-name again @@ -552,12 +554,10 @@ std::vector postProcess(std::vector steps) } else if (leavesRoundabout(instruction)) { - if (!has_entered_roundabout) - { - // in case the we are not on a roundabout, the very first instruction - // after the depart will be transformed into a roundabout and become - // the first valid instruction - } + // if (!has_entered_roundabout) + // in case the we are not on a roundabout, the very first instruction + // after the depart will be transformed into a roundabout and become + // the first valid instruction closeOffRoundabout(has_entered_roundabout, steps, step_index); has_entered_roundabout = false; on_roundabout = false; diff --git a/src/extractor/guidance/turn_analysis.cpp b/src/extractor/guidance/turn_analysis.cpp index 458457d7c..601773b93 100644 --- a/src/extractor/guidance/turn_analysis.cpp +++ b/src/extractor/guidance/turn_analysis.cpp @@ -1,6 +1,6 @@ +#include "extractor/guidance/classification_data.hpp" #include "extractor/guidance/constants.hpp" #include "extractor/guidance/turn_analysis.hpp" -#include "extractor/guidance/classification_data.hpp" #include "util/coordinate.hpp" #include "util/coordinate_calculation.hpp" @@ -133,14 +133,12 @@ TurnAnalysis::setTurnTypes(const NodeID from_nid, const EdgeID, Intersection int Intersection TurnAnalysis::handleSliproads(const EdgeID source_edge_id, Intersection intersection) const { - auto intersection_node_id = node_based_graph.GetTarget(source_edge_id); const auto linkTest = [this](const ConnectedRoad &road) { - return // isLinkClass( - // node_based_graph.GetEdgeData(road.turn.eid).road_classification.road_class) && - !node_based_graph.GetEdgeData(road.turn.eid).roundabout && road.entry_allowed && - angularDeviation(road.turn.angle, STRAIGHT_ANGLE) <= 2 * NARROW_TURN_ANGLE; + return !node_based_graph.GetEdgeData(road.turn.eid).roundabout && road.entry_allowed && + angularDeviation(road.turn.angle, STRAIGHT_ANGLE) <= 2 * NARROW_TURN_ANGLE && + !hasRoundaboutType(road.turn.instruction); }; bool hasNarrow =