Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:42

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
0006 // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
0007 
0008 // This file was modified by Oracle on 2015-2020.
0009 // Modifications copyright (c) 2016-2020, Oracle and/or its affiliates.
0010 
0011 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0012 
0013 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0014 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0015 
0016 // Use, modification and distribution is subject to the Boost Software License,
0017 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0018 // http://www.boost.org/LICENSE_1_0.txt)
0019 
0020 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
0021 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
0022 
0023 
0024 #include <boost/geometry/core/access.hpp>
0025 #include <boost/geometry/core/coordinate_dimension.hpp>
0026 #include <boost/geometry/strategies/covered_by.hpp>
0027 #include <boost/geometry/strategies/within.hpp>
0028 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
0029 
0030 
0031 namespace boost { namespace geometry { namespace strategy
0032 {
0033 
0034 
0035 namespace within
0036 {
0037 
0038 
0039 #ifndef DOXYGEN_NO_DETAIL
0040 namespace detail
0041 {
0042 
0043 
0044 struct box_within_coord
0045 {
0046     template <typename BoxContainedValue, typename BoxContainingValue>
0047     static inline bool apply(BoxContainedValue const& bed_min,
0048                              BoxContainedValue const& bed_max,
0049                              BoxContainingValue const& bing_min,
0050                              BoxContainingValue const& bing_max)
0051     {
0052         return bing_min <= bed_min && bed_max <= bing_max // contained in containing
0053             && bed_min < bed_max;                         // interiors overlap
0054     }
0055 };
0056 
0057 
0058 struct box_covered_by_coord
0059 {
0060     template <typename BoxContainedValue, typename BoxContainingValue>
0061     static inline bool apply(BoxContainedValue const& bed_min,
0062                              BoxContainedValue const& bed_max,
0063                              BoxContainingValue const& bing_min,
0064                              BoxContainingValue const& bing_max)
0065     {
0066         return bed_min >= bing_min && bed_max <= bing_max;
0067     }
0068 };
0069 
0070 
0071 struct box_within_longitude_diff
0072 {
0073     template <typename CalcT>
0074     static inline bool apply(CalcT const& diff_ed)
0075     {
0076         return diff_ed > CalcT(0);
0077     }
0078 };
0079 
0080 struct box_covered_by_longitude_diff
0081 {
0082     template <typename CalcT>
0083     static inline bool apply(CalcT const&)
0084     {
0085         return true;
0086     }
0087 };
0088 
0089 template <typename Geometry,
0090           typename CoordCheck,
0091           typename InteriorCheck>
0092 struct box_longitude_range
0093 {
0094     template <typename BoxContainedValue, typename BoxContainingValue>
0095     static inline bool apply(BoxContainedValue const& bed_min,
0096                              BoxContainedValue const& bed_max,
0097                              BoxContainingValue const& bing_min,
0098                              BoxContainingValue const& bing_max)
0099     {
0100         typedef typename select_most_precise
0101             <
0102                 BoxContainedValue,
0103                 BoxContainingValue
0104             >::type calc_t;
0105         typedef typename geometry::detail::cs_angular_units<Geometry>::type units_t;
0106         typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
0107 
0108         if (CoordCheck::apply(bed_min, bed_max, bing_min, bing_max))
0109         {
0110             return true;
0111         }
0112 
0113         // min <= max <=> diff >= 0
0114         calc_t const diff_ed = bed_max - bed_min;
0115         calc_t const diff_ing = bing_max - bing_min;
0116 
0117         // if containing covers the whole globe it contains all
0118         if (diff_ing >= constants::period())
0119         {
0120             return true;
0121         }
0122 
0123         // if containing is smaller it cannot contain
0124         // and check interior (within vs covered_by)
0125         if (diff_ing < diff_ed || ! InteriorCheck::apply(diff_ed))
0126         {
0127             return false;
0128         }
0129 
0130         // calculate positive longitude translation with bing_min as origin
0131         calc_t const diff_min = math::longitude_distance_unsigned<units_t>(bing_min, bed_min);
0132 
0133         // max of contained translated into the containing origin must be lesser than max of containing
0134         return bing_min + diff_min + diff_ed <= bing_max
0135             /*|| bing_max - diff_min - diff_ed >= bing_min*/;
0136     }
0137 };
0138 
0139 
0140 template
0141 <
0142     template <typename, std::size_t, typename> class SubStrategy,
0143     typename CSTag,
0144     std::size_t Dimension,
0145     std::size_t DimensionCount
0146 >
0147 struct relate_box_box_loop
0148 {
0149     template <typename Box1, typename Box2>
0150     static inline bool apply(Box1 const& b_contained, Box2 const& b_containing)
0151     {
0152         assert_dimension_equal<Box1, Box2>();
0153 
0154         if (! SubStrategy<Box1, Dimension, CSTag>::apply(
0155                     get<min_corner, Dimension>(b_contained),
0156                     get<max_corner, Dimension>(b_contained),
0157                     get<min_corner, Dimension>(b_containing),
0158                     get<max_corner, Dimension>(b_containing)
0159                 )
0160             )
0161         {
0162             return false;
0163         }
0164 
0165         return within::detail::relate_box_box_loop
0166             <
0167                 SubStrategy, CSTag,
0168                 Dimension + 1, DimensionCount
0169             >::apply(b_contained, b_containing);
0170     }
0171 };
0172 
0173 template
0174 <
0175     template <typename, std::size_t, typename> class SubStrategy,
0176     typename CSTag,
0177     std::size_t DimensionCount
0178 >
0179 struct relate_box_box_loop<SubStrategy, CSTag, DimensionCount, DimensionCount>
0180 {
0181     template <typename Box1, typename Box2>
0182     static inline bool apply(Box1 const& , Box2 const& )
0183     {
0184         return true;
0185     }
0186 };
0187 
0188 
0189 template <typename Geometry, std::size_t Dimension, typename CSTag>
0190 struct box_within_range
0191     : within::detail::box_within_coord
0192 {};
0193 
0194 
0195 template <typename Geometry, std::size_t Dimension, typename CSTag>
0196 struct box_covered_by_range
0197     : within::detail::box_covered_by_coord
0198 {};
0199 
0200 
0201 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
0202 template <typename Geometry>
0203 struct box_within_range<Geometry, 0, spherical_tag>
0204     : within::detail::box_longitude_range
0205         <
0206             Geometry,
0207             within::detail::box_within_coord,
0208             within::detail::box_within_longitude_diff
0209         >
0210 {};
0211 
0212 
0213 template <typename Geometry>
0214 struct box_covered_by_range<Geometry, 0, spherical_tag>
0215     : within::detail::box_longitude_range
0216         <
0217             Geometry,
0218             within::detail::box_covered_by_coord,
0219             within::detail::box_covered_by_longitude_diff
0220         >
0221 {};
0222 
0223 
0224 } // namespace detail
0225 #endif // DOXYGEN_NO_DETAIL
0226 
0227 
0228 struct cartesian_box_box
0229 {
0230     template <typename Box1, typename Box2>
0231     static inline bool apply(Box1 const& box1, Box2 const& box2)
0232     {
0233         return within::detail::relate_box_box_loop
0234             <
0235                 within::detail::box_within_range,
0236                 cartesian_tag,
0237                 0, dimension<Box1>::type::value
0238             >::apply(box1, box2);
0239     }
0240 };
0241 
0242 struct spherical_box_box
0243 {
0244     template <typename Box1, typename Box2>
0245     static inline bool apply(Box1 const& box1, Box2 const& box2)
0246     {
0247         return within::detail::relate_box_box_loop
0248             <
0249                 within::detail::box_within_range,
0250                 spherical_tag,
0251                 0, dimension<Box1>::type::value
0252             >::apply(box1, box2);
0253     }
0254 };
0255 
0256 
0257 } // namespace within
0258 
0259 
0260 namespace covered_by
0261 {
0262 
0263 
0264 struct cartesian_box_box
0265 {
0266     template <typename Box1, typename Box2>
0267     static inline bool apply(Box1 const& box1, Box2 const& box2)
0268     {
0269         return within::detail::relate_box_box_loop
0270             <
0271                 within::detail::box_covered_by_range,
0272                 cartesian_tag,
0273                 0, dimension<Box1>::type::value
0274             >::apply(box1, box2);
0275     }
0276 };
0277 
0278 struct spherical_box_box
0279 {
0280     template <typename Box1, typename Box2>
0281     static inline bool apply(Box1 const& box1, Box2 const& box2)
0282     {
0283         return within::detail::relate_box_box_loop
0284             <
0285                 within::detail::box_covered_by_range,
0286                 spherical_tag,
0287                 0, dimension<Box1>::type::value
0288             >::apply(box1, box2);
0289     }
0290 };
0291 
0292 
0293 }
0294 
0295 
0296 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0297 
0298 
0299 namespace within { namespace services
0300 {
0301 
0302 template <typename BoxContained, typename BoxContaining>
0303 struct default_strategy
0304     <
0305         BoxContained, BoxContaining,
0306         box_tag, box_tag,
0307         areal_tag, areal_tag,
0308         cartesian_tag, cartesian_tag
0309     >
0310 {
0311     typedef cartesian_box_box type;
0312 };
0313 
0314 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
0315 template <typename BoxContained, typename BoxContaining>
0316 struct default_strategy
0317     <
0318         BoxContained, BoxContaining,
0319         box_tag, box_tag,
0320         areal_tag, areal_tag,
0321         spherical_tag, spherical_tag
0322     >
0323 {
0324     typedef spherical_box_box type;
0325 };
0326 
0327 
0328 }} // namespace within::services
0329 
0330 namespace covered_by { namespace services
0331 {
0332 
0333 template <typename BoxContained, typename BoxContaining>
0334 struct default_strategy
0335     <
0336         BoxContained, BoxContaining,
0337         box_tag, box_tag,
0338         areal_tag, areal_tag,
0339         cartesian_tag, cartesian_tag
0340     >
0341 {
0342     typedef cartesian_box_box type;
0343 };
0344 
0345 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
0346 template <typename BoxContained, typename BoxContaining>
0347 struct default_strategy
0348     <
0349         BoxContained, BoxContaining,
0350         box_tag, box_tag,
0351         areal_tag, areal_tag,
0352         spherical_tag, spherical_tag
0353     >
0354 {
0355     typedef spherical_box_box type;
0356 };
0357 
0358 
0359 }} // namespace covered_by::services
0360 
0361 
0362 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0363 
0364 
0365 }}} // namespace boost::geometry::strategy
0366 
0367 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP