Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:51:36

0001 // Boost.Geometry
0002 
0003 // Copyright (c) 2020-2023, Oracle and/or its affiliates.
0004 
0005 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0006 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0007 
0008 // Licensed under the Boost Software License version 1.0.
0009 // http://www.boost.org/users/license.html
0010 
0011 #ifndef BOOST_GEOMETRY_STRATEGIES_RELATE_CARTESIAN_HPP
0012 #define BOOST_GEOMETRY_STRATEGIES_RELATE_CARTESIAN_HPP
0013 
0014 
0015 // TEMP - move to strategy
0016 #include <boost/geometry/strategies/agnostic/point_in_box_by_side.hpp>
0017 #include <boost/geometry/strategies/cartesian/intersection.hpp>
0018 #include <boost/geometry/strategies/cartesian/box_in_box.hpp>
0019 #include <boost/geometry/strategies/cartesian/point_in_point.hpp>
0020 #include <boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp>
0021 #include <boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp>
0022 #include <boost/geometry/strategies/cartesian/point_in_poly_winding.hpp>
0023 #include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
0024 
0025 #include <boost/geometry/strategies/distance/detail.hpp>
0026 #include <boost/geometry/strategies/distance/services.hpp>
0027 #include <boost/geometry/strategies/envelope/cartesian.hpp>
0028 #include <boost/geometry/strategies/relate/services.hpp>
0029 #include <boost/geometry/strategies/detail.hpp>
0030 
0031 #include <boost/geometry/strategy/cartesian/area.hpp>
0032 #include <boost/geometry/strategy/cartesian/side_robust.hpp>
0033 #include <boost/geometry/strategy/cartesian/side_by_triangle.hpp>
0034 #include <boost/geometry/strategy/cartesian/area_box.hpp>
0035 
0036 #include <boost/geometry/util/type_traits.hpp>
0037 
0038 
0039 namespace boost { namespace geometry
0040 {
0041 
0042 namespace strategies { namespace relate
0043 {
0044 
0045 template <typename CalculationType = void>
0046 class cartesian
0047     : public strategies::envelope::cartesian<CalculationType>
0048 {
0049 public:
0050     //area
0051 
0052     template <typename Geometry>
0053     static auto area(Geometry const&,
0054                      std::enable_if_t<! util::is_box<Geometry>::value> * = nullptr)
0055     {
0056         return strategy::area::cartesian<CalculationType>();
0057     }
0058 
0059     template <typename Geometry>
0060     static auto area(Geometry const&,
0061                      std::enable_if_t<util::is_box<Geometry>::value> * = nullptr)
0062     {
0063         return strategy::area::cartesian_box<CalculationType>();
0064     }
0065 
0066     // covered_by
0067 
0068     template <typename Geometry1, typename Geometry2>
0069     static auto covered_by(Geometry1 const&, Geometry2 const&,
0070                            std::enable_if_t
0071                                 <
0072                                     util::is_pointlike<Geometry1>::value
0073                                  && util::is_box<Geometry2>::value
0074                                 > * = nullptr)
0075     {
0076         return strategy::covered_by::cartesian_point_box();
0077     }
0078 
0079     template <typename Geometry1, typename Geometry2>
0080     static auto covered_by(Geometry1 const&, Geometry2 const&,
0081                            std::enable_if_t
0082                             <
0083                                 util::is_box<Geometry1>::value
0084                              && util::is_box<Geometry2>::value
0085                             > * = nullptr)
0086     {
0087         return strategy::covered_by::cartesian_box_box();
0088     }
0089 
0090     // disjoint
0091 
0092     template <typename Geometry1, typename Geometry2>
0093     static auto disjoint(Geometry1 const&, Geometry2 const&,
0094                          std::enable_if_t
0095                             <
0096                                 util::is_box<Geometry1>::value
0097                              && util::is_box<Geometry2>::value
0098                             > * = nullptr)
0099     {
0100         return strategy::disjoint::cartesian_box_box();
0101     }
0102 
0103     template <typename Geometry1, typename Geometry2>
0104     static auto disjoint(Geometry1 const&, Geometry2 const&,
0105                          std::enable_if_t
0106                             <
0107                                 util::is_segment<Geometry1>::value
0108                              && util::is_box<Geometry2>::value
0109                             > * = nullptr)
0110     {
0111         // NOTE: Inconsistent name.
0112         return strategy::disjoint::segment_box();
0113     }
0114 
0115     // relate
0116 
0117     template <typename Geometry1, typename Geometry2>
0118     static auto relate(Geometry1 const&, Geometry2 const&,
0119                        std::enable_if_t
0120                             <
0121                                 util::is_pointlike<Geometry1>::value
0122                              && util::is_pointlike<Geometry2>::value
0123                             > * = nullptr)
0124     {
0125         return strategy::within::cartesian_point_point();
0126     }
0127 
0128     template <typename Geometry1, typename Geometry2>
0129     static auto relate(Geometry1 const&, Geometry2 const&,
0130                        std::enable_if_t
0131                             <
0132                                 util::is_pointlike<Geometry1>::value
0133                              && ( util::is_linear<Geometry2>::value
0134                                || util::is_polygonal<Geometry2>::value )
0135                             > * = nullptr)
0136     {
0137         return strategy::within::cartesian_winding<void, void, CalculationType>();
0138     }
0139 
0140     // The problem is that this strategy is often used with non-geometry ranges.
0141     // So dispatching only by geometry categories is impossible.
0142     // In the past it was taking two segments, now it takes 3-point sub-ranges.
0143     // So dispatching by segments is impossible.
0144     // It could be dispatched by (linear || polygonal || non-geometry point range).
0145     // For now implement as 0-parameter, special case relate.
0146 
0147     //template <typename Geometry1, typename Geometry2>
0148     static auto relate(/*Geometry1 const&, Geometry2 const&,
0149                        std::enable_if_t
0150                             <
0151                                 ( util::is_linear<Geometry1>::value
0152                                || util::is_polygonal<Geometry1>::value )
0153                              && ( util::is_linear<Geometry2>::value
0154                                || util::is_polygonal<Geometry2>::value )
0155                             > * = nullptr*/)
0156     {
0157         return strategy::intersection::cartesian_segments<CalculationType>();
0158     }
0159 
0160     template <typename Geometry1, typename Geometry2>
0161     static auto comparable_distance(Geometry1 const&, Geometry2 const&,
0162                                     distance::detail::enable_if_pp_t<Geometry1, Geometry2> * = nullptr)
0163     {
0164         return strategy::distance::comparable::pythagoras<CalculationType>();
0165     }
0166 
0167     // side
0168 
0169     static auto side()
0170     {
0171         using side_strategy_type
0172             = typename strategy::side::services::default_strategy
0173                 <cartesian_tag, CalculationType>::type;
0174         return side_strategy_type();
0175     }
0176 
0177     // within
0178 
0179     template <typename Geometry1, typename Geometry2>
0180     static auto within(Geometry1 const&, Geometry2 const&,
0181                        std::enable_if_t
0182                             <
0183                                 util::is_pointlike<Geometry1>::value
0184                                 && util::is_box<Geometry2>::value
0185                             > * = nullptr)
0186     {
0187         return strategy::within::cartesian_point_box();
0188     }
0189 
0190     template <typename Geometry1, typename Geometry2>
0191     static auto within(Geometry1 const&, Geometry2 const&,
0192                        std::enable_if_t
0193                             <
0194                                 util::is_box<Geometry1>::value
0195                              && util::is_box<Geometry2>::value
0196                             > * = nullptr)
0197     {
0198         return strategy::within::cartesian_box_box();
0199     }
0200 
0201     template <typename ComparePolicy, typename EqualsPolicy>
0202     using compare_type = typename strategy::compare::cartesian
0203         <
0204             ComparePolicy,
0205             EqualsPolicy,
0206             -1
0207         >;
0208 };
0209 
0210 
0211 namespace services
0212 {
0213 
0214 template <typename Geometry1, typename Geometry2>
0215 struct default_strategy<Geometry1, Geometry2, cartesian_tag, cartesian_tag>
0216 {
0217     using type = strategies::relate::cartesian<>;
0218 };
0219 
0220 
0221 template <>
0222 struct strategy_converter<strategy::within::cartesian_point_point>
0223 {
0224     static auto get(strategy::within::cartesian_point_point const& )
0225     {
0226         return strategies::relate::cartesian<>();
0227     }
0228 };
0229 
0230 template <>
0231 struct strategy_converter<strategy::within::cartesian_point_box>
0232 {
0233     static auto get(strategy::within::cartesian_point_box const&)
0234     {
0235         return strategies::relate::cartesian<>();
0236     }
0237 };
0238 
0239 template <>
0240 struct strategy_converter<strategy::covered_by::cartesian_point_box>
0241 {
0242     static auto get(strategy::covered_by::cartesian_point_box const&)
0243     {
0244         return strategies::relate::cartesian<>();
0245     }
0246 };
0247 
0248 template <>
0249 struct strategy_converter<strategy::covered_by::cartesian_box_box>
0250 {
0251     static auto get(strategy::covered_by::cartesian_box_box const&)
0252     {
0253         return strategies::relate::cartesian<>();
0254     }
0255 };
0256 
0257 template <>
0258 struct strategy_converter<strategy::disjoint::cartesian_box_box>
0259 {
0260     static auto get(strategy::disjoint::cartesian_box_box const&)
0261     {
0262         return strategies::relate::cartesian<>();
0263     }
0264 };
0265 
0266 template <>
0267 struct strategy_converter<strategy::disjoint::segment_box>
0268 {
0269     static auto get(strategy::disjoint::segment_box const&)
0270     {
0271         return strategies::relate::cartesian<>();
0272     }
0273 };
0274 
0275 template <>
0276 struct strategy_converter<strategy::within::cartesian_box_box>
0277 {
0278     static auto get(strategy::within::cartesian_box_box const&)
0279     {
0280         return strategies::relate::cartesian<>();
0281     }
0282 };
0283 
0284 template <typename P1, typename P2, typename CalculationType>
0285 struct strategy_converter<strategy::within::cartesian_winding<P1, P2, CalculationType>>
0286 {
0287     static auto get(strategy::within::cartesian_winding<P1, P2, CalculationType> const& )
0288     {
0289         return strategies::relate::cartesian<CalculationType>();
0290     }
0291 };
0292 
0293 template <typename CalculationType>
0294 struct strategy_converter<strategy::intersection::cartesian_segments<CalculationType>>
0295 {
0296     static auto get(strategy::intersection::cartesian_segments<CalculationType> const& )
0297     {
0298         return strategies::relate::cartesian<CalculationType>();
0299     }
0300 };
0301 
0302 template <typename CalculationType>
0303 struct strategy_converter<strategy::within::cartesian_point_box_by_side<CalculationType>>
0304 {
0305     struct altered_strategy
0306         : strategies::relate::cartesian<CalculationType>
0307     {
0308         template <typename Geometry1, typename Geometry2>
0309         static auto covered_by(Geometry1 const&, Geometry2 const&,
0310                                std::enable_if_t
0311                                     <
0312                                         util::is_pointlike<Geometry1>::value
0313                                      && util::is_box<Geometry2>::value
0314                                     > * = nullptr)
0315         {
0316             return strategy::covered_by::cartesian_point_box_by_side<CalculationType>();
0317         }
0318 
0319         template <typename Geometry1, typename Geometry2>
0320         static auto within(Geometry1 const&, Geometry2 const&,
0321                            std::enable_if_t
0322                                 <
0323                                     util::is_pointlike<Geometry1>::value
0324                                     && util::is_box<Geometry2>::value
0325                                 > * = nullptr)
0326         {
0327             return strategy::within::cartesian_point_box_by_side<CalculationType>();
0328         }
0329     };
0330 
0331     static auto get(strategy::covered_by::cartesian_point_box_by_side<CalculationType> const&)
0332     {
0333         return altered_strategy();
0334     }
0335 
0336     static auto get(strategy::within::cartesian_point_box_by_side<CalculationType> const&)
0337     {
0338         return altered_strategy();
0339     }
0340 };
0341 
0342 template <typename CalculationType>
0343 struct strategy_converter<strategy::covered_by::cartesian_point_box_by_side<CalculationType>>
0344     : strategy_converter<strategy::within::cartesian_point_box_by_side<CalculationType>>
0345 {};
0346 
0347 template <typename P1, typename P2, typename CalculationType>
0348 struct strategy_converter<strategy::within::franklin<P1, P2, CalculationType>>
0349 {
0350     struct altered_strategy
0351         : strategies::relate::cartesian<CalculationType>
0352     {
0353         template <typename Geometry1, typename Geometry2>
0354         static auto relate(Geometry1 const&, Geometry2 const&,
0355                            std::enable_if_t
0356                                 <
0357                                     util::is_pointlike<Geometry1>::value
0358                                  && ( util::is_linear<Geometry2>::value
0359                                    || util::is_polygonal<Geometry2>::value )
0360                                 > * = nullptr)
0361         {
0362             return strategy::within::franklin<void, void, CalculationType>();
0363         }
0364     };
0365 
0366     static auto get(strategy::within::franklin<P1, P2, CalculationType> const&)
0367     {
0368         return altered_strategy();
0369     }
0370 };
0371 
0372 template <typename P1, typename P2, typename CalculationType>
0373 struct strategy_converter<strategy::within::crossings_multiply<P1, P2, CalculationType>>
0374 {
0375     struct altered_strategy
0376         : strategies::relate::cartesian<CalculationType>
0377     {
0378         template <typename Geometry1, typename Geometry2>
0379         static auto relate(Geometry1 const&, Geometry2 const&,
0380                            std::enable_if_t
0381                                 <
0382                                     util::is_pointlike<Geometry1>::value
0383                                  && ( util::is_linear<Geometry2>::value
0384                                    || util::is_polygonal<Geometry2>::value )
0385                                 > * = nullptr)
0386         {
0387             return strategy::within::crossings_multiply<void, void, CalculationType>();
0388         }
0389     };
0390 
0391     static auto get(strategy::within::crossings_multiply<P1, P2, CalculationType> const&)
0392     {
0393         return altered_strategy();
0394     }
0395 };
0396 
0397 // TEMP used in distance segment/box
0398 template <typename CalculationType>
0399 struct strategy_converter<strategy::side::side_by_triangle<CalculationType>>
0400 {
0401     static auto get(strategy::side::side_by_triangle<CalculationType> const&)
0402     {
0403         return strategies::relate::cartesian<CalculationType>();
0404     }
0405 };
0406 
0407 template <typename CalculationType>
0408 struct strategy_converter<strategy::side::side_robust<CalculationType>>
0409 {
0410     static auto get(strategy::side::side_robust<CalculationType> const&)
0411     {
0412         return strategies::relate::cartesian<CalculationType>();
0413     }
0414 };
0415 
0416 
0417 } // namespace services
0418 
0419 }} // namespace strategies::relate
0420 
0421 }} // namespace boost::geometry
0422 
0423 #endif // BOOST_GEOMETRY_STRATEGIES_RELATE_CARTESIAN_HPP