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