adjust angles pre-merge as well

This commit is contained in:
Moritz Kobitzsch 2016-08-11 13:32:41 +02:00
parent 5a9eb6ef72
commit 7886d06839
4 changed files with 71 additions and 11 deletions

View File

@ -975,6 +975,7 @@ Feature: Simple Turns
Given the node map
| | f | |
| | e | |
| | | |
| g | | d |
| | | |
| | | |
@ -1012,3 +1013,27 @@ Feature: Simple Turns
| f,a | depart,arrive | Hermannstr,Hermannstr |
| y,f | depart,arrive | Hermannstr,Hermannstr |
| f,y | depart,arrive | Hermannstr,Hermannstr |
Scenario: Turning into splitting road
Given the node map
| | a | | |
| | b | | |
| | | | |
| | | | |
| c | | d | |
| | | | |
| | | | e |
| | | | |
| | | f | |
And the ways
| nodes | name | highway | oneway |
| ab | road | primary | no |
| bc | road | primary | yes |
| fdb | road | primary | yes |
| de | turn | primary | no |
When I route I should get
| waypoints | turns | route |
| f,a | depart,arrive | road,road |
| e,a | depart,turn slight right,arrive | turn,road,road |

View File

@ -25,8 +25,6 @@ inline void print(const engine::guidance::RouteStep &step)
std::cout << static_cast<int>(step.maneuver.instruction.type) << " "
<< static_cast<int>(step.maneuver.instruction.direction_modifier) << " "
<< static_cast<int>(step.maneuver.waypoint_type) << " "
<< " Lanes: (" << static_cast<int>(lanes.lanes_in_turn) << ", "
<< static_cast<int>(lanes.first_lane_from_the_right) << ")"
<< " Duration: " << step.duration << " Distance: " << step.distance
<< " Geometry: " << step.geometry_begin << " " << step.geometry_end
<< " exit: " << step.maneuver.exit << " Intersections: " << step.intersections.size()
@ -40,6 +38,8 @@ inline void print(const engine::guidance::RouteStep &step)
std::cout << ", entry: ";
for (auto entry : intersection.entry)
std::cout << " " << (entry ? "true" : "false");
std::cout << " Lanes: (" << static_cast<int>(intersection.lanes.lanes_in_turn) << ", "
<< static_cast<int>(intersection.lanes.first_lane_from_the_right) << ")";
std::cout << ")";
}
std::cout << "] name[" << step.name_id << "]: " << step.name;

View File

@ -815,6 +815,20 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
invalidateStep(steps[step_index]);
}
}
else if (step_index + 2 < steps.size() &&
current_step.maneuver.instruction.type == TurnType::NewName &&
steps[step_index + 1].maneuver.instruction.type == TurnType::NewName &&
one_back_step.name == steps[step_index + 1].name)
{
// if we are crossing an intersection and go immediately after into a name change,
// we don't wan't to collapse the initial intersection.
// a - b ---BRIDGE -- c
steps[one_back_index] =
elongate(std::move(steps[one_back_index]),
elongate(std::move(steps[step_index]), steps[step_index + 1]));
invalidateStep(steps[step_index]);
invalidateStep(steps[step_index + 1]);
}
else if (choiceless(current_step, one_back_step) ||
one_back_step.distance <= MAX_COLLAPSE_DISTANCE)
{

View File

@ -160,7 +160,7 @@ Intersection IntersectionGenerator::getConnectedRoads(const NodeID from_node,
intersection[self_u_turn].entry_allowed = true;
}
return mergeSegregatedRoads(std::move(intersection));
return intersection;
}
bool IntersectionGenerator::canMerge(const Intersection &intersection,
@ -184,8 +184,8 @@ bool IntersectionGenerator::canMerge(const Intersection &intersection,
if (first_data.road_classification != second_data.road_classification)
return false;
//may not be on a roundabout
if( first_data.roundabout || second_data.roundabout)
// may not be on a roundabout
if (first_data.roundabout || second_data.roundabout)
return false;
// exactly one of them has to be reversed
@ -381,12 +381,12 @@ Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersecti
Intersection IntersectionGenerator::adjustForJoiningRoads(const NodeID node_at_intersection,
Intersection intersection) const
{
// nothing to do for dead ends
if ( intersection.size() <= 1)
return intersection;
for (auto &road : intersection)
{
// prune to short intersections to save on compute overhead
if (node_based_graph.GetEdgeData(road.turn.eid).distance > 10)
continue;
// to find out about the above situation, we need to look at the next intersection (at d in
// the example). If the initial road can be merged to the left/right, we are about to adjust
// the angle.
@ -395,15 +395,36 @@ Intersection IntersectionGenerator::adjustForJoiningRoads(const NodeID node_at_i
if (next_intersection_along_road.size() <= 1)
continue;
const auto adjustAngle = [](double angle, double offset) {
angle += offset;
if (angle > 360)
return angle - 360.;
else if (angle < 0)
return angle + 360.;
return angle;
};
if (canMerge(next_intersection_along_road, 0, 1))
{
std::cout << "Merge at next intersection" << std::endl;
const auto offset = 0.5 * angularDeviation(next_intersection_along_road[0].turn.angle,
next_intersection_along_road[1].turn.angle);
// at the target intersection, we merge to the right, so we need to shift the current
// angle to the left
road.turn.angle = adjustAngle(road.turn.angle, offset);
}
else if (canMerge(next_intersection_along_road, 0, next_intersection_along_road.size() - 1))
{
std::cout << "Merge at next intersection (2)" << std::endl;
const auto offset =
0.5 * angularDeviation(
next_intersection_along_road[0].turn.angle,
next_intersection_along_road[next_intersection_along_road.size() - 1]
.turn.angle);
// at the target intersection, we merge to the left, so we need to shift the current
// angle to the right
road.turn.angle = adjustAngle(road.turn.angle, -offset);
}
}
std::cout << std::flush;
return intersection;
}