radian_access.hpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
  5. // This file was modified by Oracle on 2015.
  6. // Modifications copyright (c) 2015, Oracle and/or its affiliates.
  7. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  8. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  9. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  10. // Use, modification and distribution is subject to the Boost Software License,
  11. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. #ifndef BOOST_GEOMETRY_CORE_RADIAN_ACCESS_HPP
  14. #define BOOST_GEOMETRY_CORE_RADIAN_ACCESS_HPP
  15. #include <cstddef>
  16. #include <boost/geometry/core/access.hpp>
  17. #include <boost/geometry/core/cs.hpp>
  18. #include <boost/geometry/core/coordinate_promotion.hpp>
  19. #include <boost/geometry/util/math.hpp>
  20. #include <boost/geometry/util/numeric_cast.hpp>
  21. namespace boost { namespace geometry
  22. {
  23. #ifndef DOXYGEN_NO_DETAIL
  24. namespace detail
  25. {
  26. template<std::size_t Dimension, typename Geometry>
  27. struct degree_radian_converter
  28. {
  29. typedef typename fp_coordinate_type<Geometry>::type coordinate_type;
  30. static inline coordinate_type get(Geometry const& geometry)
  31. {
  32. return util::numeric_cast
  33. <
  34. coordinate_type
  35. >(geometry::get<Dimension>(geometry)
  36. * math::d2r<coordinate_type>());
  37. }
  38. static inline void set(Geometry& geometry, coordinate_type const& radians)
  39. {
  40. geometry::set<Dimension>(geometry, util::numeric_cast
  41. <
  42. coordinate_type
  43. >(radians * math::r2d<coordinate_type>()));
  44. }
  45. };
  46. // Default, radian (or any other coordinate system) just works like "get"
  47. template <std::size_t Dimension, typename Geometry, typename DegreeOrRadian>
  48. struct radian_access
  49. {
  50. typedef typename fp_coordinate_type<Geometry>::type coordinate_type;
  51. static inline coordinate_type get(Geometry const& geometry)
  52. {
  53. return geometry::get<Dimension>(geometry);
  54. }
  55. static inline void set(Geometry& geometry, coordinate_type const& radians)
  56. {
  57. geometry::set<Dimension>(geometry, radians);
  58. }
  59. };
  60. // Specialize, any "degree" coordinate system will be converted to radian
  61. // but only for dimension 0,1 (so: dimension 2 and heigher are untouched)
  62. template
  63. <
  64. typename Geometry,
  65. template<typename> class CoordinateSystem
  66. >
  67. struct radian_access<0, Geometry, CoordinateSystem<degree> >
  68. : degree_radian_converter<0, Geometry>
  69. {};
  70. template
  71. <
  72. typename Geometry,
  73. template<typename> class CoordinateSystem
  74. >
  75. struct radian_access<1, Geometry, CoordinateSystem<degree> >
  76. : degree_radian_converter<1, Geometry>
  77. {};
  78. template<std::size_t Index, std::size_t Dimension, typename Geometry>
  79. struct degree_radian_converter_box_segment
  80. {
  81. typedef typename fp_coordinate_type<Geometry>::type coordinate_type;
  82. static inline coordinate_type get(Geometry const& geometry)
  83. {
  84. return util::numeric_cast
  85. <
  86. coordinate_type
  87. >(geometry::get<Index, Dimension>(geometry)
  88. * math::d2r<coordinate_type>());
  89. }
  90. static inline void set(Geometry& geometry, coordinate_type const& radians)
  91. {
  92. geometry::set<Index, Dimension>(geometry, util::numeric_cast
  93. <
  94. coordinate_type
  95. >(radians * math::r2d<coordinate_type>()));
  96. }
  97. };
  98. // Default, radian (or any other coordinate system) just works like "get"
  99. template <std::size_t Index, std::size_t Dimension, typename Geometry, typename DegreeOrRadian>
  100. struct radian_access_box_segment
  101. {
  102. typedef typename fp_coordinate_type<Geometry>::type coordinate_type;
  103. static inline coordinate_type get(Geometry const& geometry)
  104. {
  105. return geometry::get<Index, Dimension>(geometry);
  106. }
  107. static inline void set(Geometry& geometry, coordinate_type const& radians)
  108. {
  109. geometry::set<Index, Dimension>(geometry, radians);
  110. }
  111. };
  112. // Specialize, any "degree" coordinate system will be converted to radian
  113. // but only for dimension 0,1 (so: dimension 2 and heigher are untouched)
  114. template
  115. <
  116. typename Geometry,
  117. template<typename> class CoordinateSystem,
  118. std::size_t Index
  119. >
  120. struct radian_access_box_segment<Index, 0, Geometry, CoordinateSystem<degree> >
  121. : degree_radian_converter_box_segment<Index, 0, Geometry>
  122. {};
  123. template
  124. <
  125. typename Geometry,
  126. template<typename> class CoordinateSystem,
  127. std::size_t Index
  128. >
  129. struct radian_access_box_segment<Index, 1, Geometry, CoordinateSystem<degree> >
  130. : degree_radian_converter_box_segment<Index, 1, Geometry>
  131. {};
  132. } // namespace detail
  133. #endif // DOXYGEN_NO_DETAIL
  134. /*!
  135. \brief get coordinate value of a point, result is in Radian
  136. \details Result is in Radian, even if source coordinate system
  137. is in Degrees
  138. \return coordinate value
  139. \ingroup get
  140. \tparam Dimension dimension
  141. \tparam Geometry geometry
  142. \param geometry geometry to get coordinate value from
  143. \note Only applicable to coordinate systems templatized by units,
  144. e.g. spherical or geographic coordinate systems
  145. */
  146. template <std::size_t Dimension, typename Geometry>
  147. inline typename fp_coordinate_type<Geometry>::type get_as_radian(Geometry const& geometry)
  148. {
  149. return detail::radian_access<Dimension, Geometry,
  150. typename coordinate_system<Geometry>::type>::get(geometry);
  151. }
  152. /*!
  153. \brief set coordinate value (in radian) to a point
  154. \details Coordinate value will be set correctly, if coordinate system of
  155. point is in Degree, Radian value will be converted to Degree
  156. \ingroup set
  157. \tparam Dimension dimension
  158. \tparam Geometry geometry
  159. \param geometry geometry to assign coordinate to
  160. \param radians coordinate value to assign
  161. \note Only applicable to coordinate systems templatized by units,
  162. e.g. spherical or geographic coordinate systems
  163. */
  164. template <std::size_t Dimension, typename Geometry>
  165. inline void set_from_radian(Geometry& geometry,
  166. typename fp_coordinate_type<Geometry>::type const& radians)
  167. {
  168. detail::radian_access<Dimension, Geometry,
  169. typename coordinate_system<Geometry>::type>::set(geometry, radians);
  170. }
  171. /*!
  172. \brief get coordinate value of a segment or box, result is in Radian
  173. \details Result is in Radian, even if source coordinate system
  174. is in Degrees
  175. \return coordinate value
  176. \ingroup get
  177. \tparam Index index
  178. \tparam Dimension dimension
  179. \tparam Geometry geometry
  180. \param geometry geometry to get coordinate value from
  181. \note Only applicable to coordinate systems templatized by units,
  182. e.g. spherical or geographic coordinate systems
  183. */
  184. template <std::size_t Index, std::size_t Dimension, typename Geometry>
  185. inline typename fp_coordinate_type<Geometry>::type get_as_radian(Geometry const& geometry)
  186. {
  187. return detail::radian_access_box_segment<Index, Dimension, Geometry,
  188. typename coordinate_system<Geometry>::type>::get(geometry);
  189. }
  190. /*!
  191. \brief set coordinate value (in radian) to a segment or box
  192. \details Coordinate value will be set correctly, if coordinate system of
  193. point is in Degree, Radian value will be converted to Degree
  194. \ingroup set
  195. \tparam Index index
  196. \tparam Dimension dimension
  197. \tparam Geometry geometry
  198. \param geometry geometry to assign coordinate to
  199. \param radians coordinate value to assign
  200. \note Only applicable to coordinate systems templatized by units,
  201. e.g. spherical or geographic coordinate systems
  202. */
  203. template <std::size_t Index, std::size_t Dimension, typename Geometry>
  204. inline void set_from_radian(Geometry& geometry,
  205. typename fp_coordinate_type<Geometry>::type const& radians)
  206. {
  207. detail::radian_access_box_segment<Index, Dimension, Geometry,
  208. typename coordinate_system<Geometry>::type>::set(geometry, radians);
  209. }
  210. }} // namespace boost::geometry
  211. #endif // BOOST_GEOMETRY_CORE_RADIAN_ACCESS_HPP