1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
4
5 // This file was modified by Oracle on 2014, 2015, 2017, 2019, 2020.
6 // Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
7
8 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10
11 // Use, modification and distribution is subject to the Boost Software License,
12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
13 // http://www.boost.org/LICENSE_1_0.txt)
14
15 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
16 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
17
18
19 #include <cstddef>
20
21 #include <boost/mpl/if.hpp>
22 #include <boost/mpl/assert.hpp>
23 #include <boost/range/metafunctions.hpp>
24
25
26 #include <boost/geometry/core/is_areal.hpp>
27 #include <boost/geometry/core/point_order.hpp>
28 #include <boost/geometry/core/reverse_dispatch.hpp>
29 #include <boost/geometry/geometries/concepts/check.hpp>
30 #include <boost/geometry/algorithms/convert.hpp>
31 #include <boost/geometry/algorithms/detail/point_on_border.hpp>
32 #include <boost/geometry/algorithms/detail/overlay/clip_linestring.hpp>
33 #include <boost/geometry/algorithms/detail/overlay/follow.hpp>
34 #include <boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp>
35 #include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
36 #include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
37 #include <boost/geometry/algorithms/detail/overlay/range_in_geometry.hpp>
38 #include <boost/geometry/algorithms/detail/overlay/segment_as_subrange.hpp>
39
40 #include <boost/geometry/policies/robustness/rescale_policy_tags.hpp>
41 #include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
42 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
43
44 #include <boost/geometry/views/segment_view.hpp>
45 #include <boost/geometry/views/detail/boundary_view.hpp>
46
47 #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
48 #include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
49 #include <boost/geometry/algorithms/detail/overlay/pointlike_areal.hpp>
50 #include <boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp>
51 #include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
52
53 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
54 #include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
55 #include <boost/geometry/io/wkt/wkt.hpp>
56 #endif
57
58 namespace boost { namespace geometry
59 {
60
61 #ifndef DOXYGEN_NO_DETAIL
62 namespace detail { namespace intersection
63 {
64
65 template <typename PointOut>
66 struct intersection_segment_segment_point
67 {
68 template
69 <
70 typename Segment1, typename Segment2,
71 typename RobustPolicy,
72 typename OutputIterator, typename Strategy
73 >
applyboost::geometry::detail::intersection::intersection_segment_segment_point74 static inline OutputIterator apply(Segment1 const& segment1,
75 Segment2 const& segment2,
76 RobustPolicy const& ,
77 OutputIterator out,
78 Strategy const& strategy)
79 {
80 // Make sure this is only called with no rescaling
81 BOOST_STATIC_ASSERT((boost::is_same
82 <
83 no_rescale_policy_tag,
84 typename rescale_policy_type<RobustPolicy>::type
85 >::value));
86
87 typedef typename point_type<PointOut>::type point_type;
88
89 // Get the intersection point (or two points)
90 typedef segment_intersection_points<point_type> intersection_return_type;
91
92 typedef policies::relate::segments_intersection_points
93 <
94 intersection_return_type
95 > policy_type;
96
97 detail::segment_as_subrange<Segment1> sub_range1(segment1);
98 detail::segment_as_subrange<Segment2> sub_range2(segment2);
99
100 intersection_return_type
101 is = strategy.apply(sub_range1, sub_range2, policy_type());
102
103 for (std::size_t i = 0; i < is.count; i++)
104 {
105 PointOut p;
106 geometry::convert(is.intersections[i], p);
107 *out++ = p;
108 }
109 return out;
110 }
111 };
112
113 template <typename PointOut>
114 struct intersection_linestring_linestring_point
115 {
116 template
117 <
118 typename Linestring1, typename Linestring2,
119 typename RobustPolicy,
120 typename OutputIterator,
121 typename Strategy
122 >
applyboost::geometry::detail::intersection::intersection_linestring_linestring_point123 static inline OutputIterator apply(Linestring1 const& linestring1,
124 Linestring2 const& linestring2,
125 RobustPolicy const& robust_policy,
126 OutputIterator out,
127 Strategy const& strategy)
128 {
129 // Make sure this is only called with no rescaling
130 BOOST_STATIC_ASSERT((boost::is_same
131 <
132 no_rescale_policy_tag,
133 typename rescale_policy_type<RobustPolicy>::type
134 >::value));
135
136 typedef detail::overlay::turn_info<PointOut> turn_info;
137 std::deque<turn_info> turns;
138
139 geometry::get_intersection_points(linestring1, linestring2,
140 robust_policy, turns, strategy);
141
142 for (typename boost::range_iterator<std::deque<turn_info> const>::type
143 it = boost::begin(turns); it != boost::end(turns); ++it)
144 {
145 PointOut p;
146 geometry::convert(it->point, p);
147 *out++ = p;
148 }
149 return out;
150 }
151 };
152
153 /*!
154 \brief Version of linestring with an areal feature (polygon or multipolygon)
155 */
156 template
157 <
158 bool ReverseAreal,
159 typename GeometryOut,
160 overlay_type OverlayType,
161 bool FollowIsolatedPoints
162 >
163 struct intersection_of_linestring_with_areal
164 {
165 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
166 template <typename Turn, typename Operation>
debug_followboost::geometry::detail::intersection::intersection_of_linestring_with_areal167 static inline void debug_follow(Turn const& turn, Operation op,
168 int index)
169 {
170 std::cout << index
171 << " at " << op.seg_id
172 << " meth: " << method_char(turn.method)
173 << " op: " << operation_char(op.operation)
174 << " vis: " << visited_char(op.visited)
175 << " of: " << operation_char(turn.operations[0].operation)
176 << operation_char(turn.operations[1].operation)
177 << " " << geometry::wkt(turn.point)
178 << std::endl;
179 }
180
181 template <typename Turn>
debug_turnboost::geometry::detail::intersection::intersection_of_linestring_with_areal182 static inline void debug_turn(Turn const& t, bool non_crossing)
183 {
184 std::cout << "checking turn @"
185 << geometry::wkt(t.point)
186 << "; " << method_char(t.method)
187 << ":" << operation_char(t.operations[0].operation)
188 << "/" << operation_char(t.operations[1].operation)
189 << "; non-crossing? "
190 << std::boolalpha << non_crossing << std::noboolalpha
191 << std::endl;
192 }
193 #endif
194
195 template <typename Linestring, typename Areal, typename Strategy, typename Turns>
simple_turns_analysisboost::geometry::detail::intersection::intersection_of_linestring_with_areal196 static inline bool simple_turns_analysis(Linestring const& linestring,
197 Areal const& areal,
198 Strategy const& strategy,
199 Turns const& turns,
200 int & inside_value)
201 {
202 using namespace overlay;
203
204 bool found_continue = false;
205 bool found_intersection = false;
206 bool found_union = false;
207 bool found_front = false;
208
209 for (typename Turns::const_iterator it = turns.begin();
210 it != turns.end(); ++it)
211 {
212 method_type const method = it->method;
213 operation_type const op = it->operations[0].operation;
214
215 if (method == method_crosses)
216 {
217 return false;
218 }
219 else if (op == operation_intersection)
220 {
221 found_intersection = true;
222 }
223 else if (op == operation_union)
224 {
225 found_union = true;
226 }
227 else if (op == operation_continue)
228 {
229 found_continue = true;
230 }
231
232 if ((found_intersection || found_continue) && found_union)
233 {
234 return false;
235 }
236
237 if (it->operations[0].position == position_front)
238 {
239 found_front = true;
240 }
241 }
242
243 if (found_front)
244 {
245 if (found_intersection)
246 {
247 inside_value = 1; // inside
248 }
249 else if (found_union)
250 {
251 inside_value = -1; // outside
252 }
253 else // continue and blocked
254 {
255 inside_value = 0;
256 }
257 return true;
258 }
259
260 // if needed analyse points of a linestring
261 // NOTE: range_in_geometry checks points of a linestring
262 // until a point inside/outside areal is found
263 // TODO: Could be replaced with point_in_geometry() because found_front is false
264 inside_value = range_in_geometry(linestring, areal, strategy);
265
266 if ( (found_intersection && inside_value == -1) // going in from outside
267 || (found_continue && inside_value == -1) // going on boundary from outside
268 || (found_union && inside_value == 1) ) // going out from inside
269 {
270 return false;
271 }
272
273 return true;
274 }
275
276 template
277 <
278 typename LineString, typename Areal,
279 typename RobustPolicy,
280 typename OutputIterator, typename Strategy
281 >
applyboost::geometry::detail::intersection::intersection_of_linestring_with_areal282 static inline OutputIterator apply(LineString const& linestring, Areal const& areal,
283 RobustPolicy const& robust_policy,
284 OutputIterator out,
285 Strategy const& strategy)
286 {
287 // Make sure this is only called with no rescaling
288 BOOST_STATIC_ASSERT((boost::is_same
289 <
290 no_rescale_policy_tag,
291 typename rescale_policy_type<RobustPolicy>::type
292 >::value));
293
294 if (boost::size(linestring) == 0)
295 {
296 return out;
297 }
298
299 typedef detail::overlay::follow
300 <
301 GeometryOut,
302 LineString,
303 Areal,
304 OverlayType,
305 false, // do not remove spikes for linear geometries
306 FollowIsolatedPoints
307 > follower;
308
309 typedef typename geometry::detail::output_geometry_access
310 <
311 GeometryOut, linestring_tag, linestring_tag
312 > linear;
313
314 typedef typename point_type
315 <
316 typename linear::type
317 >::type point_type;
318
319 typedef geometry::segment_ratio
320 <
321 typename coordinate_type<point_type>::type
322 > ratio_type;
323
324 typedef detail::overlay::turn_info
325 <
326 point_type,
327 ratio_type,
328 detail::overlay::turn_operation_linear
329 <
330 point_type,
331 ratio_type
332 >
333 > turn_info;
334
335 std::deque<turn_info> turns;
336
337 detail::get_turns::no_interrupt_policy policy;
338
339 typedef detail::overlay::get_turn_info_linear_areal
340 <
341 detail::overlay::assign_null_policy
342 > turn_policy;
343
344 dispatch::get_turns
345 <
346 typename geometry::tag<LineString>::type,
347 typename geometry::tag<Areal>::type,
348 LineString,
349 Areal,
350 false,
351 (OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal),
352 turn_policy
353 >::apply(0, linestring, 1, areal,
354 strategy, robust_policy,
355 turns, policy);
356
357 int inside_value = 0;
358 if (simple_turns_analysis(linestring, areal, strategy, turns, inside_value))
359 {
360 // No crossing the boundary, it is either
361 // inside (interior + borders)
362 // or outside (exterior + borders)
363 // or on boundary
364
365 // add linestring to the output if conditions are met
366 if (follower::included(inside_value))
367 {
368 typename linear::type copy;
369 geometry::convert(linestring, copy);
370 *linear::get(out)++ = copy;
371 }
372
373 return out;
374 }
375
376 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
377 int index = 0;
378 for(typename std::deque<turn_info>::const_iterator
379 it = turns.begin(); it != turns.end(); ++it)
380 {
381 debug_follow(*it, it->operations[0], index++);
382 }
383 #endif
384
385 return follower::apply
386 (
387 linestring, areal,
388 geometry::detail::overlay::operation_intersection,
389 turns, robust_policy, out, strategy
390 );
391 }
392 };
393
394
395 template <typename Turns, typename OutputIterator>
intersection_output_turn_points(Turns const & turns,OutputIterator out)396 inline OutputIterator intersection_output_turn_points(Turns const& turns,
397 OutputIterator out)
398 {
399 for (typename Turns::const_iterator
400 it = turns.begin(); it != turns.end(); ++it)
401 {
402 *out++ = it->point;
403 }
404
405 return out;
406 }
407
408 template <typename PointOut>
409 struct intersection_areal_areal_point
410 {
411 template
412 <
413 typename Geometry1, typename Geometry2,
414 typename RobustPolicy,
415 typename OutputIterator,
416 typename Strategy
417 >
applyboost::geometry::detail::intersection::intersection_areal_areal_point418 static inline OutputIterator apply(Geometry1 const& geometry1,
419 Geometry2 const& geometry2,
420 RobustPolicy const& robust_policy,
421 OutputIterator out,
422 Strategy const& strategy)
423 {
424 typedef detail::overlay::turn_info
425 <
426 PointOut,
427 typename segment_ratio_type<PointOut, RobustPolicy>::type
428 > turn_info;
429 std::vector<turn_info> turns;
430
431 detail::get_turns::no_interrupt_policy policy;
432
433 geometry::get_turns
434 <
435 false, false, detail::overlay::assign_null_policy
436 >(geometry1, geometry2, strategy, robust_policy, turns, policy);
437
438 return intersection_output_turn_points(turns, out);
439 }
440 };
441
442 template <typename PointOut>
443 struct intersection_linear_areal_point
444 {
445 template
446 <
447 typename Geometry1, typename Geometry2,
448 typename RobustPolicy,
449 typename OutputIterator,
450 typename Strategy
451 >
applyboost::geometry::detail::intersection::intersection_linear_areal_point452 static inline OutputIterator apply(Geometry1 const& geometry1,
453 Geometry2 const& geometry2,
454 RobustPolicy const& robust_policy,
455 OutputIterator out,
456 Strategy const& strategy)
457 {
458 // Make sure this is only called with no rescaling
459 BOOST_STATIC_ASSERT((boost::is_same
460 <
461 no_rescale_policy_tag,
462 typename rescale_policy_type<RobustPolicy>::type
463 >::value));
464
465 typedef geometry::segment_ratio<typename geometry::coordinate_type<PointOut>::type> ratio_type;
466
467 typedef detail::overlay::turn_info
468 <
469 PointOut,
470 ratio_type,
471 detail::overlay::turn_operation_linear
472 <
473 PointOut,
474 ratio_type
475 >
476 > turn_info;
477
478 typedef detail::overlay::get_turn_info_linear_areal
479 <
480 detail::overlay::assign_null_policy
481 > turn_policy;
482
483 std::vector<turn_info> turns;
484
485 detail::get_turns::no_interrupt_policy interrupt_policy;
486
487 dispatch::get_turns
488 <
489 typename geometry::tag<Geometry1>::type,
490 typename geometry::tag<Geometry2>::type,
491 Geometry1,
492 Geometry2,
493 false,
494 false,
495 turn_policy
496 >::apply(0, geometry1, 1, geometry2,
497 strategy, robust_policy,
498 turns, interrupt_policy);
499
500 return intersection_output_turn_points(turns, out);
501 }
502 };
503
504 template <typename PointOut>
505 struct intersection_areal_linear_point
506 {
507 template
508 <
509 typename Geometry1, typename Geometry2,
510 typename RobustPolicy,
511 typename OutputIterator,
512 typename Strategy
513 >
applyboost::geometry::detail::intersection::intersection_areal_linear_point514 static inline OutputIterator apply(Geometry1 const& geometry1,
515 Geometry2 const& geometry2,
516 RobustPolicy const& robust_policy,
517 OutputIterator out,
518 Strategy const& strategy)
519 {
520 return intersection_linear_areal_point
521 <
522 PointOut
523 >::apply(geometry2, geometry1, robust_policy, out, strategy);
524 }
525 };
526
527
528 }} // namespace detail::intersection
529 #endif // DOXYGEN_NO_DETAIL
530
531
532
533 #ifndef DOXYGEN_NO_DISPATCH
534 namespace dispatch
535 {
536
537 template
538 <
539 // real types
540 typename Geometry1,
541 typename Geometry2,
542 typename GeometryOut,
543 overlay_type OverlayType,
544 // orientation
545 bool Reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
546 bool Reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
547 // tag dispatching:
548 typename TagIn1 = typename geometry::tag<Geometry1>::type,
549 typename TagIn2 = typename geometry::tag<Geometry2>::type,
550 typename TagOut = typename detail::setop_insert_output_tag<GeometryOut>::type,
551 // metafunction finetuning helpers:
552 typename CastedTagIn1 = typename geometry::tag_cast<TagIn1, areal_tag, linear_tag, pointlike_tag>::type,
553 typename CastedTagIn2 = typename geometry::tag_cast<TagIn2, areal_tag, linear_tag, pointlike_tag>::type,
554 typename CastedTagOut = typename geometry::tag_cast<TagOut, areal_tag, linear_tag, pointlike_tag>::type
555 >
556 struct intersection_insert
557 {
558 BOOST_MPL_ASSERT_MSG
559 (
560 false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPES_OR_ORIENTATIONS
561 , (types<Geometry1, Geometry2, GeometryOut>)
562 );
563 };
564
565
566 template
567 <
568 typename Geometry1, typename Geometry2,
569 typename GeometryOut,
570 overlay_type OverlayType,
571 bool Reverse1, bool Reverse2,
572 typename TagIn1, typename TagIn2, typename TagOut
573 >
574 struct intersection_insert
575 <
576 Geometry1, Geometry2,
577 GeometryOut,
578 OverlayType,
579 Reverse1, Reverse2,
580 TagIn1, TagIn2, TagOut,
581 areal_tag, areal_tag, areal_tag
582 > : detail::overlay::overlay
583 <
584 Geometry1, Geometry2, Reverse1, Reverse2,
585 detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
586 GeometryOut, OverlayType
587 >
588 {};
589
590
591 // Any areal type with box:
592 template
593 <
594 typename Geometry, typename Box,
595 typename GeometryOut,
596 overlay_type OverlayType,
597 bool Reverse1, bool Reverse2,
598 typename TagIn, typename TagOut
599 >
600 struct intersection_insert
601 <
602 Geometry, Box,
603 GeometryOut,
604 OverlayType,
605 Reverse1, Reverse2,
606 TagIn, box_tag, TagOut,
607 areal_tag, areal_tag, areal_tag
608 > : detail::overlay::overlay
609 <
610 Geometry, Box, Reverse1, Reverse2,
611 detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
612 GeometryOut, OverlayType
613 >
614 {};
615
616
617 template
618 <
619 typename Segment1, typename Segment2,
620 typename GeometryOut,
621 overlay_type OverlayType,
622 bool Reverse1, bool Reverse2
623 >
624 struct intersection_insert
625 <
626 Segment1, Segment2,
627 GeometryOut,
628 OverlayType,
629 Reverse1, Reverse2,
630 segment_tag, segment_tag, point_tag,
631 linear_tag, linear_tag, pointlike_tag
632 > : detail::intersection::intersection_segment_segment_point<GeometryOut>
633 {};
634
635
636 template
637 <
638 typename Linestring1, typename Linestring2,
639 typename GeometryOut,
640 overlay_type OverlayType,
641 bool Reverse1, bool Reverse2
642 >
643 struct intersection_insert
644 <
645 Linestring1, Linestring2,
646 GeometryOut,
647 OverlayType,
648 Reverse1, Reverse2,
649 linestring_tag, linestring_tag, point_tag,
650 linear_tag, linear_tag, pointlike_tag
651 > : detail::intersection::intersection_linestring_linestring_point<GeometryOut>
652 {};
653
654
655 template
656 <
657 typename Linestring, typename Box,
658 typename GeometryOut,
659 bool Reverse1, bool Reverse2
660 >
661 struct intersection_insert
662 <
663 Linestring, Box,
664 GeometryOut,
665 overlay_intersection,
666 Reverse1, Reverse2,
667 linestring_tag, box_tag, linestring_tag,
668 linear_tag, areal_tag, linear_tag
669 >
670 {
671 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
applyboost::geometry::dispatch::intersection_insert672 static inline OutputIterator apply(Linestring const& linestring,
673 Box const& box,
674 RobustPolicy const& robust_policy,
675 OutputIterator out, Strategy const& )
676 {
677 typedef typename point_type<GeometryOut>::type point_type;
678 strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
679 return detail::intersection::clip_range_with_box
680 <GeometryOut>(box, linestring, robust_policy, out, lb_strategy);
681 }
682 };
683
684
685 template
686 <
687 typename Linestring, typename Polygon,
688 typename GeometryOut,
689 overlay_type OverlayType,
690 bool ReverseLinestring, bool ReversePolygon
691 >
692 struct intersection_insert
693 <
694 Linestring, Polygon,
695 GeometryOut,
696 OverlayType,
697 ReverseLinestring, ReversePolygon,
698 linestring_tag, polygon_tag, linestring_tag,
699 linear_tag, areal_tag, linear_tag
700 > : detail::intersection::intersection_of_linestring_with_areal
701 <
702 ReversePolygon,
703 GeometryOut,
704 OverlayType,
705 false
706 >
707 {};
708
709
710 template
711 <
712 typename Linestring, typename Ring,
713 typename GeometryOut,
714 overlay_type OverlayType,
715 bool ReverseLinestring, bool ReverseRing
716 >
717 struct intersection_insert
718 <
719 Linestring, Ring,
720 GeometryOut,
721 OverlayType,
722 ReverseLinestring, ReverseRing,
723 linestring_tag, ring_tag, linestring_tag,
724 linear_tag, areal_tag, linear_tag
725 > : detail::intersection::intersection_of_linestring_with_areal
726 <
727 ReverseRing,
728 GeometryOut,
729 OverlayType,
730 false
731 >
732 {};
733
734 template
735 <
736 typename Segment, typename Box,
737 typename GeometryOut,
738 overlay_type OverlayType,
739 bool Reverse1, bool Reverse2
740 >
741 struct intersection_insert
742 <
743 Segment, Box,
744 GeometryOut,
745 OverlayType,
746 Reverse1, Reverse2,
747 segment_tag, box_tag, linestring_tag,
748 linear_tag, areal_tag, linear_tag
749 >
750 {
751 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
applyboost::geometry::dispatch::intersection_insert752 static inline OutputIterator apply(Segment const& segment,
753 Box const& box,
754 RobustPolicy const& robust_policy,
755 OutputIterator out, Strategy const& )
756 {
757 geometry::segment_view<Segment> range(segment);
758
759 typedef typename point_type<GeometryOut>::type point_type;
760 strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
761 return detail::intersection::clip_range_with_box
762 <GeometryOut>(box, range, robust_policy, out, lb_strategy);
763 }
764 };
765
766 template
767 <
768 typename Geometry1, typename Geometry2,
769 typename PointOut,
770 overlay_type OverlayType,
771 bool Reverse1, bool Reverse2,
772 typename Tag1, typename Tag2
773 >
774 struct intersection_insert
775 <
776 Geometry1, Geometry2,
777 PointOut,
778 OverlayType,
779 Reverse1, Reverse2,
780 Tag1, Tag2, point_tag,
781 areal_tag, areal_tag, pointlike_tag
782 >
783 : public detail::intersection::intersection_areal_areal_point
784 <
785 PointOut
786 >
787 {};
788
789 template
790 <
791 typename Geometry1, typename Geometry2,
792 typename PointOut,
793 overlay_type OverlayType,
794 bool Reverse1, bool Reverse2,
795 typename Tag1, typename Tag2
796 >
797 struct intersection_insert
798 <
799 Geometry1, Geometry2,
800 PointOut,
801 OverlayType,
802 Reverse1, Reverse2,
803 Tag1, Tag2, point_tag,
804 linear_tag, areal_tag, pointlike_tag
805 >
806 : public detail::intersection::intersection_linear_areal_point
807 <
808 PointOut
809 >
810 {};
811
812 template
813 <
814 typename Geometry1, typename Geometry2,
815 typename PointOut,
816 overlay_type OverlayType,
817 bool Reverse1, bool Reverse2,
818 typename Tag1, typename Tag2
819 >
820 struct intersection_insert
821 <
822 Geometry1, Geometry2,
823 PointOut,
824 OverlayType,
825 Reverse1, Reverse2,
826 Tag1, Tag2, point_tag,
827 areal_tag, linear_tag, pointlike_tag
828 >
829 : public detail::intersection::intersection_areal_linear_point
830 <
831 PointOut
832 >
833 {};
834
835 template
836 <
837 typename Geometry1, typename Geometry2, typename GeometryOut,
838 overlay_type OverlayType,
839 bool Reverse1, bool Reverse2
840 >
841 struct intersection_insert_reversed
842 {
843 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
applyboost::geometry::dispatch::intersection_insert_reversed844 static inline OutputIterator apply(Geometry1 const& g1,
845 Geometry2 const& g2,
846 RobustPolicy const& robust_policy,
847 OutputIterator out,
848 Strategy const& strategy)
849 {
850 return intersection_insert
851 <
852 Geometry2, Geometry1, GeometryOut,
853 OverlayType,
854 Reverse2, Reverse1
855 >::apply(g2, g1, robust_policy, out, strategy);
856 }
857 };
858
859
860 // dispatch for intersection(areal, areal, linear)
861 template
862 <
863 typename Geometry1, typename Geometry2,
864 typename LinestringOut,
865 bool Reverse1, bool Reverse2,
866 typename Tag1, typename Tag2
867 >
868 struct intersection_insert
869 <
870 Geometry1, Geometry2,
871 LinestringOut,
872 overlay_intersection,
873 Reverse1, Reverse2,
874 Tag1, Tag2, linestring_tag,
875 areal_tag, areal_tag, linear_tag
876 >
877 {
878 template
879 <
880 typename RobustPolicy, typename OutputIterator, typename Strategy
881 >
applyboost::geometry::dispatch::intersection_insert882 static inline OutputIterator apply(Geometry1 const& geometry1,
883 Geometry2 const& geometry2,
884 RobustPolicy const& robust_policy,
885 OutputIterator oit,
886 Strategy const& strategy)
887 {
888 detail::boundary_view<Geometry1 const> view1(geometry1);
889 detail::boundary_view<Geometry2 const> view2(geometry2);
890
891 return detail::overlay::linear_linear_linestring
892 <
893 detail::boundary_view<Geometry1 const>,
894 detail::boundary_view<Geometry2 const>,
895 LinestringOut,
896 overlay_intersection
897 >::apply(view1, view2, robust_policy, oit, strategy);
898 }
899 };
900
901 // dispatch for difference/intersection of linear geometries
902 template
903 <
904 typename Linear1, typename Linear2, typename LineStringOut,
905 overlay_type OverlayType,
906 bool Reverse1, bool Reverse2,
907 typename TagIn1, typename TagIn2
908 >
909 struct intersection_insert
910 <
911 Linear1, Linear2, LineStringOut, OverlayType,
912 Reverse1, Reverse2,
913 TagIn1, TagIn2, linestring_tag,
914 linear_tag, linear_tag, linear_tag
915 > : detail::overlay::linear_linear_linestring
916 <
917 Linear1, Linear2, LineStringOut, OverlayType
918 >
919 {};
920
921 template
922 <
923 typename Linear1, typename Linear2, typename TupledOut,
924 overlay_type OverlayType,
925 bool Reverse1, bool Reverse2,
926 typename TagIn1, typename TagIn2
927 >
928 struct intersection_insert
929 <
930 Linear1, Linear2, TupledOut, OverlayType,
931 Reverse1, Reverse2,
932 TagIn1, TagIn2, detail::tupled_output_tag,
933 linear_tag, linear_tag, detail::tupled_output_tag
934 >
935 : detail::expect_output
936 <
937 Linear1, Linear2, TupledOut,
938 // NOTE: points can be the result only in case of intersection.
939 typename boost::mpl::if_c
940 <
941 (OverlayType == overlay_intersection),
942 point_tag,
943 void
944 >::type,
945 linestring_tag
946 >
947 {
948 // NOTE: The order of geometries in TupledOut tuple/pair must correspond to the order
949 // iterators in OutputIterators tuple/pair.
950 template
951 <
952 typename RobustPolicy, typename OutputIterators, typename Strategy
953 >
applyboost::geometry::dispatch::intersection_insert954 static inline OutputIterators apply(Linear1 const& linear1,
955 Linear2 const& linear2,
956 RobustPolicy const& robust_policy,
957 OutputIterators oit,
958 Strategy const& strategy)
959 {
960 return detail::overlay::linear_linear_linestring
961 <
962 Linear1, Linear2, TupledOut, OverlayType
963 >::apply(linear1, linear2, robust_policy, oit, strategy);
964 }
965 };
966
967
968 // dispatch for difference/intersection of point-like geometries
969
970 template
971 <
972 typename Point1, typename Point2, typename PointOut,
973 overlay_type OverlayType,
974 bool Reverse1, bool Reverse2
975 >
976 struct intersection_insert
977 <
978 Point1, Point2, PointOut, OverlayType,
979 Reverse1, Reverse2,
980 point_tag, point_tag, point_tag,
981 pointlike_tag, pointlike_tag, pointlike_tag
982 > : detail::overlay::point_point_point
983 <
984 Point1, Point2, PointOut, OverlayType
985 >
986 {};
987
988
989 template
990 <
991 typename MultiPoint, typename Point, typename PointOut,
992 overlay_type OverlayType,
993 bool Reverse1, bool Reverse2
994 >
995 struct intersection_insert
996 <
997 MultiPoint, Point, PointOut, OverlayType,
998 Reverse1, Reverse2,
999 multi_point_tag, point_tag, point_tag,
1000 pointlike_tag, pointlike_tag, pointlike_tag
1001 > : detail::overlay::multipoint_point_point
1002 <
1003 MultiPoint, Point, PointOut, OverlayType
1004 >
1005 {};
1006
1007
1008 template
1009 <
1010 typename Point, typename MultiPoint, typename PointOut,
1011 overlay_type OverlayType,
1012 bool Reverse1, bool Reverse2
1013 >
1014 struct intersection_insert
1015 <
1016 Point, MultiPoint, PointOut, OverlayType,
1017 Reverse1, Reverse2,
1018 point_tag, multi_point_tag, point_tag,
1019 pointlike_tag, pointlike_tag, pointlike_tag
1020 > : detail::overlay::point_multipoint_point
1021 <
1022 Point, MultiPoint, PointOut, OverlayType
1023 >
1024 {};
1025
1026
1027 template
1028 <
1029 typename MultiPoint1, typename MultiPoint2, typename PointOut,
1030 overlay_type OverlayType,
1031 bool Reverse1, bool Reverse2
1032 >
1033 struct intersection_insert
1034 <
1035 MultiPoint1, MultiPoint2, PointOut, OverlayType,
1036 Reverse1, Reverse2,
1037 multi_point_tag, multi_point_tag, point_tag,
1038 pointlike_tag, pointlike_tag, pointlike_tag
1039 > : detail::overlay::multipoint_multipoint_point
1040 <
1041 MultiPoint1, MultiPoint2, PointOut, OverlayType
1042 >
1043 {};
1044
1045
1046 template
1047 <
1048 typename PointLike1, typename PointLike2, typename TupledOut,
1049 overlay_type OverlayType,
1050 bool Reverse1, bool Reverse2,
1051 typename TagIn1, typename TagIn2
1052 >
1053 struct intersection_insert
1054 <
1055 PointLike1, PointLike2, TupledOut, OverlayType,
1056 Reverse1, Reverse2,
1057 TagIn1, TagIn2, detail::tupled_output_tag,
1058 pointlike_tag, pointlike_tag, detail::tupled_output_tag
1059 >
1060 : detail::expect_output<PointLike1, PointLike2, TupledOut, point_tag>
1061 {
1062 // NOTE: The order of geometries in TupledOut tuple/pair must correspond to the order
1063 // of iterators in OutputIterators tuple/pair.
1064 template
1065 <
1066 typename RobustPolicy, typename OutputIterators, typename Strategy
1067 >
applyboost::geometry::dispatch::intersection_insert1068 static inline OutputIterators apply(PointLike1 const& pointlike1,
1069 PointLike2 const& pointlike2,
1070 RobustPolicy const& robust_policy,
1071 OutputIterators oits,
1072 Strategy const& strategy)
1073 {
1074 namespace bgt = boost::geometry::tuples;
1075
1076 static const bool out_point_index = bgt::find_index_if
1077 <
1078 TupledOut, geometry::detail::is_tag_same_as_pred<point_tag>::template pred
1079 >::value;
1080
1081 bgt::get<out_point_index>(oits) = intersection_insert
1082 <
1083 PointLike1, PointLike2,
1084 typename bgt::element
1085 <
1086 out_point_index, TupledOut
1087 >::type,
1088 OverlayType
1089 >::apply(pointlike1, pointlike2, robust_policy,
1090 bgt::get<out_point_index>(oits),
1091 strategy);
1092
1093 return oits;
1094 }
1095 };
1096
1097
1098 // dispatch for difference/intersection of pointlike-linear geometries
1099 template
1100 <
1101 typename Point, typename Linear, typename PointOut,
1102 overlay_type OverlayType,
1103 bool Reverse1, bool Reverse2,
1104 typename Tag
1105 >
1106 struct intersection_insert
1107 <
1108 Point, Linear, PointOut, OverlayType,
1109 Reverse1, Reverse2,
1110 point_tag, Tag, point_tag,
1111 pointlike_tag, linear_tag, pointlike_tag
1112 > : detail_dispatch::overlay::pointlike_linear_point
1113 <
1114 Point, Linear, PointOut, OverlayType,
1115 point_tag, typename tag_cast<Tag, segment_tag, linear_tag>::type
1116 >
1117 {};
1118
1119
1120 template
1121 <
1122 typename MultiPoint, typename Linear, typename PointOut,
1123 overlay_type OverlayType,
1124 bool Reverse1, bool Reverse2,
1125 typename Tag
1126 >
1127 struct intersection_insert
1128 <
1129 MultiPoint, Linear, PointOut, OverlayType,
1130 Reverse1, Reverse2,
1131 multi_point_tag, Tag, point_tag,
1132 pointlike_tag, linear_tag, pointlike_tag
1133 > : detail_dispatch::overlay::pointlike_linear_point
1134 <
1135 MultiPoint, Linear, PointOut, OverlayType,
1136 multi_point_tag,
1137 typename tag_cast<Tag, segment_tag, linear_tag>::type
1138 >
1139 {};
1140
1141
1142 // This specialization is needed because intersection() reverses the arguments
1143 // for MultiPoint/Linestring combination.
1144 template
1145 <
1146 typename Linestring, typename MultiPoint, typename PointOut,
1147 bool Reverse1, bool Reverse2
1148 >
1149 struct intersection_insert
1150 <
1151 Linestring, MultiPoint, PointOut, overlay_intersection,
1152 Reverse1, Reverse2,
1153 linestring_tag, multi_point_tag, point_tag,
1154 linear_tag, pointlike_tag, pointlike_tag
1155 >
1156 {
1157 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
applyboost::geometry::dispatch::intersection_insert1158 static inline OutputIterator apply(Linestring const& linestring,
1159 MultiPoint const& multipoint,
1160 RobustPolicy const& robust_policy,
1161 OutputIterator out,
1162 Strategy const& strategy)
1163 {
1164 return detail_dispatch::overlay::pointlike_linear_point
1165 <
1166 MultiPoint, Linestring, PointOut, overlay_intersection,
1167 multi_point_tag, linear_tag
1168 >::apply(multipoint, linestring, robust_policy, out, strategy);
1169 }
1170 };
1171
1172
1173 template
1174 <
1175 typename PointLike, typename Linear, typename TupledOut,
1176 overlay_type OverlayType,
1177 bool Reverse1, bool Reverse2,
1178 typename TagIn1, typename TagIn2
1179 >
1180 struct intersection_insert
1181 <
1182 PointLike, Linear, TupledOut, OverlayType,
1183 Reverse1, Reverse2,
1184 TagIn1, TagIn2, detail::tupled_output_tag,
1185 pointlike_tag, linear_tag, detail::tupled_output_tag
1186 >
1187 // Reuse the implementation for PointLike/PointLike.
1188 : intersection_insert
1189 <
1190 PointLike, Linear, TupledOut, OverlayType,
1191 Reverse1, Reverse2,
1192 TagIn1, TagIn2, detail::tupled_output_tag,
1193 pointlike_tag, pointlike_tag, detail::tupled_output_tag
1194 >
1195 {};
1196
1197
1198 // This specialization is needed because intersection() reverses the arguments
1199 // for MultiPoint/Linestring combination.
1200 template
1201 <
1202 typename Linestring, typename MultiPoint, typename TupledOut,
1203 bool Reverse1, bool Reverse2
1204 >
1205 struct intersection_insert
1206 <
1207 Linestring, MultiPoint, TupledOut, overlay_intersection,
1208 Reverse1, Reverse2,
1209 linestring_tag, multi_point_tag, detail::tupled_output_tag,
1210 linear_tag, pointlike_tag, detail::tupled_output_tag
1211 >
1212 {
1213 template <typename RobustPolicy, typename OutputIterators, typename Strategy>
applyboost::geometry::dispatch::intersection_insert1214 static inline OutputIterators apply(Linestring const& linestring,
1215 MultiPoint const& multipoint,
1216 RobustPolicy const& robust_policy,
1217 OutputIterators out,
1218 Strategy const& strategy)
1219 {
1220 return intersection_insert
1221 <
1222 MultiPoint, Linestring, TupledOut, overlay_intersection
1223 >::apply(multipoint, linestring, robust_policy, out, strategy);
1224 }
1225 };
1226
1227
1228 // dispatch for difference/intersection of pointlike-areal geometries
1229 template
1230 <
1231 typename Point, typename Areal, typename PointOut,
1232 overlay_type OverlayType,
1233 bool Reverse1, bool Reverse2,
1234 typename ArealTag
1235 >
1236 struct intersection_insert
1237 <
1238 Point, Areal, PointOut, OverlayType,
1239 Reverse1, Reverse2,
1240 point_tag, ArealTag, point_tag,
1241 pointlike_tag, areal_tag, pointlike_tag
1242 > : detail_dispatch::overlay::pointlike_areal_point
1243 <
1244 Point, Areal, PointOut, OverlayType,
1245 point_tag, ArealTag
1246 >
1247 {};
1248
1249 template
1250 <
1251 typename MultiPoint, typename Areal, typename PointOut,
1252 overlay_type OverlayType,
1253 bool Reverse1, bool Reverse2,
1254 typename ArealTag
1255 >
1256 struct intersection_insert
1257 <
1258 MultiPoint, Areal, PointOut, OverlayType,
1259 Reverse1, Reverse2,
1260 multi_point_tag, ArealTag, point_tag,
1261 pointlike_tag, areal_tag, pointlike_tag
1262 > : detail_dispatch::overlay::pointlike_areal_point
1263 <
1264 MultiPoint, Areal, PointOut, OverlayType,
1265 multi_point_tag, ArealTag
1266 >
1267 {};
1268
1269 // This specialization is needed because intersection() reverses the arguments
1270 // for MultiPoint/Ring and MultiPoint/Polygon combinations.
1271 template
1272 <
1273 typename Areal, typename MultiPoint, typename PointOut,
1274 bool Reverse1, bool Reverse2,
1275 typename ArealTag
1276 >
1277 struct intersection_insert
1278 <
1279 Areal, MultiPoint, PointOut, overlay_intersection,
1280 Reverse1, Reverse2,
1281 ArealTag, multi_point_tag, point_tag,
1282 areal_tag, pointlike_tag, pointlike_tag
1283 >
1284 {
1285 template <typename RobustPolicy, typename OutputIterator, typename Strategy>
applyboost::geometry::dispatch::intersection_insert1286 static inline OutputIterator apply(Areal const& areal,
1287 MultiPoint const& multipoint,
1288 RobustPolicy const& robust_policy,
1289 OutputIterator out,
1290 Strategy const& strategy)
1291 {
1292 return detail_dispatch::overlay::pointlike_areal_point
1293 <
1294 MultiPoint, Areal, PointOut, overlay_intersection,
1295 multi_point_tag, ArealTag
1296 >::apply(multipoint, areal, robust_policy, out, strategy);
1297 }
1298 };
1299
1300
1301 template
1302 <
1303 typename PointLike, typename Areal, typename TupledOut,
1304 overlay_type OverlayType,
1305 bool Reverse1, bool Reverse2,
1306 typename TagIn1, typename TagIn2
1307 >
1308 struct intersection_insert
1309 <
1310 PointLike, Areal, TupledOut, OverlayType,
1311 Reverse1, Reverse2,
1312 TagIn1, TagIn2, detail::tupled_output_tag,
1313 pointlike_tag, areal_tag, detail::tupled_output_tag
1314 >
1315 // Reuse the implementation for PointLike/PointLike.
1316 : intersection_insert
1317 <
1318 PointLike, Areal, TupledOut, OverlayType,
1319 Reverse1, Reverse2,
1320 TagIn1, TagIn2, detail::tupled_output_tag,
1321 pointlike_tag, pointlike_tag, detail::tupled_output_tag
1322 >
1323 {};
1324
1325
1326 // This specialization is needed because intersection() reverses the arguments
1327 // for MultiPoint/Ring and MultiPoint/Polygon combinations.
1328 template
1329 <
1330 typename Areal, typename MultiPoint, typename TupledOut,
1331 bool Reverse1, bool Reverse2,
1332 typename TagIn1
1333 >
1334 struct intersection_insert
1335 <
1336 Areal, MultiPoint, TupledOut, overlay_intersection,
1337 Reverse1, Reverse2,
1338 TagIn1, multi_point_tag, detail::tupled_output_tag,
1339 areal_tag, pointlike_tag, detail::tupled_output_tag
1340 >
1341 {
1342 template <typename RobustPolicy, typename OutputIterators, typename Strategy>
applyboost::geometry::dispatch::intersection_insert1343 static inline OutputIterators apply(Areal const& areal,
1344 MultiPoint const& multipoint,
1345 RobustPolicy const& robust_policy,
1346 OutputIterators out,
1347 Strategy const& strategy)
1348 {
1349 return intersection_insert
1350 <
1351 MultiPoint, Areal, TupledOut, overlay_intersection
1352 >::apply(multipoint, areal, robust_policy, out, strategy);
1353 }
1354 };
1355
1356
1357 template
1358 <
1359 typename Linestring, typename Polygon,
1360 typename TupledOut,
1361 overlay_type OverlayType,
1362 bool ReverseLinestring, bool ReversePolygon
1363 >
1364 struct intersection_insert
1365 <
1366 Linestring, Polygon,
1367 TupledOut,
1368 OverlayType,
1369 ReverseLinestring, ReversePolygon,
1370 linestring_tag, polygon_tag, detail::tupled_output_tag,
1371 linear_tag, areal_tag, detail::tupled_output_tag
1372 > : detail::intersection::intersection_of_linestring_with_areal
1373 <
1374 ReversePolygon,
1375 TupledOut,
1376 OverlayType,
1377 true
1378 >
1379 {};
1380
1381 template
1382 <
1383 typename Linestring, typename Ring,
1384 typename TupledOut,
1385 overlay_type OverlayType,
1386 bool ReverseLinestring, bool ReverseRing
1387 >
1388 struct intersection_insert
1389 <
1390 Linestring, Ring,
1391 TupledOut,
1392 OverlayType,
1393 ReverseLinestring, ReverseRing,
1394 linestring_tag, ring_tag, detail::tupled_output_tag,
1395 linear_tag, areal_tag, detail::tupled_output_tag
1396 > : detail::intersection::intersection_of_linestring_with_areal
1397 <
1398 ReverseRing,
1399 TupledOut,
1400 OverlayType,
1401 true
1402 >
1403 {};
1404
1405
1406 } // namespace dispatch
1407 #endif // DOXYGEN_NO_DISPATCH
1408
1409
1410 #ifndef DOXYGEN_NO_DETAIL
1411 namespace detail { namespace intersection
1412 {
1413
1414
1415 template
1416 <
1417 typename GeometryOut,
1418 bool ReverseSecond,
1419 overlay_type OverlayType,
1420 typename Geometry1, typename Geometry2,
1421 typename RobustPolicy,
1422 typename OutputIterator,
1423 typename Strategy
1424 >
insert(Geometry1 const & geometry1,Geometry2 const & geometry2,RobustPolicy robust_policy,OutputIterator out,Strategy const & strategy)1425 inline OutputIterator insert(Geometry1 const& geometry1,
1426 Geometry2 const& geometry2,
1427 RobustPolicy robust_policy,
1428 OutputIterator out,
1429 Strategy const& strategy)
1430 {
1431 return boost::mpl::if_c
1432 <
1433 geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
1434 geometry::dispatch::intersection_insert_reversed
1435 <
1436 Geometry1, Geometry2,
1437 GeometryOut,
1438 OverlayType,
1439 overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
1440 overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
1441 >,
1442 geometry::dispatch::intersection_insert
1443 <
1444 Geometry1, Geometry2,
1445 GeometryOut,
1446 OverlayType,
1447 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
1448 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
1449 >
1450 >::type::apply(geometry1, geometry2, robust_policy, out, strategy);
1451 }
1452
1453
1454 /*!
1455 \brief \brief_calc2{intersection} \brief_strategy
1456 \ingroup intersection
1457 \details \details_calc2{intersection_insert, spatial set theoretic intersection}
1458 \brief_strategy. \details_insert{intersection}
1459 \tparam GeometryOut \tparam_geometry{\p_l_or_c}
1460 \tparam Geometry1 \tparam_geometry
1461 \tparam Geometry2 \tparam_geometry
1462 \tparam OutputIterator \tparam_out{\p_l_or_c}
1463 \tparam Strategy \tparam_strategy_overlay
1464 \param geometry1 \param_geometry
1465 \param geometry2 \param_geometry
1466 \param out \param_out{intersection}
1467 \param strategy \param_strategy{intersection}
1468 \return \return_out
1469
1470 \qbk{distinguish,with strategy}
1471 \qbk{[include reference/algorithms/intersection.qbk]}
1472 */
1473 template
1474 <
1475 typename GeometryOut,
1476 typename Geometry1,
1477 typename Geometry2,
1478 typename OutputIterator,
1479 typename Strategy
1480 >
intersection_insert(Geometry1 const & geometry1,Geometry2 const & geometry2,OutputIterator out,Strategy const & strategy)1481 inline OutputIterator intersection_insert(Geometry1 const& geometry1,
1482 Geometry2 const& geometry2,
1483 OutputIterator out,
1484 Strategy const& strategy)
1485 {
1486 concepts::check<Geometry1 const>();
1487 concepts::check<Geometry2 const>();
1488
1489 typedef typename geometry::rescale_overlay_policy_type
1490 <
1491 Geometry1,
1492 Geometry2,
1493 typename Strategy::cs_tag
1494 >::type rescale_policy_type;
1495
1496 rescale_policy_type robust_policy
1497 = geometry::get_rescale_policy<rescale_policy_type>(
1498 geometry1, geometry2, strategy);
1499
1500 return detail::intersection::insert
1501 <
1502 GeometryOut, false, overlay_intersection
1503 >(geometry1, geometry2, robust_policy, out, strategy);
1504 }
1505
1506
1507 /*!
1508 \brief \brief_calc2{intersection}
1509 \ingroup intersection
1510 \details \details_calc2{intersection_insert, spatial set theoretic intersection}.
1511 \details_insert{intersection}
1512 \tparam GeometryOut \tparam_geometry{\p_l_or_c}
1513 \tparam Geometry1 \tparam_geometry
1514 \tparam Geometry2 \tparam_geometry
1515 \tparam OutputIterator \tparam_out{\p_l_or_c}
1516 \param geometry1 \param_geometry
1517 \param geometry2 \param_geometry
1518 \param out \param_out{intersection}
1519 \return \return_out
1520
1521 \qbk{[include reference/algorithms/intersection.qbk]}
1522 */
1523 template
1524 <
1525 typename GeometryOut,
1526 typename Geometry1,
1527 typename Geometry2,
1528 typename OutputIterator
1529 >
intersection_insert(Geometry1 const & geometry1,Geometry2 const & geometry2,OutputIterator out)1530 inline OutputIterator intersection_insert(Geometry1 const& geometry1,
1531 Geometry2 const& geometry2,
1532 OutputIterator out)
1533 {
1534 concepts::check<Geometry1 const>();
1535 concepts::check<Geometry2 const>();
1536
1537 typedef typename strategy::intersection::services::default_strategy
1538 <
1539 typename cs_tag<GeometryOut>::type
1540 >::type strategy_type;
1541
1542 return intersection_insert<GeometryOut>(geometry1, geometry2, out,
1543 strategy_type());
1544 }
1545
1546 }} // namespace detail::intersection
1547 #endif // DOXYGEN_NO_DETAIL
1548
1549
1550
1551 }} // namespace boost::geometry
1552
1553
1554 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
1555