From 3c8781855ec50be9a8fd15b7a1dc83d5c7ea0f32 Mon Sep 17 00:00:00 2001 From: Moritz Kobitzsch Date: Wed, 15 Jun 2016 14:25:22 +0200 Subject: [PATCH] handle steep off-ramps --- features/guidance/motorway.feature | 18 +++++++++++ .../guidance/classification_data.hpp | 6 ++++ src/extractor/guidance/motorway_handler.cpp | 31 ++++++++----------- src/extractor/guidance/turn_analysis.cpp | 10 ++++++ 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/features/guidance/motorway.feature b/features/guidance/motorway.feature index f39c07780..f560a3bfc 100644 --- a/features/guidance/motorway.feature +++ b/features/guidance/motorway.feature @@ -216,3 +216,21 @@ Feature: Motorway Guidance | waypoints | route | turns | | d,c | db,abc,abc | depart,merge slight left,arrive | | e,c | eb,abc,abc | depart,merge slight right,arrive | + + Scenario: Handle 90 degree off ramps correctly + Given the node map + | a | | | | | + | x | b | | c | y | + | | | | d | | + + And the ways + | nodes | name | highway | oneway | + | ab | On | motorway_link | yes | + | xb | Hwy | motorway | | + | bc | Hwy | motorway | | + | cd | Off | motorway_link | yes | + | cy | Hwy | motorway | | + + When I route I should get + | waypoints | route | turns | + | a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive | diff --git a/include/extractor/guidance/classification_data.hpp b/include/extractor/guidance/classification_data.hpp index fd63e4f06..0454041aa 100644 --- a/include/extractor/guidance/classification_data.hpp +++ b/include/extractor/guidance/classification_data.hpp @@ -58,6 +58,12 @@ inline bool isLinkClass(const FunctionalRoadClass road_class) road_class == FunctionalRoadClass::TERTIARY_LINK; } +// check wheter a class is a motorway like class +inline bool isMotorwayClass(const FunctionalRoadClass road_class) +{ + return road_class == FunctionalRoadClass::MOTORWAY || road_class == FunctionalRoadClass::TRUNK; +} + // TODO augment this with all data required for guidance generation struct RoadClassificationData { diff --git a/src/extractor/guidance/motorway_handler.cpp b/src/extractor/guidance/motorway_handler.cpp index cc81bc9dc..8d562bcc5 100644 --- a/src/extractor/guidance/motorway_handler.cpp +++ b/src/extractor/guidance/motorway_handler.cpp @@ -1,5 +1,6 @@ -#include "extractor/guidance/motorway_handler.hpp" +#include "extractor/guidance/classification_data.hpp" #include "extractor/guidance/constants.hpp" +#include "extractor/guidance/motorway_handler.hpp" #include "extractor/guidance/toolkit.hpp" #include "util/guidance/toolkit.hpp" @@ -21,10 +22,6 @@ namespace guidance { namespace detail { -inline bool isMotorwayClass(const FunctionalRoadClass road_class) -{ - return road_class == FunctionalRoadClass::MOTORWAY || road_class == FunctionalRoadClass::TRUNK; -} inline bool isMotorwayClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph) { @@ -92,7 +89,7 @@ operator()(const NodeID, const EdgeID via_eid, Intersection intersection) const const auto &in_data = node_based_graph.GetEdgeData(via_eid); // coming from motorway - if (detail::isMotorwayClass(in_data.road_classification.road_class)) + if (isMotorwayClass(in_data.road_classification.road_class)) { intersection = fromMotorway(via_eid, std::move(intersection)); std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) { @@ -111,7 +108,7 @@ operator()(const NodeID, const EdgeID via_eid, Intersection intersection) const Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection intersection) const { const auto &in_data = node_based_graph.GetEdgeData(via_eid); - BOOST_ASSERT(detail::isMotorwayClass(in_data.road_classification.road_class)); + BOOST_ASSERT(isMotorwayClass(in_data.road_classification.road_class)); const auto countExitingMotorways = [this](const Intersection &intersection) { unsigned count = 0; @@ -130,7 +127,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid); if (road.turn.angle != 0 && in_data.name_id == out_data.name_id && in_data.name_id != EMPTY_NAMEID && - detail::isMotorwayClass(out_data.road_classification.road_class)) + isMotorwayClass(out_data.road_classification.road_class)) return road.turn.angle; } return intersection[0].turn.angle; @@ -142,7 +139,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in for (const auto &road : intersection) { const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid); - if (detail::isMotorwayClass(out_data.road_classification.road_class) && + if (isMotorwayClass(out_data.road_classification.road_class) && angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < best) { best = angularDeviation(road.turn.angle, STRAIGHT_ANGLE); @@ -385,7 +382,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters { // circular order indicates a merge to the left (0-3 onto 4 if (angularDeviation(intersection[1].turn.angle, STRAIGHT_ANGLE) < - 2*NARROW_TURN_ANGLE) + 2 * NARROW_TURN_ANGLE) intersection[1].turn.instruction = {TurnType::Merge, DirectionModifier::SlightLeft}; else // fallback @@ -453,8 +450,8 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters // M R // | / // R - if (detail::isMotorwayClass(node_based_graph.GetEdgeData(intersection[1].turn.eid) - .road_classification.road_class)) + if (isMotorwayClass(node_based_graph.GetEdgeData(intersection[1].turn.eid) + .road_classification.road_class)) { intersection[1].turn.instruction = {TurnType::Turn, DirectionModifier::SlightRight}; @@ -475,12 +472,11 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters for (auto &road : intersection) { const auto &edge_data = node_based_graph.GetEdgeData(road.turn.eid); - if (!road.entry_allowed && - detail::isMotorwayClass(edge_data.road_classification.road_class)) + if (!road.entry_allowed && isMotorwayClass(edge_data.road_classification.road_class)) { passed_highway_entry = true; } - else if (detail::isMotorwayClass(edge_data.road_classification.road_class)) + else if (isMotorwayClass(edge_data.road_classification.road_class)) { road.turn.instruction = {TurnType::Merge, passed_highway_entry ? DirectionModifier::SlightRight @@ -516,9 +512,8 @@ Intersection MotorwayHandler::fallback(Intersection intersection) const if (!road.entry_allowed) continue; - const auto type = detail::isMotorwayClass(out_data.road_classification.road_class) - ? TurnType::Merge - : TurnType::Turn; + const auto type = isMotorwayClass(out_data.road_classification.road_class) ? TurnType::Merge + : TurnType::Turn; if (type == TurnType::Turn) { diff --git a/src/extractor/guidance/turn_analysis.cpp b/src/extractor/guidance/turn_analysis.cpp index c87d443a2..458457d7c 100644 --- a/src/extractor/guidance/turn_analysis.cpp +++ b/src/extractor/guidance/turn_analysis.cpp @@ -1,5 +1,6 @@ #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" @@ -84,6 +85,15 @@ std::vector TurnAnalysis::getTurns(const NodeID from_nid, const E // Handle sliproads intersection = handleSliproads(via_eid, std::move(intersection)); + // Turn On Ramps Into Off Ramps, if we come from a motorway-like road + if (isMotorwayClass(node_based_graph.GetEdgeData(via_eid).road_classification.road_class)) + { + std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) { + if (road.turn.instruction.type == TurnType::OnRamp) + road.turn.instruction.type = TurnType::OffRamp; + }); + } + std::vector turns; for (auto road : intersection) if (road.entry_allowed)