Chris@16
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@16
|
2
|
Chris@101
|
3 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@101
|
4
|
Chris@101
|
5 // This file was modified by Oracle on 2014.
|
Chris@101
|
6 // Modifications copyright (c) 2014 Oracle and/or its affiliates.
|
Chris@101
|
7
|
Chris@101
|
8 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
Chris@16
|
9
|
Chris@16
|
10 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@16
|
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
12 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
13
|
Chris@16
|
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
|
Chris@16
|
15 #define BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
|
Chris@16
|
16
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/range/metafunctions.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/geometry/core/is_areal.hpp>
|
Chris@16
|
21 #include <boost/geometry/core/point_order.hpp>
|
Chris@16
|
22 #include <boost/geometry/core/reverse_dispatch.hpp>
|
Chris@16
|
23 #include <boost/geometry/geometries/concepts/check.hpp>
|
Chris@16
|
24 #include <boost/geometry/algorithms/not_implemented.hpp>
|
Chris@16
|
25 #include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
|
Chris@101
|
26 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
Chris@101
|
27
|
Chris@101
|
28 #include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
|
Chris@101
|
29 #include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
|
Chris@16
|
30
|
Chris@16
|
31
|
Chris@16
|
32 namespace boost { namespace geometry
|
Chris@16
|
33 {
|
Chris@16
|
34
|
Chris@16
|
35 #ifndef DOXYGEN_NO_DISPATCH
|
Chris@16
|
36 namespace dispatch
|
Chris@16
|
37 {
|
Chris@16
|
38
|
Chris@16
|
39 template
|
Chris@16
|
40 <
|
Chris@16
|
41 typename Geometry1, typename Geometry2, typename GeometryOut,
|
Chris@16
|
42 typename TagIn1 = typename tag<Geometry1>::type,
|
Chris@16
|
43 typename TagIn2 = typename tag<Geometry2>::type,
|
Chris@16
|
44 typename TagOut = typename tag<GeometryOut>::type,
|
Chris@16
|
45 bool Areal1 = geometry::is_areal<Geometry1>::value,
|
Chris@16
|
46 bool Areal2 = geometry::is_areal<Geometry2>::value,
|
Chris@16
|
47 bool ArealOut = geometry::is_areal<GeometryOut>::value,
|
Chris@16
|
48 bool Reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
Chris@16
|
49 bool Reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
|
Chris@16
|
50 bool ReverseOut = detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
Chris@16
|
51 bool Reverse = geometry::reverse_dispatch<Geometry1, Geometry2>::type::value
|
Chris@16
|
52 >
|
Chris@16
|
53 struct union_insert: not_implemented<TagIn1, TagIn2, TagOut>
|
Chris@16
|
54 {};
|
Chris@16
|
55
|
Chris@16
|
56
|
Chris@16
|
57 // If reversal is needed, perform it first
|
Chris@16
|
58
|
Chris@16
|
59 template
|
Chris@16
|
60 <
|
Chris@16
|
61 typename Geometry1, typename Geometry2, typename GeometryOut,
|
Chris@16
|
62 typename TagIn1, typename TagIn2, typename TagOut,
|
Chris@101
|
63 bool Areal1, bool Areal2, bool ArealOut,
|
Chris@16
|
64 bool Reverse1, bool Reverse2, bool ReverseOut
|
Chris@16
|
65 >
|
Chris@16
|
66 struct union_insert
|
Chris@16
|
67 <
|
Chris@16
|
68 Geometry1, Geometry2, GeometryOut,
|
Chris@16
|
69 TagIn1, TagIn2, TagOut,
|
Chris@101
|
70 Areal1, Areal2, ArealOut,
|
Chris@16
|
71 Reverse1, Reverse2, ReverseOut,
|
Chris@16
|
72 true
|
Chris@16
|
73 >: union_insert<Geometry2, Geometry1, GeometryOut>
|
Chris@16
|
74 {
|
Chris@101
|
75 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
|
Chris@16
|
76 static inline OutputIterator apply(Geometry1 const& g1,
|
Chris@101
|
77 Geometry2 const& g2,
|
Chris@101
|
78 RobustPolicy const& robust_policy,
|
Chris@101
|
79 OutputIterator out,
|
Chris@16
|
80 Strategy const& strategy)
|
Chris@16
|
81 {
|
Chris@16
|
82 return union_insert
|
Chris@16
|
83 <
|
Chris@16
|
84 Geometry2, Geometry1, GeometryOut
|
Chris@101
|
85 >::apply(g2, g1, robust_policy, out, strategy);
|
Chris@16
|
86 }
|
Chris@16
|
87 };
|
Chris@16
|
88
|
Chris@16
|
89
|
Chris@16
|
90 template
|
Chris@16
|
91 <
|
Chris@16
|
92 typename Geometry1, typename Geometry2, typename GeometryOut,
|
Chris@16
|
93 typename TagIn1, typename TagIn2, typename TagOut,
|
Chris@16
|
94 bool Reverse1, bool Reverse2, bool ReverseOut
|
Chris@16
|
95 >
|
Chris@16
|
96 struct union_insert
|
Chris@16
|
97 <
|
Chris@16
|
98 Geometry1, Geometry2, GeometryOut,
|
Chris@16
|
99 TagIn1, TagIn2, TagOut,
|
Chris@16
|
100 true, true, true,
|
Chris@16
|
101 Reverse1, Reverse2, ReverseOut,
|
Chris@16
|
102 false
|
Chris@16
|
103 > : detail::overlay::overlay
|
Chris@16
|
104 <Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, GeometryOut, overlay_union>
|
Chris@16
|
105 {};
|
Chris@16
|
106
|
Chris@16
|
107
|
Chris@101
|
108 // dispatch for union of non-areal geometries
|
Chris@101
|
109 template
|
Chris@101
|
110 <
|
Chris@101
|
111 typename Geometry1, typename Geometry2, typename GeometryOut,
|
Chris@101
|
112 typename TagIn1, typename TagIn2, typename TagOut,
|
Chris@101
|
113 bool Reverse1, bool Reverse2, bool ReverseOut
|
Chris@101
|
114 >
|
Chris@101
|
115 struct union_insert
|
Chris@101
|
116 <
|
Chris@101
|
117 Geometry1, Geometry2, GeometryOut,
|
Chris@101
|
118 TagIn1, TagIn2, TagOut,
|
Chris@101
|
119 false, false, false,
|
Chris@101
|
120 Reverse1, Reverse2, ReverseOut,
|
Chris@101
|
121 false
|
Chris@101
|
122 > : union_insert
|
Chris@101
|
123 <
|
Chris@101
|
124 Geometry1, Geometry2, GeometryOut,
|
Chris@101
|
125 typename tag_cast<TagIn1, pointlike_tag, linear_tag>::type,
|
Chris@101
|
126 typename tag_cast<TagIn2, pointlike_tag, linear_tag>::type,
|
Chris@101
|
127 TagOut,
|
Chris@101
|
128 false, false, false,
|
Chris@101
|
129 Reverse1, Reverse2, ReverseOut,
|
Chris@101
|
130 false
|
Chris@101
|
131 >
|
Chris@101
|
132 {};
|
Chris@101
|
133
|
Chris@101
|
134
|
Chris@101
|
135 // dispatch for union of linear geometries
|
Chris@101
|
136 template
|
Chris@101
|
137 <
|
Chris@101
|
138 typename Linear1, typename Linear2, typename LineStringOut,
|
Chris@101
|
139 bool Reverse1, bool Reverse2, bool ReverseOut
|
Chris@101
|
140 >
|
Chris@101
|
141 struct union_insert
|
Chris@101
|
142 <
|
Chris@101
|
143 Linear1, Linear2, LineStringOut,
|
Chris@101
|
144 linear_tag, linear_tag, linestring_tag,
|
Chris@101
|
145 false, false, false,
|
Chris@101
|
146 Reverse1, Reverse2, ReverseOut,
|
Chris@101
|
147 false
|
Chris@101
|
148 > : detail::overlay::linear_linear_linestring
|
Chris@101
|
149 <
|
Chris@101
|
150 Linear1, Linear2, LineStringOut, overlay_union
|
Chris@101
|
151 >
|
Chris@101
|
152 {};
|
Chris@101
|
153
|
Chris@101
|
154
|
Chris@101
|
155 // dispatch for point-like geometries
|
Chris@101
|
156 template
|
Chris@101
|
157 <
|
Chris@101
|
158 typename PointLike1, typename PointLike2, typename PointOut,
|
Chris@101
|
159 bool Reverse1, bool Reverse2, bool ReverseOut
|
Chris@101
|
160 >
|
Chris@101
|
161 struct union_insert
|
Chris@101
|
162 <
|
Chris@101
|
163 PointLike1, PointLike2, PointOut,
|
Chris@101
|
164 pointlike_tag, pointlike_tag, point_tag,
|
Chris@101
|
165 false, false, false,
|
Chris@101
|
166 Reverse1, Reverse2, ReverseOut,
|
Chris@101
|
167 false
|
Chris@101
|
168 > : detail::overlay::union_pointlike_pointlike_point
|
Chris@101
|
169 <
|
Chris@101
|
170 PointLike1, PointLike2, PointOut
|
Chris@101
|
171 >
|
Chris@101
|
172 {};
|
Chris@101
|
173
|
Chris@101
|
174
|
Chris@16
|
175 } // namespace dispatch
|
Chris@16
|
176 #endif // DOXYGEN_NO_DISPATCH
|
Chris@16
|
177
|
Chris@16
|
178 #ifndef DOXYGEN_NO_DETAIL
|
Chris@16
|
179 namespace detail { namespace union_
|
Chris@16
|
180 {
|
Chris@16
|
181
|
Chris@16
|
182 /*!
|
Chris@16
|
183 \brief_calc2{union}
|
Chris@16
|
184 \ingroup union
|
Chris@16
|
185 \details \details_calc2{union_insert, spatial set theoretic union}.
|
Chris@16
|
186 \details_insert{union}
|
Chris@16
|
187 \tparam GeometryOut output geometry type, must be specified
|
Chris@16
|
188 \tparam Geometry1 \tparam_geometry
|
Chris@16
|
189 \tparam Geometry2 \tparam_geometry
|
Chris@16
|
190 \tparam OutputIterator output iterator
|
Chris@16
|
191 \param geometry1 \param_geometry
|
Chris@16
|
192 \param geometry2 \param_geometry
|
Chris@16
|
193 \param out \param_out{union}
|
Chris@16
|
194 \return \return_out
|
Chris@16
|
195 */
|
Chris@16
|
196 template
|
Chris@16
|
197 <
|
Chris@16
|
198 typename GeometryOut,
|
Chris@16
|
199 typename Geometry1,
|
Chris@16
|
200 typename Geometry2,
|
Chris@16
|
201 typename OutputIterator
|
Chris@16
|
202 >
|
Chris@16
|
203 inline OutputIterator union_insert(Geometry1 const& geometry1,
|
Chris@16
|
204 Geometry2 const& geometry2,
|
Chris@16
|
205 OutputIterator out)
|
Chris@16
|
206 {
|
Chris@16
|
207 concept::check<Geometry1 const>();
|
Chris@16
|
208 concept::check<Geometry2 const>();
|
Chris@16
|
209 concept::check<GeometryOut>();
|
Chris@16
|
210
|
Chris@101
|
211 typedef typename geometry::rescale_overlay_policy_type
|
Chris@101
|
212 <
|
Chris@101
|
213 Geometry1,
|
Chris@101
|
214 Geometry2
|
Chris@101
|
215 >::type rescale_policy_type;
|
Chris@101
|
216
|
Chris@16
|
217 typedef strategy_intersection
|
Chris@16
|
218 <
|
Chris@16
|
219 typename cs_tag<GeometryOut>::type,
|
Chris@16
|
220 Geometry1,
|
Chris@16
|
221 Geometry2,
|
Chris@101
|
222 typename geometry::point_type<GeometryOut>::type,
|
Chris@101
|
223 rescale_policy_type
|
Chris@16
|
224 > strategy;
|
Chris@16
|
225
|
Chris@101
|
226 rescale_policy_type robust_policy
|
Chris@101
|
227 = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
|
Chris@101
|
228
|
Chris@101
|
229 return dispatch::union_insert
|
Chris@101
|
230 <
|
Chris@101
|
231 Geometry1, Geometry2, GeometryOut
|
Chris@101
|
232 >::apply(geometry1, geometry2, robust_policy, out, strategy());
|
Chris@16
|
233 }
|
Chris@16
|
234
|
Chris@16
|
235
|
Chris@16
|
236 }} // namespace detail::union_
|
Chris@16
|
237 #endif // DOXYGEN_NO_DETAIL
|
Chris@16
|
238
|
Chris@16
|
239
|
Chris@16
|
240
|
Chris@16
|
241
|
Chris@16
|
242 /*!
|
Chris@16
|
243 \brief Combines two geometries which each other
|
Chris@16
|
244 \ingroup union
|
Chris@16
|
245 \details \details_calc2{union, spatial set theoretic union}.
|
Chris@16
|
246 \tparam Geometry1 \tparam_geometry
|
Chris@16
|
247 \tparam Geometry2 \tparam_geometry
|
Chris@16
|
248 \tparam Collection output collection, either a multi-geometry,
|
Chris@16
|
249 or a std::vector<Geometry> / std::deque<Geometry> etc
|
Chris@16
|
250 \param geometry1 \param_geometry
|
Chris@16
|
251 \param geometry2 \param_geometry
|
Chris@16
|
252 \param output_collection the output collection
|
Chris@16
|
253 \note Called union_ because union is a reserved word.
|
Chris@16
|
254
|
Chris@16
|
255 \qbk{[include reference/algorithms/union.qbk]}
|
Chris@16
|
256 */
|
Chris@16
|
257 template
|
Chris@16
|
258 <
|
Chris@16
|
259 typename Geometry1,
|
Chris@16
|
260 typename Geometry2,
|
Chris@16
|
261 typename Collection
|
Chris@16
|
262 >
|
Chris@16
|
263 inline void union_(Geometry1 const& geometry1,
|
Chris@16
|
264 Geometry2 const& geometry2,
|
Chris@16
|
265 Collection& output_collection)
|
Chris@16
|
266 {
|
Chris@16
|
267 concept::check<Geometry1 const>();
|
Chris@16
|
268 concept::check<Geometry2 const>();
|
Chris@16
|
269
|
Chris@16
|
270 typedef typename boost::range_value<Collection>::type geometry_out;
|
Chris@16
|
271 concept::check<geometry_out>();
|
Chris@16
|
272
|
Chris@16
|
273 detail::union_::union_insert<geometry_out>(geometry1, geometry2,
|
Chris@16
|
274 std::back_inserter(output_collection));
|
Chris@16
|
275 }
|
Chris@16
|
276
|
Chris@16
|
277
|
Chris@16
|
278 }} // namespace boost::geometry
|
Chris@16
|
279
|
Chris@16
|
280
|
Chris@16
|
281 #endif // BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
|