reduce numbers of intersections in findNextIntersection, don't normalise for turn lanes
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user