• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3 
4 // Copyright (c) 2015-2017, Oracle and/or its affiliates.
5 
6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
8 
9 // Licensed under the Boost Software License version 1.0.
10 // http://www.boost.org/users/license.html
11 
12 #ifndef BOOST_GEOMETRY_TEST_ENVELOPE_EXPAND_ON_SPHEROID_HPP
13 #define BOOST_GEOMETRY_TEST_ENVELOPE_EXPAND_ON_SPHEROID_HPP
14 
15 
16 #include <algorithm>
17 #include <cmath>
18 #include <cstddef>
19 #include <iostream>
20 
21 #include <boost/type_traits/is_same.hpp>
22 
23 #include <boost/geometry/core/access.hpp>
24 #include <boost/geometry/core/coordinate_dimension.hpp>
25 #include <boost/geometry/core/cs.hpp>
26 
27 #include <boost/geometry/util/condition.hpp>
28 #include <boost/geometry/util/math.hpp>
29 
30 #include <boost/geometry/views/detail/indexed_point_view.hpp>
31 
32 #include <boost/geometry/algorithms/assign.hpp>
33 
34 
35 struct rng
36 {
37     typedef double type;
38 
rngrng39     rng(double l, double h)
40         : lo(l), hi(h)
41     {
42         BOOST_GEOMETRY_ASSERT(lo <= hi);
43     }
44 
operator *(rng const & l,double v)45     friend rng operator*(rng const& l, double v) { return rng(l.lo * v, l.hi * v); }
46 
operator <=(rng const & l,rng const & r)47     friend bool operator<=(rng const& l, rng const& r) { return l.lo <= r.hi; }
operator <=(double l,rng const & r)48     friend bool operator<=(double l, rng const& r) { return l <= r.hi; }
operator <=(rng const & l,double r)49     friend bool operator<=(rng const& l, double r) { return l.lo <= r; }
50 
operator <(rng const & l,rng const & r)51     friend bool operator<(rng const& l, rng const& r) { return !operator<=(r, l); }
operator <(double l,rng const & r)52     friend bool operator<(double l, rng const& r) { return !operator<=(r, l); }
operator <(rng const & l,double r)53     friend bool operator<(rng const& l, double r) { return !operator<=(r, l); }
54 
operator ==(double l,rng const & r)55     friend bool operator==(double l, rng const& r) { return r.lo <= l && l <= r.hi; }
56 
operator <<(std::ostream & os,rng const & v)57     friend std::ostream & operator<<(std::ostream & os, rng const& v)
58     {
59         return (os << "[" << v.lo << ", " << v.hi << "]");
60     }
61 
62     double lo, hi;
63 };
64 
65 
66 template <typename Units>
units2string()67 char const* units2string()
68 {
69     if (BOOST_GEOMETRY_CONDITION((boost::is_same<Units, bg::degree>::value)))
70     {
71         return "degrees";
72     }
73     return "radians";
74 }
75 
76 template <typename CoordinateSystem>
77 struct other_system_info
78 {};
79 
80 template <>
81 struct other_system_info<bg::cs::spherical_equatorial<bg::radian> >
82 {
83     typedef bg::degree units;
84     typedef bg::cs::spherical_equatorial<units> type;
85 
convertother_system_info86     static inline double convert(double value)
87     {
88         return value * bg::math::r2d<double>();
89     }
90 
convertother_system_info91     static inline rng convert(rng const& value)
92     {
93         return value * bg::math::r2d<double>();
94     }
95 };
96 
97 template <>
98 struct other_system_info<bg::cs::spherical_equatorial<bg::degree> >
99 {
100     typedef bg::radian units;
101     typedef bg::cs::spherical_equatorial<units> type;
102 
convertother_system_info103     static inline double convert(double value)
104     {
105         return value * bg::math::d2r<double>();
106     }
107 
convertother_system_info108     static inline rng convert(rng const& value)
109     {
110         return value * bg::math::d2r<double>();
111     }
112 };
113 
114 template <>
115 struct other_system_info<bg::cs::spherical<bg::radian> >
116 {
117     typedef bg::degree units;
118     typedef bg::cs::spherical<units> type;
119 
convertother_system_info120     static inline double convert(double value)
121     {
122         return value * bg::math::r2d<double>();
123     }
124 
convertother_system_info125     static inline rng convert(rng const& value)
126     {
127         return value * bg::math::r2d<double>();
128     }
129 };
130 
131 template <>
132 struct other_system_info<bg::cs::spherical<bg::degree> >
133 {
134     typedef bg::radian units;
135     typedef bg::cs::spherical<units> type;
136 
convertother_system_info137     static inline double convert(double value)
138     {
139         return value * bg::math::d2r<double>();
140     }
141 
convertother_system_info142     static inline rng convert(rng const& value)
143     {
144         return value * bg::math::d2r<double>();
145     }
146 };
147 
148 template <>
149 struct other_system_info<bg::cs::geographic<bg::radian> >
150 {
151     typedef bg::degree units;
152     typedef bg::cs::geographic<units> type;
153 
convertother_system_info154     static inline double convert(double value)
155     {
156         return value * bg::math::r2d<double>();
157     }
158 
convertother_system_info159     static inline rng convert(rng const& value)
160     {
161         return value * bg::math::r2d<double>();
162     }
163 };
164 
165 template <>
166 struct other_system_info<bg::cs::geographic<bg::degree> >
167 {
168     typedef bg::radian units;
169     typedef bg::cs::geographic<units> type;
170 
convertother_system_info171     static inline double convert(double value)
172     {
173         return value * bg::math::d2r<double>();
174     }
175 
convertother_system_info176     static inline rng convert(rng const& value)
177     {
178         return value * bg::math::d2r<double>();
179     }
180 };
181 
182 
183 class equals_with_tolerance
184 {
185 private:
186     double m_tolerence;
187 
188     template <typename T>
get_max(T const & a,T const & b,T const & c)189     static inline T const& get_max(T const& a, T const& b, T const& c)
190     {
191         return (std::max)((std::max)(a, b), c);
192     }
193 
194     template <typename T>
check_close(T const & a,T const & b,double tol)195     static inline bool check_close(T const& a, T const& b, double tol)
196     {
197         return (a == b)
198             || (std::abs(a - b) <= tol * get_max(std::abs(a), std::abs(b), 1.0));
199     }
200 
201 public:
equals_with_tolerance(double tolerence)202     equals_with_tolerance(double tolerence) : m_tolerence(tolerence) {}
203 
operator ()(double value1,double value2) const204     inline bool operator()(double value1, double value2) const
205     {
206         return check_close(value1, value2, m_tolerence);
207     }
208 
operator ()(double l,rng const & r) const209     inline bool operator()(double l, rng const& r) const
210     {
211         return (r.lo < l && l < r.hi)
212             || check_close(l, r.lo, m_tolerence)
213             || check_close(l, r.hi, m_tolerence);
214     }
215 };
216 
217 
equals_with_eps(double l,double r)218 bool equals_with_eps(double l, double r)
219 {
220     return bg::math::equals(l, r);
221 }
222 
equals_with_eps(double l,rng r)223 bool equals_with_eps(double l, rng r)
224 {
225     return (r.lo < l && l < r.hi)
226         || bg::math::equals(l, r.lo)
227         || bg::math::equals(l, r.hi);
228 }
229 
230 
231 template
232 <
233     typename Box,
234     std::size_t DimensionCount = bg::dimension<Box>::value
235 >
236 struct box_check_equals
237 {
238     template <typename T1, typename T2, typename T3, typename T4>
applybox_check_equals239     static inline bool apply(Box const& box,
240                              T1 const& lon_min, T2 const& lat_min, double,
241                              T3 const& lon_max, T4 const& lat_max, double,
242                              double tol)
243     {
244         equals_with_tolerance equals(tol);
245 
246 #ifndef BOOST_GEOMETRY_TEST_FAILURES
247         // check latitude with tolerance when necessary
248         return equals_with_eps(bg::get<0, 0>(box), lon_min)
249             && (bg::get<0, 1>(box) < 0
250                 ? equals(bg::get<0, 1>(box), lat_min)
251                 : equals_with_eps(bg::get<0, 1>(box), lat_min))
252             && equals_with_eps(bg::get<1, 0>(box), lon_max)
253             && (bg::get<1, 1>(box) > 0
254                 ? equals(bg::get<1, 1>(box), lat_max)
255                 : equals_with_eps(bg::get<1, 1>(box), lat_max));
256 #else
257         // check latitude with tolerance when necessary
258         return bg::get<0, 0>(box) == lon_min
259             && (bg::get<0, 1>(box) < 0
260                 ? equals(bg::get<0, 1>(box), lat_min)
261                 : bg::get<0, 1>(box) == lat_min)
262             && bg::get<1, 0>(box) == lon_max
263             && (bg::get<1, 1>(box) > 0
264                 ? equals(bg::get<1, 1>(box), lat_max)
265                 : bg::get<1, 1>(box) == lat_max);
266 #endif
267     }
268 };
269 
270 template <typename Box>
271 struct box_check_equals<Box, 3>
272 {
273     template <typename T1, typename T2, typename T3, typename T4>
applybox_check_equals274     static inline bool apply(Box const& box,
275                              T1 const& lon_min, T2 const& lat_min, double height_min,
276                              T3 const& lon_max, T4 const& lat_max, double height_max,
277                              double tol)
278     {
279 #ifndef BOOST_GEOMETRY_TEST_FAILURES
280         equals_with_tolerance equals(tol);
281 
282         return box_check_equals<Box, 2>::apply(box,
283                                                lon_min, lat_min, height_min,
284                                                lon_max, lat_max, height_max,
285                                                tol)
286             && equals(bg::get<0, 2>(box), height_min)
287             && equals(bg::get<1, 2>(box), height_max);
288 #else
289         return box_equals<Box, 2>::apply(box,
290                                          lon_min, lat_min, height_min,
291                                          lon_max, lat_max, height_max,
292                                          tol)
293             && bg::get<0, 2>(box) == height_min
294             && bg::get<1, 2>(box) == height_max;
295 #endif
296     }
297 };
298 
299 
300 template
301 <
302     typename Box1,
303     typename Box2 = Box1,
304     std::size_t DimensionCount = bg::dimension<Box1>::value
305 >
306 struct box_equals
307 {
applybox_equals308     static inline bool apply(Box1 const& box1, Box2 const& box2, double tol)
309     {
310         return box_check_equals<Box1>::apply(box1,
311                     bg::get<0, 0>(box2), bg::get<0, 1>(box2), 0.0,
312                     bg::get<1, 0>(box2), bg::get<1, 1>(box2), 0.0,
313                     tol);
314     }
315 };
316 
317 template<typename Box1, typename Box2>
318 struct box_equals<Box1, Box2, 3>
319 {
applybox_equals320     static inline bool apply(Box1 const& box1, Box2 const& box2, double tol)
321     {
322         return box_check_equals<Box1>::apply(box1,
323                     bg::get<0, 0>(box2), bg::get<0, 1>(box2), bg::get<0, 2>(box2),
324                     bg::get<1, 0>(box2), bg::get<1, 1>(box2), bg::get<1, 2>(box2),
325                     tol);
326     }
327 };
328 
329 
330 template <typename Box, std::size_t Dimension = bg::dimension<Box>::value>
331 struct initialize_box
332 {
applyinitialize_box333     static inline void apply(Box& box,
334                              double lon_min, double lat_min, double,
335                              double lon_max, double lat_max, double)
336     {
337         bg::detail::indexed_point_view<Box, bg::min_corner> p_min(box);
338         bg::detail::indexed_point_view<Box, bg::max_corner> p_max(box);
339 
340         bg::assign_values(p_min, lon_min, lat_min);
341         bg::assign_values(p_max, lon_max, lat_max);
342     }
343 };
344 
345 template <typename Box>
346 struct initialize_box<Box, 3>
347 {
applyinitialize_box348     static inline void apply(Box& box,
349                              double lon_min, double lat_min, double height_min,
350                              double lon_max, double lat_max, double height_max)
351     {
352         bg::detail::indexed_point_view<Box, bg::min_corner> p_min(box);
353         bg::detail::indexed_point_view<Box, bg::max_corner> p_max(box);
354 
355         bg::assign_values(p_min, lon_min, lat_min, height_min);
356         bg::assign_values(p_max, lon_max, lat_max, height_max);
357     }
358 };
359 
360 #endif // BOOST_GEOMETRY_TEST_ENVELOPE_EXPAND_ON_SPHEROID_HPP
361