File indexing completed on 2025-01-18 09:36:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
0020 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
0021
0022
0023 #include <boost/geometry/core/access.hpp>
0024 #include <boost/geometry/core/coordinate_dimension.hpp>
0025 #include <boost/geometry/core/cs.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 namespace within
0035 {
0036
0037 #ifndef DOXYGEN_NO_DETAIL
0038 namespace detail
0039 {
0040
0041 struct within_coord
0042 {
0043 template <typename Value1, typename Value2>
0044 static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
0045 {
0046 return value > min_value && value < max_value;
0047 }
0048 };
0049
0050 struct covered_by_coord
0051 {
0052 template <typename Value1, typename Value2>
0053 static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
0054 {
0055 return value >= min_value && value <= max_value;
0056 }
0057 };
0058
0059 template <typename Geometry, std::size_t Dimension, typename CSTag>
0060 struct within_range
0061 : within_coord
0062 {};
0063
0064
0065 template <typename Geometry, std::size_t Dimension, typename CSTag>
0066 struct covered_by_range
0067 : covered_by_coord
0068 {};
0069
0070
0071
0072
0073
0074 struct within_longitude_diff
0075 {
0076 template <typename CalcT>
0077 static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value)
0078 {
0079 CalcT const c0 = 0;
0080 return diff_min > c0
0081 && (min_value + diff_min < max_value
0082 );
0083 }
0084 };
0085
0086 struct covered_by_longitude_diff
0087 {
0088 template <typename CalcT>
0089 static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value)
0090 {
0091 return min_value + diff_min <= max_value
0092 ;
0093 }
0094 };
0095
0096
0097 template <typename Geometry,
0098 typename CoordCheck,
0099 typename DiffCheck>
0100 struct longitude_range
0101 {
0102 template <typename Value1, typename Value2>
0103 static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
0104 {
0105 typedef typename select_most_precise
0106 <
0107 Value1, Value2
0108 >::type calc_t;
0109 typedef typename geometry::detail::cs_angular_units<Geometry>::type units_t;
0110 typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
0111
0112 if (CoordCheck::apply(value, min_value, max_value))
0113 {
0114 return true;
0115 }
0116
0117
0118 calc_t const diff_ing = max_value - min_value;
0119
0120
0121 if (diff_ing >= constants::period())
0122 {
0123 return true;
0124 }
0125
0126
0127 calc_t const diff_min = math::longitude_distance_unsigned<units_t, calc_t>(min_value, value);
0128
0129 return DiffCheck::template apply<calc_t>(diff_min, min_value, max_value);
0130 }
0131 };
0132
0133
0134
0135 template <typename Geometry>
0136 struct within_range<Geometry, 0, spherical_tag>
0137 : longitude_range<Geometry, within_coord, within_longitude_diff>
0138 {};
0139
0140
0141 template <typename Geometry>
0142 struct covered_by_range<Geometry, 0, spherical_tag>
0143 : longitude_range<Geometry, covered_by_coord, covered_by_longitude_diff>
0144 {};
0145
0146
0147 template
0148 <
0149 template <typename, std::size_t, typename> class SubStrategy,
0150 typename CSTag,
0151 std::size_t Dimension,
0152 std::size_t DimensionCount
0153 >
0154 struct relate_point_box_loop
0155 {
0156 template <typename Point, typename Box>
0157 static inline bool apply(Point const& point, Box const& box)
0158 {
0159 if (! SubStrategy<Point, Dimension, CSTag>::apply(get<Dimension>(point),
0160 get<min_corner, Dimension>(box),
0161 get<max_corner, Dimension>(box))
0162 )
0163 {
0164 return false;
0165 }
0166
0167 return relate_point_box_loop
0168 <
0169 SubStrategy,
0170 CSTag,
0171 Dimension + 1, DimensionCount
0172 >::apply(point, box);
0173 }
0174 };
0175
0176
0177 template
0178 <
0179 template <typename, std::size_t, typename> class SubStrategy,
0180 typename CSTag,
0181 std::size_t DimensionCount
0182 >
0183 struct relate_point_box_loop<SubStrategy, CSTag, DimensionCount, DimensionCount>
0184 {
0185 template <typename Point, typename Box>
0186 static inline bool apply(Point const& , Box const& )
0187 {
0188 return true;
0189 }
0190 };
0191
0192 }
0193 #endif
0194
0195 struct cartesian_point_box
0196 {
0197 template <typename Point, typename Box>
0198 static inline bool apply(Point const& point, Box const& box)
0199 {
0200 return detail::relate_point_box_loop
0201 <
0202 detail::within_range,
0203 cartesian_tag,
0204 0, dimension<Point>::value
0205 >::apply(point, box);
0206 }
0207 };
0208
0209 struct spherical_point_box
0210 {
0211 template <typename Point, typename Box>
0212 static inline bool apply(Point const& point, Box const& box)
0213 {
0214 return detail::relate_point_box_loop
0215 <
0216 detail::within_range,
0217 spherical_tag,
0218 0, dimension<Point>::value
0219 >::apply(point, box);
0220 }
0221 };
0222
0223
0224 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0225 namespace services
0226 {
0227
0228 template <typename Point, typename Box>
0229 struct default_strategy
0230 <
0231 Point, Box,
0232 point_tag, box_tag,
0233 pointlike_tag, areal_tag,
0234 cartesian_tag, cartesian_tag
0235 >
0236 {
0237 typedef within::cartesian_point_box type;
0238 };
0239
0240
0241 template <typename Point, typename Box>
0242 struct default_strategy
0243 <
0244 Point, Box,
0245 point_tag, box_tag,
0246 pointlike_tag, areal_tag,
0247 spherical_tag, spherical_tag
0248 >
0249 {
0250 typedef within::spherical_point_box type;
0251 };
0252
0253
0254 }
0255 #endif
0256
0257 }
0258
0259 namespace covered_by
0260 {
0261
0262 struct cartesian_point_box
0263 {
0264 template <typename Point, typename Box>
0265 static inline bool apply(Point const& point, Box const& box)
0266 {
0267 return within::detail::relate_point_box_loop
0268 <
0269 within::detail::covered_by_range,
0270 cartesian_tag,
0271 0, dimension<Point>::value
0272 >::apply(point, box);
0273 }
0274 };
0275
0276 struct spherical_point_box
0277 {
0278 template <typename Point, typename Box>
0279 static inline bool apply(Point const& point, Box const& box)
0280 {
0281 return within::detail::relate_point_box_loop
0282 <
0283 within::detail::covered_by_range,
0284 spherical_tag,
0285 0, dimension<Point>::value
0286 >::apply(point, box);
0287 }
0288 };
0289
0290
0291 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0292 namespace services
0293 {
0294
0295
0296 template <typename Point, typename Box>
0297 struct default_strategy
0298 <
0299 Point, Box,
0300 point_tag, box_tag,
0301 pointlike_tag, areal_tag,
0302 cartesian_tag, cartesian_tag
0303 >
0304 {
0305 typedef covered_by::cartesian_point_box type;
0306 };
0307
0308
0309 template <typename Point, typename Box>
0310 struct default_strategy
0311 <
0312 Point, Box,
0313 point_tag, box_tag,
0314 pointlike_tag, areal_tag,
0315 spherical_tag, spherical_tag
0316 >
0317 {
0318 typedef covered_by::spherical_point_box type;
0319 };
0320
0321
0322 }
0323 #endif
0324
0325
0326 }
0327
0328
0329 }}}
0330
0331
0332 #endif