mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-12 12:12:10 +00:00
Update for difference
Changed value (1,-1) to overlay_type now Removed dissolve flag, now an overlay type [SVN r67487]
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/convert_ring.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/add_to_containment.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/ring_properties.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
//#include <boost/geometry/strategies/intersection_result.hpp>
|
||||
@@ -174,7 +175,7 @@ struct enrich_containment
|
||||
typedef void tag3; // For the ring-container
|
||||
|
||||
|
||||
static inline void assign(item_type& larger, item_type& smaller, int direction, bool dissolve)
|
||||
static inline void assign(item_type& larger, item_type& smaller, overlay_type direction)
|
||||
{
|
||||
typedef typename geometry::coordinate_type
|
||||
<
|
||||
@@ -185,7 +186,7 @@ struct enrich_containment
|
||||
{
|
||||
if (larger.signum == 1)
|
||||
{
|
||||
smaller.push(larger, direction, dissolve);
|
||||
smaller.push(larger, direction);
|
||||
}
|
||||
else if (larger.signum == -1)
|
||||
{
|
||||
@@ -244,7 +245,7 @@ struct enrich_containment
|
||||
static inline void enrich(Selection& selection, Map& map,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
RingCollection const& collection,
|
||||
int direction, bool dissolve)
|
||||
overlay_type direction)
|
||||
{
|
||||
typedef typename boost::range_iterator<Selection>::type iterator;
|
||||
|
||||
@@ -271,7 +272,7 @@ struct enrich_containment
|
||||
collection)
|
||||
)
|
||||
{
|
||||
assign(item1, item2, direction, dissolve);
|
||||
assign(item1, item2, direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -283,7 +284,7 @@ struct enrich_containment
|
||||
static inline void divide_and_conquer(Selection& selection, Map& map,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
RingCollection const& collection,
|
||||
int direction, bool dissolve, Box const& box,
|
||||
int direction, Box const& box,
|
||||
std::size_t iteration = 0, std::size_t previous_count = 0)
|
||||
{
|
||||
std::size_t n = boost::size(selection);
|
||||
@@ -297,7 +298,7 @@ std::cout << "spatial divide n="
|
||||
|
||||
if (iteration > 3)
|
||||
{
|
||||
enrich(selection, map, geometry1, geometry2, collection, direction, dissolve);
|
||||
enrich(selection, map, geometry1, geometry2, collection, direction);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -318,16 +319,16 @@ std::cout << "spatial divide n="
|
||||
select_by_box(upper_sel, selection, upper);
|
||||
|
||||
divide_and_conquer<1 - Dimension>(lower_sel, map, geometry1, geometry2,
|
||||
collection, direction, dissolve, lower, iteration + 1, n);
|
||||
collection, direction, lower, iteration + 1, n);
|
||||
divide_and_conquer<1 - Dimension>(upper_sel, map, geometry1, geometry2,
|
||||
collection, direction, dissolve, upper, iteration + 1, n);
|
||||
collection, direction, upper, iteration + 1, n);
|
||||
}
|
||||
***/
|
||||
|
||||
static inline void enrich(Container& container,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
RingCollection const& collection,
|
||||
int direction, bool dissolve)
|
||||
overlay_type direction)
|
||||
{
|
||||
typedef typename boost::range_iterator<Container>::type iterator;
|
||||
|
||||
@@ -340,10 +341,6 @@ std::cout << "spatial divide n="
|
||||
item_type& item1 = *it1;
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
std::cout << item1.ring_id << " area: " << item1.area << std::endl;
|
||||
if (item1.area < 0)
|
||||
{
|
||||
std::cout << "(negative ";
|
||||
}
|
||||
#endif
|
||||
iterator it2 = it1;
|
||||
for (it2++; it2 != boost::end(container); ++it2)
|
||||
@@ -359,7 +356,7 @@ if (item1.area < 0)
|
||||
std::cout << " -> contains " << item2.ring_id;
|
||||
#endif
|
||||
n++;
|
||||
assign(item1, item2, direction, dissolve);
|
||||
assign(item1, item2, direction);
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
@@ -374,13 +371,13 @@ std::cout << std::endl;
|
||||
static inline void apply(Container& container,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
RingCollection const& collection,
|
||||
int direction, bool dissolve, Box const& )
|
||||
overlay_type direction, Box const& )
|
||||
{
|
||||
if (boost::size(container) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
enrich(container, geometry1, geometry2, collection, direction, dissolve);
|
||||
enrich(container, geometry1, geometry2, collection, direction);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
for (typename boost::range_iterator<Container const>::type
|
||||
@@ -409,7 +406,7 @@ std::cout << std::endl;
|
||||
|
||||
std::map<std::pair<item_type*, item_type*>, bool> map;
|
||||
divide_and_conquer<1>(selection, map, geometry1, geometry2, collection,
|
||||
direction, dissolve, box);
|
||||
direction, box);
|
||||
***/
|
||||
}
|
||||
};
|
||||
@@ -427,7 +424,7 @@ template
|
||||
inline OutputIterator add_all_rings(Container& container,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
RingCollection const& collection,
|
||||
int direction, bool dissolve,
|
||||
overlay_type direction,
|
||||
OutputIterator out)
|
||||
{
|
||||
typedef typename boost::range_iterator<Container>::type iterator;
|
||||
@@ -446,65 +443,79 @@ inline OutputIterator add_all_rings(Container& container,
|
||||
it != boost::end(container);
|
||||
++it)
|
||||
{
|
||||
if (it->positive())
|
||||
{
|
||||
if (result_filled)
|
||||
{
|
||||
*out++ = result;
|
||||
previous_id.source_index = -1;
|
||||
result_filled = false;
|
||||
}
|
||||
|
||||
bool const include_as_interior = result_filled
|
||||
&& it->id(direction) == previous_id
|
||||
&& it->included(direction);
|
||||
|
||||
bool include_and_reverse = direction == overlay_difference
|
||||
&& ! include_as_interior
|
||||
&& it->negative()
|
||||
&& it->included(direction);
|
||||
|
||||
if (it->positive() || include_and_reverse)
|
||||
{
|
||||
// If it is an outer ring, it is included if there are no parents
|
||||
// (union) or if there are parents (intersection)
|
||||
if (it->included(direction, dissolve))
|
||||
// or for difference it is an exterior ring but becomes an interior ring
|
||||
if (it->included(direction))
|
||||
{
|
||||
geometry::clear(result);
|
||||
if (result_filled && ! include_as_interior)
|
||||
{
|
||||
*out++ = result;
|
||||
previous_id.source_index = -1;
|
||||
result_filled = false;
|
||||
geometry::clear(result);
|
||||
}
|
||||
|
||||
if (include_as_interior)
|
||||
{
|
||||
include_and_reverse = true;
|
||||
}
|
||||
|
||||
previous_id = it->ring_id;
|
||||
result_filled = true;
|
||||
if (it->ring_id.source_index == 0)
|
||||
{
|
||||
convert_ring<tag_out>::apply(result,
|
||||
get_ring<tag1>::apply(it->ring_id, geometry1));
|
||||
get_ring<tag1>::apply(it->ring_id, geometry1),
|
||||
include_as_interior, include_and_reverse);
|
||||
}
|
||||
else if (it->ring_id.source_index == 1)
|
||||
{
|
||||
convert_ring<tag_out>::apply(result,
|
||||
get_ring<tag2>::apply(it->ring_id, geometry2));
|
||||
get_ring<tag2>::apply(it->ring_id, geometry2),
|
||||
include_as_interior, include_and_reverse);
|
||||
}
|
||||
else if (it->ring_id.source_index == 2)
|
||||
{
|
||||
convert_ring<tag_out>::apply(result,
|
||||
get_ring<tag3>::apply(it->ring_id, collection));
|
||||
get_ring<tag3>::apply(it->ring_id, collection),
|
||||
include_as_interior, include_and_reverse);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (include_as_interior)
|
||||
{
|
||||
// If it is an interior ring, it is included if
|
||||
// it's parent-id matches the id of the outputted exterior ring
|
||||
if (result_filled
|
||||
&& it->id() == previous_id
|
||||
&& it->included(direction, dissolve))
|
||||
if (it->ring_id.source_index == 0)
|
||||
{
|
||||
if (it->ring_id.source_index == 0)
|
||||
{
|
||||
convert_ring<tag_out>::apply(result,
|
||||
get_ring<tag1>::apply(it->ring_id,
|
||||
geometry1), true);
|
||||
}
|
||||
else if (it->ring_id.source_index == 1)
|
||||
{
|
||||
convert_ring<tag_out>::apply(result,
|
||||
get_ring<tag2>::apply(it->ring_id,
|
||||
geometry2), true);
|
||||
}
|
||||
else if (it->ring_id.source_index == 2)
|
||||
{
|
||||
convert_ring<tag_out>::apply(result,
|
||||
get_ring<tag3>::apply(it->ring_id,
|
||||
collection), true);
|
||||
}
|
||||
convert_ring<tag_out>::apply(result,
|
||||
get_ring<tag1>::apply(it->ring_id,
|
||||
geometry1), true, false);
|
||||
}
|
||||
else if (it->ring_id.source_index == 1)
|
||||
{
|
||||
convert_ring<tag_out>::apply(result,
|
||||
get_ring<tag2>::apply(it->ring_id,
|
||||
geometry2), true, false);
|
||||
}
|
||||
else if (it->ring_id.source_index == 2)
|
||||
{
|
||||
convert_ring<tag_out>::apply(result,
|
||||
get_ring<tag3>::apply(it->ring_id,
|
||||
collection), true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -526,7 +537,7 @@ template
|
||||
inline OutputIterator assemble(Rings const& rings, Map const& map,
|
||||
Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
int direction, bool dissolve, bool splitted,
|
||||
overlay_type direction, bool , bool splitted,
|
||||
OutputIterator out)
|
||||
{
|
||||
typedef typename geometry::tag<Geometry1>::type tag1;
|
||||
@@ -546,6 +557,8 @@ std::cout << "assemble" << std::endl;
|
||||
> ring_properties_container_type;
|
||||
ring_properties_container_type ring_properties_container;
|
||||
|
||||
bool const dissolve = direction == overlay_dissolve;
|
||||
|
||||
if (! splitted)
|
||||
{
|
||||
add_to_containment
|
||||
@@ -564,7 +577,7 @@ std::cout << "assemble" << std::endl;
|
||||
Geometry2
|
||||
>::apply(ring_properties_container,
|
||||
ring_identifier(1, -1,-1), geometry2,
|
||||
map, dissolve);
|
||||
map, false);
|
||||
}
|
||||
|
||||
// Add all produced rings using source index 2
|
||||
@@ -631,7 +644,7 @@ std::cout << "assemble.enrich containment" << std::endl;
|
||||
Rings,
|
||||
model::box<point_type>
|
||||
>::apply(ring_properties_container,
|
||||
geometry1, geometry2, rings, direction, dissolve, total);
|
||||
geometry1, geometry2, rings, direction, total);
|
||||
|
||||
// Sort container on parent-id
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
@@ -643,13 +656,13 @@ std::cout << "assemble.properties sort on parent-id "
|
||||
sort_on_id_or_parent_id
|
||||
<
|
||||
ring_properties<point_type>
|
||||
>());
|
||||
>(direction));
|
||||
}
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
std::cout << "assemble.add rings" << std::endl;
|
||||
#endif
|
||||
return add_all_rings<GeometryOut>(ring_properties_container,
|
||||
geometry1, geometry2, rings, direction, dissolve, out);
|
||||
geometry1, geometry2, rings, direction, out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/range/algorithm/reverse.hpp>
|
||||
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
@@ -45,11 +45,15 @@ struct convert_ring<ring_tag>
|
||||
{
|
||||
template<typename Destination, typename Source>
|
||||
static inline void apply(Destination& destination, Source const& source,
|
||||
bool append = false)
|
||||
bool append, bool reverse)
|
||||
{
|
||||
if (! append)
|
||||
{
|
||||
geometry::convert(source, destination);
|
||||
if (reverse)
|
||||
{
|
||||
boost::reverse(destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -60,17 +64,25 @@ struct convert_ring<polygon_tag>
|
||||
{
|
||||
template<typename Destination, typename Source>
|
||||
static inline void apply(Destination& destination, Source const& source,
|
||||
bool append = false)
|
||||
bool append, bool reverse)
|
||||
{
|
||||
if (! append)
|
||||
{
|
||||
geometry::convert(source, exterior_ring(destination));
|
||||
if (reverse)
|
||||
{
|
||||
boost::reverse(exterior_ring(destination));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
interior_rings(destination).resize(
|
||||
interior_rings(destination).size() + 1);
|
||||
geometry::convert(source, interior_rings(destination).back());
|
||||
if (reverse)
|
||||
{
|
||||
boost::reverse(interior_rings(destination).back());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -71,7 +71,7 @@ template<>
|
||||
struct get_ring<polygon_tag>
|
||||
{
|
||||
template<typename Polygon>
|
||||
static inline typename ring_type<Polygon>::type const& apply(
|
||||
static inline typename ring_return_type<Polygon const>::type const apply(
|
||||
ring_identifier const& id,
|
||||
Polygon const& polygon)
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ template
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
int Direction,
|
||||
overlay_type Direction,
|
||||
typename Strategy
|
||||
>
|
||||
struct overlay
|
||||
@@ -80,10 +80,11 @@ struct overlay
|
||||
|
||||
// If one input is empty, output the other one for a union.
|
||||
// For an intersection, the intersection is empty.
|
||||
// TODO: for a difference, take one of them.
|
||||
if (geometry::num_points(geometry1) == 0
|
||||
|| geometry::num_points(geometry2) == 0)
|
||||
{
|
||||
if (Direction == 1)
|
||||
if (Direction == overlay_union)
|
||||
{
|
||||
std::map<ring_identifier, int> map;
|
||||
ring_container_type rings;
|
||||
@@ -110,9 +111,9 @@ std::cout << "enrich" << std::endl;
|
||||
#endif
|
||||
typename Strategy::side_strategy_type side_strategy;
|
||||
geometry::enrich_intersection_points<Reverse1, Reverse2>(turn_points,
|
||||
Direction == -1
|
||||
? boost::geometry::detail::overlay::operation_intersection
|
||||
: boost::geometry::detail::overlay::operation_union,
|
||||
Direction == overlay_union
|
||||
? boost::geometry::detail::overlay::operation_union
|
||||
: boost::geometry::detail::overlay::operation_intersection,
|
||||
geometry1, geometry2,
|
||||
side_strategy);
|
||||
|
||||
@@ -121,10 +122,9 @@ std::cout << "traverse" << std::endl;
|
||||
#endif
|
||||
ring_container_type rings;
|
||||
geometry::traverse<Reverse1, Reverse2>(geometry1, geometry2,
|
||||
Direction == -1
|
||||
? boost::geometry::detail::overlay::operation_intersection
|
||||
: boost::geometry::detail::overlay::operation_union
|
||||
,
|
||||
Direction == overlay_union
|
||||
? boost::geometry::detail::overlay::operation_union
|
||||
: boost::geometry::detail::overlay::operation_intersection,
|
||||
turn_points, rings);
|
||||
|
||||
// TEMP condition, reversal should be done in traverse by calling "push_front"
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Copyright Barend Gehrels 2007-2010, Geodan, Amsterdam, the Netherlands.
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_TYPE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_TYPE_HPP
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
enum overlay_type
|
||||
{
|
||||
overlay_union,
|
||||
overlay_intersection,
|
||||
overlay_difference,
|
||||
overlay_dissolve
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_TYPE_HPP
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/envelope.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
|
||||
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
|
||||
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
@@ -34,6 +35,7 @@ struct ring_properties
|
||||
|
||||
bool intersects;
|
||||
bool produced;
|
||||
bool diff_included;
|
||||
|
||||
// "Stack"/counter of non-intersecting parent rings.
|
||||
// This denotes if it a negative ring should be included,
|
||||
@@ -51,6 +53,7 @@ struct ring_properties
|
||||
inline ring_properties()
|
||||
: intersects(false)
|
||||
, produced(false)
|
||||
, diff_included(false)
|
||||
, parent_count(0)
|
||||
, has_point(false)
|
||||
{
|
||||
@@ -64,6 +67,7 @@ struct ring_properties
|
||||
, area(geometry::area(geometry))
|
||||
, intersects(i)
|
||||
, produced(p)
|
||||
, diff_included(false)
|
||||
, parent_count(0)
|
||||
, box(geometry::make_envelope<box_type>(geometry))
|
||||
{
|
||||
@@ -83,8 +87,16 @@ struct ring_properties
|
||||
return geometry::math::abs(area) > geometry::math::abs(other.area);
|
||||
}
|
||||
|
||||
inline ring_identifier const& id() const
|
||||
inline ring_identifier const& id(overlay_type type) const
|
||||
{
|
||||
if (type == overlay_difference
|
||||
&& positive()
|
||||
&& parent_ring_id.source_index == 0
|
||||
&& ring_id.source_index == 1)
|
||||
{
|
||||
return parent_ring_id;
|
||||
}
|
||||
|
||||
// Return the id of ifself, or of the parent
|
||||
return positive() || parent_ring_id.source_index < 0
|
||||
? ring_id
|
||||
@@ -93,17 +105,25 @@ struct ring_properties
|
||||
|
||||
|
||||
inline void push(ring_properties<Point> const& r,
|
||||
int direction, bool dissolve)
|
||||
overlay_type direction)
|
||||
{
|
||||
if (//(r.produced || r.untouched()) &&
|
||||
r.included(direction, dissolve))
|
||||
if (r.included(direction))
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
std::cout << " id.push " << r.ring_id;
|
||||
#endif
|
||||
parent_ring_id = r.ring_id;
|
||||
}
|
||||
if (! r.produced || dissolve)
|
||||
else if (direction == overlay_difference
|
||||
&& r.ring_id.source_index == this->ring_id.source_index
|
||||
&& r.ring_id.source_index == 1)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
std::cout << " diff.parent " << r.ring_id << " of " << this->ring_id;
|
||||
#endif
|
||||
diff_included = true;
|
||||
}
|
||||
if (! r.produced || direction == overlay_dissolve)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
std::cout << " or.push " << r.ring_id;
|
||||
@@ -126,27 +146,29 @@ std::cout << " or.pop";
|
||||
}
|
||||
|
||||
|
||||
inline bool interior_included(int direction) const
|
||||
inline bool interior_included(overlay_type direction) const
|
||||
{
|
||||
if (negative())
|
||||
{
|
||||
// Original inner rings are included if there
|
||||
// are two untouched parents (union) or one (intersection);
|
||||
// Produced are ones are included if there is a parent found
|
||||
if (produced)
|
||||
{
|
||||
return parent_count > 0;
|
||||
}
|
||||
return
|
||||
(direction == 1 && parent_count == 1)
|
||||
|| (direction == -1 && parent_count > 1);
|
||||
// are two untouched parents (intersection) or one (union);
|
||||
// Produced ones are included if there is a parent found (should be!)
|
||||
return (produced && parent_count > 0)
|
||||
|| (direction == overlay_union && parent_count == 1)
|
||||
|| (direction == overlay_dissolve && parent_count == 1)
|
||||
|| (direction == overlay_intersection && parent_count > 1)
|
||||
|| (direction == overlay_difference
|
||||
&& parent_count > 1
|
||||
&& ring_id.source_index == 2 // produced
|
||||
)
|
||||
;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool included(int direction, bool dissolve) const
|
||||
inline bool included(overlay_type direction) const
|
||||
{
|
||||
if (produced && ! dissolve)
|
||||
if (produced && direction != overlay_dissolve)
|
||||
{
|
||||
// Traversed rings are included in all operations,
|
||||
// because traversal was direction-dependant.
|
||||
@@ -163,20 +185,25 @@ std::cout << " or.pop";
|
||||
if (positive())
|
||||
{
|
||||
// Outer rings are included if they don't have parents
|
||||
// (union) or have parents (intersection)
|
||||
if (produced)
|
||||
{
|
||||
return parent_count == 0;
|
||||
}
|
||||
return
|
||||
(direction == 1 && parent_count == 0)
|
||||
|| (direction == -1 && parent_count > 0);
|
||||
// (union,dissolve,difference if source=0) or have parents (intersection)
|
||||
return (produced && parent_count == 0)
|
||||
|| (direction == overlay_union && parent_count == 0)
|
||||
|| (direction == overlay_dissolve && parent_count == 0)
|
||||
|| (direction == overlay_difference
|
||||
&& parent_count == 0
|
||||
&& ring_id.source_index == 0)
|
||||
|| (direction == overlay_difference
|
||||
&& parent_count > 0
|
||||
&& ring_id.source_index == 1)
|
||||
|| (direction == overlay_intersection && parent_count > 0)
|
||||
;
|
||||
}
|
||||
else if (negative())
|
||||
{
|
||||
// Inner rings are included if the last encountered parent
|
||||
// matches the operation
|
||||
return interior_included(direction);
|
||||
return interior_included(direction)
|
||||
|| (direction == overlay_difference && diff_included);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -198,8 +225,10 @@ std::cout << " or.pop";
|
||||
std::cout << " parent: " << prop.parent_ring_id;
|
||||
if (prop.produced) std::cout << " produced";
|
||||
if (prop.intersects) std::cout << " intersects";
|
||||
if (prop.included(1, false)) std::cout << " union";
|
||||
if (prop.included(-1, false)) std::cout << " intersection";
|
||||
if (prop.included(overlay_union)) std::cout << " @union";
|
||||
if (prop.included(overlay_dissolve)) std::cout << " @dissolve";
|
||||
if (prop.included(overlay_intersection)) std::cout << " @intersection";
|
||||
if (prop.included(overlay_difference)) std::cout << " @difference";
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
@@ -210,11 +239,16 @@ std::cout << " or.pop";
|
||||
template<typename Prop>
|
||||
struct sort_on_id_or_parent_id
|
||||
{
|
||||
overlay_type m_type;
|
||||
public :
|
||||
inline sort_on_id_or_parent_id(overlay_type type)
|
||||
: m_type(type)
|
||||
{}
|
||||
|
||||
inline bool operator()(Prop const& left, Prop const& right) const
|
||||
{
|
||||
ring_identifier const& left_id = left.id();
|
||||
ring_identifier const& right_id = right.id();
|
||||
ring_identifier const& left_id = left.id(m_type);
|
||||
ring_identifier const& right_id = right.id(m_type);
|
||||
|
||||
// If it is the same, sort on size descending
|
||||
return left_id == right_id
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/geometry/algorithms/intersection.hpp>
|
||||
#include <boost/geometry/algorithms/intersection_inserter.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -51,7 +51,7 @@ inline void difference(Geometry1 const& geometry1,
|
||||
> strategy;
|
||||
|
||||
|
||||
detail::intersection::inserter<geometry_out, false, true, false>(
|
||||
detail::intersection::inserter<geometry_out, false, true, false, overlay_difference>(
|
||||
geometry1, geometry2,
|
||||
std::back_inserter(output_collection),
|
||||
strategy());
|
||||
|
||||
@@ -103,7 +103,7 @@ struct dissolve_ring_or_polygon
|
||||
std::map<ring_identifier, int> map;
|
||||
map_turns(map, turns);
|
||||
return detail::overlay::assemble<GeometryOut>(rings, map,
|
||||
geometry, geometry, 1, true, false, out);
|
||||
geometry, geometry, overlay_dissolve, true, false, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -113,6 +113,7 @@ struct intersection
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, false>::value,
|
||||
false,
|
||||
output_iterator, OneOut,
|
||||
overlay_intersection,
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, std::back_inserter(geometry_out), strategy);
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ template
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
@@ -140,6 +141,7 @@ template
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
@@ -149,9 +151,10 @@ struct intersection_inserter
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
> : detail::overlay::overlay
|
||||
<Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, -1, Strategy>
|
||||
<Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, OverlayType, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
@@ -163,6 +166,7 @@ template
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
@@ -172,38 +176,19 @@ struct intersection_inserter
|
||||
Geometry, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
> : detail::overlay::overlay
|
||||
<Geometry, Box, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, -1, Strategy>
|
||||
<Geometry, Box, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, OverlayType, Strategy>
|
||||
{};
|
||||
|
||||
/*// box/box
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename BoxOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
box_tag, box_tag, box_tag,
|
||||
true, true, true,
|
||||
Box1, Box2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, BoxOut,
|
||||
Strategy
|
||||
> : detail::intersection::intersection_box_box
|
||||
<Box1, Box2, OutputIterator, BoxOut, Strategy>
|
||||
{};
|
||||
*/
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment1, typename Segment2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
@@ -213,7 +198,7 @@ struct intersection_inserter
|
||||
Segment1, Segment2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
OverlayType, Strategy
|
||||
> : detail::intersection::intersection_segment_segment_point
|
||||
<
|
||||
Segment1, Segment2,
|
||||
@@ -228,6 +213,7 @@ template
|
||||
typename Linestring1, typename Linestring2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
@@ -237,7 +223,7 @@ struct intersection_inserter
|
||||
Linestring1, Linestring2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
OverlayType, Strategy
|
||||
> : detail::intersection::intersection_linestring_linestring_point
|
||||
<
|
||||
Linestring1, Linestring2,
|
||||
@@ -252,6 +238,7 @@ template
|
||||
typename Linestring, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
@@ -261,6 +248,7 @@ struct intersection_inserter
|
||||
Linestring, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
>
|
||||
{
|
||||
@@ -279,6 +267,7 @@ template
|
||||
typename Segment, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
@@ -288,6 +277,7 @@ struct intersection_inserter
|
||||
Segment, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
>
|
||||
{
|
||||
@@ -312,6 +302,7 @@ template
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter_reversed
|
||||
@@ -327,6 +318,7 @@ struct intersection_inserter_reversed
|
||||
Geometry2, Geometry1,
|
||||
Reverse2, Reverse1, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
>::apply(g2, g1, out, strategy);
|
||||
}
|
||||
@@ -347,6 +339,7 @@ template
|
||||
<
|
||||
typename GeometryOut,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
overlay_type OverlayType,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename OutputIterator,
|
||||
typename Strategy
|
||||
@@ -372,6 +365,7 @@ inline OutputIterator inserter(Geometry1 const& geometry1,
|
||||
overlay::do_reverse<geometry::point_order<Geometry2>::value, Reverse2>::value,
|
||||
ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
>,
|
||||
geometry::dispatch::intersection_inserter
|
||||
@@ -387,6 +381,7 @@ inline OutputIterator inserter(Geometry1 const& geometry1,
|
||||
overlay::do_reverse<geometry::point_order<Geometry2>::value, Reverse2>::value,
|
||||
ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
>
|
||||
>::type::apply(geometry1, geometry2, out, strategy);
|
||||
@@ -433,7 +428,7 @@ inline OutputIterator intersection_inserter(Geometry1 const& geometry1,
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
return detail::intersection::inserter<GeometryOut, false, false, true>(
|
||||
return detail::intersection::inserter<GeometryOut, false, false, true, overlay_intersection>(
|
||||
geometry1, geometry2, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,12 +53,12 @@ inline void sym_difference(Geometry1 const& geometry1,
|
||||
> strategy;
|
||||
|
||||
|
||||
detail::intersection::inserter<geometry_out, false, true, false>(
|
||||
detail::intersection::inserter<geometry_out, false, true, false, overlay_difference>(
|
||||
geometry1, geometry2,
|
||||
std::back_inserter(output_collection),
|
||||
strategy());
|
||||
detail::intersection::inserter<geometry_out, true, false, false>(
|
||||
geometry1, geometry2,
|
||||
detail::intersection::inserter<geometry_out, false, true, false, overlay_difference>(
|
||||
geometry2, geometry1,
|
||||
std::back_inserter(output_collection),
|
||||
strategy());
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ struct union_inserter
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
> : detail::overlay::overlay
|
||||
<Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, 1, Strategy>
|
||||
<Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, overlay_union, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
@@ -147,6 +147,7 @@ template
|
||||
typename MultiLinestring1, typename MultiLinestring2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
@@ -156,6 +157,7 @@ struct intersection_inserter
|
||||
MultiLinestring1, MultiLinestring2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
> : detail::intersection::intersection_multi_linestring_multi_linestring_point
|
||||
<
|
||||
@@ -171,6 +173,7 @@ template
|
||||
typename Linestring, typename MultiLinestring,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
@@ -180,6 +183,7 @@ struct intersection_inserter
|
||||
Linestring, MultiLinestring,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
> : detail::intersection::intersection_linestring_multi_linestring_point
|
||||
<
|
||||
@@ -195,6 +199,7 @@ template
|
||||
typename MultiLinestring, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
@@ -204,6 +209,7 @@ struct intersection_inserter
|
||||
MultiLinestring, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
> : detail::intersection::clip_multi_linestring
|
||||
<
|
||||
|
||||
Reference in New Issue
Block a user