summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/overlay/assign_parents.hpp')
-rw-r--r--boost/geometry/algorithms/detail/overlay/assign_parents.hpp45
1 files changed, 29 insertions, 16 deletions
diff --git a/boost/geometry/algorithms/detail/overlay/assign_parents.hpp b/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
index 78160f5204..c8ce651007 100644
--- a/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
+++ b/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
@@ -224,7 +224,8 @@ inline void assign_parents(Geometry1 const& geometry1,
RingCollection const& collection,
RingMap& ring_map,
Strategy const& strategy,
- bool check_for_orientation = false)
+ bool check_for_orientation = false,
+ bool discard_double_negative = false)
{
typedef typename geometry::tag<Geometry1>::type tag1;
typedef typename geometry::tag<Geometry2>::type tag2;
@@ -334,28 +335,38 @@ inline void assign_parents(Geometry1 const& geometry1,
for (map_iterator_type it = boost::begin(ring_map);
it != boost::end(ring_map); ++it)
{
- if (geometry::math::equals(it->second.get_area(), 0))
+ ring_info_type& info = it->second;
+ if (geometry::math::equals(info.get_area(), 0))
{
- it->second.discarded = true;
+ info.discarded = true;
}
- else if (it->second.parent.source_index >= 0
- && math::larger(it->second.get_area(), 0))
+ else if (info.parent.source_index >= 0)
{
- const ring_info_type& parent = ring_map[it->second.parent];
+ const ring_info_type& parent = ring_map[info.parent];
+ bool const pos = math::larger(info.get_area(), 0);
+ bool const parent_pos = math::larger(parent.area, 0);
- if (math::larger(parent.area, 0))
+ bool const double_neg = discard_double_negative && ! pos && ! parent_pos;
+
+ if ((pos && parent_pos) || double_neg)
{
// Discard positive inner ring with positive parent
- it->second.discarded = true;
+ // Also, for some cases (dissolve), negative inner ring
+ // with negative parent shouild be discarded
+ info.discarded = true;
+ }
+
+ if (pos || info.discarded)
+ {
+ // Remove parent ID from any positive or discarded inner rings
+ info.parent.source_index = -1;
}
- // Remove parent ID from any positive inner ring
- it->second.parent.source_index = -1;
}
- else if (it->second.parent.source_index < 0
- && math::smaller(it->second.get_area(), 0))
+ else if (info.parent.source_index < 0
+ && math::smaller(info.get_area(), 0))
{
// Reverse negative ring without parent
- it->second.reversed = true;
+ info.reversed = true;
}
}
}
@@ -372,7 +383,7 @@ inline void assign_parents(Geometry1 const& geometry1,
}
-// Version for one geometry (called by buffer)
+// Version for one geometry (called by buffer/dissolve)
template
<
typename Geometry,
@@ -384,13 +395,15 @@ inline void assign_parents(Geometry const& geometry,
RingCollection const& collection,
RingMap& ring_map,
Strategy const& strategy,
- bool check_for_orientation)
+ bool check_for_orientation,
+ bool discard_double_negative)
{
// Call it with an empty geometry as second geometry (source_id == 1)
// (ring_map should be empty for source_id==1)
Geometry empty;
- assign_parents(geometry, empty, collection, ring_map, strategy, check_for_orientation);
+ assign_parents(geometry, empty, collection, ring_map, strategy,
+ check_for_orientation, discard_double_negative);
}