]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/geometry/srs/projections/proj/gn_sinu.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / geometry / srs / projections / proj / gn_sinu.hpp
CommitLineData
92f5a8d4 1// Boost.Geometry - gis-projections (based on PROJ4)
11fdf7f2
TL
2
3// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
4
92f5a8d4
TL
5// This file was modified by Oracle on 2017, 2018, 2019.
6// Modifications copyright (c) 2017-2019, Oracle and/or its affiliates.
11fdf7f2
TL
7// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
8
9// Use, modification and distribution is subject to the Boost Software License,
10// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
11// http://www.boost.org/LICENSE_1_0.txt)
12
13// This file is converted from PROJ4, http://trac.osgeo.org/proj
14// PROJ4 is originally written by Gerald Evenden (then of the USGS)
15// PROJ4 is maintained by Frank Warmerdam
16// PROJ4 is converted to Boost.Geometry by Barend Gehrels
17
92f5a8d4 18// Last updated version of proj: 5.0.0
11fdf7f2
TL
19
20// Original copyright notice:
21
22// Permission is hereby granted, free of charge, to any person obtaining a
23// copy of this software and associated documentation files (the "Software"),
24// to deal in the Software without restriction, including without limitation
25// the rights to use, copy, modify, merge, publish, distribute, sublicense,
26// and/or sell copies of the Software, and to permit persons to whom the
27// Software is furnished to do so, subject to the following conditions:
28
29// The above copyright notice and this permission notice shall be included
30// in all copies or substantial portions of the Software.
31
32// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
33// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
35// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
37// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
38// DEALINGS IN THE SOFTWARE.
39
92f5a8d4
TL
40#ifndef BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP
41#define BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP
11fdf7f2 42
92f5a8d4 43#include <boost/geometry/srs/projections/impl/aasincos.hpp>
11fdf7f2
TL
44#include <boost/geometry/srs/projections/impl/base_static.hpp>
45#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
11fdf7f2 46#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
11fdf7f2 47#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
92f5a8d4
TL
48#include <boost/geometry/srs/projections/impl/pj_param.hpp>
49#include <boost/geometry/srs/projections/impl/projects.hpp>
11fdf7f2 50
92f5a8d4 51#include <boost/geometry/util/math.hpp>
11fdf7f2 52
92f5a8d4 53namespace boost { namespace geometry
11fdf7f2 54{
11fdf7f2
TL
55
56namespace projections
57{
58 #ifndef DOXYGEN_NO_DETAIL
59 namespace detail { namespace gn_sinu
60 {
61
92f5a8d4
TL
62 static const double epsilon10 = 1e-10;
63 static const int max_iter = 8;
64 static const double loop_tol = 1e-7;
11fdf7f2
TL
65
66 template <typename T>
92f5a8d4 67 struct par_gn_sinu_e
11fdf7f2 68 {
92f5a8d4 69 detail::en<T> en;
11fdf7f2
TL
70 };
71
92f5a8d4
TL
72 template <typename T>
73 struct par_gn_sinu_s
11fdf7f2 74 {
92f5a8d4
TL
75 T m, n, C_x, C_y;
76 };
11fdf7f2 77
92f5a8d4 78 /* Ellipsoidal Sinusoidal only */
11fdf7f2 79
92f5a8d4
TL
80 template <typename T, typename Parameters>
81 struct base_gn_sinu_ellipsoid
82 {
83 par_gn_sinu_e<T> m_proj_parm;
11fdf7f2
TL
84
85 // FORWARD(e_forward) ellipsoid
86 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
92f5a8d4 87 inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
11fdf7f2 88 {
92f5a8d4 89 T s, c;
11fdf7f2
TL
90
91 xy_y = pj_mlfn(lp_lat, s = sin(lp_lat), c = cos(lp_lat), this->m_proj_parm.en);
92f5a8d4 92 xy_x = lp_lon * c / sqrt(1. - par.es * s * s);
11fdf7f2
TL
93 }
94
95 // INVERSE(e_inverse) ellipsoid
96 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
92f5a8d4 97 inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
11fdf7f2 98 {
92f5a8d4 99 static const T half_pi = detail::half_pi<T>();
11fdf7f2 100
92f5a8d4 101 T s;
11fdf7f2 102
92f5a8d4 103 if ((s = fabs(lp_lat = pj_inv_mlfn(xy_y, par.es, this->m_proj_parm.en))) < half_pi) {
11fdf7f2 104 s = sin(lp_lat);
92f5a8d4
TL
105 lp_lon = xy_x * sqrt(1. - par.es * s * s) / cos(lp_lat);
106 } else if ((s - epsilon10) < half_pi)
11fdf7f2
TL
107 lp_lon = 0.;
108 else
92f5a8d4 109 BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) );
11fdf7f2
TL
110 }
111 /* General spherical sinusoidals */
112
113 static inline std::string get_name()
114 {
115 return "gn_sinu_ellipsoid";
116 }
117
118 };
119
92f5a8d4
TL
120 template <typename T, typename Parameters>
121 struct base_gn_sinu_spheroid
11fdf7f2 122 {
92f5a8d4 123 par_gn_sinu_s<T> m_proj_parm;
11fdf7f2
TL
124
125 // FORWARD(s_forward) sphere
126 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
92f5a8d4 127 inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const
11fdf7f2 128 {
92f5a8d4 129 if (this->m_proj_parm.m == 0.0)
11fdf7f2
TL
130 lp_lat = this->m_proj_parm.n != 1. ? aasin(this->m_proj_parm.n * sin(lp_lat)): lp_lat;
131 else {
92f5a8d4 132 T k, V;
11fdf7f2
TL
133 int i;
134
135 k = this->m_proj_parm.n * sin(lp_lat);
92f5a8d4 136 for (i = max_iter; i ; --i) {
11fdf7f2
TL
137 lp_lat -= V = (this->m_proj_parm.m * lp_lat + sin(lp_lat) - k) /
138 (this->m_proj_parm.m + cos(lp_lat));
92f5a8d4 139 if (fabs(V) < loop_tol)
11fdf7f2
TL
140 break;
141 }
92f5a8d4
TL
142 if (!i) {
143 BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) );
144 }
11fdf7f2
TL
145 }
146 xy_x = this->m_proj_parm.C_x * lp_lon * (this->m_proj_parm.m + cos(lp_lat));
147 xy_y = this->m_proj_parm.C_y * lp_lat;
148 }
149
150 // INVERSE(s_inverse) sphere
151 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
92f5a8d4 152 inline void inv(Parameters const& , T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const
11fdf7f2
TL
153 {
154 xy_y /= this->m_proj_parm.C_y;
92f5a8d4 155 lp_lat = (this->m_proj_parm.m != 0.0) ? aasin((this->m_proj_parm.m * xy_y + sin(xy_y)) / this->m_proj_parm.n) :
11fdf7f2
TL
156 ( this->m_proj_parm.n != 1. ? aasin(sin(xy_y) / this->m_proj_parm.n) : xy_y );
157 lp_lon = xy_x / (this->m_proj_parm.C_x * (this->m_proj_parm.m + cos(xy_y)));
158 }
159
160 static inline std::string get_name()
161 {
162 return "gn_sinu_spheroid";
163 }
164
165 };
166
167 template <typename Parameters, typename T>
92f5a8d4 168 inline void setup(Parameters& par, par_gn_sinu_s<T>& proj_parm)
11fdf7f2
TL
169 {
170 par.es = 0;
92f5a8d4 171
11fdf7f2
TL
172 proj_parm.C_x = (proj_parm.C_y = sqrt((proj_parm.m + 1.) / proj_parm.n))/(proj_parm.m + 1.);
173 }
174
175
176 // General Sinusoidal Series
92f5a8d4
TL
177 template <typename Params, typename Parameters, typename T>
178 inline void setup_gn_sinu(Params const& params, Parameters& par, par_gn_sinu_s<T>& proj_parm)
11fdf7f2 179 {
92f5a8d4
TL
180 if (pj_param_f<srs::spar::n>(params, "n", srs::dpar::n, proj_parm.n)
181 && pj_param_f<srs::spar::m>(params, "m", srs::dpar::m, proj_parm.m)) {
182 if (proj_parm.n <= 0 || proj_parm.m < 0)
183 BOOST_THROW_EXCEPTION( projection_exception(error_invalid_m_or_n) );
11fdf7f2 184 } else
92f5a8d4
TL
185 BOOST_THROW_EXCEPTION( projection_exception(error_invalid_m_or_n) );
186
11fdf7f2
TL
187 setup(par, proj_parm);
188 }
189
190 // Sinusoidal (Sanson-Flamsteed)
191 template <typename Parameters, typename T>
92f5a8d4 192 inline void setup_sinu(Parameters const& par, par_gn_sinu_e<T>& proj_parm)
11fdf7f2 193 {
92f5a8d4
TL
194 proj_parm.en = pj_enfn<T>(par.es);
195 }
196
197 // Sinusoidal (Sanson-Flamsteed)
198 template <typename Parameters, typename T>
199 inline void setup_sinu(Parameters& par, par_gn_sinu_s<T>& proj_parm)
200 {
201 proj_parm.n = 1.;
202 proj_parm.m = 0.;
203 setup(par, proj_parm);
11fdf7f2
TL
204 }
205
206 // Eckert VI
207 template <typename Parameters, typename T>
92f5a8d4 208 inline void setup_eck6(Parameters& par, par_gn_sinu_s<T>& proj_parm)
11fdf7f2
TL
209 {
210 proj_parm.m = 1.;
211 proj_parm.n = 2.570796326794896619231321691;
212 setup(par, proj_parm);
213 }
214
215 // McBryde-Thomas Flat-Polar Sinusoidal
216 template <typename Parameters, typename T>
92f5a8d4 217 inline void setup_mbtfps(Parameters& par, par_gn_sinu_s<T>& proj_parm)
11fdf7f2
TL
218 {
219 proj_parm.m = 0.5;
220 proj_parm.n = 1.785398163397448309615660845;
221 setup(par, proj_parm);
222 }
223
224 }} // namespace detail::gn_sinu
225 #endif // doxygen
226
227 /*!
228 \brief General Sinusoidal Series projection
229 \ingroup projections
230 \tparam Geographic latlong point type
231 \tparam Cartesian xy point type
232 \tparam Parameters parameter type
233 \par Projection characteristics
234 - Pseudocylindrical
235 - Spheroid
236 \par Projection parameters
237 - m (real)
238 - n (real)
239 \par Example
240 \image html ex_gn_sinu.gif
241 */
92f5a8d4
TL
242 template <typename T, typename Parameters>
243 struct gn_sinu_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<T, Parameters>
11fdf7f2 244 {
92f5a8d4
TL
245 template <typename Params>
246 inline gn_sinu_spheroid(Params const& params, Parameters & par)
11fdf7f2 247 {
92f5a8d4 248 detail::gn_sinu::setup_gn_sinu(params, par, this->m_proj_parm);
11fdf7f2
TL
249 }
250 };
251
252 /*!
253 \brief Sinusoidal (Sanson-Flamsteed) projection
254 \ingroup projections
255 \tparam Geographic latlong point type
256 \tparam Cartesian xy point type
257 \tparam Parameters parameter type
258 \par Projection characteristics
259 - Pseudocylindrical
260 - Spheroid
261 - Ellipsoid
262 \par Example
263 \image html ex_sinu.gif
264 */
92f5a8d4
TL
265 template <typename T, typename Parameters>
266 struct sinu_ellipsoid : public detail::gn_sinu::base_gn_sinu_ellipsoid<T, Parameters>
11fdf7f2 267 {
92f5a8d4
TL
268 template <typename Params>
269 inline sinu_ellipsoid(Params const& , Parameters & par)
11fdf7f2 270 {
92f5a8d4 271 detail::gn_sinu::setup_sinu(par, this->m_proj_parm);
11fdf7f2
TL
272 }
273 };
274
275 /*!
276 \brief Sinusoidal (Sanson-Flamsteed) projection
277 \ingroup projections
278 \tparam Geographic latlong point type
279 \tparam Cartesian xy point type
280 \tparam Parameters parameter type
281 \par Projection characteristics
282 - Pseudocylindrical
283 - Spheroid
284 - Ellipsoid
285 \par Example
286 \image html ex_sinu.gif
287 */
92f5a8d4
TL
288 template <typename T, typename Parameters>
289 struct sinu_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<T, Parameters>
11fdf7f2 290 {
92f5a8d4
TL
291 template <typename Params>
292 inline sinu_spheroid(Params const& , Parameters & par)
11fdf7f2 293 {
92f5a8d4 294 detail::gn_sinu::setup_sinu(par, this->m_proj_parm);
11fdf7f2
TL
295 }
296 };
297
298 /*!
299 \brief Eckert VI projection
300 \ingroup projections
301 \tparam Geographic latlong point type
302 \tparam Cartesian xy point type
303 \tparam Parameters parameter type
304 \par Projection characteristics
305 - Pseudocylindrical
306 - Spheroid
307 \par Example
308 \image html ex_eck6.gif
309 */
92f5a8d4
TL
310 template <typename T, typename Parameters>
311 struct eck6_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<T, Parameters>
11fdf7f2 312 {
92f5a8d4
TL
313 template <typename Params>
314 inline eck6_spheroid(Params const& , Parameters & par)
11fdf7f2 315 {
92f5a8d4 316 detail::gn_sinu::setup_eck6(par, this->m_proj_parm);
11fdf7f2
TL
317 }
318 };
319
320 /*!
321 \brief McBryde-Thomas Flat-Polar Sinusoidal projection
322 \ingroup projections
323 \tparam Geographic latlong point type
324 \tparam Cartesian xy point type
325 \tparam Parameters parameter type
326 \par Projection characteristics
327 - Pseudocylindrical
328 - Spheroid
329 \par Example
330 \image html ex_mbtfps.gif
331 */
92f5a8d4
TL
332 template <typename T, typename Parameters>
333 struct mbtfps_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<T, Parameters>
11fdf7f2 334 {
92f5a8d4
TL
335 template <typename Params>
336 inline mbtfps_spheroid(Params const& , Parameters & par)
11fdf7f2 337 {
92f5a8d4 338 detail::gn_sinu::setup_mbtfps(par, this->m_proj_parm);
11fdf7f2
TL
339 }
340 };
341
342 #ifndef DOXYGEN_NO_DETAIL
343 namespace detail
344 {
345
346 // Static projection
92f5a8d4
TL
347 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_gn_sinu, gn_sinu_spheroid)
348 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_sinu, sinu_spheroid, sinu_ellipsoid)
349 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_eck6, eck6_spheroid)
350 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_mbtfps, mbtfps_spheroid)
11fdf7f2
TL
351
352 // Factory entry(s)
92f5a8d4
TL
353 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(gn_sinu_entry, gn_sinu_spheroid)
354 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(sinu_entry, sinu_spheroid, sinu_ellipsoid)
355 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(eck6_entry, eck6_spheroid)
356 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(mbtfps_entry, mbtfps_spheroid)
357
358 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(gn_sinu_init)
11fdf7f2 359 {
92f5a8d4
TL
360 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(gn_sinu, gn_sinu_entry);
361 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(sinu, sinu_entry);
362 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(eck6, eck6_entry);
363 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(mbtfps, mbtfps_entry);
11fdf7f2
TL
364 }
365
366 } // namespace detail
367 #endif // doxygen
368
369} // namespace projections
370
371}} // namespace boost::geometry
372
373#endif // BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP
374