reduce numbers of intersections in findNextIntersection, don't normalise for turn lanes

This commit is contained in:
Moritz Kobitzsch
2016-11-15 11:21:26 +01:00
parent 01a57ff1d8
commit a1127c3e09
17 changed files with 203 additions and 125 deletions
@@ -99,6 +99,19 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
from_node, via_eid, traversed_in_reverse, to_node, intersection_lanes);
};
// The first coordinate (the origin) can depend on the number of lanes turning onto,
// just as the target coordinate can. Here we compute the corrected coordinate for the
// incoming edge
// to compute the length along the path
const auto in_segment_length = [&]() {
const auto in_coordinates =
coordinate_extractor.GetCoordinatesAlongRoad(from_node, via_eid, INVERT, turn_node);
return util::coordinate_calculation::getLength(
in_coordinates, util::coordinate_calculation::haversineDistance);
}();
const auto first_coordinate = extract_coordinate(from_node, via_eid, INVERT, turn_node);
for (const EdgeID onto_edge : node_based_graph.GetAdjacentEdgeRange(turn_node))
{
BOOST_ASSERT(onto_edge != SPECIAL_EDGEID);
@@ -117,14 +130,7 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
// the turn is not restricted
!restriction_map.CheckIfTurnIsRestricted(from_node, turn_node, to_node);
auto angle = 0.;
double bearing = 0.;
// The first coordinate (the origin) can depend on the number of lanes turning onto,
// just as the target coordinate can. Here we compute the corrected coordinate for the
// incoming edge.
const auto first_coordinate = extract_coordinate(from_node, via_eid, INVERT, turn_node);
double bearing = 0., out_segment_length = 0., angle = 0.;
if (from_node == to_node)
{
bearing = util::coordinate_calculation::bearing(turn_coordinate, first_coordinate);
@@ -150,14 +156,21 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
}
}
has_uturn_edge = true;
out_segment_length = in_segment_length;
BOOST_ASSERT(angle >= 0. && angle < std::numeric_limits<double>::epsilon());
}
else
{
// the default distance we lookahead on a road. This distance prevents small mapping
// errors to impact the turn angles.
const auto third_coordinate =
extract_coordinate(turn_node, onto_edge, !INVERT, to_node);
{
// segment of out segment
const auto out_coordinates = coordinate_extractor.GetCoordinatesAlongRoad(
turn_node, onto_edge, !INVERT, to_node);
out_segment_length = util::coordinate_calculation::getLength(
out_coordinates, util::coordinate_calculation::haversineDistance);
}
const auto third_coordinate = extract_coordinate(turn_node, onto_edge, !INVERT, to_node);
angle = util::coordinate_calculation::computeAngle(
first_coordinate, turn_coordinate, third_coordinate);
@@ -173,7 +186,8 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
bearing,
{TurnType::Invalid, DirectionModifier::UTurn},
INVALID_LANE_DATAID},
turn_is_valid));
turn_is_valid,
out_segment_length));
}
// We hit the case of a street leading into nothing-ness. Since the code here assumes
@@ -181,7 +195,6 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
// will never happen we add an artificial invalid uturn in this case.
if (!has_uturn_edge)
{
const auto first_coordinate = extract_coordinate(from_node, via_eid, INVERT, turn_node);
const double bearing =
util::coordinate_calculation::bearing(turn_coordinate, first_coordinate);
@@ -190,7 +203,8 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
bearing,
{TurnType::Invalid, DirectionModifier::UTurn},
INVALID_LANE_DATAID},
false});
false,
in_segment_length});
}
std::sort(std::begin(intersection),
@@ -227,41 +241,41 @@ IntersectionGenerator::GetActualNextIntersection(const NodeID starting_node,
NodeID *resulting_from_node = nullptr,
EdgeID *resulting_via_edge = nullptr) const
{
// This function skips over traffic lights/graph compression issues and similar to find the next
// actual intersection
Intersection result = GetConnectedRoads(starting_node, via_edge);
NodeID query_node = starting_node;
EdgeID query_edge = via_edge;
// Skip over stuff that has not been compressed due to barriers/parallel edges
NodeID node_at_intersection = starting_node;
EdgeID incoming_edge = via_edge;
const auto get_next_edge = [this](const NodeID from, const EdgeID via) {
const NodeID new_node = node_based_graph.GetTarget(via);
BOOST_ASSERT(node_based_graph.GetOutDegree(new_node) == 2);
const EdgeID begin_edges_new_node = node_based_graph.BeginEdges(new_node);
return (node_based_graph.GetTarget(begin_edges_new_node) == from) ? begin_edges_new_node + 1
: begin_edges_new_node;
};
// to prevent endless loops
const auto termination_node = node_based_graph.GetTarget(via_edge);
// using a maximum lookahead, we make sure not to end up in some form of loop
std::unordered_set<NodeID> visited_nodes;
while (visited_nodes.count(node_at_intersection) == 0 &&
(result.size() == 2 &&
node_based_graph.GetEdgeData(via_edge).IsCompatibleTo(
node_based_graph.GetEdgeData(result[1].eid))))
// skip trivial nodes without generating the intersection in between, stop at the very first
// intersection of degree > 2
while (0 == visited_nodes.count(query_node) &&
2 == node_based_graph.GetOutDegree(node_based_graph.GetTarget(query_edge)))
{
visited_nodes.insert(node_at_intersection);
node_at_intersection = node_based_graph.GetTarget(incoming_edge);
incoming_edge = result[1].eid;
result = GetConnectedRoads(node_at_intersection, incoming_edge);
// When looping back to the original node, we obviously are in a loop. Stop there.
if (termination_node == node_based_graph.GetTarget(incoming_edge))
visited_nodes.insert(query_node);
const auto next_node = node_based_graph.GetTarget(query_edge);
const auto next_edge = get_next_edge(query_node, query_edge);
if (!node_based_graph.GetEdgeData(query_edge)
.IsCompatibleTo(node_based_graph.GetEdgeData(next_edge)) ||
node_based_graph.GetTarget(next_edge) == starting_node)
break;
query_node = next_node;
query_edge = next_edge;
}
// return output if requested
if (resulting_from_node)
*resulting_from_node = node_at_intersection;
*resulting_from_node = query_node;
if (resulting_via_edge)
*resulting_via_edge = incoming_edge;
*resulting_via_edge = query_edge;
return result;
return GetConnectedRoads(query_node, query_edge);
}
const CoordinateExtractor &IntersectionGenerator::GetCoordinateExtractor() const