1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
5 // This file was modified by Oracle on 2014, 2020.
6 // Modifications copyright (c) 2014-2020, Oracle and/or its affiliates.
8 // Contributed and/or modified by Adam Wulkiewicz, 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_DETAIL_INTERSECTION_MULTI_HPP
15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP
17 #include <type_traits>
19 #include <boost/geometry/core/closure.hpp>
20 #include <boost/geometry/core/geometry_id.hpp>
21 #include <boost/geometry/core/point_order.hpp>
22 #include <boost/geometry/core/tags.hpp>
23 #include <boost/geometry/geometries/concepts/check.hpp>
25 // TODO: those headers probably may be removed
26 #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
27 #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
28 #include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
29 #include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
30 #include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
31 #include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
32 #include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
34 #include <boost/geometry/algorithms/detail/intersection/interface.hpp>
36 #include <boost/geometry/algorithms/covered_by.hpp>
37 #include <boost/geometry/algorithms/envelope.hpp>
38 #include <boost/geometry/algorithms/num_points.hpp>
41 namespace boost { namespace geometry
44 #ifndef DOXYGEN_NO_DETAIL
45 namespace detail { namespace intersection
49 template <typename PointOut>
50 struct intersection_multi_linestring_multi_linestring_point
54 typename MultiLinestring1, typename MultiLinestring2,
55 typename RobustPolicy,
56 typename OutputIterator, typename Strategy
58 static inline OutputIterator apply(MultiLinestring1 const& ml1,
59 MultiLinestring2 const& ml2,
60 RobustPolicy const& robust_policy,
62 Strategy const& strategy)
64 // Note, this loop is quadratic w.r.t. number of linestrings per input.
65 // Future Enhancement: first do the sections of each, then intersect.
66 for (typename boost::range_iterator
68 MultiLinestring1 const
69 >::type it1 = boost::begin(ml1);
70 it1 != boost::end(ml1);
73 for (typename boost::range_iterator
75 MultiLinestring2 const
76 >::type it2 = boost::begin(ml2);
77 it2 != boost::end(ml2);
80 out = intersection_linestring_linestring_point<PointOut>
81 ::apply(*it1, *it2, robust_policy, out, strategy);
90 template <typename PointOut>
91 struct intersection_linestring_multi_linestring_point
95 typename Linestring, typename MultiLinestring,
96 typename RobustPolicy,
97 typename OutputIterator, typename Strategy
99 static inline OutputIterator apply(Linestring const& linestring,
100 MultiLinestring const& ml,
101 RobustPolicy const& robust_policy,
103 Strategy const& strategy)
105 for (typename boost::range_iterator
107 MultiLinestring const
108 >::type it = boost::begin(ml);
109 it != boost::end(ml);
112 out = intersection_linestring_linestring_point<PointOut>
113 ::apply(linestring, *it, robust_policy, out, strategy);
121 // This loop is quite similar to the loop above, but beacuse the iterator
122 // is second (above) or first (below) argument, it is not trivial to merge them.
126 typename LineStringOut,
127 overlay_type OverlayType,
128 bool FollowIsolatedPoints
130 struct intersection_of_multi_linestring_with_areal
134 typename MultiLinestring, typename Areal,
135 typename RobustPolicy,
136 typename OutputIterator, typename Strategy
138 static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal,
139 RobustPolicy const& robust_policy,
141 Strategy const& strategy)
143 for (typename boost::range_iterator
145 MultiLinestring const
146 >::type it = boost::begin(ml);
147 it != boost::end(ml);
150 out = intersection_of_linestring_with_areal
152 ReverseAreal, LineStringOut, OverlayType, FollowIsolatedPoints
153 >::apply(*it, areal, robust_policy, out, strategy);
161 // This one calls the one above with reversed arguments
165 typename LineStringOut,
166 overlay_type OverlayType,
167 bool FollowIsolatedPoints
169 struct intersection_of_areal_with_multi_linestring
173 typename Areal, typename MultiLinestring,
174 typename RobustPolicy,
175 typename OutputIterator, typename Strategy
177 static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml,
178 RobustPolicy const& robust_policy,
180 Strategy const& strategy)
182 return intersection_of_multi_linestring_with_areal
184 ReverseAreal, LineStringOut, OverlayType, FollowIsolatedPoints
185 >::apply(ml, areal, robust_policy, out, strategy);
191 template <typename LinestringOut>
192 struct clip_multi_linestring
196 typename MultiLinestring, typename Box,
197 typename RobustPolicy,
198 typename OutputIterator, typename Strategy
200 static inline OutputIterator apply(MultiLinestring const& multi_linestring,
202 RobustPolicy const& robust_policy,
203 OutputIterator out, Strategy const& )
205 typedef typename point_type<LinestringOut>::type point_type;
206 strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
207 for (typename boost::range_iterator<MultiLinestring const>::type it
208 = boost::begin(multi_linestring);
209 it != boost::end(multi_linestring); ++it)
211 out = detail::intersection::clip_range_with_box
212 <LinestringOut>(box, *it, robust_policy, out, lb_strategy);
219 }} // namespace detail::intersection
220 #endif // DOXYGEN_NO_DETAIL
223 #ifndef DOXYGEN_NO_DISPATCH
231 typename MultiLinestring1, typename MultiLinestring2,
232 typename GeometryOut,
233 overlay_type OverlayType,
234 bool Reverse1, bool Reverse2
236 struct intersection_insert
238 MultiLinestring1, MultiLinestring2,
242 multi_linestring_tag, multi_linestring_tag, point_tag,
243 linear_tag, linear_tag, pointlike_tag
244 > : detail::intersection::intersection_multi_linestring_multi_linestring_point
253 typename Linestring, typename MultiLinestring,
254 typename GeometryOut,
255 overlay_type OverlayType,
256 bool Reverse1, bool Reverse2
258 struct intersection_insert
260 Linestring, MultiLinestring,
264 linestring_tag, multi_linestring_tag, point_tag,
265 linear_tag, linear_tag, pointlike_tag
266 > : detail::intersection::intersection_linestring_multi_linestring_point
275 typename MultiLinestring, typename Box,
276 typename GeometryOut,
277 overlay_type OverlayType,
278 bool Reverse1, bool Reverse2
280 struct intersection_insert
282 MultiLinestring, Box,
286 multi_linestring_tag, box_tag, linestring_tag,
287 linear_tag, areal_tag, linear_tag
288 > : detail::intersection::clip_multi_linestring
297 typename Linestring, typename MultiPolygon,
298 typename GeometryOut,
299 overlay_type OverlayType,
300 bool ReverseLinestring, bool ReverseMultiPolygon
302 struct intersection_insert
304 Linestring, MultiPolygon,
307 ReverseLinestring, ReverseMultiPolygon,
308 linestring_tag, multi_polygon_tag, linestring_tag,
309 linear_tag, areal_tag, linear_tag
310 > : detail::intersection::intersection_of_linestring_with_areal
320 // Derives from areal/mls because runtime arguments are in that order.
321 // areal/mls reverses it itself to mls/areal
324 typename Polygon, typename MultiLinestring,
325 typename GeometryOut,
326 overlay_type OverlayType,
327 bool ReversePolygon, bool ReverseMultiLinestring
329 struct intersection_insert
331 Polygon, MultiLinestring,
334 ReversePolygon, ReverseMultiLinestring,
335 polygon_tag, multi_linestring_tag, linestring_tag,
336 areal_tag, linear_tag, linear_tag
337 > : detail::intersection::intersection_of_areal_with_multi_linestring
349 typename MultiLinestring, typename Ring,
350 typename GeometryOut,
351 overlay_type OverlayType,
352 bool ReverseMultiLinestring, bool ReverseRing
354 struct intersection_insert
356 MultiLinestring, Ring,
359 ReverseMultiLinestring, ReverseRing,
360 multi_linestring_tag, ring_tag, linestring_tag,
361 linear_tag, areal_tag, linear_tag
362 > : detail::intersection::intersection_of_multi_linestring_with_areal
373 typename MultiLinestring, typename Polygon,
374 typename GeometryOut,
375 overlay_type OverlayType,
376 bool ReverseMultiLinestring, bool ReversePolygon
378 struct intersection_insert
380 MultiLinestring, Polygon,
383 ReverseMultiLinestring, ReversePolygon,
384 multi_linestring_tag, polygon_tag, linestring_tag,
385 linear_tag, areal_tag, linear_tag
386 > : detail::intersection::intersection_of_multi_linestring_with_areal
399 typename MultiLinestring, typename MultiPolygon,
400 typename GeometryOut,
401 overlay_type OverlayType,
402 bool ReverseMultiLinestring, bool ReverseMultiPolygon
404 struct intersection_insert
406 MultiLinestring, MultiPolygon,
409 ReverseMultiLinestring, ReverseMultiPolygon,
410 multi_linestring_tag, multi_polygon_tag, linestring_tag,
411 linear_tag, areal_tag, linear_tag
412 > : detail::intersection::intersection_of_multi_linestring_with_areal
425 typename MultiLinestring, typename Ring,
427 overlay_type OverlayType,
428 bool ReverseMultiLinestring, bool ReverseRing
430 struct intersection_insert
432 MultiLinestring, Ring,
435 ReverseMultiLinestring, ReverseRing,
436 multi_linestring_tag, ring_tag, detail::tupled_output_tag,
437 linear_tag, areal_tag, detail::tupled_output_tag
438 > : detail::intersection::intersection_of_multi_linestring_with_areal
445 , detail::expect_output
447 MultiLinestring, Ring, TupledOut,
448 // NOTE: points can be the result only in case of intersection.
449 // TODO: union should require L and A
452 (OverlayType == overlay_intersection),
463 typename MultiLinestring, typename Polygon,
465 overlay_type OverlayType,
466 bool ReverseMultiLinestring, bool ReversePolygon
468 struct intersection_insert
470 MultiLinestring, Polygon,
473 ReverseMultiLinestring, ReversePolygon,
474 multi_linestring_tag, polygon_tag, detail::tupled_output_tag,
475 linear_tag, areal_tag, detail::tupled_output_tag
476 > : detail::intersection::intersection_of_multi_linestring_with_areal
483 , detail::expect_output
485 MultiLinestring, Polygon, TupledOut,
486 // NOTE: points can be the result only in case of intersection.
487 // TODO: union should require L and A
490 (OverlayType == overlay_intersection),
500 typename Polygon, typename MultiLinestring,
502 overlay_type OverlayType,
503 bool ReversePolygon, bool ReverseMultiLinestring
505 struct intersection_insert
507 Polygon, MultiLinestring,
510 ReversePolygon, ReverseMultiLinestring,
511 polygon_tag, multi_linestring_tag, detail::tupled_output_tag,
512 areal_tag, linear_tag, detail::tupled_output_tag
513 > : detail::intersection::intersection_of_areal_with_multi_linestring
520 , detail::expect_output
522 Polygon, MultiLinestring, TupledOut,
523 // NOTE: points can be the result only in case of intersection.
524 // TODO: union should require L and A
525 // TODO: in general the result of difference should depend on the first argument
526 // but this specialization calls L/A in reality so the first argument is linear.
527 // So expect only L for difference?
530 (OverlayType == overlay_intersection),
540 typename MultiLinestring, typename MultiPolygon,
542 overlay_type OverlayType,
543 bool ReverseMultiLinestring, bool ReverseMultiPolygon
545 struct intersection_insert
547 MultiLinestring, MultiPolygon,
550 ReverseMultiLinestring, ReverseMultiPolygon,
551 multi_linestring_tag, multi_polygon_tag, detail::tupled_output_tag,
552 linear_tag, areal_tag, detail::tupled_output_tag
553 > : detail::intersection::intersection_of_multi_linestring_with_areal
560 , detail::expect_output
562 MultiLinestring, MultiPolygon, TupledOut,
563 // NOTE: points can be the result only in case of intersection.
564 // TODO: union should require L and A
567 (OverlayType == overlay_intersection),
576 } // namespace dispatch
579 }} // namespace boost::geometry
582 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP