Back to home page

EIC code displayed by LXR

 
 

    


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

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