test_envelope_expand_on_spheroid.hpp 9.9 KB

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