• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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