summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/sym_difference.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/sym_difference.hpp')
-rw-r--r--boost/geometry/algorithms/sym_difference.hpp201
1 files changed, 183 insertions, 18 deletions
diff --git a/boost/geometry/algorithms/sym_difference.hpp b/boost/geometry/algorithms/sym_difference.hpp
index de34c9c7b0..6c49ca634c 100644
--- a/boost/geometry/algorithms/sym_difference.hpp
+++ b/boost/geometry/algorithms/sym_difference.hpp
@@ -1,6 +1,11 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2015.
+// Modifications copyright (c) 2015 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -10,9 +15,12 @@
#define BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
#include <algorithm>
-
+#include <iterator>
+#include <vector>
#include <boost/geometry/algorithms/intersection.hpp>
+#include <boost/geometry/algorithms/union.hpp>
+#include <boost/geometry/geometries/multi_polygon.hpp>
namespace boost { namespace geometry
@@ -23,6 +31,177 @@ namespace detail { namespace sym_difference
{
+template <typename GeometryOut>
+struct compute_difference
+{
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename OutputIterator,
+ typename Strategy
+ >
+ static inline OutputIterator apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ return geometry::dispatch::intersection_insert
+ <
+ Geometry1,
+ Geometry2,
+ GeometryOut,
+ overlay_difference,
+ geometry::detail::overlay::do_reverse
+ <
+ geometry::point_order<Geometry1>::value
+ >::value,
+ geometry::detail::overlay::do_reverse
+ <
+ geometry::point_order<Geometry2>::value, true
+ >::value
+ >::apply(geometry1, geometry2, robust_policy, out, strategy);
+ }
+};
+
+
+
+template <typename GeometryOut, typename Geometry1, typename Geometry2>
+struct sym_difference_generic
+{
+ template
+ <
+ typename RobustPolicy,
+ typename OutputIterator,
+ typename Strategy
+ >
+ static inline OutputIterator apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ out = compute_difference
+ <
+ GeometryOut
+ >::apply(geometry1, geometry2, robust_policy, out, strategy);
+
+ return compute_difference
+ <
+ GeometryOut
+ >::apply(geometry2, geometry1, robust_policy, out, strategy);
+ }
+};
+
+
+template <typename GeometryOut, typename Areal1, typename Areal2>
+struct sym_difference_areal_areal
+{
+ template
+ <
+ typename RobustPolicy,
+ typename OutputIterator,
+ typename Strategy
+ >
+ static inline OutputIterator apply(Areal1 const& areal1,
+ Areal2 const& areal2,
+ RobustPolicy const& robust_policy,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ typedef geometry::model::multi_polygon
+ <
+ GeometryOut
+ > helper_geometry_type;
+
+ helper_geometry_type diff12, diff21;
+
+ std::back_insert_iterator<helper_geometry_type> oit12(diff12);
+ std::back_insert_iterator<helper_geometry_type> oit21(diff21);
+
+ compute_difference
+ <
+ GeometryOut
+ >::apply(areal1, areal2, robust_policy, oit12, strategy);
+
+ compute_difference
+ <
+ GeometryOut
+ >::apply(areal2, areal1, robust_policy, oit21, strategy);
+
+ return geometry::dispatch::union_insert
+ <
+ helper_geometry_type,
+ helper_geometry_type,
+ GeometryOut
+ >::apply(diff12, diff21, robust_policy, out, strategy);
+ }
+};
+
+
+}} // namespace detail::sym_difference
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename GeometryOut,
+ typename TagIn1 = typename geometry::tag_cast
+ <
+ typename tag<Geometry1>::type, areal_tag
+ >::type,
+ typename TagIn2 = typename geometry::tag_cast
+ <
+ typename tag<Geometry2>::type, areal_tag
+ >::type,
+ typename TagOut = typename geometry::tag<GeometryOut>::type
+>
+struct sym_difference_insert
+ : detail::sym_difference::sym_difference_generic
+ <
+ GeometryOut, Geometry1, Geometry2
+ >
+{};
+
+
+template
+<
+ typename Areal1,
+ typename Areal2,
+ typename GeometryOut,
+ typename TagOut
+>
+struct sym_difference_insert
+ <
+ Areal1, Areal2, GeometryOut,
+ areal_tag, areal_tag, TagOut
+ > : detail::sym_difference::sym_difference_areal_areal
+ <
+ GeometryOut, Areal1, Areal2
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sym_difference
+{
+
+
/*!
\brief \brief_calc2{symmetric difference} \brief_strategy
@@ -60,24 +239,10 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
concept::check<Geometry2 const>();
concept::check<GeometryOut>();
- out = geometry::dispatch::intersection_insert
+ return dispatch::sym_difference_insert
<
- Geometry1, Geometry2,
- GeometryOut,
- overlay_difference,
- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
+ Geometry1, Geometry2, GeometryOut
>::apply(geometry1, geometry2, robust_policy, out, strategy);
- out = geometry::dispatch::intersection_insert
- <
- Geometry2, Geometry1,
- GeometryOut,
- overlay_difference,
- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
- geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value, true>::value,
- geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value
- >::apply(geometry2, geometry1, robust_policy, out, strategy);
- return out;
}