normalize.hpp 8.2 KB

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