detect turning onto oneways at the end of the road as non obvious
This commit is contained in:
parent
af8ddac2af
commit
f347efb006
@ -1,4 +1,7 @@
|
|||||||
# UNRELEASED
|
# UNRELEASED
|
||||||
|
- Changes from 5.11:
|
||||||
|
- Guidance
|
||||||
|
- now announcing turning onto oneways at the end of a road (e.g. onto dual carriageways)
|
||||||
|
|
||||||
# 5.11.0
|
# 5.11.0
|
||||||
- Changes from 5.10:
|
- Changes from 5.10:
|
||||||
|
@ -40,8 +40,8 @@ Feature: End Of Road Instructions
|
|||||||
| ef | primary | turn | yes |
|
| ef | primary | turn | yes |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | turns |
|
| waypoints | route | turns |
|
||||||
| a,d | road, | depart,arrive |
|
| a,d | road,, | depart,end of road right,arrive |
|
||||||
|
|
||||||
@3605
|
@3605
|
||||||
Scenario: End of Road with oneway through street
|
Scenario: End of Road with oneway through street
|
||||||
|
@ -108,12 +108,12 @@ Feature: Bearing parameter
|
|||||||
| ha | yes | ring |
|
| ha | yes | ring |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | bearings | route | bearing |
|
| from | to | bearings | route | bearing |
|
||||||
| 0 | q | 0 90 | ia,ring,ring | 0->0,0->90,90->0 |
|
| 0 | q | 0 90 | ia,ring,ring,ring,ring | 0->0,0->90,180->270,270->0,90->0 |
|
||||||
| 0 | a | 45 90 | jb,ring,ring | 0->45,45->180,90->0 |
|
| 0 | a | 45 90 | jb,ring,ring,ring,ring | 0->45,45->180,180->270,270->0,90->0 |
|
||||||
| 0 | q | 90 90 | kc,ring,ring | 0->90,90->180,90->0 |
|
| 0 | q | 90 90 | kc,ring,ring,ring | 0->90,90->180,270->0,90->0 |
|
||||||
| 0 | a | 135 90 | ld,ring,ring | 0->135,135->270,90->0 |
|
| 0 | a | 135 90 | ld,ring,ring,ring | 0->135,135->270,270->0,90->0 |
|
||||||
| 0 | a | 180 90 | me,ring,ring | 0->180,180->270,90->0 |
|
| 0 | a | 180 90 | me,ring,ring,ring | 0->180,180->270,270->0,90->0 |
|
||||||
| 0 | a | 225 90 | nf,ring,ring | 0->225,225->0,90->0 |
|
| 0 | a | 225 90 | nf,ring,ring | 0->225,225->0,90->0 |
|
||||||
| 0 | a | 270 90 | og,ring,ring | 0->270,270->0,90->0 |
|
| 0 | a | 270 90 | og,ring,ring | 0->270,270->0,90->0 |
|
||||||
| 0 | a | 315 90 | ph,ring,ring | 0->315,315->90,90->0 |
|
| 0 | a | 315 90 | ph,ring,ring | 0->315,315->90,90->0 |
|
||||||
|
@ -327,6 +327,42 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
|||||||
return false;
|
return false;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
// check whether we turn onto a oneway through street. These typically happen at the end of
|
||||||
|
// roads and might not seem obvious, since it isn't always as visible that you cannot turn
|
||||||
|
// left/right. To be on the safe side, we announce these as non-obvious
|
||||||
|
const auto turns_onto_through_street = [&](const auto &road) {
|
||||||
|
// find edge opposite to the one we are checking (in-road)
|
||||||
|
const auto in_through_candidate =
|
||||||
|
intersection.FindClosestBearing(util::bearing::reverse(road.bearing));
|
||||||
|
|
||||||
|
const auto &in_data = node_based_graph.GetEdgeData(in_through_candidate->eid);
|
||||||
|
const auto &out_data = node_based_graph.GetEdgeData(road.eid);
|
||||||
|
|
||||||
|
// by asking for the same class, we ensure that we do not overrule obvious by road-class
|
||||||
|
// decisions
|
||||||
|
const auto same_class = in_data.road_classification == out_data.road_classification;
|
||||||
|
|
||||||
|
// only if the entry is allowed for one of the two, but not the other, we need to check.
|
||||||
|
// Otherwise other handlers do it better
|
||||||
|
const bool is_oneway = !in_through_candidate->entry_allowed && road.entry_allowed;
|
||||||
|
|
||||||
|
const bool not_roundabout =
|
||||||
|
!(in_data.roundabout || in_data.circular || out_data.roundabout || out_data.circular);
|
||||||
|
|
||||||
|
// for the purpose of this check, we do not care about low-priority roads (parking lots,
|
||||||
|
// mostly). Since we postulate both classes to be the same, checking one of the two is
|
||||||
|
// enough
|
||||||
|
const bool not_low_priority = !in_data.road_classification.IsLowPriorityRoadClass();
|
||||||
|
|
||||||
|
const auto in_deviation = angularDeviation(in_through_candidate->angle, STRAIGHT_ANGLE);
|
||||||
|
const auto out_deviaiton = angularDeviation(road.angle, STRAIGHT_ANGLE);
|
||||||
|
// in case the deviation isn't considerably lower for the road we are turning onto,
|
||||||
|
// consider it non-obvious. The threshold here requires a slight (60) vs sharp (120)
|
||||||
|
// degree variation, at lest (120/60 == 2)
|
||||||
|
return is_oneway && same_class && not_roundabout && not_low_priority &&
|
||||||
|
(in_deviation / (std::max(out_deviaiton, 0.5)) <= 2);
|
||||||
|
};
|
||||||
|
|
||||||
if (best_over_best_continue)
|
if (best_over_best_continue)
|
||||||
{
|
{
|
||||||
// Find left/right deviation
|
// Find left/right deviation
|
||||||
@ -366,8 +402,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
|||||||
angularDeviation(intersection[right_index].angle, STRAIGHT_ANGLE);
|
angularDeviation(intersection[right_index].angle, STRAIGHT_ANGLE);
|
||||||
|
|
||||||
// return best_option candidate if it is nearly straight and distinct from the nearest other
|
// return best_option candidate if it is nearly straight and distinct from the nearest other
|
||||||
// out
|
// out way
|
||||||
// way
|
|
||||||
if (best_option_deviation < MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
|
if (best_option_deviation < MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
|
||||||
std::min(left_deviation, right_deviation) > FUZZY_ANGLE_DIFFERENCE)
|
std::min(left_deviation, right_deviation) > FUZZY_ANGLE_DIFFERENCE)
|
||||||
return best_option;
|
return best_option;
|
||||||
@ -385,8 +420,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
|||||||
right_data.road_classification);
|
right_data.road_classification);
|
||||||
|
|
||||||
// if the best_option turn isn't narrow, but there is a nearly straight turn, we don't
|
// if the best_option turn isn't narrow, but there is a nearly straight turn, we don't
|
||||||
// consider the
|
// consider the turn obvious
|
||||||
// turn obvious
|
|
||||||
const auto check_narrow = [&intersection, best_option_deviation](const std::size_t index) {
|
const auto check_narrow = [&intersection, best_option_deviation](const std::size_t index) {
|
||||||
return angularDeviation(intersection[index].angle, STRAIGHT_ANGLE) <=
|
return angularDeviation(intersection[index].angle, STRAIGHT_ANGLE) <=
|
||||||
FUZZY_ANGLE_DIFFERENCE &&
|
FUZZY_ANGLE_DIFFERENCE &&
|
||||||
@ -400,6 +434,11 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
|||||||
if (check_narrow(left_index) && !obvious_to_left)
|
if (check_narrow(left_index) && !obvious_to_left)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// we are turning onto a through street (possibly at the end of the road). Ensure that we
|
||||||
|
// announce a turn, if it isn't a slight merge
|
||||||
|
if (turns_onto_through_street(intersection[best_option]))
|
||||||
|
return 0;
|
||||||
|
|
||||||
// checks if a given way in the intersection is distinct enough from the best_option
|
// checks if a given way in the intersection is distinct enough from the best_option
|
||||||
// candidate
|
// candidate
|
||||||
const auto isDistinct = [&](const std::size_t index, const double deviation) {
|
const auto isDistinct = [&](const std::size_t index, const double deviation) {
|
||||||
@ -437,6 +476,11 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
|||||||
if (std::abs(best_continue_deviation) < 1)
|
if (std::abs(best_continue_deviation) < 1)
|
||||||
return best_continue;
|
return best_continue;
|
||||||
|
|
||||||
|
// we are turning onto a through street (possibly at the end of the road). Ensure that we
|
||||||
|
// announce a turn, if it isn't a slight merge
|
||||||
|
if (turns_onto_through_street(intersection[best_continue]))
|
||||||
|
return 0;
|
||||||
|
|
||||||
// check if any other similar best continues exist
|
// check if any other similar best continues exist
|
||||||
std::size_t i, last = intersection.size();
|
std::size_t i, last = intersection.size();
|
||||||
for (i = 1; i < last; ++i)
|
for (i = 1; i < last; ++i)
|
||||||
|
Loading…
Reference in New Issue
Block a user