Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:43:01

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 
0005 // This file was modified by Oracle on 2017-2024.
0006 // Modifications copyright (c) 2017-2024, Oracle and/or its affiliates.
0007 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0008 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0009 
0010 // Use, modification and distribution is subject to the Boost Software License,
0011 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0012 // http://www.boost.org/LICENSE_1_0.txt)
0013 
0014 #ifndef BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
0015 #define BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
0016 
0017 
0018 #include <boost/geometry/algorithms/detail/gc_make_rtree.hpp>
0019 #include <boost/geometry/algorithms/detail/intersection/gc.hpp>
0020 #include <boost/geometry/algorithms/detail/intersection/multi.hpp>
0021 #include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
0022 #include <boost/geometry/algorithms/detail/visit.hpp>
0023 #include <boost/geometry/core/geometry_types.hpp>
0024 #include <boost/geometry/core/primary_single_tag.hpp>
0025 #include <boost/geometry/core/tag_cast.hpp>
0026 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
0027 #include <boost/geometry/strategies/default_strategy.hpp>
0028 #include <boost/geometry/strategies/detail.hpp>
0029 #include <boost/geometry/strategies/relate/cartesian.hpp>
0030 #include <boost/geometry/strategies/relate/geographic.hpp>
0031 #include <boost/geometry/strategies/relate/spherical.hpp>
0032 #include <boost/geometry/util/sequence.hpp>
0033 #include <boost/geometry/views/detail/geometry_collection_view.hpp>
0034 
0035 
0036 namespace boost { namespace geometry
0037 {
0038 
0039 #ifndef DOXYGEN_NO_DETAIL
0040 namespace detail { namespace difference
0041 {
0042 
0043 
0044 // True if the result of difference can be different than Geometry1
0045 template <typename Geometry1, typename Geometry2>
0046 using is_subtractable_t = util::bool_constant
0047     <
0048         (geometry::topological_dimension<Geometry1>::value
0049             <= geometry::topological_dimension<Geometry2>::value)
0050     >;
0051 
0052 
0053 template
0054 <
0055     typename Geometry1,
0056     typename Geometry2,
0057     typename SingleOut,
0058     typename OutTag = typename detail::setop_insert_output_tag<SingleOut>::type,
0059     bool ReturnGeometry1 = (! is_subtractable_t<Geometry1, Geometry2>::value)
0060 >
0061 struct call_intersection_insert
0062 {
0063     template
0064     <
0065         typename OutputIterator,
0066         typename Strategy
0067     >
0068     static inline OutputIterator apply(Geometry1 const& geometry1,
0069                                        Geometry2 const& geometry2,
0070                                        OutputIterator out,
0071                                        Strategy const& strategy)
0072     {
0073         return geometry::dispatch::intersection_insert
0074             <
0075                 Geometry1, Geometry2,
0076                 SingleOut,
0077                 overlay_difference,
0078                 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
0079                 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
0080             >::apply(geometry1, geometry2, out, strategy);
0081     }
0082 };
0083 
0084 
0085 template <typename Geometry1, typename Geometry2, typename SingleOut, typename OutTag>
0086 struct call_intersection_insert<Geometry1, Geometry2, SingleOut, OutTag, true>
0087 {
0088     template <typename OutputIterator, typename Strategy>
0089     static inline OutputIterator apply(Geometry1 const& geometry1,
0090                                        Geometry2 const& ,
0091                                        OutputIterator out,
0092                                        Strategy const& )
0093     {
0094         return geometry::detail::convert_to_output
0095             <
0096                 Geometry1,
0097                 SingleOut
0098             >::apply(geometry1, out);
0099     }
0100 };
0101 
0102 
0103 template
0104 <
0105     typename Geometry1,
0106     typename Geometry2,
0107     typename SingleOut
0108 >
0109 struct call_intersection_insert_tupled_base
0110 {
0111     using single_tag = primary_single_tag_t
0112         <
0113             tag_cast_t<tag_t<Geometry1>, pointlike_tag, linear_tag, areal_tag>
0114         >;
0115 
0116     typedef detail::expect_output
0117         <
0118             Geometry1, Geometry2, SingleOut, single_tag
0119         > expect_check;
0120 
0121     typedef typename geometry::detail::output_geometry_access
0122         <
0123             SingleOut, single_tag, single_tag
0124         > access;
0125 };
0126 
0127 template
0128 <
0129     typename Geometry1,
0130     typename Geometry2,
0131     typename SingleOut
0132 >
0133 struct call_intersection_insert
0134     <
0135         Geometry1, Geometry2, SingleOut,
0136         detail::tupled_output_tag,
0137         false
0138     >
0139     : call_intersection_insert_tupled_base<Geometry1, Geometry2, SingleOut>
0140 {
0141     typedef call_intersection_insert_tupled_base<Geometry1, Geometry2, SingleOut> base_t;
0142 
0143     template
0144     <
0145         typename OutputIterator,
0146         typename Strategy
0147     >
0148     static inline OutputIterator apply(Geometry1 const& geometry1,
0149                                        Geometry2 const& geometry2,
0150                                        OutputIterator out,
0151                                        Strategy const& strategy)
0152     {
0153         base_t::access::get(out) = call_intersection_insert
0154             <
0155                 Geometry1, Geometry2,
0156                 typename base_t::access::type
0157             >::apply(geometry1, geometry2,
0158                      base_t::access::get(out), strategy);
0159 
0160         return out;
0161     }
0162 };
0163 
0164 template
0165 <
0166     typename Geometry1,
0167     typename Geometry2,
0168     typename SingleOut
0169 >
0170 struct call_intersection_insert
0171     <
0172         Geometry1, Geometry2, SingleOut,
0173         detail::tupled_output_tag,
0174         true
0175     >
0176     : call_intersection_insert_tupled_base<Geometry1, Geometry2, SingleOut>
0177 {
0178     typedef call_intersection_insert_tupled_base<Geometry1, Geometry2, SingleOut> base_t;
0179 
0180     template
0181     <
0182         typename OutputIterator,
0183         typename Strategy
0184     >
0185     static inline OutputIterator apply(Geometry1 const& geometry1,
0186                                        Geometry2 const& ,
0187                                        OutputIterator out,
0188                                        Strategy const& )
0189     {
0190         base_t::access::get(out) = geometry::detail::convert_to_output
0191             <
0192                 Geometry1,
0193                 typename base_t::access::type
0194             >::apply(geometry1, base_t::access::get(out));
0195 
0196         return out;
0197     }
0198 };
0199 
0200 
0201 /*!
0202 \brief_calc2{difference} \brief_strategy
0203 \ingroup difference
0204 \details \details_calc2{difference_insert, spatial set theoretic difference}
0205     \brief_strategy. \details_inserter{difference}
0206 \tparam GeometryOut output geometry type, must be specified
0207 \tparam Geometry1 \tparam_geometry
0208 \tparam Geometry2 \tparam_geometry
0209 \tparam OutputIterator output iterator
0210 \tparam Strategy \tparam_strategy_overlay
0211 \param geometry1 \param_geometry
0212 \param geometry2 \param_geometry
0213 \param out \param_out{difference}
0214 \param strategy \param_strategy{difference}
0215 \return \return_out
0216 
0217 \qbk{distinguish,with strategy}
0218 */
0219 template
0220 <
0221     typename GeometryOut,
0222     typename Geometry1,
0223     typename Geometry2,
0224     typename OutputIterator,
0225     typename Strategy
0226 >
0227 inline OutputIterator difference_insert(Geometry1 const& geometry1,
0228                                         Geometry2 const& geometry2,
0229                                         OutputIterator out,
0230                                         Strategy const& strategy)
0231 {
0232     concepts::check<Geometry1 const>();
0233     concepts::check<Geometry2 const>();
0234     //concepts::check<GeometryOut>();
0235     geometry::detail::output_geometry_concept_check<GeometryOut>::apply();
0236 
0237     return geometry::detail::difference::call_intersection_insert
0238         <
0239             Geometry1, Geometry2, GeometryOut
0240         >::apply(geometry1, geometry2, out, strategy);
0241 }
0242 
0243 /*!
0244 \brief_calc2{difference}
0245 \ingroup difference
0246 \details \details_calc2{difference_insert, spatial set theoretic difference}.
0247     \details_insert{difference}
0248 \tparam GeometryOut output geometry type, must be specified
0249 \tparam Geometry1 \tparam_geometry
0250 \tparam Geometry2 \tparam_geometry
0251 \tparam OutputIterator output iterator
0252 \param geometry1 \param_geometry
0253 \param geometry2 \param_geometry
0254 \param out \param_out{difference}
0255 \return \return_out
0256 
0257 \qbk{[include reference/algorithms/difference_insert.qbk]}
0258 */
0259 template
0260 <
0261     typename GeometryOut,
0262     typename Geometry1,
0263     typename Geometry2,
0264     typename OutputIterator
0265 >
0266 inline OutputIterator difference_insert(Geometry1 const& geometry1,
0267                                         Geometry2 const& geometry2,
0268                                         OutputIterator out)
0269 {
0270     typedef typename strategies::relate::services::default_strategy
0271         <
0272             Geometry1,
0273             Geometry2
0274         >::type strategy_type;
0275 
0276     return difference_insert<GeometryOut>(geometry1, geometry2, out,
0277                                           strategy_type());
0278 }
0279 
0280 
0281 template
0282 <
0283     typename Geometry, typename Collection,
0284     typename CastedTag = tag_cast_t<tag_t<Geometry>, pointlike_tag, linear_tag, areal_tag>
0285 >
0286 struct multi_output_type
0287 {
0288     BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
0289         "Not implemented this Geometry type.",
0290         Geometry, CastedTag);
0291 };
0292 
0293 template <typename Geometry, typename Collection>
0294 struct multi_output_type<Geometry, Collection, pointlike_tag>
0295 {
0296     using type = typename util::sequence_find_if
0297         <
0298             typename traits::geometry_types<Collection>::type,
0299             util::is_multi_point
0300         >::type;
0301 };
0302 
0303 template <typename Geometry, typename Collection>
0304 struct multi_output_type<Geometry, Collection, linear_tag>
0305 {
0306     using type = typename util::sequence_find_if
0307         <
0308             typename traits::geometry_types<Collection>::type,
0309             util::is_multi_linestring
0310         >::type;
0311 };
0312 
0313 template <typename Geometry, typename Collection>
0314 struct multi_output_type<Geometry, Collection, areal_tag>
0315 {
0316     using type = typename util::sequence_find_if
0317         <
0318             typename traits::geometry_types<Collection>::type,
0319             util::is_multi_polygon
0320         >::type;
0321 };
0322 
0323 
0324 }} // namespace detail::difference
0325 #endif // DOXYGEN_NO_DETAIL
0326 
0327 
0328 namespace resolve_collection
0329 {
0330 
0331 
0332 template
0333 <
0334     typename Geometry1, typename Geometry2, typename Collection,
0335     typename Tag1 = geometry::tag_t<Geometry1>,
0336     typename Tag2 = geometry::tag_t<Geometry2>,
0337     typename CollectionTag = geometry::tag_t<Collection>
0338 >
0339 struct difference
0340 {
0341     template <typename Strategy>
0342     static void apply(Geometry1 const& geometry1,
0343                       Geometry2 const& geometry2,
0344                       Collection & output_collection,
0345                       Strategy const& strategy)
0346     {
0347         using single_out = typename geometry::detail::output_geometry_value
0348             <
0349                 Collection
0350             >::type;
0351 
0352         detail::difference::difference_insert<single_out>(
0353             geometry1, geometry2,
0354             geometry::detail::output_geometry_back_inserter(output_collection),
0355             strategy);
0356     }
0357 };
0358 
0359 template <typename Geometry1, typename Geometry2, typename Collection>
0360 struct difference
0361     <
0362         Geometry1, Geometry2, Collection,
0363         geometry_collection_tag, geometry_collection_tag, geometry_collection_tag
0364     >
0365 {
0366     template <typename Strategy>
0367     static void apply(Geometry1 const& geometry1,
0368                       Geometry2 const& geometry2,
0369                       Collection& output_collection,
0370                       Strategy const& strategy)
0371     {
0372         auto const rtree2 = detail::gc_make_rtree_iterators(geometry2, strategy);
0373         detail::visit_breadth_first([&](auto const& g1)
0374         {
0375             // multi-point, multi-linestring or multi_polygon
0376             typename detail::difference::multi_output_type
0377                 <
0378                     util::remove_cref_t<decltype(g1)>, Collection
0379                 >::type out;
0380 
0381             g1_minus_gc2(g1, rtree2, out, strategy);
0382 
0383             detail::intersection::gc_move_multi_back(output_collection, out);
0384 
0385             return true;
0386         }, geometry1);
0387     }
0388 
0389 private:
0390     // Implemented as separate function because msvc is unable to do nested lambda capture
0391     template <typename G1, typename Rtree2, typename MultiOut, typename Strategy>
0392     static void g1_minus_gc2(G1 const& g1, Rtree2 const& rtree2, MultiOut& out, Strategy const& strategy)
0393     {
0394         {
0395             using single_out_t = typename geometry::detail::output_geometry_value<MultiOut>::type;
0396             auto out_it = geometry::detail::output_geometry_back_inserter(out);
0397             geometry::detail::convert_to_output<G1, single_out_t>::apply(g1, out_it);
0398         }
0399 
0400         using box1_t = detail::gc_make_rtree_box_t<G1>;
0401         box1_t b1 = geometry::return_envelope<box1_t>(g1, strategy);
0402         detail::expand_by_epsilon(b1);
0403 
0404         for (auto qit = rtree2.qbegin(index::intersects(b1)); qit != rtree2.qend(); ++qit)
0405         {
0406             traits::iter_visit<Geometry2>::apply([&](auto const& g2)
0407             {
0408                 multi_out_minus_g2(out, g2, strategy);
0409             }, qit->second);
0410 
0411             if (boost::empty(out))
0412             {
0413                 return;
0414             }
0415         }
0416     }
0417 
0418     template
0419     <
0420         typename MultiOut, typename G2, typename Strategy,
0421         std::enable_if_t<detail::difference::is_subtractable_t<MultiOut, G2>::value, int> = 0
0422     >
0423     static void multi_out_minus_g2(MultiOut& out, G2 const& g2, Strategy const& strategy)
0424     {
0425         MultiOut result;
0426         difference<MultiOut, G2, MultiOut>::apply(out, g2, result, strategy);
0427         out = std::move(result);
0428     }
0429 
0430     template
0431     <
0432         typename MultiOut, typename G2, typename Strategy,
0433         std::enable_if_t<(! detail::difference::is_subtractable_t<MultiOut, G2>::value), int> = 0
0434     >
0435     static void multi_out_minus_g2(MultiOut& , G2 const& , Strategy const& )
0436     {}
0437 };
0438 
0439 
0440 template <typename Geometry1, typename Geometry2, typename Collection, typename Tag1>
0441 struct difference
0442     <
0443         Geometry1, Geometry2, Collection,
0444         Tag1, geometry_collection_tag, geometry_collection_tag
0445     >
0446 {
0447     template <typename Strategy>
0448     static void apply(Geometry1 const& geometry1,
0449                       Geometry2 const& geometry2,
0450                       Collection & output_collection,
0451                       Strategy const& strategy)
0452     {
0453         using gc_view_t = geometry::detail::geometry_collection_view<Geometry1>;
0454         difference
0455             <
0456                 gc_view_t, Geometry2, Collection
0457             >::apply(gc_view_t(geometry1), geometry2, output_collection, strategy);
0458     }
0459 };
0460 
0461 template <typename Geometry1, typename Geometry2, typename Collection, typename Tag2>
0462 struct difference
0463     <
0464         Geometry1, Geometry2, Collection,
0465         geometry_collection_tag, Tag2, geometry_collection_tag
0466     >
0467 {
0468     template <typename Strategy>
0469     static void apply(Geometry1 const& geometry1,
0470                       Geometry2 const& geometry2,
0471                       Collection & output_collection,
0472                       Strategy const& strategy)
0473     {
0474         using gc_view_t = geometry::detail::geometry_collection_view<Geometry2>;
0475         difference
0476             <
0477                 Geometry1, gc_view_t, Collection
0478             >::apply(geometry1, gc_view_t(geometry2), output_collection, strategy);
0479     }
0480 };
0481 
0482 template <typename Geometry1, typename Geometry2, typename Collection, typename Tag1, typename Tag2>
0483 struct difference
0484     <
0485         Geometry1, Geometry2, Collection,
0486         Tag1, Tag2, geometry_collection_tag
0487     >
0488 {
0489     template <typename Strategy>
0490     static void apply(Geometry1 const& geometry1,
0491                       Geometry2 const& geometry2,
0492                       Collection & output_collection,
0493                       Strategy const& strategy)
0494     {
0495         using gc1_view_t = geometry::detail::geometry_collection_view<Geometry1>;
0496         using gc2_view_t = geometry::detail::geometry_collection_view<Geometry2>;
0497         difference
0498             <
0499                 gc1_view_t, gc2_view_t, Collection
0500             >::apply(gc1_view_t(geometry1), gc2_view_t(geometry2), output_collection, strategy);
0501     }
0502 };
0503 
0504 
0505 } // namespace resolve_collection
0506 
0507 
0508 namespace resolve_strategy {
0509 
0510 template
0511 <
0512     typename Strategy,
0513     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0514 >
0515 struct difference
0516 {
0517     template <typename Geometry1, typename Geometry2, typename Collection>
0518     static inline void apply(Geometry1 const& geometry1,
0519                              Geometry2 const& geometry2,
0520                              Collection & output_collection,
0521                              Strategy const& strategy)
0522     {
0523         resolve_collection::difference
0524             <
0525                 Geometry1, Geometry2, Collection
0526             >::apply(geometry1, geometry2, output_collection, strategy);
0527     }
0528 };
0529 
0530 template <typename Strategy>
0531 struct difference<Strategy, false>
0532 {
0533     template <typename Geometry1, typename Geometry2, typename Collection>
0534     static inline void apply(Geometry1 const& geometry1,
0535                              Geometry2 const& geometry2,
0536                              Collection & output_collection,
0537                              Strategy const& strategy)
0538     {
0539         using strategies::relate::services::strategy_converter;
0540 
0541         difference
0542             <
0543                 decltype(strategy_converter<Strategy>::get(strategy))
0544             >::apply(geometry1, geometry2, output_collection,
0545                      strategy_converter<Strategy>::get(strategy));
0546     }
0547 };
0548 
0549 template <>
0550 struct difference<default_strategy, false>
0551 {
0552     template <typename Geometry1, typename Geometry2, typename Collection>
0553     static inline void apply(Geometry1 const& geometry1,
0554                              Geometry2 const& geometry2,
0555                              Collection & output_collection,
0556                              default_strategy)
0557     {
0558         typedef typename strategies::relate::services::default_strategy
0559             <
0560                 Geometry1,
0561                 Geometry2
0562             >::type strategy_type;
0563 
0564         difference
0565             <
0566                 strategy_type
0567             >::apply(geometry1, geometry2, output_collection, strategy_type());
0568     }
0569 };
0570 
0571 } // resolve_strategy
0572 
0573 
0574 namespace resolve_dynamic
0575 {
0576 
0577 template
0578 <
0579     typename Geometry1, typename Geometry2,
0580     typename Tag1 = geometry::tag_t<Geometry1>,
0581     typename Tag2 = geometry::tag_t<Geometry2>
0582 >
0583 struct difference
0584 {
0585     template <typename Collection, typename Strategy>
0586     static void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0587                       Collection& output_collection, Strategy const& strategy)
0588     {
0589         resolve_strategy::difference
0590             <
0591                 Strategy
0592             >::apply(geometry1, geometry2, output_collection, strategy);
0593     }
0594 };
0595 
0596 template <typename DynamicGeometry1, typename Geometry2, typename Tag2>
0597 struct difference<DynamicGeometry1, Geometry2, dynamic_geometry_tag, Tag2>
0598 {
0599     template <typename Collection, typename Strategy>
0600     static void apply(DynamicGeometry1 const& geometry1, Geometry2 const& geometry2,
0601                       Collection& output_collection, Strategy const& strategy)
0602     {
0603         traits::visit<DynamicGeometry1>::apply([&](auto const& g1)
0604         {
0605             resolve_strategy::difference
0606                 <
0607                     Strategy
0608                 >::apply(g1, geometry2, output_collection, strategy);
0609         }, geometry1);
0610     }
0611 };
0612 
0613 template <typename Geometry1, typename DynamicGeometry2, typename Tag1>
0614 struct difference<Geometry1, DynamicGeometry2, Tag1, dynamic_geometry_tag>
0615 {
0616     template <typename Collection, typename Strategy>
0617     static void apply(Geometry1 const& geometry1, DynamicGeometry2 const& geometry2,
0618                       Collection& output_collection, Strategy const& strategy)
0619     {
0620         traits::visit<DynamicGeometry2>::apply([&](auto const& g2)
0621         {
0622             resolve_strategy::difference
0623                 <
0624                     Strategy
0625                 >::apply(geometry1, g2, output_collection, strategy);
0626         }, geometry2);
0627     }
0628 };
0629 
0630 template <typename DynamicGeometry1, typename DynamicGeometry2>
0631 struct difference<DynamicGeometry1, DynamicGeometry2, dynamic_geometry_tag, dynamic_geometry_tag>
0632 {
0633     template <typename Collection, typename Strategy>
0634     static void apply(DynamicGeometry1 const& geometry1, DynamicGeometry2 const& geometry2,
0635                       Collection& output_collection, Strategy const& strategy)
0636     {
0637         traits::visit<DynamicGeometry1, DynamicGeometry2>::apply([&](auto const& g1, auto const& g2)
0638         {
0639             resolve_strategy::difference
0640                 <
0641                     Strategy
0642                 >::apply(g1, g2, output_collection, strategy);
0643         }, geometry1, geometry2);
0644     }
0645 };
0646 
0647 } // namespace resolve_dynamic
0648 
0649 
0650 /*!
0651 \brief_calc2{difference}
0652 \ingroup difference
0653 \details \details_calc2{difference, spatial set theoretic difference}.
0654 \tparam Geometry1 \tparam_geometry
0655 \tparam Geometry2 \tparam_geometry
0656 \tparam Collection \tparam_output_collection
0657 \tparam Strategy \tparam_strategy{Difference}
0658 \param geometry1 \param_geometry
0659 \param geometry2 \param_geometry
0660 \param output_collection the output collection
0661 \param strategy \param_strategy{difference}
0662 
0663 \qbk{distinguish,with strategy}
0664 \qbk{[include reference/algorithms/difference.qbk]}
0665 */
0666 template
0667 <
0668     typename Geometry1,
0669     typename Geometry2,
0670     typename Collection,
0671     typename Strategy
0672 >
0673 inline void difference(Geometry1 const& geometry1,
0674                        Geometry2 const& geometry2,
0675                        Collection& output_collection,
0676                        Strategy const& strategy)
0677 {
0678     resolve_dynamic::difference
0679         <
0680             Geometry1,
0681             Geometry2
0682         >::apply(geometry1, geometry2, output_collection, strategy);
0683 }
0684 
0685 
0686 /*!
0687 \brief_calc2{difference}
0688 \ingroup difference
0689 \details \details_calc2{difference, spatial set theoretic difference}.
0690 \tparam Geometry1 \tparam_geometry
0691 \tparam Geometry2 \tparam_geometry
0692 \tparam Collection \tparam_output_collection
0693 \param geometry1 \param_geometry
0694 \param geometry2 \param_geometry
0695 \param output_collection the output collection
0696 
0697 \qbk{[include reference/algorithms/difference.qbk]}
0698 */
0699 template
0700 <
0701     typename Geometry1,
0702     typename Geometry2,
0703     typename Collection
0704 >
0705 inline void difference(Geometry1 const& geometry1,
0706                        Geometry2 const& geometry2,
0707                        Collection& output_collection)
0708 {
0709     resolve_dynamic::difference
0710         <
0711             Geometry1,
0712             Geometry2
0713         >::apply(geometry1, geometry2, output_collection, default_strategy());
0714 }
0715 
0716 
0717 }} // namespace boost::geometry
0718 
0719 
0720 #endif // BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP