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.
This commit is contained in:
Michael Bell
2022-09-27 13:49:12 +01:00
committed by GitHub
parent 660cea8fcc
commit ef8f3d7508
3 changed files with 54 additions and 4 deletions
@@ -617,12 +617,13 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
std::vector<IntersectionViewDataWithAngle> pre_intersection_view;
IntersectionViewData uturn{{SPECIAL_EDGEID, 0., 0., 0.}, false, 0.};
std::size_t allowed_uturns_number = 0;
const auto is_uturn = [](const auto angle) {
return std::fabs(angle) < std::numeric_limits<double>::epsilon();
};
for (const auto &outgoing_edge : outgoing_edges)
{
const auto is_uturn = [](const auto angle) {
return std::fabs(angle) < std::numeric_limits<double>::epsilon();
};
const auto edge_it = findEdge(edge_geometries, outgoing_edge.edge);
const auto is_merged = merged_edges.count(outgoing_edge.edge) != 0;
const auto is_turn_allowed = intersection::isTurnAllowed(graph,
@@ -678,6 +679,7 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
BOOST_ASSERT(uturn.eid != SPECIAL_EDGEID);
if (uturn.entry_allowed || allowed_uturns_number == 0)
{ // Add the true U-turn if it is allowed or no other U-turns found
BOOST_ASSERT(uturn.angle == 0.);
pre_intersection_view.insert(pre_intersection_view.begin(), {uturn, 0});
}
@@ -706,6 +708,22 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
}
}
auto no_uturn = std::none_of(pre_intersection_view.begin(),
pre_intersection_view.end(),
[&is_uturn](const IntersectionViewDataWithAngle &road) {
return is_uturn(road.first.angle);
});
// After all of this, if we now don't have a u-turn, let's add one to the intersection.
// This is a hack to fix the triggered assertion ( see:
// https://github.com/Project-OSRM/osrm-backend/issues/6218 ). Ideally we would fix this more
// robustly, but this will require overhauling all of the intersection logic.
if (no_uturn)
{
BOOST_ASSERT(!uturn.entry_allowed && allowed_uturns_number > 0);
BOOST_ASSERT(uturn.angle == 0.);
pre_intersection_view.insert(pre_intersection_view.begin(), {uturn, 0});
}
// Copy intersection view data
IntersectionView intersection_view;
intersection_view.reserve(pre_intersection_view.size());