Chris@102
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@102
|
2
|
Chris@102
|
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@102
|
4
|
Chris@102
|
5 // This file was modified by Oracle on 2014.
|
Chris@102
|
6 // Modifications copyright (c) 2014, Oracle and/or its affiliates.
|
Chris@102
|
7
|
Chris@102
|
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
Chris@102
|
9
|
Chris@102
|
10 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@102
|
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@102
|
12 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
13
|
Chris@102
|
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP
|
Chris@102
|
15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP
|
Chris@102
|
16
|
Chris@102
|
17 #include <boost/geometry/core/closure.hpp>
|
Chris@102
|
18 #include <boost/geometry/core/geometry_id.hpp>
|
Chris@102
|
19 #include <boost/geometry/core/is_areal.hpp>
|
Chris@102
|
20 #include <boost/geometry/core/point_order.hpp>
|
Chris@102
|
21 #include <boost/geometry/core/tags.hpp>
|
Chris@102
|
22 #include <boost/geometry/geometries/concepts/check.hpp>
|
Chris@102
|
23
|
Chris@102
|
24 // TODO: those headers probably may be removed
|
Chris@102
|
25 #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
|
Chris@102
|
26 #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
|
Chris@102
|
27 #include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
|
Chris@102
|
28 #include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
|
Chris@102
|
29 #include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
|
Chris@102
|
30 #include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
|
Chris@102
|
31 #include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
|
Chris@102
|
32
|
Chris@102
|
33 #include <boost/geometry/algorithms/detail/intersection/interface.hpp>
|
Chris@102
|
34
|
Chris@102
|
35 #include <boost/geometry/algorithms/covered_by.hpp>
|
Chris@102
|
36 #include <boost/geometry/algorithms/envelope.hpp>
|
Chris@102
|
37 #include <boost/geometry/algorithms/num_points.hpp>
|
Chris@102
|
38
|
Chris@102
|
39 // TODO: remove this after moving num_point from multi directory
|
Chris@102
|
40 #include <boost/geometry/multi/algorithms/num_points.hpp>
|
Chris@102
|
41
|
Chris@102
|
42 namespace boost { namespace geometry
|
Chris@102
|
43 {
|
Chris@102
|
44
|
Chris@102
|
45 #ifndef DOXYGEN_NO_DETAIL
|
Chris@102
|
46 namespace detail { namespace intersection
|
Chris@102
|
47 {
|
Chris@102
|
48
|
Chris@102
|
49
|
Chris@102
|
50 template <typename PointOut>
|
Chris@102
|
51 struct intersection_multi_linestring_multi_linestring_point
|
Chris@102
|
52 {
|
Chris@102
|
53 template
|
Chris@102
|
54 <
|
Chris@102
|
55 typename MultiLinestring1, typename MultiLinestring2,
|
Chris@102
|
56 typename RobustPolicy,
|
Chris@102
|
57 typename OutputIterator, typename Strategy
|
Chris@102
|
58 >
|
Chris@102
|
59 static inline OutputIterator apply(MultiLinestring1 const& ml1,
|
Chris@102
|
60 MultiLinestring2 const& ml2,
|
Chris@102
|
61 RobustPolicy const& robust_policy,
|
Chris@102
|
62 OutputIterator out,
|
Chris@102
|
63 Strategy const& strategy)
|
Chris@102
|
64 {
|
Chris@102
|
65 // Note, this loop is quadratic w.r.t. number of linestrings per input.
|
Chris@102
|
66 // Future Enhancement: first do the sections of each, then intersect.
|
Chris@102
|
67 for (typename boost::range_iterator
|
Chris@102
|
68 <
|
Chris@102
|
69 MultiLinestring1 const
|
Chris@102
|
70 >::type it1 = boost::begin(ml1);
|
Chris@102
|
71 it1 != boost::end(ml1);
|
Chris@102
|
72 ++it1)
|
Chris@102
|
73 {
|
Chris@102
|
74 for (typename boost::range_iterator
|
Chris@102
|
75 <
|
Chris@102
|
76 MultiLinestring2 const
|
Chris@102
|
77 >::type it2 = boost::begin(ml2);
|
Chris@102
|
78 it2 != boost::end(ml2);
|
Chris@102
|
79 ++it2)
|
Chris@102
|
80 {
|
Chris@102
|
81 out = intersection_linestring_linestring_point<PointOut>
|
Chris@102
|
82 ::apply(*it1, *it2, robust_policy, out, strategy);
|
Chris@102
|
83 }
|
Chris@102
|
84 }
|
Chris@102
|
85
|
Chris@102
|
86 return out;
|
Chris@102
|
87 }
|
Chris@102
|
88 };
|
Chris@102
|
89
|
Chris@102
|
90
|
Chris@102
|
91 template <typename PointOut>
|
Chris@102
|
92 struct intersection_linestring_multi_linestring_point
|
Chris@102
|
93 {
|
Chris@102
|
94 template
|
Chris@102
|
95 <
|
Chris@102
|
96 typename Linestring, typename MultiLinestring,
|
Chris@102
|
97 typename RobustPolicy,
|
Chris@102
|
98 typename OutputIterator, typename Strategy
|
Chris@102
|
99 >
|
Chris@102
|
100 static inline OutputIterator apply(Linestring const& linestring,
|
Chris@102
|
101 MultiLinestring const& ml,
|
Chris@102
|
102 RobustPolicy const& robust_policy,
|
Chris@102
|
103 OutputIterator out,
|
Chris@102
|
104 Strategy const& strategy)
|
Chris@102
|
105 {
|
Chris@102
|
106 for (typename boost::range_iterator
|
Chris@102
|
107 <
|
Chris@102
|
108 MultiLinestring const
|
Chris@102
|
109 >::type it = boost::begin(ml);
|
Chris@102
|
110 it != boost::end(ml);
|
Chris@102
|
111 ++it)
|
Chris@102
|
112 {
|
Chris@102
|
113 out = intersection_linestring_linestring_point<PointOut>
|
Chris@102
|
114 ::apply(linestring, *it, robust_policy, out, strategy);
|
Chris@102
|
115 }
|
Chris@102
|
116
|
Chris@102
|
117 return out;
|
Chris@102
|
118 }
|
Chris@102
|
119 };
|
Chris@102
|
120
|
Chris@102
|
121
|
Chris@102
|
122 // This loop is quite similar to the loop above, but beacuse the iterator
|
Chris@102
|
123 // is second (above) or first (below) argument, it is not trivial to merge them.
|
Chris@102
|
124 template
|
Chris@102
|
125 <
|
Chris@102
|
126 bool ReverseAreal,
|
Chris@102
|
127 typename LineStringOut,
|
Chris@102
|
128 overlay_type OverlayType
|
Chris@102
|
129 >
|
Chris@102
|
130 struct intersection_of_multi_linestring_with_areal
|
Chris@102
|
131 {
|
Chris@102
|
132 template
|
Chris@102
|
133 <
|
Chris@102
|
134 typename MultiLinestring, typename Areal,
|
Chris@102
|
135 typename RobustPolicy,
|
Chris@102
|
136 typename OutputIterator, typename Strategy
|
Chris@102
|
137 >
|
Chris@102
|
138 static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal,
|
Chris@102
|
139 RobustPolicy const& robust_policy,
|
Chris@102
|
140 OutputIterator out,
|
Chris@102
|
141 Strategy const& strategy)
|
Chris@102
|
142 {
|
Chris@102
|
143 for (typename boost::range_iterator
|
Chris@102
|
144 <
|
Chris@102
|
145 MultiLinestring const
|
Chris@102
|
146 >::type it = boost::begin(ml);
|
Chris@102
|
147 it != boost::end(ml);
|
Chris@102
|
148 ++it)
|
Chris@102
|
149 {
|
Chris@102
|
150 out = intersection_of_linestring_with_areal
|
Chris@102
|
151 <
|
Chris@102
|
152 ReverseAreal, LineStringOut, OverlayType
|
Chris@102
|
153 >::apply(*it, areal, robust_policy, out, strategy);
|
Chris@102
|
154 }
|
Chris@102
|
155
|
Chris@102
|
156 return out;
|
Chris@102
|
157
|
Chris@102
|
158 }
|
Chris@102
|
159 };
|
Chris@102
|
160
|
Chris@102
|
161 // This one calls the one above with reversed arguments
|
Chris@102
|
162 template
|
Chris@102
|
163 <
|
Chris@102
|
164 bool ReverseAreal,
|
Chris@102
|
165 typename LineStringOut,
|
Chris@102
|
166 overlay_type OverlayType
|
Chris@102
|
167 >
|
Chris@102
|
168 struct intersection_of_areal_with_multi_linestring
|
Chris@102
|
169 {
|
Chris@102
|
170 template
|
Chris@102
|
171 <
|
Chris@102
|
172 typename Areal, typename MultiLinestring,
|
Chris@102
|
173 typename RobustPolicy,
|
Chris@102
|
174 typename OutputIterator, typename Strategy
|
Chris@102
|
175 >
|
Chris@102
|
176 static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml,
|
Chris@102
|
177 RobustPolicy const& robust_policy,
|
Chris@102
|
178 OutputIterator out,
|
Chris@102
|
179 Strategy const& strategy)
|
Chris@102
|
180 {
|
Chris@102
|
181 return intersection_of_multi_linestring_with_areal
|
Chris@102
|
182 <
|
Chris@102
|
183 ReverseAreal, LineStringOut, OverlayType
|
Chris@102
|
184 >::apply(ml, areal, robust_policy, out, strategy);
|
Chris@102
|
185 }
|
Chris@102
|
186 };
|
Chris@102
|
187
|
Chris@102
|
188
|
Chris@102
|
189
|
Chris@102
|
190 template <typename LinestringOut>
|
Chris@102
|
191 struct clip_multi_linestring
|
Chris@102
|
192 {
|
Chris@102
|
193 template
|
Chris@102
|
194 <
|
Chris@102
|
195 typename MultiLinestring, typename Box,
|
Chris@102
|
196 typename RobustPolicy,
|
Chris@102
|
197 typename OutputIterator, typename Strategy
|
Chris@102
|
198 >
|
Chris@102
|
199 static inline OutputIterator apply(MultiLinestring const& multi_linestring,
|
Chris@102
|
200 Box const& box,
|
Chris@102
|
201 RobustPolicy const& robust_policy,
|
Chris@102
|
202 OutputIterator out, Strategy const& )
|
Chris@102
|
203 {
|
Chris@102
|
204 typedef typename point_type<LinestringOut>::type point_type;
|
Chris@102
|
205 strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
|
Chris@102
|
206 for (typename boost::range_iterator<MultiLinestring const>::type it
|
Chris@102
|
207 = boost::begin(multi_linestring);
|
Chris@102
|
208 it != boost::end(multi_linestring); ++it)
|
Chris@102
|
209 {
|
Chris@102
|
210 out = detail::intersection::clip_range_with_box
|
Chris@102
|
211 <LinestringOut>(box, *it, robust_policy, out, lb_strategy);
|
Chris@102
|
212 }
|
Chris@102
|
213 return out;
|
Chris@102
|
214 }
|
Chris@102
|
215 };
|
Chris@102
|
216
|
Chris@102
|
217
|
Chris@102
|
218 }} // namespace detail::intersection
|
Chris@102
|
219 #endif // DOXYGEN_NO_DETAIL
|
Chris@102
|
220
|
Chris@102
|
221
|
Chris@102
|
222 #ifndef DOXYGEN_NO_DISPATCH
|
Chris@102
|
223 namespace dispatch
|
Chris@102
|
224 {
|
Chris@102
|
225
|
Chris@102
|
226
|
Chris@102
|
227 // Linear
|
Chris@102
|
228 template
|
Chris@102
|
229 <
|
Chris@102
|
230 typename MultiLinestring1, typename MultiLinestring2,
|
Chris@102
|
231 typename GeometryOut,
|
Chris@102
|
232 overlay_type OverlayType,
|
Chris@102
|
233 bool Reverse1, bool Reverse2, bool ReverseOut
|
Chris@102
|
234 >
|
Chris@102
|
235 struct intersection_insert
|
Chris@102
|
236 <
|
Chris@102
|
237 MultiLinestring1, MultiLinestring2,
|
Chris@102
|
238 GeometryOut,
|
Chris@102
|
239 OverlayType,
|
Chris@102
|
240 Reverse1, Reverse2, ReverseOut,
|
Chris@102
|
241 multi_linestring_tag, multi_linestring_tag, point_tag,
|
Chris@102
|
242 false, false, false
|
Chris@102
|
243 > : detail::intersection::intersection_multi_linestring_multi_linestring_point
|
Chris@102
|
244 <
|
Chris@102
|
245 GeometryOut
|
Chris@102
|
246 >
|
Chris@102
|
247 {};
|
Chris@102
|
248
|
Chris@102
|
249
|
Chris@102
|
250 template
|
Chris@102
|
251 <
|
Chris@102
|
252 typename Linestring, typename MultiLinestring,
|
Chris@102
|
253 typename GeometryOut,
|
Chris@102
|
254 overlay_type OverlayType,
|
Chris@102
|
255 bool Reverse1, bool Reverse2, bool ReverseOut
|
Chris@102
|
256 >
|
Chris@102
|
257 struct intersection_insert
|
Chris@102
|
258 <
|
Chris@102
|
259 Linestring, MultiLinestring,
|
Chris@102
|
260 GeometryOut,
|
Chris@102
|
261 OverlayType,
|
Chris@102
|
262 Reverse1, Reverse2, ReverseOut,
|
Chris@102
|
263 linestring_tag, multi_linestring_tag, point_tag,
|
Chris@102
|
264 false, false, false
|
Chris@102
|
265 > : detail::intersection::intersection_linestring_multi_linestring_point
|
Chris@102
|
266 <
|
Chris@102
|
267 GeometryOut
|
Chris@102
|
268 >
|
Chris@102
|
269 {};
|
Chris@102
|
270
|
Chris@102
|
271
|
Chris@102
|
272 template
|
Chris@102
|
273 <
|
Chris@102
|
274 typename MultiLinestring, typename Box,
|
Chris@102
|
275 typename GeometryOut,
|
Chris@102
|
276 overlay_type OverlayType,
|
Chris@102
|
277 bool Reverse1, bool Reverse2, bool ReverseOut
|
Chris@102
|
278 >
|
Chris@102
|
279 struct intersection_insert
|
Chris@102
|
280 <
|
Chris@102
|
281 MultiLinestring, Box,
|
Chris@102
|
282 GeometryOut,
|
Chris@102
|
283 OverlayType,
|
Chris@102
|
284 Reverse1, Reverse2, ReverseOut,
|
Chris@102
|
285 multi_linestring_tag, box_tag, linestring_tag,
|
Chris@102
|
286 false, true, false
|
Chris@102
|
287 > : detail::intersection::clip_multi_linestring
|
Chris@102
|
288 <
|
Chris@102
|
289 GeometryOut
|
Chris@102
|
290 >
|
Chris@102
|
291 {};
|
Chris@102
|
292
|
Chris@102
|
293
|
Chris@102
|
294 template
|
Chris@102
|
295 <
|
Chris@102
|
296 typename Linestring, typename MultiPolygon,
|
Chris@102
|
297 typename GeometryOut,
|
Chris@102
|
298 overlay_type OverlayType,
|
Chris@102
|
299 bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut
|
Chris@102
|
300 >
|
Chris@102
|
301 struct intersection_insert
|
Chris@102
|
302 <
|
Chris@102
|
303 Linestring, MultiPolygon,
|
Chris@102
|
304 GeometryOut,
|
Chris@102
|
305 OverlayType,
|
Chris@102
|
306 ReverseLinestring, ReverseMultiPolygon, ReverseOut,
|
Chris@102
|
307 linestring_tag, multi_polygon_tag, linestring_tag,
|
Chris@102
|
308 false, true, false
|
Chris@102
|
309 > : detail::intersection::intersection_of_linestring_with_areal
|
Chris@102
|
310 <
|
Chris@102
|
311 ReverseMultiPolygon,
|
Chris@102
|
312 GeometryOut,
|
Chris@102
|
313 OverlayType
|
Chris@102
|
314 >
|
Chris@102
|
315 {};
|
Chris@102
|
316
|
Chris@102
|
317
|
Chris@102
|
318 // Derives from areal/mls because runtime arguments are in that order.
|
Chris@102
|
319 // areal/mls reverses it itself to mls/areal
|
Chris@102
|
320 template
|
Chris@102
|
321 <
|
Chris@102
|
322 typename Polygon, typename MultiLinestring,
|
Chris@102
|
323 typename GeometryOut,
|
Chris@102
|
324 overlay_type OverlayType,
|
Chris@102
|
325 bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut
|
Chris@102
|
326 >
|
Chris@102
|
327 struct intersection_insert
|
Chris@102
|
328 <
|
Chris@102
|
329 Polygon, MultiLinestring,
|
Chris@102
|
330 GeometryOut,
|
Chris@102
|
331 OverlayType,
|
Chris@102
|
332 ReversePolygon, ReverseMultiLinestring, ReverseOut,
|
Chris@102
|
333 polygon_tag, multi_linestring_tag, linestring_tag,
|
Chris@102
|
334 true, false, false
|
Chris@102
|
335 > : detail::intersection::intersection_of_areal_with_multi_linestring
|
Chris@102
|
336 <
|
Chris@102
|
337 ReversePolygon,
|
Chris@102
|
338 GeometryOut,
|
Chris@102
|
339 OverlayType
|
Chris@102
|
340 >
|
Chris@102
|
341 {};
|
Chris@102
|
342
|
Chris@102
|
343
|
Chris@102
|
344 template
|
Chris@102
|
345 <
|
Chris@102
|
346 typename MultiLinestring, typename Ring,
|
Chris@102
|
347 typename GeometryOut,
|
Chris@102
|
348 overlay_type OverlayType,
|
Chris@102
|
349 bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
|
Chris@102
|
350 >
|
Chris@102
|
351 struct intersection_insert
|
Chris@102
|
352 <
|
Chris@102
|
353 MultiLinestring, Ring,
|
Chris@102
|
354 GeometryOut,
|
Chris@102
|
355 OverlayType,
|
Chris@102
|
356 ReverseMultiLinestring, ReverseRing, ReverseOut,
|
Chris@102
|
357 multi_linestring_tag, ring_tag, linestring_tag,
|
Chris@102
|
358 false, true, false
|
Chris@102
|
359 > : detail::intersection::intersection_of_multi_linestring_with_areal
|
Chris@102
|
360 <
|
Chris@102
|
361 ReverseRing,
|
Chris@102
|
362 GeometryOut,
|
Chris@102
|
363 OverlayType
|
Chris@102
|
364 >
|
Chris@102
|
365 {};
|
Chris@102
|
366
|
Chris@102
|
367 template
|
Chris@102
|
368 <
|
Chris@102
|
369 typename MultiLinestring, typename Polygon,
|
Chris@102
|
370 typename GeometryOut,
|
Chris@102
|
371 overlay_type OverlayType,
|
Chris@102
|
372 bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
|
Chris@102
|
373 >
|
Chris@102
|
374 struct intersection_insert
|
Chris@102
|
375 <
|
Chris@102
|
376 MultiLinestring, Polygon,
|
Chris@102
|
377 GeometryOut,
|
Chris@102
|
378 OverlayType,
|
Chris@102
|
379 ReverseMultiLinestring, ReverseRing, ReverseOut,
|
Chris@102
|
380 multi_linestring_tag, polygon_tag, linestring_tag,
|
Chris@102
|
381 false, true, false
|
Chris@102
|
382 > : detail::intersection::intersection_of_multi_linestring_with_areal
|
Chris@102
|
383 <
|
Chris@102
|
384 ReverseRing,
|
Chris@102
|
385 GeometryOut,
|
Chris@102
|
386 OverlayType
|
Chris@102
|
387 >
|
Chris@102
|
388 {};
|
Chris@102
|
389
|
Chris@102
|
390
|
Chris@102
|
391
|
Chris@102
|
392 template
|
Chris@102
|
393 <
|
Chris@102
|
394 typename MultiLinestring, typename MultiPolygon,
|
Chris@102
|
395 typename GeometryOut,
|
Chris@102
|
396 overlay_type OverlayType,
|
Chris@102
|
397 bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut
|
Chris@102
|
398 >
|
Chris@102
|
399 struct intersection_insert
|
Chris@102
|
400 <
|
Chris@102
|
401 MultiLinestring, MultiPolygon,
|
Chris@102
|
402 GeometryOut,
|
Chris@102
|
403 OverlayType,
|
Chris@102
|
404 ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut,
|
Chris@102
|
405 multi_linestring_tag, multi_polygon_tag, linestring_tag,
|
Chris@102
|
406 false, true, false
|
Chris@102
|
407 > : detail::intersection::intersection_of_multi_linestring_with_areal
|
Chris@102
|
408 <
|
Chris@102
|
409 ReverseMultiPolygon,
|
Chris@102
|
410 GeometryOut,
|
Chris@102
|
411 OverlayType
|
Chris@102
|
412 >
|
Chris@102
|
413 {};
|
Chris@102
|
414
|
Chris@102
|
415
|
Chris@102
|
416 } // namespace dispatch
|
Chris@102
|
417 #endif
|
Chris@102
|
418
|
Chris@102
|
419 }} // namespace boost::geometry
|
Chris@102
|
420
|
Chris@102
|
421
|
Chris@102
|
422 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP
|
Chris@102
|
423
|