From d3a6b5a77ed4ec9663f68aea24f960ecfb70619a Mon Sep 17 00:00:00 2001 From: Moritz Kobitzsch Date: Mon, 5 Sep 2016 16:23:30 +0200 Subject: [PATCH] detect broken roundabout-taggings --- CHANGELOG.md | 1 + features/guidance/roundabout.feature | 61 ++++++++++++++++++- src/extractor/guidance/roundabout_handler.cpp | 17 ++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff9cc7f32..6eafc1fcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Invalid only_* restrictions could result in loss of connectivity. As a fallback, we assume all turns allowed when the restriction is not valid - Fixed a bug that could result in an infinite loop when finding information about an upcoming intersection - Fixed a bug that led to not discovering if a road simply looses a considered prefix + - BREAKING: Fixed a bug that could crash postprocessing of instructions on invalid roundabout taggings. This change requires reprocessing datasets with osrm-extract and osrm-contract # 5.3.0 Changes from 5.3.0-rc.3 diff --git a/features/guidance/roundabout.feature b/features/guidance/roundabout.feature index 6d13fd72f..9700cae89 100644 --- a/features/guidance/roundabout.feature +++ b/features/guidance/roundabout.feature @@ -229,7 +229,7 @@ Feature: Basic Roundabout | a,e | ab,ce,ce | depart,roundabout-exit-1,arrive | | a,f | ab,df,df | depart,roundabout-exit-2,arrive | - Scenario: Collinear in Y + Scenario: Collinear in Y Given the node map | | a | | | b | @@ -325,3 +325,62 @@ Feature: Basic Roundabout 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 | + + #2856 - http://www.openstreetmap.org/#map=19/47.23318/-1.56563 + Scenario: Linked Roundabouts + Given the node map + | | | | | | | | | | | | | | x | + | | u | | | | | | | | | | | r | | + | | | | | | | | | | | | | | | + | | | | t | | | | | | | | | | | + | | | | | | | | | | | s | | | | + | | | v | | | i | | h | | g | | | | | + | | | | | | | | | | | | q | | | + | | | | | | | | | | | | | | | + | | | | j | | | | | | | | f | | | + | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | | a | | | | | | | | e | | | + | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | | | | b | | c | | d | | p | | | + | | | | | | | | | | | | | | | + | | | m | | | | | | | | n | | | | + | | | | | l | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | k | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | + | | w | | | | | | | | | | o | | | + + And the ways + | nodes | junction | name | highway | oneway | + | abija | roundabout | egg | primary | yes | + | defgd | roundabout | egg | primary | yes | + | bcd | roundabout | egg | primary | yes | + | ghi | | egg | primary | yes | + | amklb | | ll | primary | yes | + | wk | | ll | primary | no | + | dnope | | lr | secondary | yes | + | fqrsg | | tr | primary | yes | + | rx | | tr | primary | no | + | ituvj | | tl | primary | yes | + + And the nodes + | node | highway | + | c | give_way | + | h | give_way | + + When I route I should get + | waypoints | route | turns | + # since we cannot handle these invalid roundabout tags yet, we cannout output roundabout taggings. This will hopefully change some day + #| w,x | ll,egg,egg,tr,tr | depart,roundabout-exit-1,roundabout-exit-2,arrive | + | w,x | ll,egg,egg,tr,tr | depart,turn right,continue left,turn slight left,arrive | + diff --git a/src/extractor/guidance/roundabout_handler.cpp b/src/extractor/guidance/roundabout_handler.cpp index 6eea5657c..c21dd4505 100644 --- a/src/extractor/guidance/roundabout_handler.cpp +++ b/src/extractor/guidance/roundabout_handler.cpp @@ -270,6 +270,19 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const std::set roundabout_nodes; // needs to be sorted // this value is a hard abort to deal with potential self-loops + const auto countRoundaboutFlags = [&](const NodeID at_node) { + // FIXME: this would be nicer as boost::count_if, but our integer range does not support + // these range based handlers + std::size_t count = 0; + for (const auto edge : node_based_graph.GetAdjacentEdgeRange(at_node)) + { + const auto &edge_data = node_based_graph.GetEdgeData(edge); + if (edge_data.roundabout) + count++; + } + return count; + }; + NodeID last_node = nid; while (0 == roundabout_nodes.count(last_node)) { @@ -277,6 +290,10 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const if (node_based_graph.GetOutDegree(last_node) > 2) roundabout_nodes.insert(last_node); + // detect invalid/complex roundabout taggings + if (countRoundaboutFlags(last_node) != 2) + return RoundaboutType::None; + const auto eid = getNextOnRoundabout(last_node); if (eid == SPECIAL_EDGEID)