[overlay] fix implementation of startable flag, it should start if there

are 1 (union) or 2 (intersection) polygons on right hand
This commit is contained in:
Barend Gehrels 2016-01-10 13:32:08 +01:00
parent e4624dad28
commit 01df9eacbb
6 changed files with 101 additions and 44 deletions

View File

@ -726,22 +726,18 @@ inline void assign_startable_in_clusters(Clusters& clusters, Turns& turns,
sbs.find_open();
std::size_t const target_polygon_count =
for_operation == operation_union ? 1 : 2;
// Unset the startable flag for all 'closed' spaces
for (std::size_t i = 0; i < sbs.m_ranked_points.size(); i++)
{
const typename sbs_type::rp& ranked_point = sbs.m_ranked_points[i];
bool startable = true;
if (for_operation == operation_union
&& ranked_point.index == sort_by_side::index_to
&& ranked_point.right_hand_side_count != 0)
if (ranked_point.index == sort_by_side::index_to
&& ranked_point.polygon_count != target_polygon_count)
{
startable = false;
}
else if (for_operation == operation_intersection
&& ranked_point.index == sort_by_side::index_from
&& ranked_point.right_hand_side_count != 2)
{
startable = false;
startable = false;
}
if (! startable)
@ -751,6 +747,14 @@ inline void assign_startable_in_clusters(Clusters& clusters, Turns& turns,
op.enriched.startable = false;
}
}
#ifdef BOOST_GEOMETRY_DEBUG_SVG_LESS_BY_SEGMENT_RATIO
{
std::ostringstream out;
out << "inspect_cl" << mit->first;
debug::sorted_side_map(out.str(), sbs, turn_point, geometry1, geometry2);
}
#endif
}
}

View File

@ -34,7 +34,7 @@ struct ranked_point
, turn_index(-1)
, op_index(-1)
, index(index_unknown)
, right_hand_side_count(0)
, polygon_count(0)
, operation(operation_none)
{}
@ -45,7 +45,7 @@ struct ranked_point
, turn_index(ti)
, op_index(oi)
, index(i)
, right_hand_side_count(0)
, polygon_count(0)
, operation(op)
, seg_id(sid)
{}
@ -55,7 +55,7 @@ struct ranked_point
signed_size_type turn_index;
signed_size_type op_index;
index_type index;
int right_hand_side_count;
std::size_t polygon_count;
operation_type operation;
segment_identifier seg_id;
};
@ -362,58 +362,89 @@ struct side_sorter
Point m_from;
private :
std::size_t move(std::size_t index)
{
int const n = m_ranked_points.size();
int result = index + 1;
if (result >= n)
{
result = 0;
}
else if (result < 0)
{
result = n - 1;
}
return result;
}
std::size_t move(signed_size_type source_index, std::size_t index)
{
std::size_t result = move(index);
while (m_ranked_points[result].seg_id.source_index != source_index)
{
result = move(result);
}
return result;
}
void find_polygons_for_source(signed_size_type source_index,
std::size_t start_index)
{
int state = 1; // 'closed', because start_index is "from", arrives at the turn
std::size_t last_rank = 0;
for (std::size_t i = start_index + 1; ; i++)
std::size_t last_from_index = start_index;
std::size_t last_from_rank = m_ranked_points[start_index].main_rank;
std::size_t previous_rank = m_ranked_points[start_index].main_rank;
for (std::size_t index = move(source_index, start_index);
;
index = move(source_index, index))
{
if (i >= m_ranked_points.size())
{
i = 0;
}
rp& ranked = m_ranked_points[index];
rp& ranked = m_ranked_points[i];
if (ranked.main_rank != last_rank && state > 0)
if (ranked.main_rank != previous_rank && state == 0)
{
// Close items from previous rank
std::size_t j = i == 0 ? m_ranked_points.size() - 1 : i - 1;
while (m_ranked_points[j].main_rank == last_rank
&& j != start_index)
// Assign polygon counter if rank differs from same source
// Move back to assign, until but not including last from_rank
// This assigns to both sources
bool stop_at_next_rank = false;
for (std::size_t j = last_from_index; ; j = move(j))
{
m_ranked_points[j].right_hand_side_count++;
if (j > 0)
rp& previous = m_ranked_points[j];
if (stop_at_next_rank && previous.main_rank != previous_rank)
{
j--;
break;
}
else
if (previous.main_rank == previous_rank)
{
j = m_ranked_points.size() - 1;
stop_at_next_rank = true;
}
previous.polygon_count++;
}
}
last_rank = ranked.main_rank;
if (ranked.seg_id.source_index != source_index)
if (index == start_index)
{
continue;
}
if (i == start_index)
{
// At starting point (which is 'closed' again)
ranked.right_hand_side_count++;
return;
}
switch (ranked.index)
if (ranked.index == index_from)
{
case index_from : state++; break;
case index_to : state--; break;
default : break;
last_from_rank = ranked.main_rank;
// Actually next line is wrong, it should only do this the first time, but it makes no difference because from is not checked later
last_from_index = index;
state++;
}
else if (ranked.index == index_to)
{
state--;
}
previous_rank = ranked.main_rank;
}
}
};

View File

@ -592,6 +592,13 @@ static std::string case_recursive_boxes_27[2] =
"MULTIPOLYGON(((1 2,0 1,0 2,1 2)),((2 1,2 0,1 0,1 1,2 2,2 1)),((1 3,2 2,1 2,1 3)),((1 3,0 3,1 4,1 3)))"
};
static std::string case_recursive_boxes_28[2] =
{
// Requires startable flag per operation, assigned per cluster (as #25 but in a different configuration)
"MULTIPOLYGON(((5 1,5 0,4 0,4 2,5 3,5 1)),((4 2,3 2,3 3,4 3,4 2)))",
"MULTIPOLYGON(((2 2,2 3,3 3,4 2,3 1,2 1,2 2)),((3 4,4 3,3 3,3 4)),((4 2,5 2,4 1,4 2)))"
};
static std::string pie_21_7_21_0_3[2] =
{
"MULTIPOLYGON(((2500 2500,2500 3875,2855 3828,3187 3690,3472 3472,3690 3187,3828 2855,3875 2500,3828 2144,3690 1812,3472 1527,3187 1309,2855 1171,2499 1125,2144 1171,1812 1309,1527 1527,1309 1812,1171 2144,1125 2499,1171 2855,1309 3187,2500 2500)))",

View File

@ -235,6 +235,11 @@ struct map_visitor
}
}
}
if (! turn.operations[index].enriched.startable)
{
os << "$";
}
return result;
}
@ -250,6 +255,10 @@ struct map_visitor
bool lab1 = label_operation(turn, 0, out);
out << " / ";
bool lab2 = label_operation(turn, 1, out);
if (turn.switch_source)
{
out << "#";
}
std::string style = "fill:rgb(0,0,0);font-family:Arial;font-size:8px";
if (turn.colocated)

View File

@ -207,6 +207,9 @@ void test_areal()
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_27",
case_recursive_boxes_27[0], case_recursive_boxes_27[1],
1, 0, 0.5);
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_28",
case_recursive_boxes_28[0], case_recursive_boxes_28[1],
2, 0, 1.0);
test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],

View File

@ -198,6 +198,9 @@ void test_areal()
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_27",
case_recursive_boxes_27[0], case_recursive_boxes_27[1],
4, 0, -1, 4.5);
test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_28",
case_recursive_boxes_28[0], case_recursive_boxes_28[1],
2, 0, -1, 6.5);
test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],