Skip to content

Commit c22b0b7

Browse files
committed
Ensure u-turn exists in intersection view
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 c22b0b7

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-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: 21 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,21 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
706708
}
707709
}
708710

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

0 commit comments

Comments
 (0)