[union] set visited in clusters, like done in intersection. But now

use rank instead of next ip, which was a TODO item.
This causes one unittest case to fail, which has another reason, its turn
in a cluster is not detected because of finalization information. That is
now solved in a different way.
This commit is contained in:
Barend Gehrels
2017-05-10 14:06:45 +02:00
parent 81578d48e2
commit 4b524fc7ac
4 changed files with 33 additions and 14 deletions

View File

@@ -75,6 +75,26 @@ struct rank_with_rings
return all_equal(sort_by_side::dir_from);
}
template <typename Turns>
inline bool traversable(Turns const& turns) const
{
typedef typename boost::range_value<Turns>::type turn_type;
typedef typename turn_type::turn_operation_type turn_operation_type;
for (std::set<ring_with_direction>::const_iterator it = rings.begin();
it != rings.end(); ++it)
{
const ring_with_direction& rwd = *it;
turn_type const& turn = turns[rwd.turn_index];
turn_operation_type const& op = turn.operations[rwd.operation_index];
if (op.visited.finalized())
{
return false;
}
}
return true;
}
};
template <typename Sbs, typename Turns>
@@ -90,16 +110,12 @@ inline void aggregate_operations(Sbs const& sbs, std::vector<rank_with_rings>& a
typename Sbs::rp const& ranked_point = sbs.m_ranked_points[i];
turn_type const& turn = turns[ranked_point.turn_index];
turn_operation_type const& op = turn.operations[ranked_point.operation_index];
if (op.visited.finalized())
{
// Skip finalized operations in aggregation
// to avoid selecting them
continue;
}
if (! (op.operation == operation_intersection || op.operation == operation_continue))
{
// Don't consider union/blocked
// Don't consider union/blocked (aggregate is only used for intersections)
continue;
}

View File

@@ -37,6 +37,7 @@ struct enrichment_info
, startable(true)
, count_left(0)
, count_right(0)
, rank(-1)
, zone(-1)
, region_id(-1)
, isolated(false)
@@ -63,6 +64,7 @@ struct enrichment_info
// Counts if polygons left/right of this operation
std::size_t count_left;
std::size_t count_right;
signed_size_type rank; // in cluster
signed_size_type zone; // open zone, in cluster
signed_size_type region_id;
bool isolated;

View File

@@ -751,6 +751,7 @@ inline void gather_cluster_properties(Clusters& clusters, Turns& turns,
op.enriched.count_left = ranked.count_left;
op.enriched.count_right = ranked.count_right;
op.enriched.rank = ranked.rank;
op.enriched.zone = ranked.zone;
if ((for_operation == operation_union

View File

@@ -137,9 +137,9 @@ struct traversal
}
}
//! Sets visited for ALL truns traveling to the same turn (TODO: in same direction)
//! Sets visited for ALL turns traveling to the same turn
inline void set_visited_in_cluster(signed_size_type cluster_id,
signed_size_type next_turn_index)
signed_size_type rank)
{
typename Clusters::const_iterator mit = m_clusters.find(cluster_id);
BOOST_ASSERT(mit != m_clusters.end());
@@ -157,7 +157,7 @@ struct traversal
{
turn_operation_type& op = turn.operations[i];
if (op.visited.none()
&& op.enriched.get_next_turn_index() == next_turn_index)
&& op.enriched.rank == rank)
{
op.visited.set_visited();
}
@@ -182,10 +182,9 @@ struct traversal
{
op.visited.set_visited();
}
if (turn.cluster_id >= 0
&& target_operation == operation_intersection)
if (turn.cluster_id >= 0)
{
set_visited_in_cluster(turn.cluster_id, op.enriched.get_next_turn_index());
set_visited_in_cluster(turn.cluster_id, op.enriched.rank);
}
}
@@ -474,6 +473,7 @@ struct traversal
sort_by_side::rank_with_rings const& rwr = aggregation[i];
if (rwr.all_to()
&& rwr.traversable(m_turns)
&& selected_rank == 0)
{
// Take the first (= right) where segments leave,
@@ -543,7 +543,7 @@ struct traversal
{
// This direction is already traveled before, the same
// cannot be traveled again
return false;
continue;
}
// Take the last turn from this rank