summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/union.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/union.hpp')
-rw-r--r--boost/geometry/algorithms/union.hpp294
1 files changed, 275 insertions, 19 deletions
diff --git a/boost/geometry/algorithms/union.hpp b/boost/geometry/algorithms/union.hpp
index f0e55ec981..d3a2daf66e 100644
--- a/boost/geometry/algorithms/union.hpp
+++ b/boost/geometry/algorithms/union.hpp
@@ -2,10 +2,11 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-// This file was modified by Oracle on 2014.
-// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2017.
+// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, 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
@@ -24,6 +25,8 @@
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
#include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
@@ -214,14 +217,10 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
Geometry2
>::type rescale_policy_type;
- typedef intersection_strategies
+ typename strategy::intersection::services::default_strategy
<
- typename cs_tag<GeometryOut>::type,
- Geometry1,
- Geometry2,
- typename geometry::point_type<GeometryOut>::type,
- rescale_policy_type
- > strategy;
+ typename cs_tag<GeometryOut>::type
+ >::type strategy;
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
@@ -229,7 +228,7 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
return dispatch::union_insert
<
Geometry1, Geometry2, GeometryOut
- >::apply(geometry1, geometry2, robust_policy, out, strategy());
+ >::apply(geometry1, geometry2, robust_policy, out, strategy);
}
@@ -237,6 +236,228 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
#endif // DOXYGEN_NO_DETAIL
+namespace resolve_strategy {
+
+struct union_
+{
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename Collection,
+ typename Strategy
+ >
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ Collection & output_collection,
+ Strategy const& strategy)
+ {
+ typedef typename boost::range_value<Collection>::type geometry_out;
+
+ dispatch::union_insert
+ <
+ Geometry1, Geometry2, geometry_out
+ >::apply(geometry1, geometry2, robust_policy,
+ range::back_inserter(output_collection),
+ strategy);
+ }
+
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename RobustPolicy,
+ typename Collection
+ >
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
+ Collection & output_collection,
+ default_strategy)
+ {
+ typedef typename boost::range_value<Collection>::type geometry_out;
+
+ typedef typename strategy::intersection::services::default_strategy
+ <
+ typename cs_tag<geometry_out>::type
+ >::type strategy_type;
+
+ dispatch::union_insert
+ <
+ Geometry1, Geometry2, geometry_out
+ >::apply(geometry1, geometry2, robust_policy,
+ range::back_inserter(output_collection),
+ strategy_type());
+ }
+};
+
+} // resolve_strategy
+
+
+namespace resolve_variant
+{
+
+template <typename Geometry1, typename Geometry2>
+struct union_
+{
+ template <typename Collection, typename Strategy>
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ concepts::check<Geometry1 const>();
+ concepts::check<Geometry2 const>();
+ concepts::check<typename boost::range_value<Collection>::type>();
+
+ typedef typename geometry::rescale_overlay_policy_type
+ <
+ Geometry1,
+ Geometry2
+ >::type rescale_policy_type;
+
+ rescale_policy_type robust_policy
+ = geometry::get_rescale_policy<rescale_policy_type>(geometry1,
+ geometry2);
+
+ resolve_strategy::union_::apply(geometry1, geometry2,
+ robust_policy,
+ output_collection,
+ strategy);
+ }
+};
+
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
+struct union_<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
+{
+ template <typename Collection, typename Strategy>
+ struct visitor: static_visitor<>
+ {
+ Geometry2 const& m_geometry2;
+ Collection& m_output_collection;
+ Strategy const& m_strategy;
+
+ visitor(Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ : m_geometry2(geometry2)
+ , m_output_collection(output_collection)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry1>
+ void operator()(Geometry1 const& geometry1) const
+ {
+ union_
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, m_geometry2, m_output_collection, m_strategy);
+ }
+ };
+
+ template <typename Collection, typename Strategy>
+ static inline void
+ apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<Collection, Strategy>(geometry2,
+ output_collection,
+ strategy),
+ geometry1);
+ }
+};
+
+
+template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct union_<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename Collection, typename Strategy>
+ struct visitor: static_visitor<>
+ {
+ Geometry1 const& m_geometry1;
+ Collection& m_output_collection;
+ Strategy const& m_strategy;
+
+ visitor(Geometry1 const& geometry1,
+ Collection& output_collection,
+ Strategy const& strategy)
+ : m_geometry1(geometry1)
+ , m_output_collection(output_collection)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry2>
+ void operator()(Geometry2 const& geometry2) const
+ {
+ union_
+ <
+ Geometry1,
+ Geometry2
+ >::apply(m_geometry1, geometry2, m_output_collection, m_strategy);
+ }
+ };
+
+ template <typename Collection, typename Strategy>
+ static inline void
+ apply(Geometry1 const& geometry1,
+ variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<Collection, Strategy>(geometry1,
+ output_collection,
+ strategy),
+ geometry2);
+ }
+};
+
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
+struct union_<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
+{
+ template <typename Collection, typename Strategy>
+ struct visitor: static_visitor<>
+ {
+ Collection& m_output_collection;
+ Strategy const& m_strategy;
+
+ visitor(Collection& output_collection, Strategy const& strategy)
+ : m_output_collection(output_collection)
+ , m_strategy(strategy)
+ {}
+
+ template <typename Geometry1, typename Geometry2>
+ void operator()(Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
+ {
+ union_
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, m_output_collection, m_strategy);
+ }
+ };
+
+ template <typename Collection, typename Strategy>
+ static inline void
+ apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<Collection, Strategy>(output_collection,
+ strategy),
+ geometry1, geometry2);
+ }
+};
+
+} // namespace resolve_variant
/*!
@@ -247,31 +468,66 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
\tparam Geometry2 \tparam_geometry
\tparam Collection output collection, either a multi-geometry,
or a std::vector<Geometry> / std::deque<Geometry> etc
+\tparam Strategy \tparam_strategy{Union_}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param output_collection the output collection
+\param strategy \param_strategy{union_}
\note Called union_ because union is a reserved word.
+\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/union.qbk]}
*/
template
<
typename Geometry1,
typename Geometry2,
- typename Collection
+ typename Collection,
+ typename Strategy
>
inline void union_(Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- Collection& output_collection)
+ Geometry2 const& geometry2,
+ Collection& output_collection,
+ Strategy const& strategy)
{
- concepts::check<Geometry1 const>();
- concepts::check<Geometry2 const>();
+ resolve_variant::union_
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, output_collection, strategy);
+}
- typedef typename boost::range_value<Collection>::type geometry_out;
- concepts::check<geometry_out>();
- detail::union_::union_insert<geometry_out>(geometry1, geometry2,
- range::back_inserter(output_collection));
+/*!
+\brief Combines two geometries which each other
+\ingroup union
+\details \details_calc2{union, spatial set theoretic union}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Collection output collection, either a multi-geometry,
+ or a std::vector<Geometry> / std::deque<Geometry> etc
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param output_collection the output collection
+\note Called union_ because union is a reserved word.
+
+\qbk{[include reference/algorithms/union.qbk]}
+*/
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Collection
+>
+inline void union_(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection)
+{
+ resolve_variant::union_
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, output_collection, default_strategy());
}