Skip to content

Commit ef8f3d7

Browse files
authored
Ensure u-turn exists in intersection view (#6376)
Due to some rather complex logic that tries to calculate intersection angles by looking further up the road, it's possible to return an intersection view that is missing a u-turn - something which is assumed to exist in later guidance calculations. We apply a fix here by ensuring the u-turn is always included in the returned view.
1 parent 660cea8 commit ef8f3d7

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
- ADDED: Support snapping to multiple ways at an input location. [#5953](https://github.com/Project-OSRM/osrm-backend/pull/5953)
6060
- FIXED: Fix snapping target locations to ways used in turn restrictions. [#6339](https://github.com/Project-OSRM/osrm-backend/pull/6339)
6161
- ADDED: Support OSM traffic signal directions. [#6153](https://github.com/Project-OSRM/osrm-backend/pull/6153)
62+
- FIXED: Ensure u-turn exists in intersection view. [#6376](https://github.com/Project-OSRM/osrm-backend/pull/6376)
6263
- Profile:
6364
- CHANGED: Bicycle surface speeds [#6212](https://github.com/Project-OSRM/osrm-backend/pull/6212)
6465

features/foot/intersection.feature

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
@routing @foot
2+
Feature: Foot - Intersections
3+
4+
Background:
5+
Given the profile "foot"
6+
Given a grid size of 2 meters
7+
8+
# https://github.com/Project-OSRM/osrm-backend/issues/6218
9+
Scenario: Foot - Handles non-planar intersections
10+
Given the node map
11+
12+
"""
13+
f
14+
|
15+
a
16+
|
17+
b---c---d
18+
|
19+
e
20+
"""
21+
22+
And the ways
23+
| nodes | highway | foot | layer |
24+
| ac | footway | yes | 0 |
25+
| bc | footway | yes | 0 |
26+
| cd | footway | yes | 0 |
27+
| cef | footway | yes | 1 |
28+
29+
When I route I should get
30+
| from | to | route |
31+
| a | d | ac,cd,cd |

src/extractor/intersection/intersection_analysis.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -617,12 +617,13 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
617617
std::vector<IntersectionViewDataWithAngle> pre_intersection_view;
618618
IntersectionViewData uturn{{SPECIAL_EDGEID, 0., 0., 0.}, false, 0.};
619619
std::size_t allowed_uturns_number = 0;
620+
621+
const auto is_uturn = [](const auto angle) {
622+
return std::fabs(angle) < std::numeric_limits<double>::epsilon();
623+
};
624+
620625
for (const auto &outgoing_edge : outgoing_edges)
621626
{
622-
const auto is_uturn = [](const auto angle) {
623-
return std::fabs(angle) < std::numeric_limits<double>::epsilon();
624-
};
625-
626627
const auto edge_it = findEdge(edge_geometries, outgoing_edge.edge);
627628
const auto is_merged = merged_edges.count(outgoing_edge.edge) != 0;
628629
const auto is_turn_allowed = intersection::isTurnAllowed(graph,
@@ -678,6 +679,7 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
678679
BOOST_ASSERT(uturn.eid != SPECIAL_EDGEID);
679680
if (uturn.entry_allowed || allowed_uturns_number == 0)
680681
{ // Add the true U-turn if it is allowed or no other U-turns found
682+
BOOST_ASSERT(uturn.angle == 0.);
681683
pre_intersection_view.insert(pre_intersection_view.begin(), {uturn, 0});
682684
}
683685

@@ -706,6 +708,22 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
706708
}
707709
}
708710

711+
auto no_uturn = std::none_of(pre_intersection_view.begin(),
712+
pre_intersection_view.end(),
713+
[&is_uturn](const IntersectionViewDataWithAngle &road) {
714+
return is_uturn(road.first.angle);
715+
});
716+
// After all of this, if we now don't have a u-turn, let's add one to the intersection.
717+
// This is a hack to fix the triggered assertion ( see:
718+
// https://github.com/Project-OSRM/osrm-backend/issues/6218 ). Ideally we would fix this more
719+
// robustly, but this will require overhauling all of the intersection logic.
720+
if (no_uturn)
721+
{
722+
BOOST_ASSERT(!uturn.entry_allowed && allowed_uturns_number > 0);
723+
BOOST_ASSERT(uturn.angle == 0.);
724+
pre_intersection_view.insert(pre_intersection_view.begin(), {uturn, 0});
725+
}
726+
709727
// Copy intersection view data
710728
IntersectionView intersection_view;
711729
intersection_view.reserve(pre_intersection_view.size());

0 commit comments

Comments
 (0)