1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
5 // This file was modified by Oracle on 2014.
6 // Modifications copyright (c) 2014 Oracle and/or its affiliates.
8 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
15 #define BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
18 #include <boost/range/metafunctions.hpp>
20 #include <boost/geometry/core/is_areal.hpp>
21 #include <boost/geometry/core/point_order.hpp>
22 #include <boost/geometry/core/reverse_dispatch.hpp>
23 #include <boost/geometry/geometries/concepts/check.hpp>
24 #include <boost/geometry/algorithms/not_implemented.hpp>
25 #include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
26 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
28 #include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
29 #include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
32 namespace boost { namespace geometry
35 #ifndef DOXYGEN_NO_DISPATCH
41 typename Geometry1, typename Geometry2, typename GeometryOut,
42 typename TagIn1 = typename tag<Geometry1>::type,
43 typename TagIn2 = typename tag<Geometry2>::type,
44 typename TagOut = typename tag<GeometryOut>::type,
45 bool Areal1 = geometry::is_areal<Geometry1>::value,
46 bool Areal2 = geometry::is_areal<Geometry2>::value,
47 bool ArealOut = geometry::is_areal<GeometryOut>::value,
48 bool Reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
49 bool Reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
50 bool ReverseOut = detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
51 bool Reverse = geometry::reverse_dispatch<Geometry1, Geometry2>::type::value
53 struct union_insert: not_implemented<TagIn1, TagIn2, TagOut>
57 // If reversal is needed, perform it first
61 typename Geometry1, typename Geometry2, typename GeometryOut,
62 typename TagIn1, typename TagIn2, typename TagOut,
63 bool Areal1, bool Areal2, bool ArealOut,
64 bool Reverse1, bool Reverse2, bool ReverseOut
68 Geometry1, Geometry2, GeometryOut,
69 TagIn1, TagIn2, TagOut,
70 Areal1, Areal2, ArealOut,
71 Reverse1, Reverse2, ReverseOut,
73 >: union_insert<Geometry2, Geometry1, GeometryOut>
75 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
76 static inline OutputIterator apply(Geometry1 const& g1,
78 RobustPolicy const& robust_policy,
80 Strategy const& strategy)
84 Geometry2, Geometry1, GeometryOut
85 >::apply(g2, g1, robust_policy, out, strategy);
92 typename Geometry1, typename Geometry2, typename GeometryOut,
93 typename TagIn1, typename TagIn2, typename TagOut,
94 bool Reverse1, bool Reverse2, bool ReverseOut
98 Geometry1, Geometry2, GeometryOut,
99 TagIn1, TagIn2, TagOut,
101 Reverse1, Reverse2, ReverseOut,
103 > : detail::overlay::overlay
104 <Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, GeometryOut, overlay_union>
108 // dispatch for union of non-areal geometries
111 typename Geometry1, typename Geometry2, typename GeometryOut,
112 typename TagIn1, typename TagIn2, typename TagOut,
113 bool Reverse1, bool Reverse2, bool ReverseOut
117 Geometry1, Geometry2, GeometryOut,
118 TagIn1, TagIn2, TagOut,
120 Reverse1, Reverse2, ReverseOut,
124 Geometry1, Geometry2, GeometryOut,
125 typename tag_cast<TagIn1, pointlike_tag, linear_tag>::type,
126 typename tag_cast<TagIn2, pointlike_tag, linear_tag>::type,
129 Reverse1, Reverse2, ReverseOut,
135 // dispatch for union of linear geometries
138 typename Linear1, typename Linear2, typename LineStringOut,
139 bool Reverse1, bool Reverse2, bool ReverseOut
143 Linear1, Linear2, LineStringOut,
144 linear_tag, linear_tag, linestring_tag,
146 Reverse1, Reverse2, ReverseOut,
148 > : detail::overlay::linear_linear_linestring
150 Linear1, Linear2, LineStringOut, overlay_union
155 // dispatch for point-like geometries
158 typename PointLike1, typename PointLike2, typename PointOut,
159 bool Reverse1, bool Reverse2, bool ReverseOut
163 PointLike1, PointLike2, PointOut,
164 pointlike_tag, pointlike_tag, point_tag,
166 Reverse1, Reverse2, ReverseOut,
168 > : detail::overlay::union_pointlike_pointlike_point
170 PointLike1, PointLike2, PointOut
175 } // namespace dispatch
176 #endif // DOXYGEN_NO_DISPATCH
178 #ifndef DOXYGEN_NO_DETAIL
179 namespace detail { namespace union_
185 \details \details_calc2{union_insert, spatial set theoretic union}.
186 \details_insert{union}
187 \tparam GeometryOut output geometry type, must be specified
188 \tparam Geometry1 \tparam_geometry
189 \tparam Geometry2 \tparam_geometry
190 \tparam OutputIterator output iterator
191 \param geometry1 \param_geometry
192 \param geometry2 \param_geometry
193 \param out \param_out{union}
198 typename GeometryOut,
201 typename OutputIterator
203 inline OutputIterator union_insert(Geometry1 const& geometry1,
204 Geometry2 const& geometry2,
207 concepts::check<Geometry1 const>();
208 concepts::check<Geometry2 const>();
209 concepts::check<GeometryOut>();
211 typedef typename geometry::rescale_overlay_policy_type
215 >::type rescale_policy_type;
217 typedef intersection_strategies
219 typename cs_tag<GeometryOut>::type,
222 typename geometry::point_type<GeometryOut>::type,
226 rescale_policy_type robust_policy
227 = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
229 return dispatch::union_insert
231 Geometry1, Geometry2, GeometryOut
232 >::apply(geometry1, geometry2, robust_policy, out, strategy());
236 }} // namespace detail::union_
237 #endif // DOXYGEN_NO_DETAIL
243 \brief Combines two geometries which each other
245 \details \details_calc2{union, spatial set theoretic union}.
246 \tparam Geometry1 \tparam_geometry
247 \tparam Geometry2 \tparam_geometry
248 \tparam Collection output collection, either a multi-geometry,
249 or a std::vector<Geometry> / std::deque<Geometry> etc
250 \param geometry1 \param_geometry
251 \param geometry2 \param_geometry
252 \param output_collection the output collection
253 \note Called union_ because union is a reserved word.
255 \qbk{[include reference/algorithms/union.qbk]}
263 inline void union_(Geometry1 const& geometry1,
264 Geometry2 const& geometry2,
265 Collection& output_collection)
267 concepts::check<Geometry1 const>();
268 concepts::check<Geometry2 const>();
270 typedef typename boost::range_value<Collection>::type geometry_out;
271 concepts::check<geometry_out>();
273 detail::union_::union_insert<geometry_out>(geometry1, geometry2,
274 range::back_inserter(output_collection));
278 }} // namespace boost::geometry
281 #endif // BOOST_GEOMETRY_ALGORITHMS_UNION_HPP