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, 2016, 2017.
8 // Modifications copyright (c) 2014-2017 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 #ifndef BOOST_GEOMETRY_CORE_SRS_HPP
20 #define BOOST_GEOMETRY_CORE_SRS_HPP
21 
22 
23 #include <cstddef>
24 
25 #include <boost/static_assert.hpp>
26 
27 #include <boost/geometry/core/radius.hpp>
28 #include <boost/geometry/core/tag.hpp>
29 #include <boost/geometry/core/tags.hpp>
30 
31 
32 namespace boost { namespace geometry
33 {
34 
35 namespace srs
36 {
37 
38 /*!
39     \brief Defines spheroid radius values for use in geographical CS calculations
40     \note See http://en.wikipedia.org/wiki/Figure_of_the_Earth
41           and http://en.wikipedia.org/wiki/World_Geodetic_System#A_new_World_Geodetic_System:_WGS84
42 */
43 template <typename RadiusType>
44 class spheroid
45 {
46 public:
spheroid(RadiusType const & a,RadiusType const & b)47     spheroid(RadiusType const& a, RadiusType const& b)
48         : m_a(a)
49         , m_b(b)
50     {}
51 
spheroid()52     spheroid()
53         : m_a(RadiusType(6378137.0))
54         , m_b(RadiusType(6356752.3142451793))
55     {}
56 
57     template <std::size_t I>
get_radius() const58     RadiusType get_radius() const
59     {
60         BOOST_STATIC_ASSERT(I < 3);
61 
62         return I < 2 ? m_a : m_b;
63     }
64 
65     template <std::size_t I>
set_radius(RadiusType const & radius)66     void set_radius(RadiusType const& radius)
67     {
68         BOOST_STATIC_ASSERT(I < 3);
69 
70         (I < 2 ? m_a : m_b) = radius;
71     }
72 
73 private:
74     RadiusType m_a, m_b; // equatorial radius, polar radius
75 };
76 
77 } // namespace srs
78 
79 // Traits specializations for spheroid
80 #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
81 namespace traits
82 {
83 
84 template <typename RadiusType>
85 struct tag< srs::spheroid<RadiusType> >
86 {
87     typedef srs_spheroid_tag type;
88 };
89 
90 template <typename RadiusType>
91 struct radius_type< srs::spheroid<RadiusType> >
92 {
93     typedef RadiusType type;
94 };
95 
96 template <typename RadiusType, std::size_t Dimension>
97 struct radius_access<srs::spheroid<RadiusType>, Dimension>
98 {
99     typedef srs::spheroid<RadiusType> spheroid_type;
100 
getboost::geometry::traits::radius_access101     static inline RadiusType get(spheroid_type const& s)
102     {
103         return s.template get_radius<Dimension>();
104     }
105 
setboost::geometry::traits::radius_access106     static inline void set(spheroid_type& s, RadiusType const& value)
107     {
108         s.template set_radius<Dimension>(value);
109     }
110 };
111 
112 } // namespace traits
113 #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
114 
115 
116 namespace srs
117 {
118 
119 /*!
120     \brief Defines sphere radius value for use in spherical CS calculations
121 */
122 template <typename RadiusType>
123 class sphere
124 {
125 public:
sphere(RadiusType const & r)126     explicit sphere(RadiusType const& r)
127         : m_r(r)
128     {}
129 
sphere()130     sphere()
131         : m_r(RadiusType((2.0 * 6378137.0 + 6356752.3142451793) / 3.0))
132     {}
133 
134     template <std::size_t I>
get_radius() const135     RadiusType get_radius() const
136     {
137         BOOST_STATIC_ASSERT(I < 3);
138 
139         return m_r;
140     }
141 
142     template <std::size_t I>
set_radius(RadiusType const & radius)143     void set_radius(RadiusType const& radius)
144     {
145         BOOST_STATIC_ASSERT(I < 3);
146 
147         m_r = radius;
148     }
149 
150 private:
151     RadiusType m_r; // radius
152 };
153 
154 } // namespace srs
155 
156 // Traits specializations for sphere
157 #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
158 namespace traits
159 {
160 
161 template <typename RadiusType>
162 struct tag< srs::sphere<RadiusType> >
163 {
164     typedef srs_sphere_tag type;
165 };
166 
167 template <typename RadiusType>
168 struct radius_type< srs::sphere<RadiusType> >
169 {
170     typedef RadiusType type;
171 };
172 
173 template <typename RadiusType, std::size_t Dimension>
174 struct radius_access<srs::sphere<RadiusType>, Dimension>
175 {
176     typedef srs::sphere<RadiusType> sphere_type;
177 
getboost::geometry::traits::radius_access178     static inline RadiusType get(sphere_type const& s)
179     {
180         return s.template get_radius<Dimension>();
181     }
182 
setboost::geometry::traits::radius_access183     static inline void set(sphere_type& s, RadiusType const& value)
184     {
185         s.template set_radius<Dimension>(value);
186     }
187 };
188 
189 } // namespace traits
190 #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
191 
192 
193 }} // namespace boost::geometry
194 
195 
196 #endif // BOOST_GEOMETRY_CORE_SRS_HPP
197