1 #ifndef BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP
2 #define BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP
4 // Boost.Geometry - extensions-gis-projections (based on PROJ4)
5 // This file is automatically generated. DO NOT EDIT.
7 // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
9 // This file was modified by Oracle on 2017.
10 // Modifications copyright (c) 2017, Oracle and/or its affiliates.
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
13 // Use, modification and distribution is subject to the Boost Software License,
14 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15 // http://www.boost.org/LICENSE_1_0.txt)
17 // This file is converted from PROJ4, http://trac.osgeo.org/proj
18 // PROJ4 is originally written by Gerald Evenden (then of the USGS)
19 // PROJ4 is maintained by Frank Warmerdam
20 // PROJ4 is converted to Boost.Geometry by Barend Gehrels
22 // Last updated version of proj: 4.9.1
24 // Original copyright notice:
26 // Permission is hereby granted, free of charge, to any person obtaining a
27 // copy of this software and associated documentation files (the "Software"),
28 // to deal in the Software without restriction, including without limitation
29 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
30 // and/or sell copies of the Software, and to permit persons to whom the
31 // Software is furnished to do so, subject to the following conditions:
33 // The above copyright notice and this permission notice shall be included
34 // in all copies or substantial portions of the Software.
36 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
37 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
39 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
41 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
42 // DEALINGS IN THE SOFTWARE.
44 #include <boost/geometry/util/math.hpp>
45 #include <boost/math/special_functions/hypot.hpp>
47 #include <boost/geometry/srs/projections/impl/base_static.hpp>
48 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
49 #include <boost/geometry/srs/projections/impl/projects.hpp>
50 #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
51 #include <boost/geometry/srs/projections/impl/aasincos.hpp>
52 #include <boost/geometry/srs/projections/impl/pj_zpoly1.hpp>
54 namespace boost { namespace geometry
57 namespace srs { namespace par4
65 }} //namespace srs::par4
69 #ifndef DOXYGEN_NO_DETAIL
70 namespace detail { namespace mod_ster
73 static const double EPSLN = 1e-10;
83 /* based upon Snyder and Linck, USGS-NMD */
85 // template class, using CRTP to implement forward/inverse
86 template <typename CalculationType, typename Parameters>
87 struct base_mod_ster_ellipsoid : public base_t_fi<base_mod_ster_ellipsoid<CalculationType, Parameters>,
88 CalculationType, Parameters>
91 typedef CalculationType geographic_type;
92 typedef CalculationType cartesian_type;
94 par_mod_ster<CalculationType> m_proj_parm;
96 inline base_mod_ster_ellipsoid(const Parameters& par)
97 : base_t_fi<base_mod_ster_ellipsoid<CalculationType, Parameters>,
98 CalculationType, Parameters>(*this, par) {}
100 // FORWARD(e_forward) ellipsoid
101 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
102 inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
104 static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
106 CalculationType sinlon, coslon, esphi, chi, schi, cchi, s;
107 COMPLEX<CalculationType> p;
109 sinlon = sin(lp_lon);
110 coslon = cos(lp_lon);
111 esphi = this->m_par.e * sin(lp_lat);
112 chi = 2. * atan(tan((HALFPI + lp_lat) * .5) *
113 pow((1. - esphi) / (1. + esphi), this->m_par.e * .5)) - HALFPI;
116 s = 2. / (1. + this->m_proj_parm.schio * schi + this->m_proj_parm.cchio * cchi * coslon);
117 p.r = s * cchi * sinlon;
118 p.i = s * (this->m_proj_parm.cchio * schi - this->m_proj_parm.schio * cchi * coslon);
119 p = pj_zpoly1(p, this->m_proj_parm.zcoeff, this->m_proj_parm.n);
124 // INVERSE(e_inverse) ellipsoid
125 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
126 inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
128 static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
131 COMPLEX<CalculationType> p, fxy, fpxy, dp;
132 CalculationType den, rh = 0, z, sinz = 0, cosz = 0, chi, phi = 0, dphi, esphi;
136 for (nn = 20; nn ;--nn) {
137 fxy = pj_zpolyd1(p, this->m_proj_parm.zcoeff, this->m_proj_parm.n, &fpxy);
140 den = fpxy.r * fpxy.r + fpxy.i * fpxy.i;
141 dp.r = -(fxy.r * fpxy.r + fxy.i * fpxy.i) / den;
142 dp.i = -(fxy.i * fpxy.r - fxy.r * fpxy.i) / den;
145 if ((fabs(dp.r) + fabs(dp.i)) <= EPSLN)
149 rh = boost::math::hypot(p.r, p.i);
150 z = 2. * atan(.5 * rh);
153 lp_lon = this->m_par.lam0;
154 if (fabs(rh) <= EPSLN) {
155 lp_lat = this->m_par.phi0;
158 chi = aasin(cosz * this->m_proj_parm.schio + p.i * sinz * this->m_proj_parm.cchio / rh);
160 for (nn = 20; nn ;--nn) {
161 esphi = this->m_par.e * sin(phi);
162 dphi = 2. * atan(tan((HALFPI + chi) * .5) *
163 pow((1. + esphi) / (1. - esphi), this->m_par.e * .5)) - HALFPI - phi;
165 if (fabs(dphi) <= EPSLN)
171 lp_lon = atan2(p.r * sinz, rh * this->m_proj_parm.cchio * cosz - p.i *
172 this->m_proj_parm.schio * sinz);
174 lp_lon = lp_lat = HUGE_VAL;
177 static inline std::string get_name()
179 return "mod_ster_ellipsoid";
184 template <typename Parameters, typename T>
185 inline void setup(Parameters& par, par_mod_ster<T>& proj_parm) /* general initialization */
190 esphi = par.e * sin(par.phi0);
191 chio = 2. * atan(tan((geometry::math::half_pi<T>() + par.phi0) * .5) *
192 pow((1. - esphi) / (1. + esphi), par.e * .5)) - geometry::math::half_pi<T>();
195 proj_parm.schio = sin(chio);
196 proj_parm.cchio = cos(chio);
200 // Miller Oblated Stereographic
201 template <typename Parameters, typename T>
202 inline void setup_mil_os(Parameters& par, par_mod_ster<T>& proj_parm)
204 static COMPLEX<T> /* Miller Oblated Stereographic */
212 par.lam0 = geometry::math::d2r<T>() * 20.;
213 par.phi0 = geometry::math::d2r<T>() * 18.;
214 proj_parm.zcoeff = AB;
216 setup(par, proj_parm);
219 // Lee Oblated Stereographic
220 template <typename Parameters, typename T>
221 inline void setup_lee_os(Parameters& par, par_mod_ster<T>& proj_parm)
223 static COMPLEX<T> /* Lee Oblated Stereographic */
227 {-0.0088162, -0.00617325}
231 par.lam0 = geometry::math::d2r<T>() * -165.;
232 par.phi0 = geometry::math::d2r<T>() * -10.;
233 proj_parm.zcoeff = AB;
235 setup(par, proj_parm);
238 // Mod. Stererographics of 48 U.S.
239 template <typename Parameters, typename T>
240 inline void setup_gs48(Parameters& par, par_mod_ster<T>& proj_parm)
242 static COMPLEX<T> /* 48 United States */
252 par.lam0 = geometry::math::d2r<T>() * -96.;
253 par.phi0 = geometry::math::d2r<T>() * -39.;
254 proj_parm.zcoeff = AB;
257 setup(par, proj_parm);
260 // Mod. Stererographics of Alaska
261 template <typename Parameters, typename T>
262 inline void setup_alsk(Parameters& par, par_mod_ster<T>& proj_parm)
265 ABe[] = { /* Alaska ellipsoid */
267 {.0052083, -.0027404},
268 {.0072721, .0048181},
269 {-.0151089, -.1932526},
270 {.0642675, -.1381226},
271 {.3582802, -.2884586}},
272 ABs[] = { /* Alaska sphere */
274 {.0052513, -.0041175},
275 {.0074606, .0048125},
276 {-.0153783, -.1968253},
277 {.0636871, -.1408027},
278 {.3660976, -.2937382}
282 par.lam0 = geometry::math::d2r<T>() * -152.;
283 par.phi0 = geometry::math::d2r<T>() * 64.;
284 if (par.es) { /* fixed ellipsoid/sphere */
285 proj_parm.zcoeff = ABe;
287 par.e = sqrt(par.es = 0.00676866);
289 proj_parm.zcoeff = ABs;
292 setup(par, proj_parm);
295 // Mod. Stererographics of 50 U.S.
296 template <typename Parameters, typename T>
297 inline void setup_gs50(Parameters& par, par_mod_ster<T>& proj_parm)
300 ABe[] = { /* GS50 ellipsoid */
302 {.0210669, .0053804},
303 {-.1031415, -.0571664},
304 {-.0323337, -.0322847},
305 {.0502303, .1211983},
306 {.0251805, .0895678},
307 {-.0012315, -.1416121},
308 {.0072202, -.1317091},
309 {-.0194029, .0759677},
310 {-.0210072, .0834037}
312 ABs[] = { /* GS50 sphere */
314 {.0211642, .0037608},
315 {-.1036018, -.0575102},
316 {-.0329095, -.0320119},
317 {.0499471, .1223335},
318 {.0260460, .0899805},
319 {.0007388, -.1435792},
320 {.0075848, -.1334108},
321 {-.0216473, .0776645},
322 {-.0225161, .0853673}
326 par.lam0 = geometry::math::d2r<T>() * -120.;
327 par.phi0 = geometry::math::d2r<T>() * 45.;
328 if (par.es) { /* fixed ellipsoid/sphere */
329 proj_parm.zcoeff = ABe;
331 par.e = sqrt(par.es = 0.00676866);
333 proj_parm.zcoeff = ABs;
336 setup(par, proj_parm);
339 }} // namespace detail::mod_ster
343 \brief Miller Oblated Stereographic projection
345 \tparam Geographic latlong point type
346 \tparam Cartesian xy point type
347 \tparam Parameters parameter type
348 \par Projection characteristics
351 \image html ex_mil_os.gif
353 template <typename CalculationType, typename Parameters>
354 struct mil_os_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>
356 inline mil_os_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par)
358 detail::mod_ster::setup_mil_os(this->m_par, this->m_proj_parm);
363 \brief Lee Oblated Stereographic projection
365 \tparam Geographic latlong point type
366 \tparam Cartesian xy point type
367 \tparam Parameters parameter type
368 \par Projection characteristics
371 \image html ex_lee_os.gif
373 template <typename CalculationType, typename Parameters>
374 struct lee_os_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>
376 inline lee_os_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par)
378 detail::mod_ster::setup_lee_os(this->m_par, this->m_proj_parm);
383 \brief Mod. Stererographics of 48 U.S. projection
385 \tparam Geographic latlong point type
386 \tparam Cartesian xy point type
387 \tparam Parameters parameter type
388 \par Projection characteristics
391 \image html ex_gs48.gif
393 template <typename CalculationType, typename Parameters>
394 struct gs48_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>
396 inline gs48_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par)
398 detail::mod_ster::setup_gs48(this->m_par, this->m_proj_parm);
403 \brief Mod. Stererographics of Alaska projection
405 \tparam Geographic latlong point type
406 \tparam Cartesian xy point type
407 \tparam Parameters parameter type
408 \par Projection characteristics
411 \image html ex_alsk.gif
413 template <typename CalculationType, typename Parameters>
414 struct alsk_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>
416 inline alsk_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par)
418 detail::mod_ster::setup_alsk(this->m_par, this->m_proj_parm);
423 \brief Mod. Stererographics of 50 U.S. projection
425 \tparam Geographic latlong point type
426 \tparam Cartesian xy point type
427 \tparam Parameters parameter type
428 \par Projection characteristics
431 \image html ex_gs50.gif
433 template <typename CalculationType, typename Parameters>
434 struct gs50_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>
436 inline gs50_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par)
438 detail::mod_ster::setup_gs50(this->m_par, this->m_proj_parm);
442 #ifndef DOXYGEN_NO_DETAIL
447 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mil_os, mil_os_ellipsoid, mil_os_ellipsoid)
448 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lee_os, lee_os_ellipsoid, lee_os_ellipsoid)
449 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gs48, gs48_ellipsoid, gs48_ellipsoid)
450 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::alsk, alsk_ellipsoid, alsk_ellipsoid)
451 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gs50, gs50_ellipsoid, gs50_ellipsoid)
454 template <typename CalculationType, typename Parameters>
455 class mil_os_entry : public detail::factory_entry<CalculationType, Parameters>
458 virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
460 return new base_v_fi<mil_os_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
464 template <typename CalculationType, typename Parameters>
465 class lee_os_entry : public detail::factory_entry<CalculationType, Parameters>
468 virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
470 return new base_v_fi<lee_os_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
474 template <typename CalculationType, typename Parameters>
475 class gs48_entry : public detail::factory_entry<CalculationType, Parameters>
478 virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
480 return new base_v_fi<gs48_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
484 template <typename CalculationType, typename Parameters>
485 class alsk_entry : public detail::factory_entry<CalculationType, Parameters>
488 virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
490 return new base_v_fi<alsk_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
494 template <typename CalculationType, typename Parameters>
495 class gs50_entry : public detail::factory_entry<CalculationType, Parameters>
498 virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
500 return new base_v_fi<gs50_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
504 template <typename CalculationType, typename Parameters>
505 inline void mod_ster_init(detail::base_factory<CalculationType, Parameters>& factory)
507 factory.add_to_factory("mil_os", new mil_os_entry<CalculationType, Parameters>);
508 factory.add_to_factory("lee_os", new lee_os_entry<CalculationType, Parameters>);
509 factory.add_to_factory("gs48", new gs48_entry<CalculationType, Parameters>);
510 factory.add_to_factory("alsk", new alsk_entry<CalculationType, Parameters>);
511 factory.add_to_factory("gs50", new gs50_entry<CalculationType, Parameters>);
514 } // namespace detail
517 } // namespace projections
519 }} // namespace boost::geometry
521 #endif // BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP