Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:11

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
0004 
0005 // This file was modified by Oracle on 2014-2021.
0006 // Modifications copyright (c) 2014-2021 Oracle and/or its affiliates.
0007 
0008 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0009 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
0010 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0011 
0012 // Use, modification and distribution is subject to the Boost Software License,
0013 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0014 // http://www.boost.org/LICENSE_1_0.txt)
0015 
0016 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
0017 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
0018 
0019 
0020 #include <cstddef>
0021 #include <deque>
0022 #include <type_traits>
0023 
0024 #include <boost/range/begin.hpp>
0025 #include <boost/range/end.hpp>
0026 #include <boost/range/size.hpp>
0027 
0028 #include <boost/geometry/algorithms/convert.hpp>
0029 #include <boost/geometry/algorithms/detail/point_on_border.hpp>
0030 #include <boost/geometry/algorithms/detail/overlay/clip_linestring.hpp>
0031 #include <boost/geometry/algorithms/detail/overlay/follow.hpp>
0032 #include <boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp>
0033 #include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
0034 #include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
0035 #include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
0036 #include <boost/geometry/algorithms/detail/overlay/pointlike_areal.hpp>
0037 #include <boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp>
0038 #include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
0039 #include <boost/geometry/algorithms/detail/overlay/range_in_geometry.hpp>
0040 #include <boost/geometry/algorithms/detail/overlay/segment_as_subrange.hpp>
0041 
0042 #include <boost/geometry/core/point_order.hpp>
0043 #include <boost/geometry/core/reverse_dispatch.hpp>
0044 #include <boost/geometry/core/static_assert.hpp>
0045 
0046 #include <boost/geometry/geometries/concepts/check.hpp>
0047 
0048 #include <boost/geometry/policies/robustness/rescale_policy_tags.hpp>
0049 #include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
0050 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
0051 
0052 #include <boost/geometry/strategies/default_strategy.hpp>
0053 #include <boost/geometry/strategies/detail.hpp>
0054 #include <boost/geometry/strategies/relate/services.hpp>
0055 
0056 #include <boost/geometry/views/segment_view.hpp>
0057 #include <boost/geometry/views/detail/boundary_view.hpp>
0058 
0059 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
0060 #include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
0061 #include <boost/geometry/io/wkt/wkt.hpp>
0062 #include <boost/geometry/util/for_each_with_index.hpp>
0063 #endif
0064 
0065 namespace boost { namespace geometry
0066 {
0067 
0068 #ifndef DOXYGEN_NO_DETAIL
0069 namespace detail { namespace intersection
0070 {
0071 
0072 template <typename PointOut>
0073 struct intersection_segment_segment_point
0074 {
0075     template
0076     <
0077         typename Segment1, typename Segment2,
0078         typename RobustPolicy,
0079         typename OutputIterator, typename Strategy
0080     >
0081     static inline OutputIterator apply(Segment1 const& segment1,
0082             Segment2 const& segment2,
0083             RobustPolicy const& ,
0084             OutputIterator out,
0085             Strategy const& strategy)
0086     {
0087         // Make sure this is only called with no rescaling
0088         BOOST_STATIC_ASSERT((std::is_same
0089            <
0090                no_rescale_policy_tag,
0091                typename rescale_policy_type<RobustPolicy>::type
0092            >::value));
0093 
0094         typedef typename point_type<PointOut>::type point_type;
0095 
0096         // Get the intersection point (or two points)
0097         typedef segment_intersection_points<point_type> intersection_return_type;
0098 
0099         typedef policies::relate::segments_intersection_points
0100             <
0101                 intersection_return_type
0102             > policy_type;
0103 
0104         detail::segment_as_subrange<Segment1> sub_range1(segment1);
0105         detail::segment_as_subrange<Segment2> sub_range2(segment2);
0106 
0107         intersection_return_type
0108             is = strategy.relate().apply(sub_range1, sub_range2, policy_type());
0109 
0110         for (std::size_t i = 0; i < is.count; i++)
0111         {
0112             PointOut p;
0113             geometry::convert(is.intersections[i], p);
0114             *out++ = p;
0115         }
0116         return out;
0117     }
0118 };
0119 
0120 template <typename PointOut>
0121 struct intersection_linestring_linestring_point
0122 {
0123     template
0124     <
0125         typename Linestring1, typename Linestring2,
0126         typename RobustPolicy,
0127         typename OutputIterator,
0128         typename Strategy
0129     >
0130     static inline OutputIterator apply(Linestring1 const& linestring1,
0131             Linestring2 const& linestring2,
0132             RobustPolicy const& robust_policy,
0133             OutputIterator out,
0134             Strategy const& strategy)
0135     {
0136         // Make sure this is only called with no rescaling
0137         BOOST_STATIC_ASSERT((std::is_same
0138            <
0139                no_rescale_policy_tag,
0140                typename rescale_policy_type<RobustPolicy>::type
0141            >::value));
0142 
0143         typedef detail::overlay::turn_info<PointOut> turn_info;
0144         std::deque<turn_info> turns;
0145 
0146         geometry::get_intersection_points(linestring1, linestring2,
0147                                           robust_policy, turns, strategy);
0148 
0149         for (auto const& turn : turns)
0150         {
0151             PointOut p;
0152             geometry::convert(turn.point, p);
0153             *out++ = p;
0154         }
0155         return out;
0156     }
0157 };
0158 
0159 /*!
0160 \brief Version of linestring with an areal feature (polygon or multipolygon)
0161 */
0162 template
0163 <
0164     bool ReverseAreal,
0165     typename GeometryOut,
0166     overlay_type OverlayType,
0167     bool FollowIsolatedPoints
0168 >
0169 struct intersection_of_linestring_with_areal
0170 {
0171 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
0172     template <typename Turn, typename Operation>
0173     static inline void debug_follow(Turn const& turn, Operation op,
0174                                     int index)
0175     {
0176         std::cout << index
0177                   << " at " << op.seg_id
0178                   << " meth: " << method_char(turn.method)
0179                   << " op: " << operation_char(op.operation)
0180                   << " vis: " << visited_char(op.visited)
0181                   << " of:  " << operation_char(turn.operations[0].operation)
0182                   << operation_char(turn.operations[1].operation)
0183                   << " " << geometry::wkt(turn.point)
0184                   << std::endl;
0185     }
0186 
0187     template <typename Turn>
0188     static inline void debug_turn(Turn const& t, bool non_crossing)
0189     {
0190         std::cout << "checking turn @"
0191                   << geometry::wkt(t.point)
0192                   << "; " << method_char(t.method)
0193                   << ":" << operation_char(t.operations[0].operation)
0194                   << "/" << operation_char(t.operations[1].operation)
0195                   << "; non-crossing? "
0196                   << std::boolalpha << non_crossing << std::noboolalpha
0197                   << std::endl;
0198     }
0199 #endif
0200 
0201     template <typename Linestring, typename Areal, typename Strategy, typename Turns>
0202     static inline bool simple_turns_analysis(Linestring const& linestring,
0203                                              Areal const& areal,
0204                                              Strategy const& strategy,
0205                                              Turns const& turns,
0206                                              int & inside_value)
0207     {
0208         using namespace overlay;
0209 
0210         bool found_continue = false;
0211         bool found_intersection = false;
0212         bool found_union = false;
0213         bool found_front = false;
0214 
0215         for (auto const& turn : turns)
0216         {
0217             method_type const method = turn.method;
0218             operation_type const op = turn.operations[0].operation;
0219 
0220             if (method == method_crosses)
0221             {
0222                 return false;
0223             }
0224             else if (op == operation_intersection)
0225             {
0226                 found_intersection = true;
0227             }
0228             else if (op == operation_union)
0229             {
0230                 found_union = true;
0231             }
0232             else if (op == operation_continue)
0233             {
0234                 found_continue = true;
0235             }
0236 
0237             if ((found_intersection || found_continue) && found_union)
0238             {
0239                 return false;
0240             }
0241 
0242             if (turn.operations[0].position == position_front)
0243             {
0244                 found_front = true;
0245             }
0246         }
0247 
0248         if (found_front)
0249         {
0250             if (found_intersection)
0251             {
0252                 inside_value = 1; // inside
0253             }
0254             else if (found_union)
0255             {
0256                 inside_value = -1; // outside
0257             }
0258             else // continue and blocked
0259             {
0260                 inside_value = 0;
0261             }
0262             return true;
0263         }
0264 
0265         // if needed analyse points of a linestring
0266         // NOTE: range_in_geometry checks points of a linestring
0267         // until a point inside/outside areal is found
0268         // TODO: Could be replaced with point_in_geometry() because found_front is false
0269         inside_value = range_in_geometry(linestring, areal, strategy);
0270 
0271         if ( (found_intersection && inside_value == -1) // going in from outside
0272           || (found_continue && inside_value == -1) // going on boundary from outside
0273           || (found_union && inside_value == 1) ) // going out from inside
0274         {
0275             return false;
0276         }
0277 
0278         return true;
0279     }
0280 
0281     template
0282     <
0283         typename LineString, typename Areal,
0284         typename RobustPolicy,
0285         typename OutputIterator, typename Strategy
0286     >
0287     static inline OutputIterator apply(LineString const& linestring, Areal const& areal,
0288             RobustPolicy const& robust_policy,
0289             OutputIterator out,
0290             Strategy const& strategy)
0291     {
0292         // Make sure this is only called with no rescaling
0293         BOOST_STATIC_ASSERT((std::is_same
0294            <
0295                no_rescale_policy_tag,
0296                typename rescale_policy_type<RobustPolicy>::type
0297            >::value));
0298 
0299         if (boost::size(linestring) == 0)
0300         {
0301             return out;
0302         }
0303 
0304         typedef detail::overlay::follow
0305                 <
0306                     GeometryOut,
0307                     LineString,
0308                     Areal,
0309                     OverlayType,
0310                     false, // do not remove spikes for linear geometries
0311                     FollowIsolatedPoints
0312                 > follower;
0313 
0314         typedef typename geometry::detail::output_geometry_access
0315             <
0316                 GeometryOut, linestring_tag, linestring_tag
0317             > linear;
0318 
0319         typedef typename point_type
0320             <
0321                 typename linear::type
0322             >::type point_type;
0323 
0324         typedef geometry::segment_ratio
0325             <
0326                 typename coordinate_type<point_type>::type
0327             > ratio_type;
0328 
0329         typedef detail::overlay::turn_info
0330             <
0331                 point_type,
0332                 ratio_type,
0333                 detail::overlay::turn_operation_linear
0334                     <
0335                         point_type,
0336                         ratio_type
0337                     >
0338             > turn_info;
0339 
0340         std::deque<turn_info> turns;
0341 
0342         detail::get_turns::no_interrupt_policy policy;
0343 
0344         typedef detail::overlay::get_turn_info_linear_areal
0345             <
0346                 detail::overlay::assign_null_policy
0347             > turn_policy;
0348 
0349         dispatch::get_turns
0350             <
0351                 typename geometry::tag<LineString>::type,
0352                 typename geometry::tag<Areal>::type,
0353                 LineString,
0354                 Areal,
0355                 false,
0356                 (OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal),
0357                 turn_policy
0358             >::apply(0, linestring, 1, areal,
0359                      strategy, robust_policy,
0360                      turns, policy);
0361 
0362         int inside_value = 0;
0363         if (simple_turns_analysis(linestring, areal, strategy, turns, inside_value))
0364         {
0365             // No crossing the boundary, it is either
0366             // inside (interior + borders)
0367             // or outside (exterior + borders)
0368             // or on boundary
0369 
0370             // add linestring to the output if conditions are met
0371             if (follower::included(inside_value))
0372             {
0373                 typename linear::type copy;
0374                 geometry::convert(linestring, copy);
0375                 *linear::get(out)++ = copy;
0376             }
0377 
0378             return out;
0379         }
0380 
0381 #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
0382         for_each_with_index(turns, [](auto index, auto const& turn)
0383         {
0384             debug_follow(turn, turn.operations[0], index);
0385         });
0386 #endif
0387 
0388         return follower::apply
0389                 (
0390                     linestring, areal,
0391                     geometry::detail::overlay::operation_intersection,
0392                     turns, robust_policy, out, strategy
0393                 );
0394     }
0395 };
0396 
0397 
0398 template <typename Turns, typename OutputIterator>
0399 inline OutputIterator intersection_output_turn_points(Turns const& turns,
0400                                                       OutputIterator out)
0401 {
0402     for (auto const& turn : turns)
0403     {
0404         *out++ = turn.point;
0405     }
0406 
0407     return out;
0408 }
0409 
0410 template <typename PointOut>
0411 struct intersection_areal_areal_point
0412 {
0413     template
0414     <
0415         typename Geometry1, typename Geometry2,
0416         typename RobustPolicy,
0417         typename OutputIterator,
0418         typename Strategy
0419     >
0420     static inline OutputIterator apply(Geometry1 const& geometry1,
0421                                        Geometry2 const& geometry2,
0422                                        RobustPolicy const& robust_policy,
0423                                        OutputIterator out,
0424                                        Strategy const& strategy)
0425     {
0426         typedef detail::overlay::turn_info
0427             <
0428                 PointOut,
0429                 typename segment_ratio_type<PointOut, RobustPolicy>::type
0430             > turn_info;
0431         std::vector<turn_info> turns;
0432 
0433         detail::get_turns::no_interrupt_policy policy;
0434 
0435         geometry::get_turns
0436             <
0437                 false, false, detail::overlay::assign_null_policy
0438             >(geometry1, geometry2, strategy, robust_policy, turns, policy);
0439 
0440         return intersection_output_turn_points(turns, out);
0441     }
0442 };
0443 
0444 template <typename PointOut>
0445 struct intersection_linear_areal_point
0446 {
0447     template
0448     <
0449         typename Geometry1, typename Geometry2,
0450         typename RobustPolicy,
0451         typename OutputIterator,
0452         typename Strategy
0453     >
0454     static inline OutputIterator apply(Geometry1 const& geometry1,
0455                                        Geometry2 const& geometry2,
0456                                        RobustPolicy const& robust_policy,
0457                                        OutputIterator out,
0458                                        Strategy const& strategy)
0459     {
0460         // Make sure this is only called with no rescaling
0461         BOOST_STATIC_ASSERT((std::is_same
0462            <
0463                no_rescale_policy_tag,
0464                typename rescale_policy_type<RobustPolicy>::type
0465            >::value));
0466 
0467         typedef geometry::segment_ratio<typename geometry::coordinate_type<PointOut>::type> ratio_type;
0468 
0469         typedef detail::overlay::turn_info
0470             <
0471                 PointOut,
0472                 ratio_type,
0473                 detail::overlay::turn_operation_linear
0474                     <
0475                         PointOut,
0476                         ratio_type
0477                     >
0478             > turn_info;
0479 
0480         typedef detail::overlay::get_turn_info_linear_areal
0481             <
0482                 detail::overlay::assign_null_policy
0483             > turn_policy;
0484 
0485         std::vector<turn_info> turns;
0486 
0487         detail::get_turns::no_interrupt_policy interrupt_policy;
0488 
0489         dispatch::get_turns
0490             <
0491                 typename geometry::tag<Geometry1>::type,
0492                 typename geometry::tag<Geometry2>::type,
0493                 Geometry1,
0494                 Geometry2,
0495                 false,
0496                 false,
0497                 turn_policy
0498             >::apply(0, geometry1, 1, geometry2,
0499                      strategy, robust_policy,
0500                      turns, interrupt_policy);
0501 
0502         return intersection_output_turn_points(turns, out);
0503     }
0504 };
0505 
0506 template <typename PointOut>
0507 struct intersection_areal_linear_point
0508 {
0509     template
0510     <
0511         typename Geometry1, typename Geometry2,
0512         typename RobustPolicy,
0513         typename OutputIterator,
0514         typename Strategy
0515     >
0516     static inline OutputIterator apply(Geometry1 const& geometry1,
0517                                        Geometry2 const& geometry2,
0518                                        RobustPolicy const& robust_policy,
0519                                        OutputIterator out,
0520                                        Strategy const& strategy)
0521     {
0522         return intersection_linear_areal_point
0523             <
0524                 PointOut
0525             >::apply(geometry2, geometry1, robust_policy, out, strategy);
0526     }
0527 };
0528 
0529 
0530 }} // namespace detail::intersection
0531 #endif // DOXYGEN_NO_DETAIL
0532 
0533 
0534 
0535 #ifndef DOXYGEN_NO_DISPATCH
0536 namespace dispatch
0537 {
0538 
0539 template
0540 <
0541     // real types
0542     typename Geometry1,
0543     typename Geometry2,
0544     typename GeometryOut,
0545     overlay_type OverlayType,
0546     // orientation
0547     bool Reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
0548     bool Reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
0549     // tag dispatching:
0550     typename TagIn1 = typename geometry::tag<Geometry1>::type,
0551     typename TagIn2 = typename geometry::tag<Geometry2>::type,
0552     typename TagOut = typename detail::setop_insert_output_tag<GeometryOut>::type,
0553     // metafunction finetuning helpers:
0554     typename CastedTagIn1 = typename geometry::tag_cast<TagIn1, areal_tag, linear_tag, pointlike_tag>::type,
0555     typename CastedTagIn2 = typename geometry::tag_cast<TagIn2, areal_tag, linear_tag, pointlike_tag>::type,
0556     typename CastedTagOut = typename geometry::tag_cast<TagOut, areal_tag, linear_tag, pointlike_tag>::type
0557 >
0558 struct intersection_insert
0559 {
0560     BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
0561         "Not or not yet implemented for these Geometry types or their order.",
0562         Geometry1, Geometry2, GeometryOut,
0563         std::integral_constant<overlay_type, OverlayType>);
0564 };
0565 
0566 
0567 template
0568 <
0569     typename Geometry1, typename Geometry2,
0570     typename GeometryOut,
0571     overlay_type OverlayType,
0572     bool Reverse1, bool Reverse2,
0573     typename TagIn1, typename TagIn2, typename TagOut
0574 >
0575 struct intersection_insert
0576     <
0577         Geometry1, Geometry2,
0578         GeometryOut,
0579         OverlayType,
0580         Reverse1, Reverse2,
0581         TagIn1, TagIn2, TagOut,
0582         areal_tag, areal_tag, areal_tag
0583     > : detail::overlay::overlay
0584         <
0585             Geometry1, Geometry2, Reverse1, Reverse2,
0586             detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
0587             GeometryOut, OverlayType
0588         >
0589 {};
0590 
0591 
0592 // Any areal type with box:
0593 template
0594 <
0595     typename Geometry, typename Box,
0596     typename GeometryOut,
0597     overlay_type OverlayType,
0598     bool Reverse1, bool Reverse2,
0599     typename TagIn, typename TagOut
0600 >
0601 struct intersection_insert
0602     <
0603         Geometry, Box,
0604         GeometryOut,
0605         OverlayType,
0606         Reverse1, Reverse2,
0607         TagIn, box_tag, TagOut,
0608         areal_tag, areal_tag, areal_tag
0609     > : detail::overlay::overlay
0610         <
0611             Geometry, Box, Reverse1, Reverse2,
0612             detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
0613             GeometryOut, OverlayType
0614         >
0615 {};
0616 
0617 
0618 template
0619 <
0620     typename Segment1, typename Segment2,
0621     typename GeometryOut,
0622     overlay_type OverlayType,
0623     bool Reverse1, bool Reverse2
0624 >
0625 struct intersection_insert
0626     <
0627         Segment1, Segment2,
0628         GeometryOut,
0629         OverlayType,
0630         Reverse1, Reverse2,
0631         segment_tag, segment_tag, point_tag,
0632         linear_tag, linear_tag, pointlike_tag
0633     > : detail::intersection::intersection_segment_segment_point<GeometryOut>
0634 {};
0635 
0636 
0637 template
0638 <
0639     typename Linestring1, typename Linestring2,
0640     typename GeometryOut,
0641     overlay_type OverlayType,
0642     bool Reverse1, bool Reverse2
0643 >
0644 struct intersection_insert
0645     <
0646         Linestring1, Linestring2,
0647         GeometryOut,
0648         OverlayType,
0649         Reverse1, Reverse2,
0650         linestring_tag, linestring_tag, point_tag,
0651         linear_tag, linear_tag, pointlike_tag
0652     > : detail::intersection::intersection_linestring_linestring_point<GeometryOut>
0653 {};
0654 
0655 
0656 template
0657 <
0658     typename Linestring, typename Box,
0659     typename GeometryOut,
0660     bool Reverse1, bool Reverse2
0661 >
0662 struct intersection_insert
0663     <
0664         Linestring, Box,
0665         GeometryOut,
0666         overlay_intersection,
0667         Reverse1, Reverse2,
0668         linestring_tag, box_tag, linestring_tag,
0669         linear_tag, areal_tag, linear_tag
0670     >
0671 {
0672     template <typename RobustPolicy, typename OutputIterator, typename Strategy>
0673     static inline OutputIterator apply(Linestring const& linestring,
0674             Box const& box,
0675             RobustPolicy const& robust_policy,
0676             OutputIterator out, Strategy const& )
0677     {
0678         typedef typename point_type<GeometryOut>::type point_type;
0679         strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
0680         return detail::intersection::clip_range_with_box
0681             <GeometryOut>(box, linestring, robust_policy, out, lb_strategy);
0682     }
0683 };
0684 
0685 
0686 template
0687 <
0688     typename Linestring, typename Polygon,
0689     typename GeometryOut,
0690     overlay_type OverlayType,
0691     bool ReverseLinestring, bool ReversePolygon
0692 >
0693 struct intersection_insert
0694     <
0695         Linestring, Polygon,
0696         GeometryOut,
0697         OverlayType,
0698         ReverseLinestring, ReversePolygon,
0699         linestring_tag, polygon_tag, linestring_tag,
0700         linear_tag, areal_tag, linear_tag
0701     > : detail::intersection::intersection_of_linestring_with_areal
0702             <
0703                 ReversePolygon,
0704                 GeometryOut,
0705                 OverlayType,
0706                 false
0707             >
0708 {};
0709 
0710 
0711 template
0712 <
0713     typename Linestring, typename Ring,
0714     typename GeometryOut,
0715     overlay_type OverlayType,
0716     bool ReverseLinestring, bool ReverseRing
0717 >
0718 struct intersection_insert
0719     <
0720         Linestring, Ring,
0721         GeometryOut,
0722         OverlayType,
0723         ReverseLinestring, ReverseRing,
0724         linestring_tag, ring_tag, linestring_tag,
0725         linear_tag, areal_tag, linear_tag
0726     > : detail::intersection::intersection_of_linestring_with_areal
0727             <
0728                 ReverseRing,
0729                 GeometryOut,
0730                 OverlayType,
0731                 false
0732             >
0733 {};
0734 
0735 template
0736 <
0737     typename Segment, typename Box,
0738     typename GeometryOut,
0739     overlay_type OverlayType,
0740     bool Reverse1, bool Reverse2
0741 >
0742 struct intersection_insert
0743     <
0744         Segment, Box,
0745         GeometryOut,
0746         OverlayType,
0747         Reverse1, Reverse2,
0748         segment_tag, box_tag, linestring_tag,
0749         linear_tag, areal_tag, linear_tag
0750     >
0751 {
0752     template <typename RobustPolicy, typename OutputIterator, typename Strategy>
0753     static inline OutputIterator apply(Segment const& segment,
0754             Box const& box,
0755             RobustPolicy const& robust_policy,
0756             OutputIterator out, Strategy const& )
0757     {
0758         geometry::segment_view<Segment> range(segment);
0759 
0760         typedef typename point_type<GeometryOut>::type point_type;
0761         strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
0762         return detail::intersection::clip_range_with_box
0763             <GeometryOut>(box, range, robust_policy, out, lb_strategy);
0764     }
0765 };
0766 
0767 template
0768 <
0769     typename Geometry1, typename Geometry2,
0770     typename PointOut,
0771     overlay_type OverlayType,
0772     bool Reverse1, bool Reverse2,
0773     typename Tag1, typename Tag2
0774 >
0775 struct intersection_insert
0776     <
0777         Geometry1, Geometry2,
0778         PointOut,
0779         OverlayType,
0780         Reverse1, Reverse2,
0781         Tag1, Tag2, point_tag,
0782         areal_tag, areal_tag, pointlike_tag
0783     >
0784     : public detail::intersection::intersection_areal_areal_point
0785         <
0786             PointOut
0787         >
0788 {};
0789 
0790 template
0791 <
0792     typename Geometry1, typename Geometry2,
0793     typename PointOut,
0794     overlay_type OverlayType,
0795     bool Reverse1, bool Reverse2,
0796     typename Tag1, typename Tag2
0797 >
0798 struct intersection_insert
0799     <
0800         Geometry1, Geometry2,
0801         PointOut,
0802         OverlayType,
0803         Reverse1, Reverse2,
0804         Tag1, Tag2, point_tag,
0805         linear_tag, areal_tag, pointlike_tag
0806     >
0807     : public detail::intersection::intersection_linear_areal_point
0808         <
0809             PointOut
0810         >
0811 {};
0812 
0813 template
0814 <
0815     typename Geometry1, typename Geometry2,
0816     typename PointOut,
0817     overlay_type OverlayType,
0818     bool Reverse1, bool Reverse2,
0819     typename Tag1, typename Tag2
0820 >
0821 struct intersection_insert
0822     <
0823         Geometry1, Geometry2,
0824         PointOut,
0825         OverlayType,
0826         Reverse1, Reverse2,
0827         Tag1, Tag2, point_tag,
0828         areal_tag, linear_tag, pointlike_tag
0829     >
0830     : public detail::intersection::intersection_areal_linear_point
0831         <
0832             PointOut
0833         >
0834 {};
0835 
0836 template
0837 <
0838     typename Geometry1, typename Geometry2, typename GeometryOut,
0839     overlay_type OverlayType,
0840     bool Reverse1, bool Reverse2
0841 >
0842 struct intersection_insert_reversed
0843 {
0844     template <typename RobustPolicy, typename OutputIterator, typename Strategy>
0845     static inline OutputIterator apply(Geometry1 const& g1,
0846                 Geometry2 const& g2,
0847                 RobustPolicy const& robust_policy,
0848                 OutputIterator out,
0849                 Strategy const& strategy)
0850     {
0851         return intersection_insert
0852             <
0853                 Geometry2, Geometry1, GeometryOut,
0854                 OverlayType,
0855                 Reverse2, Reverse1
0856             >::apply(g2, g1, robust_policy, out, strategy);
0857     }
0858 };
0859 
0860 
0861 // dispatch for intersection(areal, areal, linear)
0862 template
0863 <
0864     typename Geometry1, typename Geometry2,
0865     typename LinestringOut,
0866     bool Reverse1, bool Reverse2,
0867     typename Tag1, typename Tag2
0868 >
0869 struct intersection_insert
0870     <
0871         Geometry1, Geometry2,
0872         LinestringOut,
0873         overlay_intersection,
0874         Reverse1, Reverse2,
0875         Tag1, Tag2, linestring_tag,
0876         areal_tag, areal_tag, linear_tag
0877     >
0878 {
0879     template
0880     <
0881         typename RobustPolicy, typename OutputIterator, typename Strategy
0882     >
0883     static inline OutputIterator apply(Geometry1 const& geometry1,
0884                                        Geometry2 const& geometry2,
0885                                        RobustPolicy const& robust_policy,
0886                                        OutputIterator oit,
0887                                        Strategy const& strategy)
0888     {
0889         detail::boundary_view<Geometry1 const> view1(geometry1);
0890         detail::boundary_view<Geometry2 const> view2(geometry2);
0891 
0892         return detail::overlay::linear_linear_linestring
0893             <
0894                 detail::boundary_view<Geometry1 const>,
0895                 detail::boundary_view<Geometry2 const>,
0896                 LinestringOut,
0897                 overlay_intersection
0898             >::apply(view1, view2, robust_policy, oit, strategy);
0899     }
0900 };
0901 
0902 // dispatch for difference/intersection of linear geometries
0903 template
0904 <
0905     typename Linear1, typename Linear2, typename LineStringOut,
0906     overlay_type OverlayType,
0907     bool Reverse1, bool Reverse2,
0908     typename TagIn1, typename TagIn2
0909 >
0910 struct intersection_insert
0911     <
0912         Linear1, Linear2, LineStringOut, OverlayType,
0913         Reverse1, Reverse2,
0914         TagIn1, TagIn2, linestring_tag,
0915         linear_tag, linear_tag, linear_tag
0916     > : detail::overlay::linear_linear_linestring
0917         <
0918             Linear1, Linear2, LineStringOut, OverlayType
0919         >
0920 {};
0921 
0922 template
0923 <
0924     typename Linear1, typename Linear2, typename TupledOut,
0925     overlay_type OverlayType,
0926     bool Reverse1, bool Reverse2,
0927     typename TagIn1, typename TagIn2
0928 >
0929 struct intersection_insert
0930     <
0931         Linear1, Linear2, TupledOut, OverlayType,
0932         Reverse1, Reverse2,
0933         TagIn1, TagIn2, detail::tupled_output_tag,
0934         linear_tag, linear_tag, detail::tupled_output_tag
0935     >
0936     : detail::expect_output
0937         <
0938             Linear1, Linear2, TupledOut,
0939             // NOTE: points can be the result only in case of intersection.
0940             std::conditional_t
0941                 <
0942                     (OverlayType == overlay_intersection),
0943                     point_tag,
0944                     void
0945                 >,
0946             linestring_tag
0947         >
0948 {
0949     // NOTE: The order of geometries in TupledOut tuple/pair must correspond to the order
0950     // iterators in OutputIterators tuple/pair.
0951     template
0952     <
0953         typename RobustPolicy, typename OutputIterators, typename Strategy
0954     >
0955     static inline OutputIterators apply(Linear1 const& linear1,
0956                                         Linear2 const& linear2,
0957                                         RobustPolicy const& robust_policy,
0958                                         OutputIterators oit,
0959                                         Strategy const& strategy)
0960     {
0961         return detail::overlay::linear_linear_linestring
0962             <
0963                 Linear1, Linear2, TupledOut, OverlayType
0964             >::apply(linear1, linear2, robust_policy, oit, strategy);
0965     }
0966 };
0967 
0968 
0969 // dispatch for difference/intersection of point-like geometries
0970 
0971 template
0972 <
0973     typename Point1, typename Point2, typename PointOut,
0974     overlay_type OverlayType,
0975     bool Reverse1, bool Reverse2
0976 >
0977 struct intersection_insert
0978     <
0979         Point1, Point2, PointOut, OverlayType,
0980         Reverse1, Reverse2,
0981         point_tag, point_tag, point_tag,
0982         pointlike_tag, pointlike_tag, pointlike_tag
0983     > : detail::overlay::point_point_point
0984         <
0985             Point1, Point2, PointOut, OverlayType
0986         >
0987 {};
0988 
0989 
0990 template
0991 <
0992     typename MultiPoint, typename Point, typename PointOut,
0993     overlay_type OverlayType,
0994     bool Reverse1, bool Reverse2
0995 >
0996 struct intersection_insert
0997     <
0998         MultiPoint, Point, PointOut, OverlayType,
0999         Reverse1, Reverse2,
1000         multi_point_tag, point_tag, point_tag,
1001         pointlike_tag, pointlike_tag, pointlike_tag
1002     > : detail::overlay::multipoint_point_point
1003         <
1004             MultiPoint, Point, PointOut, OverlayType
1005         >
1006 {};
1007 
1008 
1009 template
1010 <
1011     typename Point, typename MultiPoint, typename PointOut,
1012     overlay_type OverlayType,
1013     bool Reverse1, bool Reverse2
1014 >
1015 struct intersection_insert
1016     <
1017         Point, MultiPoint, PointOut, OverlayType,
1018         Reverse1, Reverse2,
1019         point_tag, multi_point_tag, point_tag,
1020         pointlike_tag, pointlike_tag, pointlike_tag
1021     > : detail::overlay::point_multipoint_point
1022         <
1023             Point, MultiPoint, PointOut, OverlayType
1024         >
1025 {};
1026 
1027 
1028 template
1029 <
1030     typename MultiPoint1, typename MultiPoint2, typename PointOut,
1031     overlay_type OverlayType,
1032     bool Reverse1, bool Reverse2
1033 >
1034 struct intersection_insert
1035     <
1036         MultiPoint1, MultiPoint2, PointOut, OverlayType,
1037         Reverse1, Reverse2,
1038         multi_point_tag, multi_point_tag, point_tag,
1039         pointlike_tag, pointlike_tag, pointlike_tag
1040     > : detail::overlay::multipoint_multipoint_point
1041         <
1042             MultiPoint1, MultiPoint2, PointOut, OverlayType
1043         >
1044 {};
1045 
1046 
1047 template
1048 <
1049     typename PointLike1, typename PointLike2, typename TupledOut,
1050     overlay_type OverlayType,
1051     bool Reverse1, bool Reverse2,
1052     typename TagIn1, typename TagIn2
1053 >
1054 struct intersection_insert
1055     <
1056         PointLike1, PointLike2, TupledOut, OverlayType,
1057         Reverse1, Reverse2,
1058         TagIn1, TagIn2, detail::tupled_output_tag,
1059         pointlike_tag, pointlike_tag, detail::tupled_output_tag
1060     >
1061     : detail::expect_output<PointLike1, PointLike2, TupledOut, point_tag>
1062 {
1063     // NOTE: The order of geometries in TupledOut tuple/pair must correspond to the order
1064     // of iterators in OutputIterators tuple/pair.
1065     template
1066     <
1067         typename RobustPolicy, typename OutputIterators, typename Strategy
1068     >
1069     static inline OutputIterators apply(PointLike1 const& pointlike1,
1070                                         PointLike2 const& pointlike2,
1071                                         RobustPolicy const& robust_policy,
1072                                         OutputIterators oits,
1073                                         Strategy const& strategy)
1074     {
1075         namespace bgt = boost::geometry::tuples;
1076 
1077         static const bool out_point_index = bgt::find_index_if
1078             <
1079                 TupledOut, geometry::detail::is_tag_same_as_pred<point_tag>::template pred
1080             >::value;
1081 
1082         bgt::get<out_point_index>(oits) = intersection_insert
1083             <
1084                 PointLike1, PointLike2,
1085                 typename bgt::element
1086                     <
1087                         out_point_index, TupledOut
1088                     >::type,
1089                 OverlayType
1090             >::apply(pointlike1, pointlike2, robust_policy,
1091                      bgt::get<out_point_index>(oits),
1092                      strategy);
1093 
1094         return oits;
1095     }
1096 };
1097 
1098 
1099 // dispatch for difference/intersection of pointlike-linear geometries
1100 template
1101 <
1102     typename Point, typename Linear, typename PointOut,
1103     overlay_type OverlayType,
1104     bool Reverse1, bool Reverse2,
1105     typename Tag
1106 >
1107 struct intersection_insert
1108     <
1109         Point, Linear, PointOut, OverlayType,
1110         Reverse1, Reverse2,
1111         point_tag, Tag, point_tag,
1112         pointlike_tag, linear_tag, pointlike_tag
1113     > : detail_dispatch::overlay::pointlike_linear_point
1114         <
1115             Point, Linear, PointOut, OverlayType,
1116             point_tag, typename tag_cast<Tag, segment_tag, linear_tag>::type
1117         >
1118 {};
1119 
1120 
1121 template
1122 <
1123     typename MultiPoint, typename Linear, typename PointOut,
1124     overlay_type OverlayType,
1125     bool Reverse1, bool Reverse2,
1126     typename Tag
1127 >
1128 struct intersection_insert
1129     <
1130         MultiPoint, Linear, PointOut, OverlayType,
1131         Reverse1, Reverse2,
1132         multi_point_tag, Tag, point_tag,
1133         pointlike_tag, linear_tag, pointlike_tag
1134     > : detail_dispatch::overlay::pointlike_linear_point
1135         <
1136             MultiPoint, Linear, PointOut, OverlayType,
1137             multi_point_tag,
1138             typename tag_cast<Tag, segment_tag, linear_tag>::type
1139         >
1140 {};
1141 
1142 
1143 // This specialization is needed because intersection() reverses the arguments
1144 // for MultiPoint/Linestring combination.
1145 template
1146 <
1147     typename Linestring, typename MultiPoint, typename PointOut,
1148     bool Reverse1, bool Reverse2
1149 >
1150 struct intersection_insert
1151     <
1152         Linestring, MultiPoint, PointOut, overlay_intersection,
1153         Reverse1, Reverse2,
1154         linestring_tag, multi_point_tag, point_tag,
1155         linear_tag, pointlike_tag, pointlike_tag
1156     >
1157 {
1158     template <typename RobustPolicy, typename OutputIterator, typename Strategy>
1159     static inline OutputIterator apply(Linestring const& linestring,
1160                                        MultiPoint const& multipoint,
1161                                        RobustPolicy const& robust_policy,
1162                                        OutputIterator out,
1163                                        Strategy const& strategy)
1164     {
1165         return detail_dispatch::overlay::pointlike_linear_point
1166             <
1167                 MultiPoint, Linestring, PointOut, overlay_intersection,
1168                 multi_point_tag, linear_tag
1169             >::apply(multipoint, linestring, robust_policy, out, strategy);
1170     }
1171 };
1172 
1173 
1174 template
1175 <
1176     typename PointLike, typename Linear, typename TupledOut,
1177     overlay_type OverlayType,
1178     bool Reverse1, bool Reverse2,
1179     typename TagIn1, typename TagIn2
1180 >
1181 struct intersection_insert
1182     <
1183         PointLike, Linear, TupledOut, OverlayType,
1184         Reverse1, Reverse2,
1185         TagIn1, TagIn2, detail::tupled_output_tag,
1186         pointlike_tag, linear_tag, detail::tupled_output_tag
1187     >
1188     // Reuse the implementation for PointLike/PointLike.
1189     : intersection_insert
1190         <
1191             PointLike, Linear, TupledOut, OverlayType,
1192             Reverse1, Reverse2,
1193             TagIn1, TagIn2, detail::tupled_output_tag,
1194             pointlike_tag, pointlike_tag, detail::tupled_output_tag
1195         >
1196 {};
1197 
1198 
1199 // This specialization is needed because intersection() reverses the arguments
1200 // for MultiPoint/Linestring combination.
1201 template
1202 <
1203     typename Linestring, typename MultiPoint, typename TupledOut,
1204     bool Reverse1, bool Reverse2
1205 >
1206 struct intersection_insert
1207     <
1208         Linestring, MultiPoint, TupledOut, overlay_intersection,
1209         Reverse1, Reverse2,
1210         linestring_tag, multi_point_tag, detail::tupled_output_tag,
1211         linear_tag, pointlike_tag, detail::tupled_output_tag
1212     >
1213 {
1214     template <typename RobustPolicy, typename OutputIterators, typename Strategy>
1215     static inline OutputIterators apply(Linestring const& linestring,
1216                                         MultiPoint const& multipoint,
1217                                         RobustPolicy const& robust_policy,
1218                                         OutputIterators out,
1219                                         Strategy const& strategy)
1220     {
1221         return intersection_insert
1222             <
1223                 MultiPoint, Linestring, TupledOut, overlay_intersection
1224             >::apply(multipoint, linestring, robust_policy, out, strategy);
1225     }
1226 };
1227 
1228 
1229 // dispatch for difference/intersection of pointlike-areal geometries
1230 template
1231 <
1232     typename Point, typename Areal, typename PointOut,
1233     overlay_type OverlayType,
1234     bool Reverse1, bool Reverse2,
1235     typename ArealTag
1236 >
1237 struct intersection_insert
1238     <
1239         Point, Areal, PointOut, OverlayType,
1240         Reverse1, Reverse2,
1241         point_tag, ArealTag, point_tag,
1242         pointlike_tag, areal_tag, pointlike_tag
1243     > : detail_dispatch::overlay::pointlike_areal_point
1244         <
1245             Point, Areal, PointOut, OverlayType,
1246             point_tag, ArealTag
1247         >
1248 {};
1249 
1250 template
1251 <
1252     typename MultiPoint, typename Areal, typename PointOut,
1253     overlay_type OverlayType,
1254     bool Reverse1, bool Reverse2,
1255     typename ArealTag
1256 >
1257 struct intersection_insert
1258     <
1259         MultiPoint, Areal, PointOut, OverlayType,
1260         Reverse1, Reverse2,
1261         multi_point_tag, ArealTag, point_tag,
1262         pointlike_tag, areal_tag, pointlike_tag
1263     > : detail_dispatch::overlay::pointlike_areal_point
1264         <
1265             MultiPoint, Areal, PointOut, OverlayType,
1266             multi_point_tag, ArealTag
1267         >
1268 {};
1269 
1270 // This specialization is needed because intersection() reverses the arguments
1271 // for MultiPoint/Ring and MultiPoint/Polygon combinations.
1272 template
1273 <
1274     typename Areal, typename MultiPoint, typename PointOut,
1275     bool Reverse1, bool Reverse2,
1276     typename ArealTag
1277 >
1278 struct intersection_insert
1279     <
1280         Areal, MultiPoint, PointOut, overlay_intersection,
1281         Reverse1, Reverse2,
1282         ArealTag, multi_point_tag, point_tag,
1283         areal_tag, pointlike_tag, pointlike_tag
1284     >
1285 {
1286     template <typename RobustPolicy, typename OutputIterator, typename Strategy>
1287     static inline OutputIterator apply(Areal const& areal,
1288                                        MultiPoint const& multipoint,
1289                                        RobustPolicy const& robust_policy,
1290                                        OutputIterator out,
1291                                        Strategy const& strategy)
1292     {
1293         return detail_dispatch::overlay::pointlike_areal_point
1294             <
1295                 MultiPoint, Areal, PointOut, overlay_intersection,
1296                 multi_point_tag, ArealTag
1297             >::apply(multipoint, areal, robust_policy, out, strategy);
1298     }
1299 };
1300 
1301 
1302 template
1303 <
1304     typename PointLike, typename Areal, typename TupledOut,
1305     overlay_type OverlayType,
1306     bool Reverse1, bool Reverse2,
1307     typename TagIn1, typename TagIn2
1308 >
1309 struct intersection_insert
1310     <
1311         PointLike, Areal, TupledOut, OverlayType,
1312         Reverse1, Reverse2,
1313         TagIn1, TagIn2, detail::tupled_output_tag,
1314         pointlike_tag, areal_tag, detail::tupled_output_tag
1315     >
1316     // Reuse the implementation for PointLike/PointLike.
1317     : intersection_insert
1318         <
1319             PointLike, Areal, TupledOut, OverlayType,
1320             Reverse1, Reverse2,
1321             TagIn1, TagIn2, detail::tupled_output_tag,
1322             pointlike_tag, pointlike_tag, detail::tupled_output_tag
1323         >
1324 {};
1325 
1326 
1327 // This specialization is needed because intersection() reverses the arguments
1328 // for MultiPoint/Ring and MultiPoint/Polygon combinations.
1329 template
1330 <
1331     typename Areal, typename MultiPoint, typename TupledOut,
1332     bool Reverse1, bool Reverse2,
1333     typename TagIn1
1334 >
1335 struct intersection_insert
1336     <
1337         Areal, MultiPoint, TupledOut, overlay_intersection,
1338         Reverse1, Reverse2,
1339         TagIn1, multi_point_tag, detail::tupled_output_tag,
1340         areal_tag, pointlike_tag, detail::tupled_output_tag
1341     >
1342 {
1343     template <typename RobustPolicy, typename OutputIterators, typename Strategy>
1344     static inline OutputIterators apply(Areal const& areal,
1345                                         MultiPoint const& multipoint,
1346                                         RobustPolicy const& robust_policy,
1347                                         OutputIterators out,
1348                                         Strategy const& strategy)
1349     {
1350         return intersection_insert
1351             <
1352                 MultiPoint, Areal, TupledOut, overlay_intersection
1353             >::apply(multipoint, areal, robust_policy, out, strategy);
1354     }
1355 };
1356 
1357 
1358 template
1359 <
1360     typename Linestring, typename Polygon,
1361     typename TupledOut,
1362     overlay_type OverlayType,
1363     bool ReverseLinestring, bool ReversePolygon
1364 >
1365 struct intersection_insert
1366     <
1367         Linestring, Polygon,
1368         TupledOut,
1369         OverlayType,
1370         ReverseLinestring, ReversePolygon,
1371         linestring_tag, polygon_tag, detail::tupled_output_tag,
1372         linear_tag, areal_tag, detail::tupled_output_tag
1373     > : detail::intersection::intersection_of_linestring_with_areal
1374             <
1375                 ReversePolygon,
1376                 TupledOut,
1377                 OverlayType,
1378                 true
1379             >
1380 {};
1381 
1382 template
1383 <
1384     typename Linestring, typename Ring,
1385     typename TupledOut,
1386     overlay_type OverlayType,
1387     bool ReverseLinestring, bool ReverseRing
1388 >
1389 struct intersection_insert
1390     <
1391         Linestring, Ring,
1392         TupledOut,
1393         OverlayType,
1394         ReverseLinestring, ReverseRing,
1395         linestring_tag, ring_tag, detail::tupled_output_tag,
1396         linear_tag, areal_tag, detail::tupled_output_tag
1397     > : detail::intersection::intersection_of_linestring_with_areal
1398             <
1399                 ReverseRing,
1400                 TupledOut,
1401                 OverlayType,
1402                 true
1403             >
1404 {};
1405 
1406 
1407 } // namespace dispatch
1408 #endif // DOXYGEN_NO_DISPATCH
1409 
1410 
1411 #ifndef DOXYGEN_NO_DETAIL
1412 namespace detail { namespace intersection
1413 {
1414 
1415 
1416 template
1417 <
1418     typename GeometryOut,
1419     bool ReverseSecond,
1420     overlay_type OverlayType,
1421     typename Geometry1, typename Geometry2,
1422     typename RobustPolicy,
1423     typename OutputIterator,
1424     typename Strategy
1425 >
1426 inline OutputIterator insert(Geometry1 const& geometry1,
1427             Geometry2 const& geometry2,
1428             RobustPolicy robust_policy,
1429             OutputIterator out,
1430             Strategy const& strategy)
1431 {
1432     return std::conditional_t
1433         <
1434             geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
1435             geometry::dispatch::intersection_insert_reversed
1436             <
1437                 Geometry1, Geometry2,
1438                 GeometryOut,
1439                 OverlayType,
1440                 overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
1441                 overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
1442             >,
1443             geometry::dispatch::intersection_insert
1444             <
1445                 Geometry1, Geometry2,
1446                 GeometryOut,
1447                 OverlayType,
1448                 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
1449                 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
1450             >
1451         >::apply(geometry1, geometry2, robust_policy, out, strategy);
1452 }
1453 
1454 
1455 /*!
1456 \brief \brief_calc2{intersection} \brief_strategy
1457 \ingroup intersection
1458 \details \details_calc2{intersection_insert, spatial set theoretic intersection}
1459     \brief_strategy. \details_insert{intersection}
1460 \tparam GeometryOut \tparam_geometry{\p_l_or_c}
1461 \tparam Geometry1 \tparam_geometry
1462 \tparam Geometry2 \tparam_geometry
1463 \tparam OutputIterator \tparam_out{\p_l_or_c}
1464 \tparam Strategy \tparam_strategy_overlay
1465 \param geometry1 \param_geometry
1466 \param geometry2 \param_geometry
1467 \param out \param_out{intersection}
1468 \param strategy \param_strategy{intersection}
1469 \return \return_out
1470 
1471 \qbk{distinguish,with strategy}
1472 \qbk{[include reference/algorithms/intersection.qbk]}
1473 */
1474 template
1475 <
1476     typename GeometryOut,
1477     typename Geometry1,
1478     typename Geometry2,
1479     typename OutputIterator,
1480     typename Strategy
1481 >
1482 inline OutputIterator intersection_insert(Geometry1 const& geometry1,
1483             Geometry2 const& geometry2,
1484             OutputIterator out,
1485             Strategy const& strategy)
1486 {
1487     concepts::check<Geometry1 const>();
1488     concepts::check<Geometry2 const>();
1489 
1490     typedef typename geometry::rescale_overlay_policy_type
1491         <
1492             Geometry1,
1493             Geometry2,
1494             typename Strategy::cs_tag
1495         >::type rescale_policy_type;
1496 
1497     rescale_policy_type robust_policy
1498             = geometry::get_rescale_policy<rescale_policy_type>(
1499                 geometry1, geometry2, strategy);
1500 
1501     return detail::intersection::insert
1502         <
1503             GeometryOut, false, overlay_intersection
1504         >(geometry1, geometry2, robust_policy, out, strategy);
1505 }
1506 
1507 
1508 /*!
1509 \brief \brief_calc2{intersection}
1510 \ingroup intersection
1511 \details \details_calc2{intersection_insert, spatial set theoretic intersection}.
1512     \details_insert{intersection}
1513 \tparam GeometryOut \tparam_geometry{\p_l_or_c}
1514 \tparam Geometry1 \tparam_geometry
1515 \tparam Geometry2 \tparam_geometry
1516 \tparam OutputIterator \tparam_out{\p_l_or_c}
1517 \param geometry1 \param_geometry
1518 \param geometry2 \param_geometry
1519 \param out \param_out{intersection}
1520 \return \return_out
1521 
1522 \qbk{[include reference/algorithms/intersection.qbk]}
1523 */
1524 template
1525 <
1526     typename GeometryOut,
1527     typename Geometry1,
1528     typename Geometry2,
1529     typename OutputIterator
1530 >
1531 inline OutputIterator intersection_insert(Geometry1 const& geometry1,
1532             Geometry2 const& geometry2,
1533             OutputIterator out)
1534 {
1535     concepts::check<Geometry1 const>();
1536     concepts::check<Geometry2 const>();
1537 
1538     typedef typename strategies::relate::services::default_strategy
1539         <
1540             Geometry1, Geometry2
1541         >::type strategy_type;
1542 
1543     return intersection_insert<GeometryOut>(geometry1, geometry2, out,
1544                                             strategy_type());
1545 }
1546 
1547 }} // namespace detail::intersection
1548 #endif // DOXYGEN_NO_DETAIL
1549 
1550 
1551 
1552 }} // namespace boost::geometry
1553 
1554 
1555 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP