Prevent loops in extraction based on merge
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
#include "extractor/guidance/intersection_generator.hpp"
|
||||
#include "extractor/guidance/constants.hpp"
|
||||
#include "extractor/guidance/intersection_generator.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/range/algorithm/count_if.hpp>
|
||||
@@ -268,8 +269,11 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection,
|
||||
return becomes_narrower;
|
||||
};
|
||||
|
||||
const bool is_y_arm_first = isValidYArm(first_index, second_index);
|
||||
const bool is_y_arm_second = isValidYArm(second_index, first_index);
|
||||
|
||||
// Only merge valid y-arms
|
||||
if (!isValidYArm(first_index, second_index) || !isValidYArm(second_index, first_index))
|
||||
if (!is_y_arm_first || !is_y_arm_second)
|
||||
return false;
|
||||
|
||||
if (angle_between < 60)
|
||||
@@ -577,10 +581,14 @@ IntersectionGenerator::GetActualNextIntersection(const NodeID starting_node,
|
||||
// to prevent endless loops
|
||||
const auto termination_node = node_based_graph.GetTarget(via_edge);
|
||||
|
||||
while (result.size() == 2 &&
|
||||
node_based_graph.GetEdgeData(via_edge).IsCompatibleTo(
|
||||
node_based_graph.GetEdgeData(result[1].turn.eid)))
|
||||
// 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].turn.eid))))
|
||||
{
|
||||
visited_nodes.insert(node_at_intersection);
|
||||
node_at_intersection = node_based_graph.GetTarget(incoming_edge);
|
||||
incoming_edge = result[1].turn.eid;
|
||||
result = GetConnectedRoads(node_at_intersection, incoming_edge);
|
||||
|
||||
@@ -56,9 +56,14 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
|
||||
auto intersection = intersection_generator(at_node, road.turn.eid);
|
||||
auto in_edge = road.turn.eid;
|
||||
// skip over traffic lights
|
||||
while (intersection.size() == 2)
|
||||
// to prevent ending up in an endless loop, we remember all visited nodes. This is
|
||||
// necessary, since merging of roads can actually create enterable loops of degree two
|
||||
std::unordered_set<NodeID> visited_nodes;
|
||||
auto node = at_node;
|
||||
while (intersection.size() == 2 && visited_nodes.count(node) == 0)
|
||||
{
|
||||
const auto node = node_based_graph.GetTarget(in_edge);
|
||||
visited_nodes.insert(node);
|
||||
node = node_based_graph.GetTarget(in_edge);
|
||||
if (node == at_node)
|
||||
{
|
||||
// we ended up in a loop without exit
|
||||
@@ -70,6 +75,11 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
|
||||
output_node = node_based_graph.GetTarget(in_edge);
|
||||
intersection = intersection_generator(node, in_edge);
|
||||
}
|
||||
if (intersection.size() <= 2)
|
||||
{
|
||||
output_node = SPECIAL_NODEID;
|
||||
intersection.clear();
|
||||
}
|
||||
return intersection;
|
||||
};
|
||||
|
||||
@@ -162,6 +172,9 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
|
||||
const auto next_road_next_intersection =
|
||||
findNextIntersectionForRoad(intersection_node_id, next_road, next_intersection_node);
|
||||
|
||||
if (next_road_next_intersection.empty())
|
||||
return intersection;
|
||||
|
||||
// If we are at a traffic loop at the end of a road, don't consider it a sliproad
|
||||
if (intersection_node_id == next_intersection_node)
|
||||
return intersection;
|
||||
@@ -194,13 +207,14 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
|
||||
const auto link_data = node_based_graph.GetEdgeData(road.turn.eid);
|
||||
// Check if the road continues here
|
||||
const bool is_through_street =
|
||||
!target_intersection.empty() &&
|
||||
target_intersection.end() !=
|
||||
std::find_if(target_intersection.begin() + 1,
|
||||
target_intersection.end(),
|
||||
[this, &link_data](const ConnectedRoad &road) {
|
||||
return node_based_graph.GetEdgeData(road.turn.eid).name_id ==
|
||||
link_data.name_id;
|
||||
});
|
||||
std::find_if(target_intersection.begin() + 1,
|
||||
target_intersection.end(),
|
||||
[this, &link_data](const ConnectedRoad &road) {
|
||||
return node_based_graph.GetEdgeData(road.turn.eid).name_id ==
|
||||
link_data.name_id;
|
||||
});
|
||||
|
||||
// if the sliproad candidate is a through street, we cannot handle it as a sliproad
|
||||
if (is_through_street)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#include "util/debug.hpp"
|
||||
|
||||
#include "extractor/guidance/turn_lane_augmentation.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "util/simple_logger.hpp"
|
||||
|
||||
Reference in New Issue
Block a user