handle intersection-access for roundabout correctly

This commit is contained in:
Moritz Kobitzsch 2016-05-26 14:55:34 +02:00 committed by Patrick Niklaus
parent 51066ff18f
commit 797f2a196b
No known key found for this signature in database
GPG Key ID: E426891B5F978B1B
3 changed files with 81 additions and 28 deletions

View File

@ -367,3 +367,25 @@ Feature: Basic Roundabout
| h,d | gh,cd,cd | depart,roundabout-exit-2,arrive |
| h,f | gh,ef,ef | depart,roundabout-exit-1,arrive |
Scenario: Enter and Exit -- Bearing
Given the node map
| | | a | | |
| | | b | | |
| h | g | | c | d |
| | | e | | |
| | | f | | |
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bgecb | roundabout |
When I route I should get
| waypoints | route | turns | bearing |
| a,d | ab,cd,cd | depart,roundabout turn left exit-3,arrive | 0->180,180->224,90->0 |
| a,f | ab,ef,ef | depart,roundabout turn straight exit-2,arrive | 0->180,180->224,180->0 |
| a,h | ab,gh,gh | depart,roundabout turn right exit-1,arrive | 0->180,180->224,270->0 |

View File

@ -337,3 +337,27 @@ Feature: Basic Roundabout
| a,e | ac,de,de | depart,roundabout-exit-1,arrive |
| a,f | ac,bf,bf | depart,roundabout-exit-2,arrive |
Scenario: Enter and Exit - Bearings
Given the node map
| | | | a | | | |
| | | | | | | |
| | | i | b | l | | |
| h | | g | | c | | d |
| | | j | e | k | | |
| | | | | | | |
| | | | f | | | |
And the ways
| nodes | junction |
| ab | |
| cd | |
| ef | |
| gh | |
| bigjekclb | roundabout |
When I route I should get
| waypoints | route | turns | bearing |
| a,d | ab,cd,cd | depart,roundabout-exit-3,arrive | 0->180,180->270,90->0 |
| a,f | ab,ef,ef | depart,roundabout-exit-2,arrive | 0->180,180->270,180->0 |
| a,h | ab,gh,gh | depart,roundabout-exit-1,arrive | 0->180,180->270,270->0 |

View File

@ -41,11 +41,11 @@ void print(const std::vector<RouteStep> &steps)
int segment = 0;
for (const auto &step : steps)
{
std::cout << "\t[" << ++segment << "]: " << step.maneuver.instruction.type
<< " " << step.maneuver.instruction.direction_modifier << " " << static_cast<int>(step.maneuver.waypoint_type)
<< " Duration: " << step.duration << " Distance: " << step.distance
<< " Geometry: " << step.geometry_begin << " " << step.geometry_end
<< " exit: " << step.maneuver.exit
std::cout << "\t[" << ++segment << "]: " << step.maneuver.instruction.type << " "
<< step.maneuver.instruction.direction_modifier << " "
<< static_cast<int>(step.maneuver.waypoint_type) << " Duration: " << step.duration
<< " Distance: " << step.distance << " Geometry: " << step.geometry_begin << " "
<< step.geometry_end << " exit: " << step.maneuver.exit
<< " Intersections: " << step.intersections.size() << " [";
for (const auto &intersection : step.intersections)
@ -203,7 +203,9 @@ void closeOffRoundabout(const bool on_roundabout,
// removal.
std::vector<std::size_t> intermediate_steps;
BOOST_ASSERT(!steps[step_index].intersections.empty());
const auto exit_intersection = steps[step_index].intersections.back();
// the very first intersection in the steps represents the location of the turn. Following
// intersections are locations passed along the way
const auto exit_intersection = steps[step_index].intersections.front();
const auto exit_bearing = exit_intersection.bearings[exit_intersection.out];
if (step_index > 1)
{
@ -250,7 +252,8 @@ void closeOffRoundabout(const bool on_roundabout,
// All other cases are handled by first rotating both bearings to an
// entry_bearing of 0.
BOOST_ASSERT(!propagation_step.intersections.empty());
const double angle = [](const double entry_bearing, const double exit_bearing) {
const double angle =
[](const double entry_bearing, const double exit_bearing) {
const double offset = 360 - entry_bearing;
const double rotated_exit = [](double bearing, const double offset) {
bearing += offset;
@ -259,7 +262,9 @@ void closeOffRoundabout(const bool on_roundabout,
const auto angle = 540 - rotated_exit;
return angle > 360 ? angle - 360 : angle;
}(util::bearing::reverseBearing(entry_intersection.bearings[entry_intersection.in]), exit_bearing);
}(util::bearing::reverseBearing(
entry_intersection.bearings[entry_intersection.in]),
exit_bearing);
propagation_step.maneuver.instruction.direction_modifier =
::osrm::util::guidance::getTurnDirection(angle);
@ -378,8 +383,11 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
}
}
// Potential U-Turn
else if (bearingsAreReversed(util::bearing::reverseBearing(one_back_step.intersections.front().bearings[one_back_step.intersections.front().in]),
current_step.intersections.front().bearings[current_step.intersections.front().out]))
else if (bearingsAreReversed(util::bearing::reverseBearing(
one_back_step.intersections.front()
.bearings[one_back_step.intersections.front().in]),
current_step.intersections.front()
.bearings[current_step.intersections.front().out]))
{
BOOST_ASSERT(two_back_index < steps.size());
@ -755,7 +763,6 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
if (steps.size() < 2 || geometry.locations.size() == 2)
return;
BOOST_ASSERT(geometry.locations.size() >= steps.size());
auto &next_to_last_step = *(steps.end() - 2);
// in the end, the situation with the roundabout cannot occur. As a result, we can remove