1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
7 // This file was modified by Oracle on 2015-2018.
8 // Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
10 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
15 // Use, modification and distribution is subject to the Boost Software License,
16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
17 // http://www.boost.org/LICENSE_1_0.txt)
19 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
20 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
23 #include <boost/geometry/core/access.hpp>
24 #include <boost/geometry/core/coordinate_dimension.hpp>
25 #include <boost/geometry/core/cs.hpp>
26 #include <boost/geometry/strategies/covered_by.hpp>
27 #include <boost/geometry/strategies/within.hpp>
28 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
31 namespace boost { namespace geometry { namespace strategy
37 #ifndef DOXYGEN_NO_DETAIL
43 template <typename Value1, typename Value2>
44 static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
46 return value > min_value && value < max_value;
50 struct covered_by_coord
52 template <typename Value1, typename Value2>
53 static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
55 return value >= min_value && value <= max_value;
59 template <typename Geometry, std::size_t Dimension, typename CSTag>
65 template <typename Geometry, std::size_t Dimension, typename CSTag>
66 struct covered_by_range
71 // NOTE: the result would be the same if instead of structs defined below
72 // the above xxx_range were used with the following arguments:
73 // (min_value + diff_min, min_value, max_value)
74 struct within_longitude_diff
76 template <typename CalcT>
77 static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value)
81 && (min_value + diff_min < max_value
82 /*|| max_value - diff_min > min_value*/);
86 struct covered_by_longitude_diff
88 template <typename CalcT>
89 static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value)
91 return min_value + diff_min <= max_value
92 /*|| max_value - diff_min >= min_value*/;
97 template <typename Geometry,
100 struct longitude_range
102 template <typename Value1, typename Value2>
103 static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
105 typedef typename select_most_precise
109 typedef typename geometry::detail::cs_angular_units<Geometry>::type units_t;
110 typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
112 if (CoordCheck::apply(value, min_value, max_value))
117 // min <= max <=> diff >= 0
118 calc_t const diff_ing = max_value - min_value;
120 // if containing covers the whole globe it contains all
121 if (diff_ing >= constants::period())
126 // calculate positive longitude translation with min_value as origin
127 calc_t const diff_min = math::longitude_distance_unsigned<units_t, calc_t>(min_value, value);
129 return DiffCheck::template apply<calc_t>(diff_min, min_value, max_value);
134 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
135 template <typename Geometry>
136 struct within_range<Geometry, 0, spherical_tag>
137 : longitude_range<Geometry, within_coord, within_longitude_diff>
141 template <typename Geometry>
142 struct covered_by_range<Geometry, 0, spherical_tag>
143 : longitude_range<Geometry, covered_by_coord, covered_by_longitude_diff>
149 template <typename, std::size_t, typename> class SubStrategy,
150 typename CSTag, // cartesian_tag or spherical_tag
151 std::size_t Dimension,
152 std::size_t DimensionCount
154 struct relate_point_box_loop
156 template <typename Point, typename Box>
157 static inline bool apply(Point const& point, Box const& box)
159 if (! SubStrategy<Point, Dimension, CSTag>::apply(get<Dimension>(point),
160 get<min_corner, Dimension>(box),
161 get<max_corner, Dimension>(box))
167 return relate_point_box_loop
171 Dimension + 1, DimensionCount
172 >::apply(point, box);
179 template <typename, std::size_t, typename> class SubStrategy,
181 std::size_t DimensionCount
183 struct relate_point_box_loop<SubStrategy, CSTag, DimensionCount, DimensionCount>
185 template <typename Point, typename Box>
186 static inline bool apply(Point const& , Box const& )
192 } // namespace detail
193 #endif // DOXYGEN_NO_DETAIL
195 struct cartesian_point_box
197 template <typename Point, typename Box>
198 static inline bool apply(Point const& point, Box const& box)
200 return detail::relate_point_box_loop
202 detail::within_range,
204 0, dimension<Point>::value
205 >::apply(point, box);
209 struct spherical_point_box
211 template <typename Point, typename Box>
212 static inline bool apply(Point const& point, Box const& box)
214 return detail::relate_point_box_loop
216 detail::within_range,
218 0, dimension<Point>::value
219 >::apply(point, box);
224 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
228 template <typename Point, typename Box>
229 struct default_strategy
233 pointlike_tag, areal_tag,
234 cartesian_tag, cartesian_tag
237 typedef within::cartesian_point_box type;
240 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
241 template <typename Point, typename Box>
242 struct default_strategy
246 pointlike_tag, areal_tag,
247 spherical_tag, spherical_tag
250 typedef within::spherical_point_box type;
254 } // namespace services
255 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
257 } // namespace within
262 struct cartesian_point_box
264 template <typename Point, typename Box>
265 static inline bool apply(Point const& point, Box const& box)
267 return within::detail::relate_point_box_loop
269 within::detail::covered_by_range,
271 0, dimension<Point>::value
272 >::apply(point, box);
276 struct spherical_point_box
278 template <typename Point, typename Box>
279 static inline bool apply(Point const& point, Box const& box)
281 return within::detail::relate_point_box_loop
283 within::detail::covered_by_range,
285 0, dimension<Point>::value
286 >::apply(point, box);
291 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
296 template <typename Point, typename Box>
297 struct default_strategy
301 pointlike_tag, areal_tag,
302 cartesian_tag, cartesian_tag
305 typedef covered_by::cartesian_point_box type;
308 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
309 template <typename Point, typename Box>
310 struct default_strategy
314 pointlike_tag, areal_tag,
315 spherical_tag, spherical_tag
318 typedef covered_by::spherical_point_box type;
322 } // namespace services
323 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
326 } // namespace covered_by
329 }}} // namespace boost::geometry::strategy
332 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP