normalize.hpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2015-2020, Oracle and/or its affiliates.
  3. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  4. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  5. // Licensed under the Boost Software License version 1.0.
  6. // http://www.boost.org/users/license.html
  7. #ifndef BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP
  8. #define BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP
  9. #include <cstddef>
  10. #include <type_traits>
  11. #include <boost/numeric/conversion/cast.hpp>
  12. #include <boost/geometry/core/access.hpp>
  13. #include <boost/geometry/core/coordinate_system.hpp>
  14. #include <boost/geometry/core/coordinate_type.hpp>
  15. #include <boost/geometry/core/cs.hpp>
  16. #include <boost/geometry/core/tag.hpp>
  17. #include <boost/geometry/core/tags.hpp>
  18. #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
  19. #include <boost/geometry/util/normalize_spheroidal_box_coordinates.hpp>
  20. #include <boost/geometry/views/detail/indexed_point_view.hpp>
  21. namespace boost { namespace geometry
  22. {
  23. namespace strategy { namespace normalize
  24. {
  25. #ifndef DOXYGEN_NO_DETAIL
  26. namespace detail
  27. {
  28. struct do_nothing
  29. {
  30. template <typename GeometryIn, typename GeometryOut>
  31. static inline void apply(GeometryIn const&, GeometryOut&)
  32. {
  33. }
  34. };
  35. template <std::size_t Dimension, std::size_t DimensionCount>
  36. struct assign_loop
  37. {
  38. template <typename CoordinateType, typename PointIn, typename PointOut>
  39. static inline void apply(CoordinateType const& longitude,
  40. CoordinateType const& latitude,
  41. PointIn const& point_in,
  42. PointOut& point_out)
  43. {
  44. geometry::set<Dimension>(point_out, boost::numeric_cast
  45. <
  46. typename coordinate_type<PointOut>::type
  47. >(geometry::get<Dimension>(point_in)));
  48. assign_loop
  49. <
  50. Dimension + 1, DimensionCount
  51. >::apply(longitude, latitude, point_in, point_out);
  52. }
  53. };
  54. template <std::size_t DimensionCount>
  55. struct assign_loop<DimensionCount, DimensionCount>
  56. {
  57. template <typename CoordinateType, typename PointIn, typename PointOut>
  58. static inline void apply(CoordinateType const&,
  59. CoordinateType const&,
  60. PointIn const&,
  61. PointOut&)
  62. {
  63. }
  64. };
  65. template <std::size_t DimensionCount>
  66. struct assign_loop<0, DimensionCount>
  67. {
  68. template <typename CoordinateType, typename PointIn, typename PointOut>
  69. static inline void apply(CoordinateType const& longitude,
  70. CoordinateType const& latitude,
  71. PointIn const& point_in,
  72. PointOut& point_out)
  73. {
  74. geometry::set<0>(point_out, boost::numeric_cast
  75. <
  76. typename coordinate_type<PointOut>::type
  77. >(longitude));
  78. assign_loop
  79. <
  80. 1, DimensionCount
  81. >::apply(longitude, latitude, point_in, point_out);
  82. }
  83. };
  84. template <std::size_t DimensionCount>
  85. struct assign_loop<1, DimensionCount>
  86. {
  87. template <typename CoordinateType, typename PointIn, typename PointOut>
  88. static inline void apply(CoordinateType const& longitude,
  89. CoordinateType const& latitude,
  90. PointIn const& point_in,
  91. PointOut& point_out)
  92. {
  93. geometry::set<1>(point_out, boost::numeric_cast
  94. <
  95. typename coordinate_type<PointOut>::type
  96. >(latitude));
  97. assign_loop
  98. <
  99. 2, DimensionCount
  100. >::apply(longitude, latitude, point_in, point_out);
  101. }
  102. };
  103. template <typename PointIn, typename PointOut, bool IsEquatorial = true>
  104. struct normalize_point
  105. {
  106. static inline void apply(PointIn const& point_in, PointOut& point_out)
  107. {
  108. typedef typename coordinate_type<PointIn>::type in_coordinate_type;
  109. in_coordinate_type longitude = geometry::get<0>(point_in);
  110. in_coordinate_type latitude = geometry::get<1>(point_in);
  111. math::normalize_spheroidal_coordinates
  112. <
  113. typename geometry::detail::cs_angular_units<PointIn>::type,
  114. IsEquatorial,
  115. in_coordinate_type
  116. >(longitude, latitude);
  117. assign_loop
  118. <
  119. 0, dimension<PointIn>::value
  120. >::apply(longitude, latitude, point_in, point_out);
  121. }
  122. };
  123. template <typename BoxIn, typename BoxOut, bool IsEquatorial = true>
  124. class normalize_box
  125. {
  126. template <typename UnitsIn, typename UnitsOut, typename CoordinateInType>
  127. static inline void apply_to_coordinates(CoordinateInType& lon_min,
  128. CoordinateInType& lat_min,
  129. CoordinateInType& lon_max,
  130. CoordinateInType& lat_max,
  131. BoxIn const& box_in,
  132. BoxOut& box_out)
  133. {
  134. geometry::detail::indexed_point_view<BoxOut, min_corner> p_min_out(box_out);
  135. assign_loop
  136. <
  137. 0, dimension<BoxIn>::value
  138. >::apply(lon_min,
  139. lat_min,
  140. geometry::detail::indexed_point_view
  141. <
  142. BoxIn const, min_corner
  143. >(box_in),
  144. p_min_out);
  145. geometry::detail::indexed_point_view<BoxOut, max_corner> p_max_out(box_out);
  146. assign_loop
  147. <
  148. 0, dimension<BoxIn>::value
  149. >::apply(lon_max,
  150. lat_max,
  151. geometry::detail::indexed_point_view
  152. <
  153. BoxIn const, max_corner
  154. >(box_in),
  155. p_max_out);
  156. }
  157. public:
  158. static inline void apply(BoxIn const& box_in, BoxOut& box_out)
  159. {
  160. typedef typename coordinate_type<BoxIn>::type in_coordinate_type;
  161. in_coordinate_type lon_min = geometry::get<min_corner, 0>(box_in);
  162. in_coordinate_type lat_min = geometry::get<min_corner, 1>(box_in);
  163. in_coordinate_type lon_max = geometry::get<max_corner, 0>(box_in);
  164. in_coordinate_type lat_max = geometry::get<max_corner, 1>(box_in);
  165. math::normalize_spheroidal_box_coordinates
  166. <
  167. typename geometry::detail::cs_angular_units<BoxIn>::type,
  168. IsEquatorial,
  169. in_coordinate_type
  170. >(lon_min, lat_min, lon_max, lat_max);
  171. apply_to_coordinates
  172. <
  173. typename geometry::detail::cs_angular_units<BoxIn>::type,
  174. typename geometry::detail::cs_angular_units<BoxOut>::type
  175. >(lon_min, lat_min, lon_max, lat_max, box_in, box_out);
  176. }
  177. };
  178. } // namespace detail
  179. #endif // DOXYGEN_NO_DETAIL
  180. struct cartesian_point
  181. : detail::do_nothing
  182. {};
  183. struct cartesian_box
  184. : detail::do_nothing
  185. {};
  186. struct spherical_point
  187. {
  188. template <typename PointIn, typename PointOut>
  189. static inline void apply(PointIn const& point_in, PointOut& point_out)
  190. {
  191. detail::normalize_point
  192. <
  193. PointIn, PointOut,
  194. (! std::is_same
  195. <
  196. typename cs_tag<PointIn>::type,
  197. spherical_polar_tag
  198. >::value)
  199. >::apply(point_in, point_out);
  200. }
  201. };
  202. struct spherical_box
  203. {
  204. template <typename BoxIn, typename BoxOut>
  205. static inline void apply(BoxIn const& box_in, BoxOut& box_out)
  206. {
  207. detail::normalize_box
  208. <
  209. BoxIn, BoxOut,
  210. (! std::is_same
  211. <
  212. typename cs_tag<BoxIn>::type,
  213. spherical_polar_tag
  214. >::value)
  215. >::apply(box_in, box_out);
  216. }
  217. };
  218. }} // namespace strategy::normalize
  219. }} // namespace boost::geometry
  220. #endif // BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP