Back to home page

EIC code displayed by LXR

 
 

    


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

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