File indexing completed on 2025-01-18 09:36:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
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
0053 && bed_min < bed_max;
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
0114 calc_t const diff_ed = bed_max - bed_min;
0115 calc_t const diff_ing = bing_max - bing_min;
0116
0117
0118 if (diff_ing >= constants::period())
0119 {
0120 return true;
0121 }
0122
0123
0124
0125 if (diff_ing < diff_ed || ! InteriorCheck::apply(diff_ed))
0126 {
0127 return false;
0128 }
0129
0130
0131 calc_t const diff_min = math::longitude_distance_unsigned<units_t>(bing_min, bed_min);
0132
0133
0134 return bing_min + diff_min + diff_ed <= bing_max
0135 ;
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
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 }
0225 #endif
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 }
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
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 }}
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
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 }}
0360
0361
0362 #endif
0363
0364
0365 }}}
0366
0367 #endif