• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
6 
7 // This file was modified by Oracle on 2014.
8 // Modifications copyright (c) 2014 Oracle and/or its affiliates.
9 
10 // Contributed and/or modified by Adam Wulkiewicz, 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_RADIUS_HPP
21 #define BOOST_GEOMETRY_CORE_RADIUS_HPP
22 
23 
24 #include <cstddef>
25 
26 #include <boost/static_assert.hpp>
27 #include <boost/type_traits/is_pointer.hpp>
28 
29 #include <boost/geometry/core/tag.hpp>
30 #include <boost/geometry/core/tags.hpp>
31 #include <boost/geometry/util/bare_type.hpp>
32 
33 
34 namespace boost { namespace geometry
35 {
36 
37 namespace traits
38 {
39 
40 /*!
41     \brief Traits class to get/set radius of a circle/sphere/(ellipse)
42     \details the radius access meta-functions give read/write access to the radius of a circle or a sphere,
43     or to the major/minor axis or an ellipse, or to one of the 3 equatorial radii of an ellipsoid.
44 
45     It should be specialized per geometry, in namespace core_dispatch. Those specializations should
46     forward the call via traits to the geometry class, which could be specified by the user.
47 
48     There is a corresponding generic radius_get and radius_set function
49     \par Geometries:
50         - n-sphere (circle,sphere)
51         - upcoming ellipse
52     \par Specializations should provide:
53         - inline static T get(Geometry const& geometry)
54         - inline static void set(Geometry& geometry, T const& radius)
55     \ingroup traits
56 */
57 template <typename Geometry, std::size_t Dimension>
58 struct radius_access {};
59 
60 
61 /*!
62     \brief Traits class indicating the type (double,float,...) of the radius of a circle or a sphere
63     \par Geometries:
64         - n-sphere (circle,sphere)
65         - upcoming ellipse
66     \par Specializations should provide:
67         - typedef T type (double,float,int,etc)
68     \ingroup traits
69 */
70 template <typename Geometry>
71 struct radius_type {};
72 
73 } // namespace traits
74 
75 
76 #ifndef DOXYGEN_NO_DISPATCH
77 namespace core_dispatch
78 {
79 
80 template <typename Tag, typename Geometry>
81 struct radius_type
82 {
83     //typedef core_dispatch_specialization_required type;
84 };
85 
86 /*!
87     \brief radius access meta-functions, used by concept n-sphere and upcoming ellipse.
88 */
89 template <typename Tag,
90           typename Geometry,
91           std::size_t Dimension,
92           typename IsPointer>
93 struct radius_access
94 {
95     //static inline CoordinateType get(Geometry const& ) {}
96     //static inline void set(Geometry& g, CoordinateType const& value) {}
97 };
98 
99 } // namespace core_dispatch
100 #endif // DOXYGEN_NO_DISPATCH
101 
102 
103 /*!
104     \brief Metafunction to get the type of radius of a circle / sphere / ellipse / etc.
105     \ingroup access
106     \tparam Geometry the type of geometry
107 */
108 template <typename Geometry>
109 struct radius_type
110 {
111     typedef typename core_dispatch::radius_type
112                         <
113                             typename tag<Geometry>::type,
114                             typename util::bare_type<Geometry>::type
115                         >::type type;
116 };
117 
118 /*!
119     \brief Function to get radius of a circle / sphere / ellipse / etc.
120     \return radius The radius for a given axis
121     \ingroup access
122     \param geometry the geometry to get the radius from
123     \tparam I index of the axis
124 */
125 template <std::size_t I, typename Geometry>
get_radius(Geometry const & geometry)126 inline typename radius_type<Geometry>::type get_radius(Geometry const& geometry)
127 {
128     return core_dispatch::radius_access
129             <
130                 typename tag<Geometry>::type,
131                 typename util::bare_type<Geometry>::type,
132                 I,
133                 typename boost::is_pointer<Geometry>::type
134             >::get(geometry);
135 }
136 
137 /*!
138     \brief Function to set the radius of a circle / sphere / ellipse / etc.
139     \ingroup access
140     \tparam I index of the axis
141     \param geometry the geometry to change
142     \param radius the radius to set
143 */
144 template <std::size_t I, typename Geometry>
set_radius(Geometry & geometry,typename radius_type<Geometry>::type const & radius)145 inline void set_radius(Geometry& geometry,
146                        typename radius_type<Geometry>::type const& radius)
147 {
148     core_dispatch::radius_access
149         <
150             typename tag<Geometry>::type,
151             typename util::bare_type<Geometry>::type,
152             I,
153             typename boost::is_pointer<Geometry>::type
154         >::set(geometry, radius);
155 }
156 
157 
158 
159 #ifndef DOXYGEN_NO_DETAIL
160 namespace detail
161 {
162 
163 template <typename Tag, typename Geometry, std::size_t Dimension>
164 struct radius_access
165 {
getboost::geometry::detail::radius_access166     static inline typename radius_type<Geometry>::type get(Geometry const& geometry)
167     {
168         return traits::radius_access<Geometry, Dimension>::get(geometry);
169     }
setboost::geometry::detail::radius_access170     static inline void set(Geometry& geometry,
171                            typename radius_type<Geometry>::type const& value)
172     {
173         traits::radius_access<Geometry, Dimension>::set(geometry, value);
174     }
175 };
176 
177 } // namespace detail
178 #endif // DOXYGEN_NO_DETAIL
179 
180 
181 #ifndef DOXYGEN_NO_DISPATCH
182 namespace core_dispatch
183 {
184 
185 template <typename Tag,
186           typename Geometry,
187           std::size_t Dimension>
188 struct radius_access<Tag, Geometry, Dimension, boost::true_type>
189 {
190     typedef typename geometry::radius_type<Geometry>::type radius_type;
191 
getboost::geometry::core_dispatch::radius_access192     static inline radius_type get(const Geometry * geometry)
193     {
194         return radius_access
195                 <
196                     Tag,
197                     Geometry,
198                     Dimension,
199                     typename boost::is_pointer<Geometry>::type
200                 >::get(*geometry);
201     }
202 
setboost::geometry::core_dispatch::radius_access203     static inline void set(Geometry * geometry, radius_type const& value)
204     {
205         return radius_access
206                 <
207                     Tag,
208                     Geometry,
209                     Dimension,
210                     typename boost::is_pointer<Geometry>::type
211                 >::set(*geometry, value);
212     }
213 };
214 
215 
216 template <typename Geometry>
217 struct radius_type<srs_sphere_tag, Geometry>
218 {
219     typedef typename traits::radius_type<Geometry>::type type;
220 };
221 
222 template <typename Geometry, std::size_t Dimension>
223 struct radius_access<srs_sphere_tag, Geometry, Dimension, boost::false_type>
224     : detail::radius_access<srs_sphere_tag, Geometry, Dimension>
225 {
226     //BOOST_STATIC_ASSERT(Dimension == 0);
227     BOOST_STATIC_ASSERT(Dimension < 3);
228 };
229 
230 template <typename Geometry>
231 struct radius_type<srs_spheroid_tag, Geometry>
232 {
233     typedef typename traits::radius_type<Geometry>::type type;
234 };
235 
236 template <typename Geometry, std::size_t Dimension>
237 struct radius_access<srs_spheroid_tag, Geometry, Dimension, boost::false_type>
238     : detail::radius_access<srs_spheroid_tag, Geometry, Dimension>
239 {
240     //BOOST_STATIC_ASSERT(Dimension == 0 || Dimension == 2);
241     BOOST_STATIC_ASSERT(Dimension < 3);
242 };
243 
244 } // namespace core_dispatch
245 #endif // DOXYGEN_NO_DISPATCH
246 
247 
248 }} // namespace boost::geometry
249 
250 
251 #endif // BOOST_GEOMETRY_CORE_RADIUS_HPP
252