Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:35:05

0001 // Boost.Geometry
0002 
0003 // Copyright (c) 2020-2024, Oracle and/or its affiliates.
0004 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0005 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0006 
0007 // Licensed under the Boost Software License version 1.0.
0008 // http://www.boost.org/users/license.html
0009 
0010 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_AREAL_AREAL_HPP
0011 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_AREAL_AREAL_HPP
0012 
0013 
0014 #include <boost/core/ignore_unused.hpp>
0015 
0016 #include <boost/geometry/algorithms/detail/intersection/interface.hpp>
0017 
0018 
0019 namespace boost { namespace geometry
0020 {
0021 
0022 #ifndef DOXYGEN_NO_DETAIL
0023 namespace detail { namespace intersection
0024 {
0025 
0026 
0027 template
0028 <
0029     typename GeometryOut,
0030     typename OutTag = typename geometry::detail::setop_insert_output_tag
0031                         <
0032                             typename geometry::detail::output_geometry_value
0033                                 <
0034                                     GeometryOut
0035                                 >::type
0036                         >::type
0037 >
0038 struct intersection_areal_areal_
0039 {
0040     template
0041     <
0042         typename Areal1,
0043         typename Areal2,
0044         typename Strategy
0045     >
0046     static inline void apply(Areal1 const& areal1,
0047                              Areal2 const& areal2,
0048                              GeometryOut& geometry_out,
0049                              Strategy const& strategy)
0050     {
0051         geometry::dispatch::intersection_insert
0052             <
0053                 Areal1, Areal2,
0054                 typename boost::range_value<GeometryOut>::type,
0055                 overlay_intersection
0056             >::apply(areal1, areal2,
0057                      geometry::range::back_inserter(geometry_out),
0058                      strategy);
0059     }
0060 };
0061 
0062 // TODO: Ideally this should be done in one call of intersection_insert
0063 //   just like it's done for all other combinations
0064 template <typename TupledOut>
0065 struct intersection_areal_areal_<TupledOut, tupled_output_tag>
0066 {
0067     template
0068     <
0069         typename Areal1,
0070         typename Areal2,
0071         typename Strategy
0072     >
0073     static inline void apply(Areal1 const& areal1,
0074                              Areal2 const& areal2,
0075                              TupledOut& geometry_out,
0076                              Strategy const& strategy)
0077     {
0078         using single_out = typename geometry::detail::output_geometry_value
0079             <
0080                 TupledOut
0081             >::type;
0082 
0083         boost::ignore_unused
0084             <
0085                 geometry::detail::expect_output
0086                     <
0087                         Areal1, Areal2, single_out,
0088                         point_tag, linestring_tag, polygon_tag
0089                     >
0090             >();
0091 
0092         using areal = geometry::detail::output_geometry_access
0093             <
0094                 single_out, polygon_tag, polygon_tag
0095             >;
0096         using linear = geometry::detail::output_geometry_access
0097             <
0098                 single_out, linestring_tag, linestring_tag
0099             >;
0100         using pointlike = geometry::detail::output_geometry_access
0101             <
0102                 single_out, point_tag, point_tag
0103             >;
0104 
0105         // A * A -> A
0106         call_intersection(areal1, areal2,
0107                           areal::get(geometry_out),
0108                           strategy);
0109 
0110         bool const is_areal_empty = boost::empty(areal::get(geometry_out));
0111         TupledOut temp_out;
0112 
0113         // L * L -> (L, P)
0114         call_intersection(geometry::detail::boundary_view<Areal1 const>(areal1),
0115                           geometry::detail::boundary_view<Areal2 const>(areal2),
0116                           ! is_areal_empty
0117                             ? temp_out
0118                             : geometry_out,
0119                           strategy);
0120 
0121         if (! is_areal_empty)
0122         {
0123             // NOTE: the original areal geometry could be used instead of boundary here
0124             //   however this results in static assert failure related to rescale policy
0125             // After the removing of rescaling replacing boundary with areal geometry results in
0126             // some tests failing.
0127             using areal_out_type = typename geometry::tuples::element
0128             <
0129                 areal::index, TupledOut
0130             >::type;
0131 
0132             using areal_out_boundary_type = geometry::detail::boundary_view
0133                 <
0134                     areal_out_type const
0135                 >;
0136 
0137             areal_out_boundary_type areal_out_boundary(areal::get(geometry_out));
0138 
0139             // L - L -> L
0140             call_difference(linear::get(temp_out),
0141                             areal_out_boundary,
0142                             linear::get(geometry_out),
0143                             strategy);
0144 
0145             // P - L -> P
0146             call_difference(pointlike::get(temp_out),
0147                             areal_out_boundary,
0148                             pointlike::get(geometry_out),
0149                             strategy);
0150         }
0151 
0152         return;
0153     }
0154 
0155 private:
0156     template
0157     <
0158         typename Geometry1,
0159         typename Geometry2,
0160         typename GeometryOut,
0161         typename Strategy
0162     >
0163     static inline void call_intersection(Geometry1 const& geometry1,
0164                                          Geometry2 const& geometry2,
0165                                          GeometryOut& geometry_out,
0166                                          Strategy const& strategy)
0167     {
0168         geometry::dispatch::intersection_insert
0169             <
0170                 Geometry1,
0171                 Geometry2,
0172                 typename geometry::detail::output_geometry_value
0173                     <
0174                         GeometryOut
0175                     >::type,
0176                 overlay_intersection
0177             >::apply(geometry1,
0178                      geometry2,
0179                      geometry::detail::output_geometry_back_inserter(geometry_out),
0180                      strategy);
0181     }
0182 
0183     template
0184     <
0185         typename Geometry1,
0186         typename Geometry2,
0187         typename GeometryOut,
0188         typename Strategy
0189     >
0190     static inline void call_difference(Geometry1 const& geometry1,
0191                                        Geometry2 const& geometry2,
0192                                        GeometryOut& geometry_out,
0193                                        Strategy const& strategy)
0194     {
0195         geometry::dispatch::intersection_insert
0196             <
0197                 Geometry1,
0198                 Geometry2,
0199                 typename boost::range_value<GeometryOut>::type,
0200                 overlay_difference
0201             >::apply(geometry1,
0202                      geometry2,
0203                      geometry::range::back_inserter(geometry_out),
0204                      strategy);
0205     }
0206 };
0207 
0208 
0209 struct intersection_areal_areal
0210 {
0211     template
0212     <
0213         typename Areal1,
0214         typename Areal2,
0215         typename GeometryOut,
0216         typename Strategy
0217     >
0218     static inline bool apply(Areal1 const& areal1,
0219                              Areal2 const& areal2,
0220                              GeometryOut& geometry_out,
0221                              Strategy const& strategy)
0222     {
0223         intersection_areal_areal_
0224             <
0225                 GeometryOut
0226             >::apply(areal1, areal2, geometry_out, strategy);
0227 
0228         return true;
0229     }
0230 };
0231 
0232 
0233 }} // namespace detail::intersection
0234 #endif // DOXYGEN_NO_DETAIL
0235 
0236 
0237 #ifndef DOXYGEN_NO_DISPATCH
0238 namespace dispatch
0239 {
0240 
0241 
0242 template
0243 <
0244     typename Polygon1, typename Polygon2
0245 >
0246 struct intersection
0247     <
0248         Polygon1, Polygon2,
0249         polygon_tag, polygon_tag,
0250         false
0251     >
0252     : detail::intersection::intersection_areal_areal
0253 {};
0254 
0255 template
0256 <
0257     typename Polygon, typename Ring
0258 >
0259 struct intersection
0260     <
0261         Polygon, Ring,
0262         polygon_tag, ring_tag,
0263         false
0264     >
0265     : detail::intersection::intersection_areal_areal
0266 {};
0267 
0268 template
0269 <
0270     typename Ring1, typename Ring2
0271 >
0272 struct intersection
0273     <
0274         Ring1, Ring2,
0275         ring_tag, ring_tag,
0276         false
0277     >
0278     : detail::intersection::intersection_areal_areal
0279 {};
0280 
0281 template
0282 <
0283     typename Polygon, typename MultiPolygon
0284 >
0285 struct intersection
0286     <
0287         Polygon, MultiPolygon,
0288         polygon_tag, multi_polygon_tag,
0289         false
0290     >
0291     : detail::intersection::intersection_areal_areal
0292 {};
0293 
0294 template
0295 <
0296     typename MultiPolygon, typename Ring
0297 >
0298 struct intersection
0299     <
0300         MultiPolygon, Ring,
0301         multi_polygon_tag, ring_tag,
0302         false
0303     >
0304     : detail::intersection::intersection_areal_areal
0305 {};
0306 
0307 template
0308 <
0309     typename MultiPolygon1, typename MultiPolygon2
0310 >
0311 struct intersection
0312     <
0313         MultiPolygon1, MultiPolygon2,
0314         multi_polygon_tag, multi_polygon_tag,
0315         false
0316     >
0317     : detail::intersection::intersection_areal_areal
0318 {};
0319 
0320 
0321 } // namespace dispatch
0322 #endif // DOXYGEN_NO_DISPATCH
0323 
0324 }} // namespace boost::geometry
0325 
0326 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_AREAL_AREAL_HPP