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-2016.
8 // Modifications copyright (c) 2015-2016, 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/strategies/covered_by.hpp>
26 #include <boost/geometry/strategies/within.hpp>
27 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
30 namespace boost { namespace geometry { namespace strategy
37 template <typename Geometry, std::size_t Dimension, typename CSTag>
40 template <typename Value1, typename Value2>
41 static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
43 return value > min_value && value < max_value;
48 template <typename Geometry, std::size_t Dimension, typename CSTag>
49 struct covered_by_range
51 template <typename Value1, typename Value2>
52 static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
54 return value >= min_value && value <= max_value;
59 // NOTE: the result would be the same if instead of structs defined below
60 // the above xxx_range were used with the following arguments:
61 // (min_value + diff_min, min_value, max_value)
62 struct within_longitude_range
64 template <typename CalcT>
65 static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value)
68 return diff_min > c0 && min_value + diff_min < max_value;
72 struct covered_by_longitude_range
74 template <typename CalcT>
75 static inline bool apply(CalcT const& diff_min, CalcT const& min_value, CalcT const& max_value)
77 return min_value + diff_min <= max_value;
82 template <typename Geometry,
84 struct longitude_range
86 template <typename Value1, typename Value2>
87 static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
89 typedef typename select_most_precise
93 typedef typename coordinate_system<Geometry>::type::units units_t;
94 typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
96 // min <= max <=> diff >= 0
97 calc_t const diff_ing = max_value - min_value;
99 // if containing covers the whole globe it contains all
100 if (diff_ing >= constants::period())
105 // calculate positive longitude translation with min_value as origin
106 calc_t const diff_min = math::longitude_distance_unsigned<units_t, calc_t>(min_value, value);
108 return ResultCheck::template apply<calc_t>(diff_min, min_value, max_value);
113 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
114 template <typename Geometry>
115 struct within_range<Geometry, 0, spherical_tag>
116 : longitude_range<Geometry, within_longitude_range>
120 template <typename Geometry>
121 struct covered_by_range<Geometry, 0, spherical_tag>
122 : longitude_range<Geometry, covered_by_longitude_range>
128 template <typename, std::size_t, typename> class SubStrategy,
131 std::size_t Dimension,
132 std::size_t DimensionCount
134 struct relate_point_box_loop
136 static inline bool apply(Point const& point, Box const& box)
138 typedef typename tag_cast<typename cs_tag<Point>::type, spherical_tag>::type cs_tag_t;
140 if (! SubStrategy<Point, Dimension, cs_tag_t>::apply(get<Dimension>(point),
141 get<min_corner, Dimension>(box),
142 get<max_corner, Dimension>(box))
148 return relate_point_box_loop
152 Dimension + 1, DimensionCount
153 >::apply(point, box);
160 template <typename, std::size_t, typename> class SubStrategy,
163 std::size_t DimensionCount
165 struct relate_point_box_loop<SubStrategy, Point, Box, DimensionCount, DimensionCount>
167 static inline bool apply(Point const& , Box const& )
178 template <typename, std::size_t, typename> class SubStrategy = within_range
182 static inline bool apply(Point const& point, Box const& box)
184 return relate_point_box_loop
188 0, dimension<Point>::type::value
189 >::apply(point, box);
194 } // namespace within
197 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
200 namespace within { namespace services
203 template <typename Point, typename Box>
204 struct default_strategy
207 point_tag, areal_tag,
208 cartesian_tag, cartesian_tag,
212 typedef within::point_in_box<Point, Box> type;
215 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
216 template <typename Point, typename Box>
217 struct default_strategy
220 point_tag, areal_tag,
221 spherical_tag, spherical_tag,
225 typedef within::point_in_box<Point, Box> type;
229 }} // namespace within::services
232 namespace covered_by { namespace services
236 template <typename Point, typename Box>
237 struct default_strategy
240 point_tag, areal_tag,
241 cartesian_tag, cartesian_tag,
245 typedef within::point_in_box
248 within::covered_by_range
252 // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
253 template <typename Point, typename Box>
254 struct default_strategy
257 point_tag, areal_tag,
258 spherical_tag, spherical_tag,
262 typedef within::point_in_box
265 within::covered_by_range
270 }} // namespace covered_by::services
273 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
276 }}} // namespace boost::geometry::strategy
279 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP