summaryrefslogtreecommitdiff
path: root/boost/geometry/srs/projections/proj
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/srs/projections/proj')
-rw-r--r--boost/geometry/srs/projections/proj/aea.hpp349
-rw-r--r--boost/geometry/srs/projections/proj/aeqd.hpp654
-rw-r--r--boost/geometry/srs/projections/proj/airy.hpp257
-rw-r--r--boost/geometry/srs/projections/proj/aitoff.hpp324
-rw-r--r--boost/geometry/srs/projections/proj/august.hpp168
-rw-r--r--boost/geometry/srs/projections/proj/bacon.hpp272
-rw-r--r--boost/geometry/srs/projections/proj/bipc.hpp297
-rw-r--r--boost/geometry/srs/projections/proj/boggs.hpp185
-rw-r--r--boost/geometry/srs/projections/proj/bonne.hpp298
-rw-r--r--boost/geometry/srs/projections/proj/cass.hpp292
-rw-r--r--boost/geometry/srs/projections/proj/cc.hpp171
-rw-r--r--boost/geometry/srs/projections/proj/cea.hpp269
-rw-r--r--boost/geometry/srs/projections/proj/chamb.hpp288
-rw-r--r--boost/geometry/srs/projections/proj/collg.hpp183
-rw-r--r--boost/geometry/srs/projections/proj/crast.hpp175
-rw-r--r--boost/geometry/srs/projections/proj/denoy.hpp174
-rw-r--r--boost/geometry/srs/projections/proj/eck1.hpp167
-rw-r--r--boost/geometry/srs/projections/proj/eck2.hpp184
-rw-r--r--boost/geometry/srs/projections/proj/eck3.hpp321
-rw-r--r--boost/geometry/srs/projections/proj/eck4.hpp195
-rw-r--r--boost/geometry/srs/projections/proj/eck5.hpp168
-rw-r--r--boost/geometry/srs/projections/proj/eqc.hpp175
-rw-r--r--boost/geometry/srs/projections/proj/eqdc.hpp250
-rw-r--r--boost/geometry/srs/projections/proj/etmerc.hpp395
-rw-r--r--boost/geometry/srs/projections/proj/fahey.hpp168
-rw-r--r--boost/geometry/srs/projections/proj/fouc_s.hpp201
-rw-r--r--boost/geometry/srs/projections/proj/gall.hpp169
-rw-r--r--boost/geometry/srs/projections/proj/geocent.hpp169
-rw-r--r--boost/geometry/srs/projections/proj/geos.hpp377
-rw-r--r--boost/geometry/srs/projections/proj/gins8.hpp170
-rw-r--r--boost/geometry/srs/projections/proj/gn_sinu.hpp426
-rw-r--r--boost/geometry/srs/projections/proj/gnom.hpp266
-rw-r--r--boost/geometry/srs/projections/proj/goode.hpp187
-rw-r--r--boost/geometry/srs/projections/proj/gstmerc.hpp202
-rw-r--r--boost/geometry/srs/projections/proj/hammer.hpp201
-rw-r--r--boost/geometry/srs/projections/proj/hatano.hpp211
-rw-r--r--boost/geometry/srs/projections/proj/healpix.hpp897
-rw-r--r--boost/geometry/srs/projections/proj/igh.hpp377
-rw-r--r--boost/geometry/srs/projections/proj/imw_p.hpp320
-rw-r--r--boost/geometry/srs/projections/proj/isea.hpp1311
-rw-r--r--boost/geometry/srs/projections/proj/krovak.hpp360
-rw-r--r--boost/geometry/srs/projections/proj/labrd.hpp269
-rw-r--r--boost/geometry/srs/projections/proj/laea.hpp447
-rw-r--r--boost/geometry/srs/projections/proj/lagrng.hpp195
-rw-r--r--boost/geometry/srs/projections/proj/larr.hpp164
-rw-r--r--boost/geometry/srs/projections/proj/lask.hpp173
-rw-r--r--boost/geometry/srs/projections/proj/latlong.hpp292
-rw-r--r--boost/geometry/srs/projections/proj/lcc.hpp282
-rw-r--r--boost/geometry/srs/projections/proj/lcca.hpp231
-rw-r--r--boost/geometry/srs/projections/proj/loxim.hpp205
-rw-r--r--boost/geometry/srs/projections/proj/lsat.hpp341
-rw-r--r--boost/geometry/srs/projections/proj/mbt_fps.hpp194
-rw-r--r--boost/geometry/srs/projections/proj/mbtfpp.hpp199
-rw-r--r--boost/geometry/srs/projections/proj/mbtfpq.hpp208
-rw-r--r--boost/geometry/srs/projections/proj/merc.hpp267
-rw-r--r--boost/geometry/srs/projections/proj/mill.hpp167
-rw-r--r--boost/geometry/srs/projections/proj/mod_ster.hpp522
-rw-r--r--boost/geometry/srs/projections/proj/moll.hpp294
-rw-r--r--boost/geometry/srs/projections/proj/natearth.hpp228
-rw-r--r--boost/geometry/srs/projections/proj/nell.hpp180
-rw-r--r--boost/geometry/srs/projections/proj/nell_h.hpp184
-rw-r--r--boost/geometry/srs/projections/proj/nocol.hpp190
-rw-r--r--boost/geometry/srs/projections/proj/nsper.hpp355
-rw-r--r--boost/geometry/srs/projections/proj/nzmg.hpp255
-rw-r--r--boost/geometry/srs/projections/proj/ob_tran.hpp575
-rw-r--r--boost/geometry/srs/projections/proj/ocea.hpp231
-rw-r--r--boost/geometry/srs/projections/proj/oea.hpp214
-rw-r--r--boost/geometry/srs/projections/proj/omerc.hpp354
-rw-r--r--boost/geometry/srs/projections/proj/ortho.hpp257
-rw-r--r--boost/geometry/srs/projections/proj/poly.hpp311
-rw-r--r--boost/geometry/srs/projections/proj/putp2.hpp193
-rw-r--r--boost/geometry/srs/projections/proj/putp3.hpp227
-rw-r--r--boost/geometry/srs/projections/proj/putp4p.hpp231
-rw-r--r--boost/geometry/srs/projections/proj/putp5.hpp229
-rw-r--r--boost/geometry/srs/projections/proj/putp6.hpp255
-rw-r--r--boost/geometry/srs/projections/proj/qsc.hpp539
-rw-r--r--boost/geometry/srs/projections/proj/robin.hpp298
-rw-r--r--boost/geometry/srs/projections/proj/rouss.hpp241
-rw-r--r--boost/geometry/srs/projections/proj/rpoly.hpp187
-rw-r--r--boost/geometry/srs/projections/proj/sconics.hpp570
-rw-r--r--boost/geometry/srs/projections/proj/somerc.hpp227
-rw-r--r--boost/geometry/srs/projections/proj/stere.hpp545
-rw-r--r--boost/geometry/srs/projections/proj/sterea.hpp210
-rw-r--r--boost/geometry/srs/projections/proj/sts.hpp325
-rw-r--r--boost/geometry/srs/projections/proj/tcc.hpp163
-rw-r--r--boost/geometry/srs/projections/proj/tcea.hpp176
-rw-r--r--boost/geometry/srs/projections/proj/tmerc.hpp495
-rw-r--r--boost/geometry/srs/projections/proj/tpeqd.hpp235
-rw-r--r--boost/geometry/srs/projections/proj/urm5.hpp185
-rw-r--r--boost/geometry/srs/projections/proj/urmfps.hpp235
-rw-r--r--boost/geometry/srs/projections/proj/vandg.hpp257
-rw-r--r--boost/geometry/srs/projections/proj/vandg2.hpp237
-rw-r--r--boost/geometry/srs/projections/proj/vandg4.hpp194
-rw-r--r--boost/geometry/srs/projections/proj/wag2.hpp172
-rw-r--r--boost/geometry/srs/projections/proj/wag3.hpp180
-rw-r--r--boost/geometry/srs/projections/proj/wag7.hpp161
-rw-r--r--boost/geometry/srs/projections/proj/wink1.hpp174
-rw-r--r--boost/geometry/srs/projections/proj/wink2.hpp195
98 files changed, 27343 insertions, 0 deletions
diff --git a/boost/geometry/srs/projections/proj/aea.hpp b/boost/geometry/srs/projections/proj/aea.hpp
new file mode 100644
index 0000000000..1df5896c34
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/aea.hpp
@@ -0,0 +1,349 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_AEA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_AEA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the aea (Albers Equal Area) projection.
+// Author: Gerald Evenden
+// Copyright (c) 1995, Gerald Evenden
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/core/ignore_unused.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
+#include <boost/geometry/srs/projections/impl/pj_msfn.hpp>
+#include <boost/geometry/srs/projections/impl/pj_qsfn.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct aea {};
+ struct leac {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace aea
+ {
+
+ static const double EPS10 = 1.e-10;
+ static const double TOL7 = 1.e-7;
+ static const double EPSILON = 1.0e-7;
+ static const double TOL = 1.0e-10;
+ static const int N_ITER = 15;
+
+ template <typename T>
+ struct par_aea
+ {
+ T ec;
+ T n;
+ T c;
+ T dd;
+ T n2;
+ T rho0;
+ T phi1;
+ T phi2;
+ T en[EN_SIZE];
+ int ellips;
+ };
+
+ /* determine latitude angle phi-1 */
+ template <typename T>
+ inline T phi1_(T const& qs, T const& Te, T const& Tone_es)
+ {
+ int i;
+ T Phi, sinpi, cospi, con, com, dphi;
+
+ Phi = asin (.5 * qs);
+ if (Te < EPSILON)
+ return( Phi );
+ i = N_ITER;
+ do {
+ sinpi = sin (Phi);
+ cospi = cos (Phi);
+ con = Te * sinpi;
+ com = 1. - con * con;
+ dphi = .5 * com * com / cospi * (qs / Tone_es -
+ sinpi / com + .5 / Te * log ((1. - con) /
+ (1. + con)));
+ Phi += dphi;
+ } while (fabs(dphi) > TOL && --i);
+ return( i ? Phi : HUGE_VAL );
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_aea_ellipsoid : public base_t_fi<base_aea_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_aea<CalculationType> m_proj_parm;
+
+ inline base_aea_ellipsoid(const Parameters& par)
+ : base_t_fi<base_aea_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid & spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType rho = 0.0;
+ if ((rho = this->m_proj_parm.c - (this->m_proj_parm.ellips ? this->m_proj_parm.n * pj_qsfn(sin(lp_lat),
+ this->m_par.e, this->m_par.one_es) : this->m_proj_parm.n2 * sin(lp_lat))) < 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ rho = this->m_proj_parm.dd * sqrt(rho);
+ xy_x = rho * sin( lp_lon *= this->m_proj_parm.n );
+ xy_y = this->m_proj_parm.rho0 - rho * cos(lp_lon);
+ }
+
+ // INVERSE(e_inverse) ellipsoid & spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType rho = 0.0;
+ if( (rho = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.rho0 - xy_y)) != 0.0 ) {
+ if (this->m_proj_parm.n < 0.) {
+ rho = -rho;
+ xy_x = -xy_x;
+ xy_y = -xy_y;
+ }
+ lp_lat = rho / this->m_proj_parm.dd;
+ if (this->m_proj_parm.ellips) {
+ lp_lat = (this->m_proj_parm.c - lp_lat * lp_lat) / this->m_proj_parm.n;
+ if (fabs(this->m_proj_parm.ec - fabs(lp_lat)) > TOL7) {
+ if ((lp_lat = phi1_(lp_lat, this->m_par.e, this->m_par.one_es)) == HUGE_VAL)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ } else
+ lp_lat = lp_lat < 0. ? -HALFPI : HALFPI;
+ } else if (fabs(lp_lat = (this->m_proj_parm.c - lp_lat * lp_lat) / this->m_proj_parm.n2) <= 1.)
+ lp_lat = asin(lp_lat);
+ else
+ lp_lat = lp_lat < 0. ? -HALFPI : HALFPI;
+ lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n;
+ } else {
+ lp_lon = 0.;
+ lp_lat = this->m_proj_parm.n > 0. ? HALFPI : - HALFPI;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "aea_ellipsoid";
+ }
+
+ };
+
+ template <typename Parameters, typename T>
+ inline void setup(Parameters& par, par_aea<T>& proj_parm)
+ {
+ T cosphi, sinphi;
+ int secant;
+
+ if (fabs(proj_parm.phi1 + proj_parm.phi2) < EPS10)
+ BOOST_THROW_EXCEPTION( projection_exception(-21) );
+ proj_parm.n = sinphi = sin(proj_parm.phi1);
+ cosphi = cos(proj_parm.phi1);
+ secant = fabs(proj_parm.phi1 - proj_parm.phi2) >= EPS10;
+ if( (proj_parm.ellips = (par.es > 0.))) {
+ T ml1, m1;
+
+ if (!pj_enfn(par.es, proj_parm.en))
+ BOOST_THROW_EXCEPTION( projection_exception(0) );
+ m1 = pj_msfn(sinphi, cosphi, par.es);
+ ml1 = pj_qsfn(sinphi, par.e, par.one_es);
+ if (secant) { /* secant cone */
+ T ml2, m2;
+
+ sinphi = sin(proj_parm.phi2);
+ cosphi = cos(proj_parm.phi2);
+ m2 = pj_msfn(sinphi, cosphi, par.es);
+ ml2 = pj_qsfn(sinphi, par.e, par.one_es);
+ proj_parm.n = (m1 * m1 - m2 * m2) / (ml2 - ml1);
+ }
+ proj_parm.ec = 1. - .5 * par.one_es * log((1. - par.e) /
+ (1. + par.e)) / par.e;
+ proj_parm.c = m1 * m1 + proj_parm.n * ml1;
+ proj_parm.dd = 1. / proj_parm.n;
+ proj_parm.rho0 = proj_parm.dd * sqrt(proj_parm.c - proj_parm.n * pj_qsfn(sin(par.phi0),
+ par.e, par.one_es));
+ } else {
+ if (secant) proj_parm.n = .5 * (proj_parm.n + sin(proj_parm.phi2));
+ proj_parm.n2 = proj_parm.n + proj_parm.n;
+ proj_parm.c = cosphi * cosphi + proj_parm.n2 * sinphi;
+ proj_parm.dd = 1. / proj_parm.n;
+ proj_parm.rho0 = proj_parm.dd * sqrt(proj_parm.c - proj_parm.n2 * sin(par.phi0));
+ }
+ }
+
+
+ // Albers Equal Area
+ template <typename Parameters, typename T>
+ inline void setup_aea(Parameters& par, par_aea<T>& proj_parm)
+ {
+ proj_parm.phi1 = pj_param(par.params, "rlat_1").f;
+ proj_parm.phi2 = pj_param(par.params, "rlat_2").f;
+ setup(par, proj_parm);
+ }
+
+ // Lambert Equal Area Conic
+ template <typename Parameters, typename T>
+ inline void setup_leac(Parameters& par, par_aea<T>& proj_parm)
+ {
+ static const T HALFPI = detail::HALFPI<T>();
+
+ proj_parm.phi2 = pj_param(par.params, "rlat_1").f;
+ proj_parm.phi1 = pj_param(par.params, "bsouth").i ? -HALFPI : HALFPI;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::aea
+ #endif // doxygen
+
+ /*!
+ \brief Albers Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ - lat_2: Latitude of second standard parallel (degrees)
+ \par Example
+ \image html ex_aea.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct aea_ellipsoid : public detail::aea::base_aea_ellipsoid<CalculationType, Parameters>
+ {
+ inline aea_ellipsoid(const Parameters& par) : detail::aea::base_aea_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::aea::setup_aea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Lambert Equal Area Conic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ - south: Denotes southern hemisphere UTM zone (boolean)
+ \par Example
+ \image html ex_leac.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct leac_ellipsoid : public detail::aea::base_aea_ellipsoid<CalculationType, Parameters>
+ {
+ inline leac_ellipsoid(const Parameters& par) : detail::aea::base_aea_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::aea::setup_leac(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::aea, aea_ellipsoid, aea_ellipsoid)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::leac, leac_ellipsoid, leac_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class aea_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<aea_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class leac_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<leac_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void aea_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("aea", new aea_entry<CalculationType, Parameters>);
+ factory.add_to_factory("leac", new leac_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AEA_HPP
+
diff --git a/boost/geometry/srs/projections/proj/aeqd.hpp b/boost/geometry/srs/projections/proj/aeqd.hpp
new file mode 100644
index 0000000000..de499213db
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/aeqd.hpp
@@ -0,0 +1,654 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the aeqd (Azimuthal Equidistant) projection.
+// Author: Gerald Evenden
+// Copyright (c) 1995, Gerald Evenden
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/config.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
+
+#include <boost/geometry/srs/projections/par4.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct aeqd {};
+ //struct aeqd_guam {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace aeqd
+ {
+
+ static const double EPS10 = 1.e-10;
+ static const double TOL = 1.e-14;
+ static const int N_POLE = 0;
+ static const int S_POLE = 1;
+ static const int EQUIT = 2;
+ static const int OBLIQ = 3;
+
+ template <typename T>
+ struct par_aeqd
+ {
+ T sinph0;
+ T cosph0;
+ T en[EN_SIZE];
+ T M1;
+ T N1;
+ T Mp;
+ T He;
+ T G;
+ int mode;
+ };
+
+ template <typename T, typename Par, typename ProjParm>
+ inline void e_forward(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y, Par const& par, ProjParm const& proj_parm)
+ {
+ T coslam, cosphi, sinphi, rho, s, H, H2, c, Az, t, ct, st, cA, sA;
+
+ coslam = cos(lp_lon);
+ cosphi = cos(lp_lat);
+ sinphi = sin(lp_lat);
+ switch (proj_parm.mode) {
+ case N_POLE:
+ coslam = - coslam;
+ BOOST_FALLTHROUGH;
+ case S_POLE:
+ xy_x = (rho = fabs(proj_parm.Mp - pj_mlfn(lp_lat, sinphi, cosphi, proj_parm.en))) *
+ sin(lp_lon);
+ xy_y = rho * coslam;
+ break;
+ case EQUIT:
+ case OBLIQ:
+ if (fabs(lp_lon) < EPS10 && fabs(lp_lat - par.phi0) < EPS10) {
+ xy_x = xy_y = 0.;
+ break;
+ }
+ t = atan2(par.one_es * sinphi + par.es * proj_parm.N1 * proj_parm.sinph0 *
+ sqrt(1. - par.es * sinphi * sinphi), cosphi);
+ ct = cos(t); st = sin(t);
+ Az = atan2(sin(lp_lon) * ct, proj_parm.cosph0 * st - proj_parm.sinph0 * coslam * ct);
+ cA = cos(Az); sA = sin(Az);
+ s = aasin(fabs(sA) < TOL ?
+ (proj_parm.cosph0 * st - proj_parm.sinph0 * coslam * ct) / cA :
+ sin(lp_lon) * ct / sA );
+ H = proj_parm.He * cA;
+ H2 = H * H;
+ c = proj_parm.N1 * s * (1. + s * s * (- H2 * (1. - H2)/6. +
+ s * ( proj_parm.G * H * (1. - 2. * H2 * H2) / 8. +
+ s * ((H2 * (4. - 7. * H2) - 3. * proj_parm.G * proj_parm.G * (1. - 7. * H2)) /
+ 120. - s * proj_parm.G * H / 48.))));
+ xy_x = c * sA;
+ xy_y = c * cA;
+ break;
+ }
+ }
+
+ template <typename T, typename Par, typename ProjParm>
+ inline void e_inverse(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat, Par const& par, ProjParm const& proj_parm)
+ {
+ static const T HALFPI = detail::HALFPI<T>();
+
+ T c, Az, cosAz, A, B, D, E, F, psi, t;
+
+ if ((c = boost::math::hypot(xy_x, xy_y)) < EPS10) {
+ lp_lat = par.phi0;
+ lp_lon = 0.;
+ return;
+ }
+ if (proj_parm.mode == OBLIQ || proj_parm.mode == EQUIT) {
+ cosAz = cos(Az = atan2(xy_x, xy_y));
+ t = proj_parm.cosph0 * cosAz;
+ B = par.es * t / par.one_es;
+ A = - B * t;
+ B *= 3. * (1. - A) * proj_parm.sinph0;
+ D = c / proj_parm.N1;
+ E = D * (1. - D * D * (A * (1. + A) / 6. + B * (1. + 3.*A) * D / 24.));
+ F = 1. - E * E * (A / 2. + B * E / 6.);
+ psi = aasin(proj_parm.sinph0 * cos(E) + t * sin(E));
+ lp_lon = aasin(sin(Az) * sin(E) / cos(psi));
+ if ((t = fabs(psi)) < EPS10)
+ lp_lat = 0.;
+ else if (fabs(t - HALFPI) < 0.)
+ lp_lat = HALFPI;
+ else
+ lp_lat = atan((1. - par.es * F * proj_parm.sinph0 / sin(psi)) * tan(psi) /
+ par.one_es);
+ } else { /* Polar */
+ lp_lat = pj_inv_mlfn(proj_parm.mode == N_POLE ? proj_parm.Mp - c : proj_parm.Mp + c,
+ par.es, proj_parm.en);
+ lp_lon = atan2(xy_x, proj_parm.mode == N_POLE ? -xy_y : xy_y);
+ }
+ }
+
+ template <typename T, typename Par, typename ProjParm>
+ inline void e_guam_fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y, Par const& par, ProjParm const& proj_parm)
+ {
+ T cosphi, sinphi, t;
+
+ cosphi = cos(lp_lat);
+ sinphi = sin(lp_lat);
+ t = 1. / sqrt(1. - par.es * sinphi * sinphi);
+ xy_x = lp_lon * cosphi * t;
+ xy_y = pj_mlfn(lp_lat, sinphi, cosphi, proj_parm.en) - proj_parm.M1 +
+ .5 * lp_lon * lp_lon * cosphi * sinphi * t;
+ }
+
+ template <typename T, typename Par, typename ProjParm>
+ inline void e_guam_inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat, Par const& par, ProjParm const& proj_parm)
+ {
+ T x2, t;
+ int i;
+
+ x2 = 0.5 * xy_x * xy_x;
+ lp_lat = par.phi0;
+ for (i = 0; i < 3; ++i) {
+ t = par.e * sin(lp_lat);
+ lp_lat = pj_inv_mlfn(proj_parm.M1 + xy_y -
+ x2 * tan(lp_lat) * (t = sqrt(1. - t * t)), par.es, proj_parm.en);
+ }
+ lp_lon = xy_x * t / cos(lp_lat);
+ }
+
+ template <typename T, typename Par, typename ProjParm>
+ inline void s_forward(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y, Par const& /*par*/, ProjParm const& proj_parm)
+ {
+ static const T HALFPI = detail::HALFPI<T>();
+
+ T coslam, cosphi, sinphi;
+
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ coslam = cos(lp_lon);
+ switch (proj_parm.mode) {
+ case EQUIT:
+ xy_y = cosphi * coslam;
+ goto oblcon;
+ case OBLIQ:
+ xy_y = proj_parm.sinph0 * sinphi + proj_parm.cosph0 * cosphi * coslam;
+ oblcon:
+ if (fabs(fabs(xy_y) - 1.) < TOL)
+ if (xy_y < 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ else
+ xy_x = xy_y = 0.;
+ else {
+ xy_y = acos(xy_y);
+ xy_y /= sin(xy_y);
+ xy_x = xy_y * cosphi * sin(lp_lon);
+ xy_y *= (proj_parm.mode == EQUIT) ? sinphi :
+ proj_parm.cosph0 * sinphi - proj_parm.sinph0 * cosphi * coslam;
+ }
+ break;
+ case N_POLE:
+ lp_lat = -lp_lat;
+ coslam = -coslam;
+ BOOST_FALLTHROUGH;
+ case S_POLE:
+ if (fabs(lp_lat - HALFPI) < EPS10)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ xy_x = (xy_y = (HALFPI + lp_lat)) * sin(lp_lon);
+ xy_y *= coslam;
+ break;
+ }
+ }
+
+ template <typename T, typename Par, typename ProjParm>
+ inline void s_inverse(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat, Par const& par, ProjParm const& proj_parm)
+ {
+ static const T ONEPI = detail::ONEPI<T>();
+ static const T HALFPI = detail::HALFPI<T>();
+
+ T cosc, c_rh, sinc;
+
+ if ((c_rh = boost::math::hypot(xy_x, xy_y)) > ONEPI) {
+ if (c_rh - EPS10 > ONEPI)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ c_rh = ONEPI;
+ } else if (c_rh < EPS10) {
+ lp_lat = par.phi0;
+ lp_lon = 0.;
+ return;
+ }
+ if (proj_parm.mode == OBLIQ || proj_parm.mode == EQUIT) {
+ sinc = sin(c_rh);
+ cosc = cos(c_rh);
+ if (proj_parm.mode == EQUIT) {
+ lp_lat = aasin(xy_y * sinc / c_rh);
+ xy_x *= sinc;
+ xy_y = cosc * c_rh;
+ } else {
+ lp_lat = aasin(cosc * proj_parm.sinph0 + xy_y * sinc * proj_parm.cosph0 /
+ c_rh);
+ xy_y = (cosc - proj_parm.sinph0 * sin(lp_lat)) * c_rh;
+ xy_x *= sinc * proj_parm.cosph0;
+ }
+ lp_lon = atan2(xy_x, xy_y);
+ } else if (proj_parm.mode == N_POLE) {
+ lp_lat = HALFPI - c_rh;
+ lp_lon = atan2(xy_x, -xy_y);
+ } else {
+ lp_lat = c_rh - HALFPI;
+ lp_lon = atan2(xy_x, xy_y);
+ }
+ }
+
+ // Azimuthal Equidistant
+ template <typename Parameters, typename T>
+ inline void setup_aeqd(Parameters& par, par_aeqd<T>& proj_parm, bool is_sphere, bool is_guam)
+ {
+ static const T HALFPI = detail::HALFPI<T>();
+
+ par.phi0 = pj_param(par.params, "rlat_0").f;
+ if (fabs(fabs(par.phi0) - HALFPI) < EPS10) {
+ proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE;
+ proj_parm.sinph0 = par.phi0 < 0. ? -1. : 1.;
+ proj_parm.cosph0 = 0.;
+ } else if (fabs(par.phi0) < EPS10) {
+ proj_parm.mode = EQUIT;
+ proj_parm.sinph0 = 0.;
+ proj_parm.cosph0 = 1.;
+ } else {
+ proj_parm.mode = OBLIQ;
+ proj_parm.sinph0 = sin(par.phi0);
+ proj_parm.cosph0 = cos(par.phi0);
+ }
+ if (is_sphere) {
+ } else {
+ if (!pj_enfn(par.es, proj_parm.en))
+ BOOST_THROW_EXCEPTION( projection_exception(0) );
+ if (is_guam) {
+ proj_parm.M1 = pj_mlfn(par.phi0, proj_parm.sinph0, proj_parm.cosph0, proj_parm.en);
+ } else {
+ switch (proj_parm.mode) {
+ case N_POLE:
+ proj_parm.Mp = pj_mlfn<T>(HALFPI, 1., 0., proj_parm.en);
+ break;
+ case S_POLE:
+ proj_parm.Mp = pj_mlfn<T>(-HALFPI, -1., 0., proj_parm.en);
+ break;
+ case EQUIT:
+ case OBLIQ:
+ proj_parm.N1 = 1. / sqrt(1. - par.es * proj_parm.sinph0 * proj_parm.sinph0);
+ proj_parm.G = proj_parm.sinph0 * (proj_parm.He = par.e / sqrt(par.one_es));
+ proj_parm.He *= proj_parm.cosph0;
+ break;
+ }
+ }
+ }
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_aeqd_e : public base_t_fi<base_aeqd_e<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_aeqd<CalculationType> m_proj_parm;
+
+ inline base_aeqd_e(const Parameters& par)
+ : base_t_fi<base_aeqd_e<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) elliptical
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ e_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm);
+ }
+
+ // INVERSE(e_inverse) elliptical
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ e_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm);
+ }
+
+ static inline std::string get_name()
+ {
+ return "aeqd_e";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_aeqd_e_guam : public base_t_fi<base_aeqd_e_guam<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_aeqd<CalculationType> m_proj_parm;
+
+ inline base_aeqd_e_guam(const Parameters& par)
+ : base_t_fi<base_aeqd_e_guam<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_guam_fwd) Guam elliptical
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ e_guam_fwd(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm);
+ }
+
+ // INVERSE(e_guam_inv) Guam elliptical
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ e_guam_inv(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm);
+ }
+
+ static inline std::string get_name()
+ {
+ return "aeqd_e_guam";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename BGParameters, typename CalculationType, typename Parameters>
+ struct base_aeqd_e_static : public base_t_fi<base_aeqd_e_static<BGParameters, CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_aeqd<CalculationType> m_proj_parm;
+
+ static const bool is_guam = ! boost::is_same
+ <
+ typename srs::par4::detail::tuples_find_if
+ <
+ BGParameters,
+ //srs::par4::detail::is_guam
+ srs::par4::detail::is_param<srs::par4::guam>::pred
+ >::type,
+ void
+ >::value;
+
+ inline base_aeqd_e_static(const Parameters& par)
+ : base_t_fi<base_aeqd_e_static<BGParameters, CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par)
+ {}
+
+ // FORWARD(e_forward or e_guam_fwd) elliptical
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ if (is_guam)
+ e_guam_fwd(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm);
+ else
+ e_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm);
+ }
+
+ // INVERSE(e_inverse or e_guam_inv) elliptical
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ if (is_guam)
+ e_guam_inv(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm);
+ else
+ e_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm);
+ }
+
+ static inline std::string get_name()
+ {
+ return "aeqd_e_static";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_aeqd_s : public base_t_fi<base_aeqd_s<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_aeqd<CalculationType> m_proj_parm;
+
+ inline base_aeqd_s(const Parameters& par)
+ : base_t_fi<base_aeqd_s<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spherical
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ s_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm);
+ }
+
+ // INVERSE(s_inverse) spherical
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ s_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm);
+ }
+
+ static inline std::string get_name()
+ {
+ return "aeqd_s";
+ }
+
+ };
+
+ }} // namespace detail::aeqd
+ #endif // doxygen
+
+ /*!
+ \brief Azimuthal Equidistant projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_0: Latitude of origin (degrees)
+ - guam (boolean)
+ \par Example
+ \image html ex_aeqd.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct aeqd_e : public detail::aeqd::base_aeqd_e<CalculationType, Parameters>
+ {
+ inline aeqd_e(const Parameters& par) : detail::aeqd::base_aeqd_e<CalculationType, Parameters>(par)
+ {
+ detail::aeqd::setup_aeqd(this->m_par, this->m_proj_parm, false, false);
+ }
+ };
+
+ /*!
+ \brief Azimuthal Equidistant projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_0: Latitude of origin (degrees)
+ - guam (boolean)
+ \par Example
+ \image html ex_aeqd.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct aeqd_e_guam : public detail::aeqd::base_aeqd_e_guam<CalculationType, Parameters>
+ {
+ inline aeqd_e_guam(const Parameters& par) : detail::aeqd::base_aeqd_e_guam<CalculationType, Parameters>(par)
+ {
+ detail::aeqd::setup_aeqd(this->m_par, this->m_proj_parm, false, true);
+ }
+ };
+
+ /*!
+ \brief Azimuthal Equidistant projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_0: Latitude of origin (degrees)
+ - guam (boolean)
+ \par Example
+ \image html ex_aeqd.gif
+ */
+ template <typename BGParameters, typename CalculationType, typename Parameters>
+ struct aeqd_e_static : public detail::aeqd::base_aeqd_e_static<BGParameters, CalculationType, Parameters>
+ {
+ inline aeqd_e_static(const Parameters& par) : detail::aeqd::base_aeqd_e_static<BGParameters, CalculationType, Parameters>(par)
+ {
+ detail::aeqd::setup_aeqd(this->m_par, this->m_proj_parm,
+ false,
+ detail::aeqd::base_aeqd_e_static<BGParameters, CalculationType, Parameters>::is_guam);
+ }
+ };
+
+ /*!
+ \brief Azimuthal Equidistant projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_0: Latitude of origin (degrees)
+ - guam (boolean)
+ \par Example
+ \image html ex_aeqd.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct aeqd_s : public detail::aeqd::base_aeqd_s<CalculationType, Parameters>
+ {
+ inline aeqd_s(const Parameters& par) : detail::aeqd::base_aeqd_s<CalculationType, Parameters>(par)
+ {
+ detail::aeqd::setup_aeqd(this->m_par, this->m_proj_parm, true, false);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ template <typename BGP, typename CT, typename P>
+ struct static_projection_type<srs::par4::aeqd, srs_sphere_tag, BGP, CT, P>
+ {
+ typedef aeqd_s<CT, P> type;
+ };
+ template <typename BGP, typename CT, typename P>
+ struct static_projection_type<srs::par4::aeqd, srs_spheroid_tag, BGP, CT, P>
+ {
+ typedef aeqd_e_static<BGP, CT, P> type;
+ };
+ //BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::aeqd, aeqd_s, aeqd_e_static)
+ //BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::aeqd_guam, aeqd_guam, aeqd_guam)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class aeqd_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ bool const guam = pj_param(par.params, "bguam").i != 0;
+
+ if (par.es && ! guam)
+ return new base_v_fi<aeqd_e<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ else if (par.es && guam)
+ return new base_v_fi<aeqd_e_guam<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ else
+ return new base_v_fi<aeqd_s<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void aeqd_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("aeqd", new aeqd_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP
+
diff --git a/boost/geometry/srs/projections/proj/airy.hpp b/boost/geometry/srs/projections/proj/airy.hpp
new file mode 100644
index 0000000000..557d95f3e4
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/airy.hpp
@@ -0,0 +1,257 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the airy (Airy) projection.
+// Author: Gerald Evenden
+// Copyright (c) 1995, Gerald Evenden
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+#include <boost/geometry/srs/projections/par4.hpp> // airy tag
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ // already defined in par4.hpp as ellps name
+ //struct airy {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace airy
+ {
+
+ static const double EPS = 1.e-10;
+ static const int N_POLE = 0;
+ static const int S_POLE = 1;
+ static const int EQUIT = 2;
+ static const int OBLIQ = 3;
+
+ template <typename T>
+ struct par_airy
+ {
+ T p_halfpi;
+ T sinph0;
+ T cosph0;
+ T Cb;
+ int mode;
+ int no_cut; /* do not cut at hemisphere limit */
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_airy_spheroid : public base_t_f<base_airy_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_airy<CalculationType> m_proj_parm;
+
+ inline base_airy_spheroid(const Parameters& par)
+ : base_t_f<base_airy_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType sinlam, coslam, cosphi, sinphi, t, s, Krho, cosz;
+
+ sinlam = sin(lp_lon);
+ coslam = cos(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ case OBLIQ:
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ cosz = cosphi * coslam;
+ if (this->m_proj_parm.mode == OBLIQ)
+ cosz = this->m_proj_parm.sinph0 * sinphi + this->m_proj_parm.cosph0 * cosz;
+ if (!this->m_proj_parm.no_cut && cosz < -EPS)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ if (fabs(s = 1. - cosz) > EPS) {
+ t = 0.5 * (1. + cosz);
+ Krho = -log(t)/s - this->m_proj_parm.Cb / t;
+ } else
+ Krho = 0.5 - this->m_proj_parm.Cb;
+ xy_x = Krho * cosphi * sinlam;
+ if (this->m_proj_parm.mode == OBLIQ)
+ xy_y = Krho * (this->m_proj_parm.cosph0 * sinphi -
+ this->m_proj_parm.sinph0 * cosphi * coslam);
+ else
+ xy_y = Krho * sinphi;
+ break;
+ case S_POLE:
+ case N_POLE:
+ lp_lat = fabs(this->m_proj_parm.p_halfpi - lp_lat);
+ if (!this->m_proj_parm.no_cut && (lp_lat - EPS) > HALFPI)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ if ((lp_lat *= 0.5) > EPS) {
+ t = tan(lp_lat);
+ Krho = -2.*(log(cos(lp_lat)) / t + t * this->m_proj_parm.Cb);
+ xy_x = Krho * sinlam;
+ xy_y = Krho * coslam;
+ if (this->m_proj_parm.mode == N_POLE)
+ xy_y = -xy_y;
+ } else
+ xy_x = xy_y = 0.;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "airy_spheroid";
+ }
+
+ };
+
+ // Airy
+ template <typename Parameters, typename T>
+ inline void setup_airy(Parameters& par, par_airy<T>& proj_parm)
+ {
+ static const T HALFPI = detail::HALFPI<T>();
+
+ T beta;
+
+ proj_parm.no_cut = pj_param(par.params, "bno_cut").i;
+ beta = 0.5 * (HALFPI - pj_param(par.params, "rlat_b").f);
+ if (fabs(beta) < EPS)
+ proj_parm.Cb = -0.5;
+ else {
+ proj_parm.Cb = 1./tan(beta);
+ proj_parm.Cb *= proj_parm.Cb * log(cos(beta));
+ }
+ if (fabs(fabs(par.phi0) - HALFPI) < EPS)
+ if (par.phi0 < 0.) {
+ proj_parm.p_halfpi = -HALFPI;
+ proj_parm.mode = S_POLE;
+ } else {
+ proj_parm.p_halfpi = HALFPI;
+ proj_parm.mode = N_POLE;
+ }
+ else {
+ if (fabs(par.phi0) < EPS)
+ proj_parm.mode = EQUIT;
+ else {
+ proj_parm.mode = OBLIQ;
+ proj_parm.sinph0 = sin(par.phi0);
+ proj_parm.cosph0 = cos(par.phi0);
+ }
+ }
+ par.es = 0.;
+ }
+
+ }} // namespace detail::airy
+ #endif // doxygen
+
+ /*!
+ \brief Airy projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Projection parameters
+ - no_cut: Do not cut at hemisphere limit (boolean)
+ - lat_b (degrees)
+ \par Example
+ \image html ex_airy.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct airy_spheroid : public detail::airy::base_airy_spheroid<CalculationType, Parameters>
+ {
+ inline airy_spheroid(const Parameters& par) : detail::airy::base_airy_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::airy::setup_airy(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::airy, airy_spheroid, airy_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class airy_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<airy_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void airy_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("airy", new airy_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
+
diff --git a/boost/geometry/srs/projections/proj/aitoff.hpp b/boost/geometry/srs/projections/proj/aitoff.hpp
new file mode 100644
index 0000000000..7d34a23287
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/aitoff.hpp
@@ -0,0 +1,324 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the aitoff (Aitoff) and wintri (Winkel Tripel)
+// projections.
+// Author: Gerald Evenden
+// Copyright (c) 1995, Gerald Evenden
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/core/ignore_unused.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct aitoff {};
+ struct wintri {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace aitoff
+ {
+ template <typename T>
+ struct par_aitoff
+ {
+ T cosphi1;
+ int mode;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_aitoff_spheroid : public base_t_fi<base_aitoff_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_aitoff<CalculationType> m_proj_parm;
+
+ inline base_aitoff_spheroid(const Parameters& par)
+ : base_t_fi<base_aitoff_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType c, d;
+
+ if((d = acos(cos(lp_lat) * cos(c = 0.5 * lp_lon)))) {/* basic Aitoff */
+ xy_x = 2. * d * cos(lp_lat) * sin(c) * (xy_y = 1. / sin(d));
+ xy_y *= d * sin(lp_lat);
+ } else
+ xy_x = xy_y = 0.;
+ if (this->m_proj_parm.mode) { /* Winkel Tripel */
+ xy_x = (xy_x + lp_lon * this->m_proj_parm.cosphi1) * 0.5;
+ xy_y = (xy_y + lp_lat) * 0.5;
+ }
+ }
+ /***********************************************************************************
+ *
+ * Inverse functions added by Drazen Tutic and Lovro Gradiser based on paper:
+ *
+ * I.Özbug Biklirici and Cengizhan Ipbüker. A General Algorithm for the Inverse
+ * Transformation of Map Projections Using Jacobian Matrices. In Proceedings of the
+ * Third International Symposium Mathematical & Computational Applications,
+ * pages 175{182, Turkey, September 2002.
+ *
+ * Expected accuracy is defined by EPSILON = 1e-12. Should be appropriate for
+ * most applications of Aitoff and Winkel Tripel projections.
+ *
+ * Longitudes of 180W and 180E can be mixed in solution obtained.
+ *
+ * Inverse for Aitoff projection in poles is undefined, longitude value of 0 is assumed.
+ *
+ * Contact : dtutic@geof.hr
+ * Date: 2015-02-16
+ *
+ ************************************************************************************/
+
+ // INVERSE(s_inverse) sphere
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType ONEPI = detail::ONEPI<CalculationType>();
+ static const CalculationType TWOPI = detail::TWOPI<CalculationType>();
+ static const CalculationType EPSILON = 1e-12;
+
+ int iter, MAXITER = 10, round = 0, MAXROUND = 20;
+ CalculationType D, C, f1, f2, f1p, f1l, f2p, f2l, dp, dl, sl, sp, cp, cl, x, y;
+
+ if ((fabs(xy_x) < EPSILON) && (fabs(xy_y) < EPSILON )) { lp_lat = 0.; lp_lon = 0.; return; }
+
+ /* intial values for Newton-Raphson method */
+ lp_lat = xy_y; lp_lon = xy_x;
+ do {
+ iter = 0;
+ do {
+ sl = sin(lp_lon * 0.5); cl = cos(lp_lon * 0.5);
+ sp = sin(lp_lat); cp = cos(lp_lat);
+ D = cp * cl;
+ C = 1. - D * D;
+ D = acos(D) / pow(C, 1.5);
+ f1 = 2. * D * C * cp * sl;
+ f2 = D * C * sp;
+ f1p = 2.* (sl * cl * sp * cp / C - D * sp * sl);
+ f1l = cp * cp * sl * sl / C + D * cp * cl * sp * sp;
+ f2p = sp * sp * cl / C + D * sl * sl * cp;
+ f2l = 0.5 * (sp * cp * sl / C - D * sp * cp * cp * sl * cl);
+ if (this->m_proj_parm.mode) { /* Winkel Tripel */
+ f1 = 0.5 * (f1 + lp_lon * this->m_proj_parm.cosphi1);
+ f2 = 0.5 * (f2 + lp_lat);
+ f1p *= 0.5;
+ f1l = 0.5 * (f1l + this->m_proj_parm.cosphi1);
+ f2p = 0.5 * (f2p + 1.);
+ f2l *= 0.5;
+ }
+ f1 -= xy_x; f2 -= xy_y;
+ dl = (f2 * f1p - f1 * f2p) / (dp = f1p * f2l - f2p * f1l);
+ dp = (f1 * f2l - f2 * f1l) / dp;
+ while (dl > ONEPI) dl -= ONEPI; /* set to interval [-ONEPI, ONEPI] */
+ while (dl < -ONEPI) dl += ONEPI; /* set to interval [-ONEPI, ONEPI] */
+ lp_lat -= dp; lp_lon -= dl;
+ } while ((fabs(dp) > EPSILON || fabs(dl) > EPSILON) && (iter++ < MAXITER));
+ if (lp_lat > TWOPI) lp_lat -= 2.*(lp_lat-TWOPI); /* correct if symmetrical solution for Aitoff */
+ if (lp_lat < -TWOPI) lp_lat -= 2.*(lp_lat+TWOPI); /* correct if symmetrical solution for Aitoff */
+ if ((fabs(fabs(lp_lat) - TWOPI) < EPSILON) && (!this->m_proj_parm.mode)) lp_lon = 0.; /* if pole in Aitoff, return longitude of 0 */
+
+ /* calculate x,y coordinates with solution obtained */
+ if((D = acos(cos(lp_lat) * cos(C = 0.5 * lp_lon)))) {/* Aitoff */
+ x = 2. * D * cos(lp_lat) * sin(C) * (y = 1. / sin(D));
+ y *= D * sin(lp_lat);
+ } else
+ x = y = 0.;
+ if (this->m_proj_parm.mode) { /* Winkel Tripel */
+ x = (x + lp_lon * this->m_proj_parm.cosphi1) * 0.5;
+ y = (y + lp_lat) * 0.5;
+ }
+ /* if too far from given values of x,y, repeat with better approximation of phi,lam */
+ } while (((fabs(xy_x-x) > EPSILON) || (fabs(xy_y-y) > EPSILON)) && (round++ < MAXROUND));
+
+ //if (iter == MAXITER && round == MAXROUND) fprintf(stderr, "Warning: Accuracy of 1e-12 not reached. Last increments: dlat=%e and dlon=%e\n", dp, dl);
+ }
+
+ static inline std::string get_name()
+ {
+ return "aitoff_spheroid";
+ }
+
+ };
+
+ template <typename Parameters, typename T>
+ inline void setup(Parameters& par, par_aitoff<T>& proj_parm)
+ {
+ boost::ignore_unused(proj_parm);
+ par.es = 0.;
+ }
+
+
+ // Aitoff
+ template <typename Parameters, typename T>
+ inline void setup_aitoff(Parameters& par, par_aitoff<T>& proj_parm)
+ {
+ proj_parm.mode = 0;
+ setup(par, proj_parm);
+ }
+
+ // Winkel Tripel
+ template <typename Parameters, typename T>
+ inline void setup_wintri(Parameters& par, par_aitoff<T>& proj_parm)
+ {
+ static const T TWO_D_PI = detail::TWO_D_PI<T>();
+
+ proj_parm.mode = 1;
+ if (pj_param(par.params, "tlat_1").i) {
+ if ((proj_parm.cosphi1 = cos(pj_param(par.params, "rlat_1").f)) == 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-22) );
+ } else /* 50d28' or phi1=acos(2/pi) */
+ proj_parm.cosphi1 = TWO_D_PI;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::aitoff
+ #endif // doxygen
+
+ /*!
+ \brief Aitoff projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ \par Example
+ \image html ex_aitoff.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct aitoff_spheroid : public detail::aitoff::base_aitoff_spheroid<CalculationType, Parameters>
+ {
+ inline aitoff_spheroid(const Parameters& par) : detail::aitoff::base_aitoff_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::aitoff::setup_aitoff(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Winkel Tripel projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ \par Example
+ \image html ex_wintri.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct wintri_spheroid : public detail::aitoff::base_aitoff_spheroid<CalculationType, Parameters>
+ {
+ inline wintri_spheroid(const Parameters& par) : detail::aitoff::base_aitoff_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::aitoff::setup_wintri(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::aitoff, aitoff_spheroid, aitoff_spheroid)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wintri, wintri_spheroid, wintri_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class aitoff_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<aitoff_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class wintri_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<wintri_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void aitoff_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("aitoff", new aitoff_entry<CalculationType, Parameters>);
+ factory.add_to_factory("wintri", new wintri_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP
+
diff --git a/boost/geometry/srs/projections/proj/august.hpp b/boost/geometry/srs/projections/proj/august.hpp
new file mode 100644
index 0000000000..7358cfb12f
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/august.hpp
@@ -0,0 +1,168 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_AUGUST_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_AUGUST_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct august {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace august
+ {
+
+ //static const double M = 1.333333333333333;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_august_spheroid : public base_t_f<base_august_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_august_spheroid(const Parameters& par)
+ : base_t_f<base_august_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType M = 1.333333333333333333333333333333333333;
+
+ CalculationType t, c1, c, x1, x12, y1, y12;
+
+ t = tan(.5 * lp_lat);
+ c1 = sqrt(1. - t * t);
+ c = 1. + c1 * cos(lp_lon *= .5);
+ x1 = sin(lp_lon) * c1 / c;
+ y1 = t / c;
+ xy_x = M * x1 * (3. + (x12 = x1 * x1) - 3. * (y12 = y1 * y1));
+ xy_y = M * y1 * (3. + 3. * x12 - y12);
+ }
+
+ static inline std::string get_name()
+ {
+ return "august_spheroid";
+ }
+
+ };
+
+ // August Epicycloidal
+ template <typename Parameters>
+ inline void setup_august(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::august
+ #endif // doxygen
+
+ /*!
+ \brief August Epicycloidal projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_august.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct august_spheroid : public detail::august::base_august_spheroid<CalculationType, Parameters>
+ {
+ inline august_spheroid(const Parameters& par) : detail::august::base_august_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::august::setup_august(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::august, august_spheroid, august_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class august_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<august_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void august_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("august", new august_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AUGUST_HPP
+
diff --git a/boost/geometry/srs/projections/proj/bacon.hpp b/boost/geometry/srs/projections/proj/bacon.hpp
new file mode 100644
index 0000000000..5e8d37980f
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/bacon.hpp
@@ -0,0 +1,272 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_BACON_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_BACON_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct apian {};
+ struct ortel {};
+ struct bacon {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace bacon
+ {
+
+ //static const double HLFPI2 = 2.46740110027233965467;
+ static const double EPS = 1e-10;
+
+ struct par_bacon
+ {
+ int bacn;
+ int ortl;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_bacon_spheroid : public base_t_f<base_bacon_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_bacon m_proj_parm;
+
+ inline base_bacon_spheroid(const Parameters& par)
+ : base_t_f<base_bacon_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+ static const CalculationType HLFPI2 = detail::HALFPI_SQR<CalculationType>();
+
+ CalculationType ax, f;
+
+ xy_y = this->m_proj_parm.bacn ? HALFPI * sin(lp_lat) : lp_lat;
+ if ((ax = fabs(lp_lon)) >= EPS) {
+ if (this->m_proj_parm.ortl && ax >= HALFPI)
+ xy_x = sqrt(HLFPI2 - lp_lat * lp_lat + EPS) + ax - HALFPI;
+ else {
+ f = 0.5 * (HLFPI2 / ax + ax);
+ xy_x = ax - f + sqrt(f * f - xy_y * xy_y);
+ }
+ if (lp_lon < 0.) xy_x = - xy_x;
+ } else
+ xy_x = 0.;
+ }
+
+ static inline std::string get_name()
+ {
+ return "bacon_spheroid";
+ }
+
+ };
+
+ // Apian Globular I
+ template <typename Parameters>
+ inline void setup_apian(Parameters& par, par_bacon& proj_parm)
+ {
+ proj_parm.bacn = proj_parm.ortl = 0;
+ par.es = 0.;
+ }
+
+ // Ortelius Oval
+ template <typename Parameters>
+ inline void setup_ortel(Parameters& par, par_bacon& proj_parm)
+ {
+ proj_parm.bacn = 0;
+ proj_parm.ortl = 1;
+ par.es = 0.;
+ }
+
+ // Bacon Globular
+ template <typename Parameters>
+ inline void setup_bacon(Parameters& par, par_bacon& proj_parm)
+ {
+ proj_parm.bacn = 1;
+ proj_parm.ortl = 0;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::bacon
+ #endif // doxygen
+
+ /*!
+ \brief Apian Globular I projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_apian.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct apian_spheroid : public detail::bacon::base_bacon_spheroid<CalculationType, Parameters>
+ {
+ inline apian_spheroid(const Parameters& par) : detail::bacon::base_bacon_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::bacon::setup_apian(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Ortelius Oval projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_ortel.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct ortel_spheroid : public detail::bacon::base_bacon_spheroid<CalculationType, Parameters>
+ {
+ inline ortel_spheroid(const Parameters& par) : detail::bacon::base_bacon_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::bacon::setup_ortel(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Bacon Globular projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_bacon.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct bacon_spheroid : public detail::bacon::base_bacon_spheroid<CalculationType, Parameters>
+ {
+ inline bacon_spheroid(const Parameters& par) : detail::bacon::base_bacon_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::bacon::setup_bacon(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::apian, apian_spheroid, apian_spheroid)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::bacon, bacon_spheroid, bacon_spheroid)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::ortel, ortel_spheroid, ortel_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class apian_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<apian_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class ortel_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<ortel_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class bacon_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<bacon_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void bacon_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("apian", new apian_entry<CalculationType, Parameters>);
+ factory.add_to_factory("ortel", new ortel_entry<CalculationType, Parameters>);
+ factory.add_to_factory("bacon", new bacon_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_BACON_HPP
+
diff --git a/boost/geometry/srs/projections/proj/bipc.hpp b/boost/geometry/srs/projections/proj/bipc.hpp
new file mode 100644
index 0000000000..6f014d0e66
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/bipc.hpp
@@ -0,0 +1,297 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct bipc {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace bipc
+ {
+
+ static const double EPS = 1e-10;
+ static const double EPS10 = 1e-10;
+ static const double ONEEPS = 1.000000001;
+ static const int NITER = 10;
+ static const double lamB = -.34894976726250681539;
+ static const double n = .63055844881274687180;
+ static const double F = 1.89724742567461030582;
+ static const double Azab = .81650043674686363166;
+ static const double Azba = 1.82261843856185925133;
+ static const double T = 1.27246578267089012270;
+ static const double rhoc = 1.20709121521568721927;
+ static const double cAzc = .69691523038678375519;
+ static const double sAzc = .71715351331143607555;
+ static const double C45 = .70710678118654752469;
+ static const double S45 = .70710678118654752410;
+ static const double C20 = .93969262078590838411;
+ static const double S20 = -.34202014332566873287;
+ static const double R110 = 1.91986217719376253360;
+ static const double R104 = 1.81514242207410275904;
+
+ struct par_bipc
+ {
+ int noskew;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_bipc_spheroid : public base_t_fi<base_bipc_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_bipc m_proj_parm;
+
+ inline base_bipc_spheroid(const Parameters& par)
+ : base_t_fi<base_bipc_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+ static const CalculationType ONEPI = detail::ONEPI<CalculationType>();
+
+ CalculationType cphi, sphi, tphi, t, al, Az, z, Av, cdlam, sdlam, r;
+ int tag;
+
+ cphi = cos(lp_lat);
+ sphi = sin(lp_lat);
+ cdlam = cos(sdlam = lamB - lp_lon);
+ sdlam = sin(sdlam);
+ if (fabs(fabs(lp_lat) - HALFPI) < EPS10) {
+ Az = lp_lat < 0. ? ONEPI : 0.;
+ tphi = HUGE_VAL;
+ } else {
+ tphi = sphi / cphi;
+ Az = atan2(sdlam , C45 * (tphi - cdlam));
+ }
+ if( (tag = (Az > Azba)) ) {
+ cdlam = cos(sdlam = lp_lon + R110);
+ sdlam = sin(sdlam);
+ z = S20 * sphi + C20 * cphi * cdlam;
+ if (fabs(z) > 1.) {
+ if (fabs(z) > ONEEPS)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ else
+ z = z < 0. ? -1. : 1.;
+ } else
+ z = acos(z);
+ if (tphi != HUGE_VAL)
+ Az = atan2(sdlam, (C20 * tphi - S20 * cdlam));
+ Av = Azab;
+ xy_y = rhoc;
+ } else {
+ z = S45 * (sphi + cphi * cdlam);
+ if (fabs(z) > 1.) {
+ if (fabs(z) > ONEEPS)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ else
+ z = z < 0. ? -1. : 1.;
+ } else
+ z = acos(z);
+ Av = Azba;
+ xy_y = -rhoc;
+ }
+ if (z < 0.) BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ r = F * (t = pow(tan(.5 * z), n));
+ if ((al = .5 * (R104 - z)) < 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ al = (t + pow(al, n)) / T;
+ if (fabs(al) > 1.) {
+ if (fabs(al) > ONEEPS)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ else
+ al = al < 0. ? -1. : 1.;
+ } else
+ al = acos(al);
+ if (fabs(t = n * (Av - Az)) < al)
+ r /= cos(al + (tag ? t : -t));
+ xy_x = r * sin(t);
+ xy_y += (tag ? -r : r) * cos(t);
+ if (this->m_proj_parm.noskew) {
+ t = xy_x;
+ xy_x = -xy_x * cAzc - xy_y * sAzc;
+ xy_y = -xy_y * cAzc + t * sAzc;
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType t, r, rp, rl, al, z, fAz, Az, s, c, Av;
+ int neg, i;
+
+ if (this->m_proj_parm.noskew) {
+ t = xy_x;
+ xy_x = -xy_x * cAzc + xy_y * sAzc;
+ xy_y = -xy_y * cAzc - t * sAzc;
+ }
+ if( (neg = (xy_x < 0.)) ) {
+ xy_y = rhoc - xy_y;
+ s = S20;
+ c = C20;
+ Av = Azab;
+ } else {
+ xy_y += rhoc;
+ s = S45;
+ c = C45;
+ Av = Azba;
+ }
+ rl = rp = r = boost::math::hypot(xy_x, xy_y);
+ fAz = fabs(Az = atan2(xy_x, xy_y));
+ for (i = NITER; i ; --i) {
+ z = 2. * atan(pow(r / F,1 / n));
+ al = acos((pow(tan(.5 * z), n) +
+ pow(tan(.5 * (R104 - z)), n)) / T);
+ if (fAz < al)
+ r = rp * cos(al + (neg ? Az : -Az));
+ if (fabs(rl - r) < EPS)
+ break;
+ rl = r;
+ }
+ if (! i)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ Az = Av - Az / n;
+ lp_lat = asin(s * cos(z) + c * sin(z) * cos(Az));
+ lp_lon = atan2(sin(Az), c / tan(z) - s * cos(Az));
+ if (neg)
+ lp_lon -= R110;
+ else
+ lp_lon = lamB - lp_lon;
+ }
+
+ static inline std::string get_name()
+ {
+ return "bipc_spheroid";
+ }
+
+ };
+
+ // Bipolar conic of western hemisphere
+ template <typename Parameters>
+ inline void setup_bipc(Parameters& par, par_bipc& proj_parm)
+ {
+ proj_parm.noskew = pj_param(par.params, "bns").i;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::bipc
+ #endif // doxygen
+
+ /*!
+ \brief Bipolar conic of western hemisphere projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ \par Projection parameters
+ - ns (boolean)
+ \par Example
+ \image html ex_bipc.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct bipc_spheroid : public detail::bipc::base_bipc_spheroid<CalculationType, Parameters>
+ {
+ inline bipc_spheroid(const Parameters& par) : detail::bipc::base_bipc_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::bipc::setup_bipc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::bipc, bipc_spheroid, bipc_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class bipc_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<bipc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void bipc_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("bipc", new bipc_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP
+
diff --git a/boost/geometry/srs/projections/proj/boggs.hpp b/boost/geometry/srs/projections/proj/boggs.hpp
new file mode 100644
index 0000000000..6c371e430f
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/boggs.hpp
@@ -0,0 +1,185 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_BOGGS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_BOGGS_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct boggs {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace boggs
+ {
+
+ static const int NITER = 20;
+ static const double EPS = 1e-7;
+ static const double ONETOL = 1.000001;
+ static const double FXC = 2.00276;
+ static const double FXC2 = 1.11072;
+ static const double FYC = 0.49931;
+ static const double FYC2 = 1.41421356237309504880;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_boggs_spheroid : public base_t_f<base_boggs_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_boggs_spheroid(const Parameters& par)
+ : base_t_f<base_boggs_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+ static const CalculationType ONEPI = detail::ONEPI<CalculationType>();
+
+ CalculationType theta, th1, c;
+ int i;
+
+ theta = lp_lat;
+ if (fabs(fabs(lp_lat) - HALFPI) < EPS)
+ xy_x = 0.;
+ else {
+ c = sin(theta) * ONEPI;
+ for (i = NITER; i; --i) {
+ theta -= th1 = (theta + sin(theta) - c) /
+ (1. + cos(theta));
+ if (fabs(th1) < EPS) break;
+ }
+ theta *= 0.5;
+ xy_x = FXC * lp_lon / (1. / cos(lp_lat) + FXC2 / cos(theta));
+ }
+ xy_y = FYC * (lp_lat + FYC2 * sin(theta));
+ }
+
+ static inline std::string get_name()
+ {
+ return "boggs_spheroid";
+ }
+
+ };
+
+ // Boggs Eumorphic
+ template <typename Parameters>
+ inline void setup_boggs(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::boggs
+ #endif // doxygen
+
+ /*!
+ \brief Boggs Eumorphic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - no inverse
+ - Spheroid
+ \par Example
+ \image html ex_boggs.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct boggs_spheroid : public detail::boggs::base_boggs_spheroid<CalculationType, Parameters>
+ {
+ inline boggs_spheroid(const Parameters& par) : detail::boggs::base_boggs_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::boggs::setup_boggs(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::boggs, boggs_spheroid, boggs_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class boggs_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<boggs_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void boggs_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("boggs", new boggs_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_BOGGS_HPP
+
diff --git a/boost/geometry/srs/projections/proj/bonne.hpp b/boost/geometry/srs/projections/proj/bonne.hpp
new file mode 100644
index 0000000000..52120a905f
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/bonne.hpp
@@ -0,0 +1,298 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct bonne {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace bonne
+ {
+
+ static const double EPS10 = 1e-10;
+
+ template <typename T>
+ struct par_bonne
+ {
+ T phi1;
+ T cphi1;
+ T am1;
+ T m1;
+ T en[EN_SIZE];
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_bonne_ellipsoid : public base_t_fi<base_bonne_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_bonne<CalculationType> m_proj_parm;
+
+ inline base_bonne_ellipsoid(const Parameters& par)
+ : base_t_fi<base_bonne_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType rh, E, c;
+
+ rh = this->m_proj_parm.am1 + this->m_proj_parm.m1 - pj_mlfn(lp_lat, E = sin(lp_lat), c = cos(lp_lat), this->m_proj_parm.en);
+ E = c * lp_lon / (rh * sqrt(1. - this->m_par.es * E * E));
+ xy_x = rh * sin(E);
+ xy_y = this->m_proj_parm.am1 - rh * cos(E);
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType s, rh;
+
+ rh = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.am1 - xy_y);
+ lp_lat = pj_inv_mlfn(this->m_proj_parm.am1 + this->m_proj_parm.m1 - rh, this->m_par.es, this->m_proj_parm.en);
+ if ((s = fabs(lp_lat)) < HALFPI) {
+ s = sin(lp_lat);
+ lp_lon = rh * atan2(xy_x, xy_y) *
+ sqrt(1. - this->m_par.es * s * s) / cos(lp_lat);
+ } else if (fabs(s - HALFPI) <= EPS10)
+ lp_lon = 0.;
+ else
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ }
+
+ static inline std::string get_name()
+ {
+ return "bonne_ellipsoid";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_bonne_spheroid : public base_t_fi<base_bonne_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_bonne<CalculationType> m_proj_parm;
+
+ inline base_bonne_spheroid(const Parameters& par)
+ : base_t_fi<base_bonne_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType E, rh;
+
+ rh = this->m_proj_parm.cphi1 + this->m_proj_parm.phi1 - lp_lat;
+ if (fabs(rh) > EPS10) {
+ xy_x = rh * sin(E = lp_lon * cos(lp_lat) / rh);
+ xy_y = this->m_proj_parm.cphi1 - rh * cos(E);
+ } else
+ xy_x = xy_y = 0.;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType rh;
+
+ rh = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.cphi1 - xy_y);
+ lp_lat = this->m_proj_parm.cphi1 + this->m_proj_parm.phi1 - rh;
+ if (fabs(lp_lat) > HALFPI)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ if (fabs(fabs(lp_lat) - HALFPI) <= EPS10)
+ lp_lon = 0.;
+ else
+ lp_lon = rh * atan2(xy_x, xy_y) / cos(lp_lat);
+ }
+
+ static inline std::string get_name()
+ {
+ return "bonne_spheroid";
+ }
+
+ };
+
+ // Bonne (Werner lat_1=90)
+ template <typename Parameters, typename T>
+ inline void setup_bonne(Parameters& par, par_bonne<T>& proj_parm)
+ {
+ static const T HALFPI = detail::HALFPI<T>();
+
+ T c;
+
+ proj_parm.phi1 = pj_param(par.params, "rlat_1").f;
+ if (fabs(proj_parm.phi1) < EPS10)
+ BOOST_THROW_EXCEPTION( projection_exception(-23) );
+ if (par.es) {
+ pj_enfn(par.es, proj_parm.en);
+ proj_parm.m1 = pj_mlfn(proj_parm.phi1, proj_parm.am1 = sin(proj_parm.phi1),
+ c = cos(proj_parm.phi1), proj_parm.en);
+ proj_parm.am1 = c / (sqrt(1. - par.es * proj_parm.am1 * proj_parm.am1) * proj_parm.am1);
+ } else {
+ if (fabs(proj_parm.phi1) + EPS10 >= HALFPI)
+ proj_parm.cphi1 = 0.;
+ else
+ proj_parm.cphi1 = 1. / tan(proj_parm.phi1);
+ }
+ }
+
+ }} // namespace detail::bonne
+ #endif // doxygen
+
+ /*!
+ \brief Bonne (Werner lat_1=90) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ \par Example
+ \image html ex_bonne.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct bonne_ellipsoid : public detail::bonne::base_bonne_ellipsoid<CalculationType, Parameters>
+ {
+ inline bonne_ellipsoid(const Parameters& par) : detail::bonne::base_bonne_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::bonne::setup_bonne(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Bonne (Werner lat_1=90) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ \par Example
+ \image html ex_bonne.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct bonne_spheroid : public detail::bonne::base_bonne_spheroid<CalculationType, Parameters>
+ {
+ inline bonne_spheroid(const Parameters& par) : detail::bonne::base_bonne_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::bonne::setup_bonne(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::bonne, bonne_spheroid, bonne_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class bonne_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<bonne_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ else
+ return new base_v_fi<bonne_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void bonne_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("bonne", new bonne_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP
+
diff --git a/boost/geometry/srs/projections/proj/cass.hpp b/boost/geometry/srs/projections/proj/cass.hpp
new file mode 100644
index 0000000000..b5f32b5aab
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/cass.hpp
@@ -0,0 +1,292 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_CASS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_CASS_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct cass {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace cass
+ {
+
+ //static const double EPS10 = 1e-10;
+ //static const double C1 = .16666666666666666666;
+ //static const double C2 = .00833333333333333333;
+ //static const double C3 = .04166666666666666666;
+ //static const double C4 = .33333333333333333333;
+ //static const double C5 = .06666666666666666666;
+
+ template <typename T>
+ inline T C1() { return .16666666666666666666666666666666666666; }
+ template <typename T>
+ inline T C2() { return .00833333333333333333333333333333333333; }
+ template <typename T>
+ inline T C3() { return .04166666666666666666666666666666666666; }
+ template <typename T>
+ inline T C4() { return .33333333333333333333333333333333333333; }
+ template <typename T>
+ inline T C5() { return .06666666666666666666666666666666666666; }
+
+ template <typename T>
+ struct par_cass
+ {
+ T m0;
+ T en[EN_SIZE];
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_cass_ellipsoid : public base_t_fi<base_cass_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_cass<CalculationType> m_proj_parm;
+
+ inline base_cass_ellipsoid(const Parameters& par)
+ : base_t_fi<base_cass_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType C1 = cass::C1<CalculationType>();
+ static const CalculationType C2 = cass::C2<CalculationType>();
+ static const CalculationType C3 = cass::C3<CalculationType>();
+
+ CalculationType n = sin(lp_lat);
+ CalculationType c = cos(lp_lat);
+ xy_y = pj_mlfn(lp_lat, n, c, this->m_proj_parm.en);
+ n = 1./sqrt(1. - this->m_par.es * n * n);
+ CalculationType tn = tan(lp_lat); CalculationType t = tn * tn;
+ CalculationType a1 = lp_lon * c;
+ c *= this->m_par.es * c / (1 - this->m_par.es);
+ CalculationType a2 = a1 * a1;
+ xy_x = n * a1 * (1. - a2 * t *
+ (C1 - (8. - t + 8. * c) * a2 * C2));
+ xy_y -= this->m_proj_parm.m0 - n * tn * a2 *
+ (.5 + (5. - t + 6. * c) * a2 * C3);
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType C3 = cass::C3<CalculationType>();
+ static const CalculationType C4 = cass::C4<CalculationType>();
+ static const CalculationType C5 = cass::C5<CalculationType>();
+
+ CalculationType ph1;
+
+ ph1 = pj_inv_mlfn(this->m_proj_parm.m0 + xy_y, this->m_par.es, this->m_proj_parm.en);
+ CalculationType tn = tan(ph1); CalculationType t = tn * tn;
+ CalculationType n = sin(ph1);
+ CalculationType r = 1. / (1. - this->m_par.es * n * n);
+ n = sqrt(r);
+ r *= (1. - this->m_par.es) * n;
+ CalculationType dd = xy_x / n;
+ CalculationType d2 = dd * dd;
+ lp_lat = ph1 - (n * tn / r) * d2 *
+ (.5 - (1. + 3. * t) * d2 * C3);
+ lp_lon = dd * (1. + t * d2 *
+ (-C4 + (1. + 3. * t) * d2 * C5)) / cos(ph1);
+ }
+
+ static inline std::string get_name()
+ {
+ return "cass_ellipsoid";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_cass_spheroid : public base_t_fi<base_cass_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_cass<CalculationType> m_proj_parm;
+
+ inline base_cass_spheroid(const Parameters& par)
+ : base_t_fi<base_cass_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = asin(cos(lp_lat) * sin(lp_lon));
+ xy_y = atan2(tan(lp_lat) , cos(lp_lon)) - this->m_par.phi0;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType dd = xy_y + this->m_par.phi0;
+ lp_lat = asin(sin(dd) * cos(xy_x));
+ lp_lon = atan2(tan(xy_x), cos(dd));
+ }
+
+ static inline std::string get_name()
+ {
+ return "cass_spheroid";
+ }
+
+ };
+
+ // Cassini
+ template <typename Parameters, typename T>
+ inline void setup_cass(Parameters& par, par_cass<T>& proj_parm)
+ {
+ if (par.es) {
+ if (!pj_enfn(par.es, proj_parm.en))
+ BOOST_THROW_EXCEPTION( projection_exception(0) );
+ proj_parm.m0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en);
+ } else {
+ }
+ }
+
+ }} // namespace detail::cass
+ #endif // doxygen
+
+ /*!
+ \brief Cassini projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_cass.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct cass_ellipsoid : public detail::cass::base_cass_ellipsoid<CalculationType, Parameters>
+ {
+ inline cass_ellipsoid(const Parameters& par) : detail::cass::base_cass_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::cass::setup_cass(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Cassini projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_cass.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct cass_spheroid : public detail::cass::base_cass_spheroid<CalculationType, Parameters>
+ {
+ inline cass_spheroid(const Parameters& par) : detail::cass::base_cass_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::cass::setup_cass(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::cass, cass_spheroid, cass_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class cass_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<cass_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ else
+ return new base_v_fi<cass_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void cass_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("cass", new cass_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CASS_HPP
+
diff --git a/boost/geometry/srs/projections/proj/cc.hpp b/boost/geometry/srs/projections/proj/cc.hpp
new file mode 100644
index 0000000000..c7fc1f20ab
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/cc.hpp
@@ -0,0 +1,171 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_CC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_CC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct cc {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace cc
+ {
+
+ static const double EPS10 = 1.e-10;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_cc_spheroid : public base_t_fi<base_cc_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ inline base_cc_spheroid(const Parameters& par)
+ : base_t_fi<base_cc_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ if (fabs(fabs(lp_lat) - HALFPI) <= EPS10)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ xy_x = lp_lon;
+ xy_y = tan(lp_lat);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = atan(xy_y);
+ lp_lon = xy_x;
+ }
+
+ static inline std::string get_name()
+ {
+ return "cc_spheroid";
+ }
+
+ };
+
+ // Central Cylindrical
+ template <typename Parameters>
+ inline void setup_cc(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::cc
+ #endif // doxygen
+
+ /*!
+ \brief Central Cylindrical projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ \par Example
+ \image html ex_cc.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct cc_spheroid : public detail::cc::base_cc_spheroid<CalculationType, Parameters>
+ {
+ inline cc_spheroid(const Parameters& par) : detail::cc::base_cc_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::cc::setup_cc(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::cc, cc_spheroid, cc_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class cc_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<cc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void cc_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("cc", new cc_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CC_HPP
+
diff --git a/boost/geometry/srs/projections/proj/cea.hpp b/boost/geometry/srs/projections/proj/cea.hpp
new file mode 100644
index 0000000000..b6d8707e08
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/cea.hpp
@@ -0,0 +1,269 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_CEA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_CEA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_auth.hpp>
+#include <boost/geometry/srs/projections/impl/pj_qsfn.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct cea {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace cea
+ {
+
+ static const double EPS = 1e-10;
+
+ template <typename T>
+ struct par_cea
+ {
+ T qp;
+ T apa[APA_SIZE];
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_cea_ellipsoid : public base_t_fi<base_cea_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_cea<CalculationType> m_proj_parm;
+
+ inline base_cea_ellipsoid(const Parameters& par)
+ : base_t_fi<base_cea_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = this->m_par.k0 * lp_lon;
+ xy_y = .5 * pj_qsfn(sin(lp_lat), this->m_par.e, this->m_par.one_es) / this->m_par.k0;
+ }
+
+ // INVERSE(e_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = pj_authlat(asin( 2. * xy_y * this->m_par.k0 / this->m_proj_parm.qp), this->m_proj_parm.apa);
+ lp_lon = xy_x / this->m_par.k0;
+ }
+
+ static inline std::string get_name()
+ {
+ return "cea_ellipsoid";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_cea_spheroid : public base_t_fi<base_cea_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_cea<CalculationType> m_proj_parm;
+
+ inline base_cea_spheroid(const Parameters& par)
+ : base_t_fi<base_cea_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = this->m_par.k0 * lp_lon;
+ xy_y = sin(lp_lat) / this->m_par.k0;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType t;
+
+ if ((t = fabs(xy_y *= this->m_par.k0)) - EPS <= 1.) {
+ if (t >= 1.)
+ lp_lat = xy_y < 0. ? -HALFPI : HALFPI;
+ else
+ lp_lat = asin(xy_y);
+ lp_lon = xy_x / this->m_par.k0;
+ } else
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ }
+
+ static inline std::string get_name()
+ {
+ return "cea_spheroid";
+ }
+
+ };
+
+ // Equal Area Cylindrical
+ template <typename Parameters, typename T>
+ inline void setup_cea(Parameters& par, par_cea<T>& proj_parm)
+ {
+ T t = 0;
+
+ if (pj_param(par.params, "tlat_ts").i &&
+ (par.k0 = cos(t = pj_param(par.params, "rlat_ts").f)) < 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-24) );
+ if (par.es) {
+ t = sin(t);
+ par.k0 /= sqrt(1. - par.es * t * t);
+ par.e = sqrt(par.es);
+ if (!pj_authset(par.es, proj_parm.apa))
+ BOOST_THROW_EXCEPTION( projection_exception(0) );
+ proj_parm.qp = pj_qsfn(1., par.e, par.one_es);
+ } else {
+ }
+ }
+
+ }} // namespace detail::cea
+ #endif // doxygen
+
+ /*!
+ \brief Equal Area Cylindrical projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ \par Example
+ \image html ex_cea.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct cea_ellipsoid : public detail::cea::base_cea_ellipsoid<CalculationType, Parameters>
+ {
+ inline cea_ellipsoid(const Parameters& par) : detail::cea::base_cea_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::cea::setup_cea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Equal Area Cylindrical projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ \par Example
+ \image html ex_cea.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct cea_spheroid : public detail::cea::base_cea_spheroid<CalculationType, Parameters>
+ {
+ inline cea_spheroid(const Parameters& par) : detail::cea::base_cea_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::cea::setup_cea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::cea, cea_spheroid, cea_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class cea_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<cea_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ else
+ return new base_v_fi<cea_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void cea_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("cea", new cea_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CEA_HPP
+
diff --git a/boost/geometry/srs/projections/proj/chamb.hpp b/boost/geometry/srs/projections/proj/chamb.hpp
new file mode 100644
index 0000000000..9fd123bb2e
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/chamb.hpp
@@ -0,0 +1,288 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+#include <cstdio>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct chamb {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace chamb
+ {
+
+ //static const double THIRD = 0.333333333333333333;
+ static const double TOL = 1e-9;
+
+ // specific for 'chamb'
+ template <typename T>
+ struct VECT { T r, Az; };
+ template <typename T>
+ struct XY { T x, y; };
+
+ template <typename T>
+ struct par_chamb
+ {
+ struct { /* control point data */
+ T phi, lam;
+ T cosphi, sinphi;
+ VECT<T> v;
+ XY<T> p;
+ T Az;
+ } c[3];
+ XY<T> p;
+ T beta_0, beta_1, beta_2;
+ };
+
+ template <typename T>
+ inline VECT<T> /* distance and azimuth from point 1 to point 2 */
+ vect(T const& dphi, T const& c1, T const& s1, T const& c2, T const& s2, T const& dlam)
+ {
+ VECT<T> v;
+ T cdl, dp, dl;
+
+ cdl = cos(dlam);
+ if (fabs(dphi) > 1. || fabs(dlam) > 1.)
+ v.r = aacos(s1 * s2 + c1 * c2 * cdl);
+ else { /* more accurate for smaller distances */
+ dp = sin(.5 * dphi);
+ dl = sin(.5 * dlam);
+ v.r = 2. * aasin(sqrt(dp * dp + c1 * c2 * dl * dl));
+ }
+ if (fabs(v.r) > TOL)
+ v.Az = atan2(c2 * sin(dlam), c1 * s2 - s1 * c2 * cdl);
+ else
+ v.r = v.Az = 0.;
+ return v;
+ }
+
+ template <typename T>
+ inline T /* law of cosines */
+ lc(T const& b, T const& c, T const& a)
+ {
+ return aacos(.5 * (b * b + c * c - a * a) / (b * c));
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_chamb_spheroid : public base_t_f<base_chamb_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_chamb<CalculationType> m_proj_parm;
+
+ inline base_chamb_spheroid(const Parameters& par)
+ : base_t_f<base_chamb_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType THIRD = detail::THIRD<CalculationType>();
+
+ CalculationType sinphi, cosphi, a;
+ VECT<CalculationType> v[3];
+ int i, j;
+
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ for (i = 0; i < 3; ++i) { /* dist/azimiths from control */
+ v[i] = vect(lp_lat - this->m_proj_parm.c[i].phi, this->m_proj_parm.c[i].cosphi, this->m_proj_parm.c[i].sinphi,
+ cosphi, sinphi, lp_lon - this->m_proj_parm.c[i].lam);
+ if ( ! v[i].r)
+ break;
+ v[i].Az = adjlon(v[i].Az - this->m_proj_parm.c[i].v.Az);
+ }
+ if (i < 3) /* current point at control point */
+ { xy_x = this->m_proj_parm.c[i].p.x; xy_y = this->m_proj_parm.c[i].p.y; }
+ else { /* point mean of intersepts */
+ { xy_x = this->m_proj_parm.p.x; xy_y = this->m_proj_parm.p.y; }
+ for (i = 0; i < 3; ++i) {
+ j = i == 2 ? 0 : i + 1;
+ a = lc(this->m_proj_parm.c[i].v.r, v[i].r, v[j].r);
+ if (v[i].Az < 0.)
+ a = -a;
+ if (! i) { /* coord comp unique to each arc */
+ xy_x += v[i].r * cos(a);
+ xy_y -= v[i].r * sin(a);
+ } else if (i == 1) {
+ a = this->m_proj_parm.beta_1 - a;
+ xy_x -= v[i].r * cos(a);
+ xy_y -= v[i].r * sin(a);
+ } else {
+ a = this->m_proj_parm.beta_2 - a;
+ xy_x += v[i].r * cos(a);
+ xy_y += v[i].r * sin(a);
+ }
+ }
+ xy_x *= THIRD; /* mean of arc intercepts */
+ xy_y *= THIRD;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "chamb_spheroid";
+ }
+
+ };
+
+ // Chamberlin Trimetric
+ template <typename Parameters, typename T>
+ inline void setup_chamb(Parameters& par, par_chamb<T>& proj_parm)
+ {
+ static const T ONEPI = detail::ONEPI<T>();
+
+ int i, j;
+ char line[10];
+
+ for (i = 0; i < 3; ++i) { /* get control point locations */
+ (void)sprintf(line, "rlat_%d", i+1);
+ proj_parm.c[i].phi = pj_param(par.params, line).f;
+ (void)sprintf(line, "rlon_%d", i+1);
+ proj_parm.c[i].lam = pj_param(par.params, line).f;
+ proj_parm.c[i].lam = adjlon(proj_parm.c[i].lam - par.lam0);
+ proj_parm.c[i].cosphi = cos(proj_parm.c[i].phi);
+ proj_parm.c[i].sinphi = sin(proj_parm.c[i].phi);
+ }
+ for (i = 0; i < 3; ++i) { /* inter ctl pt. distances and azimuths */
+ j = i == 2 ? 0 : i + 1;
+ proj_parm.c[i].v = vect(proj_parm.c[j].phi - proj_parm.c[i].phi, proj_parm.c[i].cosphi, proj_parm.c[i].sinphi,
+ proj_parm.c[j].cosphi, proj_parm.c[j].sinphi, proj_parm.c[j].lam - proj_parm.c[i].lam);
+ if (! proj_parm.c[i].v.r)
+ BOOST_THROW_EXCEPTION( projection_exception(-25) );
+ /* co-linearity problem ignored for now */
+ }
+ proj_parm.beta_0 = lc(proj_parm.c[0].v.r, proj_parm.c[2].v.r, proj_parm.c[1].v.r);
+ proj_parm.beta_1 = lc(proj_parm.c[0].v.r, proj_parm.c[1].v.r, proj_parm.c[2].v.r);
+ proj_parm.beta_2 = ONEPI - proj_parm.beta_0;
+ proj_parm.p.y = 2. * (proj_parm.c[0].p.y = proj_parm.c[1].p.y = proj_parm.c[2].v.r * sin(proj_parm.beta_0));
+ proj_parm.c[2].p.y = 0.;
+ proj_parm.c[0].p.x = - (proj_parm.c[1].p.x = 0.5 * proj_parm.c[0].v.r);
+ proj_parm.p.x = proj_parm.c[2].p.x = proj_parm.c[0].p.x + proj_parm.c[2].v.r * cos(proj_parm.beta_0);
+ par.es = 0.;
+ }
+
+ }} // namespace detail::chamb
+ #endif // doxygen
+
+ /*!
+ \brief Chamberlin Trimetric projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Projection parameters
+ - lat_1: Latitude of control point 1 (degrees)
+ - lon_1: Longitude of control point 1 (degrees)
+ - lat_2: Latitude of control point 2 (degrees)
+ - lon_2: Longitude of control point 2 (degrees)
+ - lat_3: Latitude of control point 3 (degrees)
+ - lon_3: Longitude of control point 3 (degrees)
+ \par Example
+ \image html ex_chamb.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct chamb_spheroid : public detail::chamb::base_chamb_spheroid<CalculationType, Parameters>
+ {
+ inline chamb_spheroid(const Parameters& par) : detail::chamb::base_chamb_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::chamb::setup_chamb(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::chamb, chamb_spheroid, chamb_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class chamb_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<chamb_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void chamb_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("chamb", new chamb_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP
+
diff --git a/boost/geometry/srs/projections/proj/collg.hpp b/boost/geometry/srs/projections/proj/collg.hpp
new file mode 100644
index 0000000000..0bc347a305
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/collg.hpp
@@ -0,0 +1,183 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_COLLG_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_COLLG_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct collg {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace collg
+ {
+
+ static const double FXC = 1.12837916709551257390;
+ static const double FYC = 1.77245385090551602729;
+ static const double ONEEPS = 1.0000001;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_collg_spheroid : public base_t_fi<base_collg_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_collg_spheroid(const Parameters& par)
+ : base_t_fi<base_collg_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ if ((xy_y = 1. - sin(lp_lat)) <= 0.)
+ xy_y = 0.;
+ else
+ xy_y = sqrt(xy_y);
+ xy_x = FXC * lp_lon * xy_y;
+ xy_y = FYC * (1. - xy_y);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y / FYC - 1.;
+ if (fabs(lp_lat = 1. - lp_lat * lp_lat) < 1.)
+ lp_lat = asin(lp_lat);
+ else if (fabs(lp_lat) > ONEEPS)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ else
+ lp_lat = lp_lat < 0. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ if ((lp_lon = 1. - sin(lp_lat)) <= 0.)
+ lp_lon = 0.;
+ else
+ lp_lon = xy_x / (FXC * sqrt(lp_lon));
+ }
+
+ static inline std::string get_name()
+ {
+ return "collg_spheroid";
+ }
+
+ };
+
+ // Collignon
+ template <typename Parameters>
+ inline void setup_collg(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace collg
+ #endif // doxygen
+
+ /*!
+ \brief Collignon projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_collg.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct collg_spheroid : public detail::collg::base_collg_spheroid<CalculationType, Parameters>
+ {
+ inline collg_spheroid(const Parameters& par) : detail::collg::base_collg_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::collg::setup_collg(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::collg, collg_spheroid, collg_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class collg_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<collg_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void collg_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("collg", new collg_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_COLLG_HPP
+
diff --git a/boost/geometry/srs/projections/proj/crast.hpp b/boost/geometry/srs/projections/proj/crast.hpp
new file mode 100644
index 0000000000..4aea886071
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/crast.hpp
@@ -0,0 +1,175 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_CRAST_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_CRAST_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct crast {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace crast
+ {
+
+ static const double XM = 0.97720502380583984317;
+ static const double RXM = 1.02332670794648848847;
+ static const double YM = 3.06998012383946546542;
+ static const double RYM = 0.32573500793527994772;
+ //static const double THIRD = 0.333333333333333333;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_crast_spheroid : public base_t_fi<base_crast_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_crast_spheroid(const Parameters& par)
+ : base_t_fi<base_crast_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType THIRD = detail::THIRD<CalculationType>();
+
+ lp_lat *= THIRD;
+ xy_x = XM * lp_lon * (2. * cos(lp_lat + lp_lat) - 1.);
+ xy_y = YM * sin(lp_lat);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType THIRD = detail::THIRD<CalculationType>();
+
+ lp_lat = 3. * asin(xy_y * RYM);
+ lp_lon = xy_x * RXM / (2. * cos((lp_lat + lp_lat) * THIRD) - 1);
+ }
+
+ static inline std::string get_name()
+ {
+ return "crast_spheroid";
+ }
+
+ };
+
+ // Craster Parabolic (Putnins P4)
+ template <typename Parameters>
+ inline void setup_crast(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::crast
+ #endif // doxygen
+
+ /*!
+ \brief Craster Parabolic (Putnins P4) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_crast.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct crast_spheroid : public detail::crast::base_crast_spheroid<CalculationType, Parameters>
+ {
+ inline crast_spheroid(const Parameters& par) : detail::crast::base_crast_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::crast::setup_crast(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::crast, crast_spheroid, crast_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class crast_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<crast_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void crast_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("crast", new crast_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CRAST_HPP
+
diff --git a/boost/geometry/srs/projections/proj/denoy.hpp b/boost/geometry/srs/projections/proj/denoy.hpp
new file mode 100644
index 0000000000..afedae8734
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/denoy.hpp
@@ -0,0 +1,174 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_DENOY_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_DENOY_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct denoy {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace denoy
+ {
+
+ static const double C0 = 0.95;
+ //static const double C1 = -.08333333333333333333;
+ //static const double C3 = .00166666666666666666;
+ static const double D1 = 0.9;
+ static const double D5 = 0.03;
+
+ template <typename T>
+ inline T C1() { return -.0833333333333333333333333333333; }
+ template <typename T>
+ inline T C3() { return .0016666666666666666666666666666; }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_denoy_spheroid : public base_t_f<base_denoy_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_denoy_spheroid(const Parameters& par)
+ : base_t_f<base_denoy_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType C1 = denoy::C1<CalculationType>();
+ static const CalculationType C3 = denoy::C3<CalculationType>();
+
+ xy_y = lp_lat;
+ xy_x = lp_lon;
+ lp_lon = fabs(lp_lon);
+ xy_x *= cos((C0 + lp_lon * (C1 + lp_lon * lp_lon * C3)) *
+ (lp_lat * (D1 + D5 * lp_lat * lp_lat * lp_lat * lp_lat)));
+ }
+
+ static inline std::string get_name()
+ {
+ return "denoy_spheroid";
+ }
+
+ };
+
+ // Denoyer Semi-Elliptical
+ template <typename Parameters>
+ inline void setup_denoy(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::denoy
+ #endif // doxygen
+
+ /*!
+ \brief Denoyer Semi-Elliptical projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - no inverse
+ - Spheroid
+ \par Example
+ \image html ex_denoy.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct denoy_spheroid : public detail::denoy::base_denoy_spheroid<CalculationType, Parameters>
+ {
+ inline denoy_spheroid(const Parameters& par) : detail::denoy::base_denoy_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::denoy::setup_denoy(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::denoy, denoy_spheroid, denoy_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class denoy_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<denoy_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void denoy_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("denoy", new denoy_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_DENOY_HPP
+
diff --git a/boost/geometry/srs/projections/proj/eck1.hpp b/boost/geometry/srs/projections/proj/eck1.hpp
new file mode 100644
index 0000000000..41f0f6424f
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/eck1.hpp
@@ -0,0 +1,167 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK1_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ECK1_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct eck1 {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eck1
+ {
+
+ static const double FC = .92131773192356127802;
+ static const double RP = .31830988618379067154;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_eck1_spheroid : public base_t_fi<base_eck1_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_eck1_spheroid(const Parameters& par)
+ : base_t_fi<base_eck1_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = FC * lp_lon * (1. - RP * fabs(lp_lat));
+ xy_y = FC * lp_lat;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y / FC;
+ lp_lon = xy_x / (FC * (1. - RP * fabs(lp_lat)));
+ }
+
+ static inline std::string get_name()
+ {
+ return "eck1_spheroid";
+ }
+
+ };
+
+ // Eckert I
+ template <typename Parameters>
+ inline void setup_eck1(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::eck1
+ #endif // doxygen
+
+ /*!
+ \brief Eckert I projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_eck1.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct eck1_spheroid : public detail::eck1::base_eck1_spheroid<CalculationType, Parameters>
+ {
+ inline eck1_spheroid(const Parameters& par) : detail::eck1::base_eck1_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::eck1::setup_eck1(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eck1, eck1_spheroid, eck1_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class eck1_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eck1_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void eck1_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("eck1", new eck1_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK1_HPP
+
diff --git a/boost/geometry/srs/projections/proj/eck2.hpp b/boost/geometry/srs/projections/proj/eck2.hpp
new file mode 100644
index 0000000000..737057bfcd
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/eck2.hpp
@@ -0,0 +1,184 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK2_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ECK2_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct eck2 {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eck2
+ {
+
+ static const double FXC = 0.46065886596178063902;
+ static const double FYC = 1.44720250911653531871;
+ //static const double C13 = 0.33333333333333333333;
+ static const double ONEEPS = 1.0000001;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_eck2_spheroid : public base_t_fi<base_eck2_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_eck2_spheroid(const Parameters& par)
+ : base_t_fi<base_eck2_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = FXC * lp_lon * (xy_y = sqrt(4. - 3. * sin(fabs(lp_lat))));
+ xy_y = FYC * (2. - xy_y);
+ if ( lp_lat < 0.) xy_y = -xy_y;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+ static const CalculationType C13 = detail::THIRD<CalculationType>();
+
+ lp_lon = xy_x / (FXC * ( lp_lat = 2. - fabs(xy_y) / FYC) );
+ lp_lat = (4. - lp_lat * lp_lat) * C13;
+ if (fabs(lp_lat) >= 1.) {
+ if (fabs(lp_lat) > ONEEPS)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ else
+ lp_lat = lp_lat < 0. ? -HALFPI : HALFPI;
+ } else
+ lp_lat = asin(lp_lat);
+ if (xy_y < 0)
+ lp_lat = -lp_lat;
+ }
+
+ static inline std::string get_name()
+ {
+ return "eck2_spheroid";
+ }
+
+ };
+
+ // Eckert II
+ template <typename Parameters>
+ inline void setup_eck2(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::eck2
+ #endif // doxygen
+
+ /*!
+ \brief Eckert II projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_eck2.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct eck2_spheroid : public detail::eck2::base_eck2_spheroid<CalculationType, Parameters>
+ {
+ inline eck2_spheroid(const Parameters& par) : detail::eck2::base_eck2_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::eck2::setup_eck2(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eck2, eck2_spheroid, eck2_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class eck2_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eck2_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void eck2_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("eck2", new eck2_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK2_HPP
+
diff --git a/boost/geometry/srs/projections/proj/eck3.hpp b/boost/geometry/srs/projections/proj/eck3.hpp
new file mode 100644
index 0000000000..dbc1beb625
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/eck3.hpp
@@ -0,0 +1,321 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK3_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ECK3_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/core/ignore_unused.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct eck3 {};
+ struct putp1 {};
+ struct wag6 {};
+ struct kav7 {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eck3
+ {
+
+ template <typename T>
+ struct par_eck3
+ {
+ T C_x, C_y, A, B;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_eck3_spheroid : public base_t_fi<base_eck3_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_eck3<CalculationType> m_proj_parm;
+
+ inline base_eck3_spheroid(const Parameters& par)
+ : base_t_fi<base_eck3_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_y = this->m_proj_parm.C_y * lp_lat;
+ xy_x = this->m_proj_parm.C_x * lp_lon * (this->m_proj_parm.A + asqrt(1. - this->m_proj_parm.B * lp_lat * lp_lat));
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y / this->m_proj_parm.C_y;
+ lp_lon = xy_x / (this->m_proj_parm.C_x * (this->m_proj_parm.A + asqrt(1. - this->m_proj_parm.B * lp_lat * lp_lat)));
+ }
+
+ static inline std::string get_name()
+ {
+ return "eck3_spheroid";
+ }
+
+ };
+
+ template <typename Parameters, typename T>
+ inline void setup(Parameters& par, par_eck3<T>& proj_parm)
+ {
+ boost::ignore_unused(proj_parm);
+ par.es = 0.;
+ }
+
+
+ // Eckert III
+ template <typename Parameters, typename T>
+ inline void setup_eck3(Parameters& par, par_eck3<T>& proj_parm)
+ {
+ proj_parm.C_x = .42223820031577120149;
+ proj_parm.C_y = .84447640063154240298;
+ proj_parm.A = 1.;
+ proj_parm.B = 0.4052847345693510857755;
+ setup(par, proj_parm);
+ }
+
+ // Putnins P1
+ template <typename Parameters, typename T>
+ inline void setup_putp1(Parameters& par, par_eck3<T>& proj_parm)
+ {
+ proj_parm.C_x = 1.89490;
+ proj_parm.C_y = 0.94745;
+ proj_parm.A = -0.5;
+ proj_parm.B = 0.30396355092701331433;
+ setup(par, proj_parm);
+ }
+
+ // Wagner VI
+ template <typename Parameters, typename T>
+ inline void setup_wag6(Parameters& par, par_eck3<T>& proj_parm)
+ {
+ proj_parm.C_x = proj_parm.C_y = 0.94745;
+ proj_parm.A = 0.;
+ proj_parm.B = 0.30396355092701331433;
+ setup(par, proj_parm);
+ }
+
+ // Kavraisky VII
+ template <typename Parameters, typename T>
+ inline void setup_kav7(Parameters& par, par_eck3<T>& proj_parm)
+ {
+ proj_parm.C_x = 0.2632401569273184856851;
+ proj_parm.C_x = 0.8660254037844;
+ proj_parm.C_y = 1.;
+ proj_parm.A = 0.;
+ proj_parm.B = 0.30396355092701331433;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::eck3
+ #endif // doxygen
+
+ /*!
+ \brief Eckert III projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_eck3.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct eck3_spheroid : public detail::eck3::base_eck3_spheroid<CalculationType, Parameters>
+ {
+ inline eck3_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::eck3::setup_eck3(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Putnins P1 projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_putp1.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct putp1_spheroid : public detail::eck3::base_eck3_spheroid<CalculationType, Parameters>
+ {
+ inline putp1_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::eck3::setup_putp1(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Wagner VI projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_wag6.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct wag6_spheroid : public detail::eck3::base_eck3_spheroid<CalculationType, Parameters>
+ {
+ inline wag6_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::eck3::setup_wag6(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Kavraisky VII projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_kav7.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct kav7_spheroid : public detail::eck3::base_eck3_spheroid<CalculationType, Parameters>
+ {
+ inline kav7_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::eck3::setup_kav7(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eck3, eck3_spheroid, eck3_spheroid)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp1, putp1_spheroid, putp1_spheroid)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wag6, wag6_spheroid, wag6_spheroid)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::kav7, kav7_spheroid, kav7_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class eck3_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eck3_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class putp1_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<putp1_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class wag6_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<wag6_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class kav7_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<kav7_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void eck3_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("eck3", new eck3_entry<CalculationType, Parameters>);
+ factory.add_to_factory("putp1", new putp1_entry<CalculationType, Parameters>);
+ factory.add_to_factory("wag6", new wag6_entry<CalculationType, Parameters>);
+ factory.add_to_factory("kav7", new kav7_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK3_HPP
+
diff --git a/boost/geometry/srs/projections/proj/eck4.hpp b/boost/geometry/srs/projections/proj/eck4.hpp
new file mode 100644
index 0000000000..4307b59439
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/eck4.hpp
@@ -0,0 +1,195 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK4_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ECK4_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct eck4 {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eck4
+ {
+
+ static const double C_x = .42223820031577120149;
+ static const double C_y = 1.32650042817700232218;
+ static const double RC_y = .75386330736002178205;
+ static const double C_p = 3.57079632679489661922;
+ static const double RC_p = .28004957675577868795;
+ static const double EPS = 1e-7;
+ static const int NITER = 6;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_eck4_spheroid : public base_t_fi<base_eck4_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_eck4_spheroid(const Parameters& par)
+ : base_t_fi<base_eck4_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType p, V, s, c;
+ int i;
+
+ p = C_p * sin(lp_lat);
+ V = lp_lat * lp_lat;
+ lp_lat *= 0.895168 + V * ( 0.0218849 + V * 0.00826809 );
+ for (i = NITER; i ; --i) {
+ c = cos(lp_lat);
+ s = sin(lp_lat);
+ lp_lat -= V = (lp_lat + s * (c + 2.) - p) /
+ (1. + c * (c + 2.) - s * s);
+ if (fabs(V) < EPS)
+ break;
+ }
+ if (!i) {
+ xy_x = C_x * lp_lon;
+ xy_y = lp_lat < 0. ? -C_y : C_y;
+ } else {
+ xy_x = C_x * lp_lon * (1. + cos(lp_lat));
+ xy_y = C_y * sin(lp_lat);
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType c;
+
+ lp_lat = aasin(xy_y / C_y);
+ lp_lon = xy_x / (C_x * (1. + (c = cos(lp_lat))));
+ lp_lat = aasin((lp_lat + sin(lp_lat) * (c + 2.)) / C_p);
+ }
+
+ static inline std::string get_name()
+ {
+ return "eck4_spheroid";
+ }
+
+ };
+
+ // Eckert IV
+ template <typename Parameters>
+ inline void setup_eck4(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::eck4
+ #endif // doxygen
+
+ /*!
+ \brief Eckert IV projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_eck4.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct eck4_spheroid : public detail::eck4::base_eck4_spheroid<CalculationType, Parameters>
+ {
+ inline eck4_spheroid(const Parameters& par) : detail::eck4::base_eck4_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::eck4::setup_eck4(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eck4, eck4_spheroid, eck4_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class eck4_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eck4_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void eck4_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("eck4", new eck4_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK4_HPP
+
diff --git a/boost/geometry/srs/projections/proj/eck5.hpp b/boost/geometry/srs/projections/proj/eck5.hpp
new file mode 100644
index 0000000000..bc075702e8
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/eck5.hpp
@@ -0,0 +1,168 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK5_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ECK5_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct eck5 {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eck5
+ {
+
+ static const double XF = 0.44101277172455148219;
+ static const double RXF = 2.26750802723822639137;
+ static const double YF = 0.88202554344910296438;
+ static const double RYF = 1.13375401361911319568;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_eck5_spheroid : public base_t_fi<base_eck5_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_eck5_spheroid(const Parameters& par)
+ : base_t_fi<base_eck5_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = XF * (1. + cos(lp_lat)) * lp_lon;
+ xy_y = YF * lp_lat;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lon = RXF * xy_x / (1. + cos( lp_lat = RYF * xy_y));
+ }
+
+ static inline std::string get_name()
+ {
+ return "eck5_spheroid";
+ }
+
+ };
+
+ // Eckert V
+ template <typename Parameters>
+ inline void setup_eck5(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::eck5
+ #endif // doxygen
+
+ /*!
+ \brief Eckert V projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_eck5.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct eck5_spheroid : public detail::eck5::base_eck5_spheroid<CalculationType, Parameters>
+ {
+ inline eck5_spheroid(const Parameters& par) : detail::eck5::base_eck5_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::eck5::setup_eck5(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eck5, eck5_spheroid, eck5_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class eck5_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eck5_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void eck5_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("eck5", new eck5_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK5_HPP
+
diff --git a/boost/geometry/srs/projections/proj/eqc.hpp b/boost/geometry/srs/projections/proj/eqc.hpp
new file mode 100644
index 0000000000..5234ce9b8d
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/eqc.hpp
@@ -0,0 +1,175 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_EQC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_EQC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct eqc {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eqc
+ {
+ template <typename T>
+ struct par_eqc
+ {
+ T rc;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_eqc_spheroid : public base_t_fi<base_eqc_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_eqc<CalculationType> m_proj_parm;
+
+ inline base_eqc_spheroid(const Parameters& par)
+ : base_t_fi<base_eqc_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = this->m_proj_parm.rc * lp_lon;
+ xy_y = lp_lat - this->m_par.phi0;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lon = xy_x / this->m_proj_parm.rc;
+ lp_lat = xy_y + this->m_par.phi0;
+ }
+
+ static inline std::string get_name()
+ {
+ return "eqc_spheroid";
+ }
+
+ };
+
+ // Equidistant Cylindrical (Plate Caree)
+ template <typename Parameters, typename T>
+ inline void setup_eqc(Parameters& par, par_eqc<T>& proj_parm)
+ {
+ if ((proj_parm.rc = cos(pj_param(par.params, "rlat_ts").f)) <= 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-24) );
+ par.es = 0.;
+ }
+
+ }} // namespace detail::eqc
+ #endif // doxygen
+
+ /*!
+ \brief Equidistant Cylindrical (Plate Caree) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ - lat_0: Latitude of origin
+ \par Example
+ \image html ex_eqc.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct eqc_spheroid : public detail::eqc::base_eqc_spheroid<CalculationType, Parameters>
+ {
+ inline eqc_spheroid(const Parameters& par) : detail::eqc::base_eqc_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::eqc::setup_eqc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eqc, eqc_spheroid, eqc_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class eqc_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eqc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void eqc_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("eqc", new eqc_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_EQC_HPP
+
diff --git a/boost/geometry/srs/projections/proj/eqdc.hpp b/boost/geometry/srs/projections/proj/eqdc.hpp
new file mode 100644
index 0000000000..1af11338a4
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/eqdc.hpp
@@ -0,0 +1,250 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
+#include <boost/geometry/srs/projections/impl/pj_msfn.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct eqdc {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eqdc
+ {
+
+ static const double EPS10 = 1.e-10;
+
+ template <typename T>
+ struct par_eqdc
+ {
+ T phi1;
+ T phi2;
+ T n;
+ T rho0;
+ T c;
+ T en[EN_SIZE];
+ int ellips;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_eqdc_ellipsoid : public base_t_fi<base_eqdc_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_eqdc<CalculationType> m_proj_parm;
+
+ inline base_eqdc_ellipsoid(const Parameters& par)
+ : base_t_fi<base_eqdc_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) sphere & ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType rho = 0.0;
+ rho = this->m_proj_parm.c - (this->m_proj_parm.ellips ? pj_mlfn(lp_lat, sin(lp_lat),
+ cos(lp_lat), this->m_proj_parm.en) : lp_lat);
+ xy_x = rho * sin( lp_lon *= this->m_proj_parm.n );
+ xy_y = this->m_proj_parm.rho0 - rho * cos(lp_lon);
+ }
+
+ // INVERSE(e_inverse) sphere & ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType rho = 0.0;
+ if ((rho = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.rho0 - xy_y)) != 0.0 ) {
+ if (this->m_proj_parm.n < 0.) {
+ rho = -rho;
+ xy_x = -xy_x;
+ xy_y = -xy_y;
+ }
+ lp_lat = this->m_proj_parm.c - rho;
+ if (this->m_proj_parm.ellips)
+ lp_lat = pj_inv_mlfn(lp_lat, this->m_par.es, this->m_proj_parm.en);
+ lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n;
+ } else {
+ lp_lon = 0.;
+ lp_lat = this->m_proj_parm.n > 0. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>();
+ }
+ }
+
+ // SPECIAL(fac)
+ #ifdef SPECIAL_FACTORS_NOT_CONVERTED
+ inline void fac(Geographic lp, Factors &fac) const
+ {
+ CalculationType sinphi, cosphi;
+
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ this->m_fac.code |= IS_ANAL_HK;
+ this->m_fac.h = 1.;
+ this->m_fac.k = this->m_proj_parm.n * (this->m_proj_parm.c - (this->m_proj_parm.ellips ? pj_mlfn(lp_lat, sinphi,
+ cosphi, this->m_proj_parm.en) : lp_lat)) / pj_msfn(sinphi, cosphi, this->m_par.es);
+ }
+ #endif
+
+ static inline std::string get_name()
+ {
+ return "eqdc_ellipsoid";
+ }
+
+ };
+
+ // Equidistant Conic
+ template <typename Parameters, typename T>
+ inline void setup_eqdc(Parameters& par, par_eqdc<T>& proj_parm)
+ {
+ T cosphi, sinphi;
+ int secant;
+
+ proj_parm.phi1 = pj_param(par.params, "rlat_1").f;
+ proj_parm.phi2 = pj_param(par.params, "rlat_2").f;
+ if (fabs(proj_parm.phi1 + proj_parm.phi2) < EPS10)
+ BOOST_THROW_EXCEPTION( projection_exception(-21) );
+ if (!pj_enfn(par.es, proj_parm.en))
+ BOOST_THROW_EXCEPTION( projection_exception(0) );
+ proj_parm.n = sinphi = sin(proj_parm.phi1);
+ cosphi = cos(proj_parm.phi1);
+ secant = fabs(proj_parm.phi1 - proj_parm.phi2) >= EPS10;
+ if( (proj_parm.ellips = (par.es > 0.)) ) {
+ double ml1, m1;
+
+ m1 = pj_msfn(sinphi, cosphi, par.es);
+ ml1 = pj_mlfn(proj_parm.phi1, sinphi, cosphi, proj_parm.en);
+ if (secant) { /* secant cone */
+ sinphi = sin(proj_parm.phi2);
+ cosphi = cos(proj_parm.phi2);
+ proj_parm.n = (m1 - pj_msfn(sinphi, cosphi, par.es)) /
+ (pj_mlfn(proj_parm.phi2, sinphi, cosphi, proj_parm.en) - ml1);
+ }
+ proj_parm.c = ml1 + m1 / proj_parm.n;
+ proj_parm.rho0 = proj_parm.c - pj_mlfn(par.phi0, sin(par.phi0),
+ cos(par.phi0), proj_parm.en);
+ } else {
+ if (secant)
+ proj_parm.n = (cosphi - cos(proj_parm.phi2)) / (proj_parm.phi2 - proj_parm.phi1);
+ proj_parm.c = proj_parm.phi1 + cos(proj_parm.phi1) / proj_parm.n;
+ proj_parm.rho0 = proj_parm.c - par.phi0;
+ }
+ }
+
+ }} // namespace detail::eqdc
+ #endif // doxygen
+
+ /*!
+ \brief Equidistant Conic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ - lat_2: Latitude of second standard parallel (degrees)
+ \par Example
+ \image html ex_eqdc.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct eqdc_ellipsoid : public detail::eqdc::base_eqdc_ellipsoid<CalculationType, Parameters>
+ {
+ inline eqdc_ellipsoid(const Parameters& par) : detail::eqdc::base_eqdc_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::eqdc::setup_eqdc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eqdc, eqdc_ellipsoid, eqdc_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class eqdc_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eqdc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void eqdc_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("eqdc", new eqdc_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP
+
diff --git a/boost/geometry/srs/projections/proj/etmerc.hpp b/boost/geometry/srs/projections/proj/etmerc.hpp
new file mode 100644
index 0000000000..479c128f11
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/etmerc.hpp
@@ -0,0 +1,395 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ETMERC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ETMERC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Copyright (c) 2008 Gerald I. Evenden
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct etmerc {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace etmerc
+ {
+
+ static const int PROJ_ETMERC_ORDER = 6;
+
+ template <typename T>
+ struct par_etmerc
+ {
+ T Qn; /* Merid. quad., scaled to the projection */
+ T Zb; /* Radius vector in polar coord. systems */
+ T cgb[6]; /* Constants for Gauss -> Geo lat */
+ T cbg[6]; /* Constants for Geo lat -> Gauss */
+ T utg[6]; /* Constants for transv. merc. -> geo */
+ T gtu[6]; /* Constants for geo -> transv. merc. */
+ };
+
+ /* The code in this file is largly based upon procedures:
+ *
+ * Written by: Knud Poder and Karsten Engsager
+ *
+ * Based on math from: R.Koenig and K.H. Weise, "Mathematische
+ * Grundlagen der hoeheren Geodaesie und Kartographie,
+ * Springer-Verlag, Berlin/Goettingen" Heidelberg, 1951.
+ *
+ * Modified and used here by permission of Reference Networks
+ * Division, Kort og Matrikelstyrelsen (KMS), Copenhagen, Denmark
+ */
+
+
+
+
+
+ template <typename T>
+ inline T
+ log1py(T const& x) { /* Compute log(1+x) accurately */
+ volatile T
+ y = 1 + x,
+ z = y - 1;
+ /* Here's the explanation for this magic: y = 1 + z, exactly, and z
+ * approx x, thus log(y)/z (which is nearly constant near z = 0) returns
+ * a good approximation to the true log(1 + x)/x. The multiplication x *
+ * (log(y)/z) introduces little additional error. */
+ return z == 0 ? x : x * log(y) / z;
+ }
+
+ template <typename T>
+ inline T
+ asinhy(T const& x) { /* Compute asinh(x) accurately */
+ T y = fabs(x); /* Enforce odd parity */
+ y = log1py(y * (1 + y/(boost::math::hypot(1.0, y) + 1)));
+ return x < 0 ? -y : y;
+ }
+
+ template <typename T>
+ inline T
+ gatg(const T *p1, int len_p1, T const& B) {
+ const T *p;
+ T h = 0, h1, h2 = 0, cos_2B;
+
+ cos_2B = 2*cos(2*B);
+ for (p = p1 + len_p1, h1 = *--p; p - p1; h2 = h1, h1 = h)
+ h = -h2 + cos_2B*h1 + *--p;
+ return (B + h*sin(2*B));
+ }
+
+ template <typename T>
+ inline T
+ clenS(const T *a, int size, T const& arg_r, T const& arg_i, T *R, T *I) {
+ T r, i, hr, hr1, hr2, hi, hi1, hi2;
+ T sin_arg_r, cos_arg_r, sinh_arg_i, cosh_arg_i;
+
+ /* arguments */
+ const T* p = a + size;
+ sin_arg_r = sin(arg_r);
+ cos_arg_r = cos(arg_r);
+ sinh_arg_i = sinh(arg_i);
+ cosh_arg_i = cosh(arg_i);
+ r = 2*cos_arg_r*cosh_arg_i;
+ i = -2*sin_arg_r*sinh_arg_i;
+ /* summation loop */
+ for (hi1 = hr1 = hi = 0, hr = *--p; a - p;) {
+ hr2 = hr1;
+ hi2 = hi1;
+ hr1 = hr;
+ hi1 = hi;
+ hr = -hr2 + r*hr1 - i*hi1 + *--p;
+ hi = -hi2 + i*hr1 + r*hi1;
+ }
+ r = sin_arg_r*cosh_arg_i;
+ i = cos_arg_r*sinh_arg_i;
+ *R = r*hr - i*hi;
+ *I = r*hi + i*hr;
+ return(*R);
+ }
+
+ template <typename T>
+ inline T
+ clens(const T *a, int size, T const& arg_r) {
+ T r, hr, hr1, hr2, cos_arg_r;
+
+ const T* p = a + size;
+ cos_arg_r = cos(arg_r);
+ r = 2*cos_arg_r;
+ /* summation loop */
+ for (hr1 = 0, hr = *--p; a - p;) {
+ hr2 = hr1;
+ hr1 = hr;
+ hr = -hr2 + r*hr1 + *--p;
+ }
+ return(sin(arg_r)*hr);
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_etmerc_ellipsoid : public base_t_fi<base_etmerc_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_etmerc<CalculationType> m_proj_parm;
+
+ inline base_etmerc_ellipsoid(const Parameters& par)
+ : base_t_fi<base_etmerc_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType sin_Cn, cos_Cn, cos_Ce, sin_Ce, dCn, dCe;
+ CalculationType Cn = lp_lat, Ce = lp_lon;
+
+ /* ell. LAT, LNG -> Gaussian LAT, LNG */
+ Cn = gatg(this->m_proj_parm.cbg, PROJ_ETMERC_ORDER, Cn);
+ /* Gaussian LAT, LNG -> compl. sph. LAT */
+ sin_Cn = sin(Cn);
+ cos_Cn = cos(Cn);
+ sin_Ce = sin(Ce);
+ cos_Ce = cos(Ce);
+
+ Cn = atan2(sin_Cn, cos_Ce*cos_Cn);
+ Ce = atan2(sin_Ce*cos_Cn, boost::math::hypot(sin_Cn, cos_Cn*cos_Ce));
+ /* compl. sph. N, E -> ell. norm. N, E */
+ Ce = asinhy(tan(Ce)); /* Replaces: Ce = log(tan(FORTPI + Ce*0.5)); */
+ Cn += clenS(this->m_proj_parm.gtu, PROJ_ETMERC_ORDER, 2*Cn, 2*Ce, &dCn, &dCe);
+ Ce += dCe;
+ if (fabs(Ce) <= 2.623395162778) {
+ xy_y = this->m_proj_parm.Qn * Cn + this->m_proj_parm.Zb; /* Northing */
+ xy_x = this->m_proj_parm.Qn * Ce; /* Easting */
+ } else
+ xy_x = xy_y = HUGE_VAL;
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType sin_Cn, cos_Cn, cos_Ce, sin_Ce, dCn, dCe;
+ CalculationType Cn = xy_y, Ce = xy_x;
+
+ /* normalize N, E */
+ Cn = (Cn - this->m_proj_parm.Zb)/this->m_proj_parm.Qn;
+ Ce = Ce/this->m_proj_parm.Qn;
+ if (fabs(Ce) <= 2.623395162778) { /* 150 degrees */
+ /* norm. N, E -> compl. sph. LAT, LNG */
+ Cn += clenS(this->m_proj_parm.utg, PROJ_ETMERC_ORDER, 2*Cn, 2*Ce, &dCn, &dCe);
+ Ce += dCe;
+ Ce = atan(sinh(Ce)); /* Replaces: Ce = 2*(atan(exp(Ce)) - FORTPI); */
+ /* compl. sph. LAT -> Gaussian LAT, LNG */
+ sin_Cn = sin(Cn);
+ cos_Cn = cos(Cn);
+ sin_Ce = sin(Ce);
+ cos_Ce = cos(Ce);
+ Ce = atan2(sin_Ce, cos_Ce*cos_Cn);
+ Cn = atan2(sin_Cn*cos_Ce, boost::math::hypot(sin_Ce, cos_Ce*cos_Cn));
+ /* Gaussian LAT, LNG -> ell. LAT, LNG */
+ lp_lat = gatg(this->m_proj_parm.cgb, PROJ_ETMERC_ORDER, Cn);
+ lp_lon = Ce;
+ }
+ else
+ lp_lat = lp_lon = HUGE_VAL;
+ }
+
+ static inline std::string get_name()
+ {
+ return "etmerc_ellipsoid";
+ }
+
+ };
+
+ // Extended Transverse Mercator
+ template <typename Parameters, typename T>
+ inline void setup_etmerc(Parameters& par, par_etmerc<T>& proj_parm)
+ {
+ T f, n, np, Z;
+
+ if (par.es <= 0)
+ BOOST_THROW_EXCEPTION( projection_exception(-34) );
+ f = par.es / (1 + sqrt(1 - par.es)); /* Replaces: f = 1 - sqrt(1-par.es); */
+ /* third flattening */
+ np = n = f/(2 - f);
+
+ /* COEF. OF TRIG SERIES GEO <-> GAUSS */
+ /* cgb := Gaussian -> Geodetic, KW p190 - 191 (61) - (62) */
+ /* cbg := Geodetic -> Gaussian, KW p186 - 187 (51) - (52) */
+ /* PROJ_ETMERC_ORDER = 6th degree : Engsager and Poder: ICC2007 */
+ proj_parm.cgb[0] = n*( 2 + n*(-2/3.0 + n*(-2 + n*(116/45.0 + n*(26/45.0 +
+ n*(-2854/675.0 ))))));
+ proj_parm.cbg[0] = n*(-2 + n*( 2/3.0 + n*( 4/3.0 + n*(-82/45.0 + n*(32/45.0 +
+ n*( 4642/4725.0))))));
+ np *= n;
+ proj_parm.cgb[1] = np*(7/3.0 + n*( -8/5.0 + n*(-227/45.0 + n*(2704/315.0 +
+ n*( 2323/945.0)))));
+ proj_parm.cbg[1] = np*(5/3.0 + n*(-16/15.0 + n*( -13/9.0 + n*( 904/315.0 +
+ n*(-1522/945.0)))));
+ np *= n;
+ /* n^5 coeff corrected from 1262/105 -> -1262/105 */
+ proj_parm.cgb[2] = np*( 56/15.0 + n*(-136/35.0 + n*(-1262/105.0 +
+ n*( 73814/2835.0))));
+ proj_parm.cbg[2] = np*(-26/15.0 + n*( 34/21.0 + n*( 8/5.0 +
+ n*(-12686/2835.0))));
+ np *= n;
+ /* n^5 coeff corrected from 322/35 -> 332/35 */
+ proj_parm.cgb[3] = np*(4279/630.0 + n*(-332/35.0 + n*(-399572/14175.0)));
+ proj_parm.cbg[3] = np*(1237/630.0 + n*( -12/5.0 + n*( -24832/14175.0)));
+ np *= n;
+ proj_parm.cgb[4] = np*(4174/315.0 + n*(-144838/6237.0 ));
+ proj_parm.cbg[4] = np*(-734/315.0 + n*( 109598/31185.0));
+ np *= n;
+ proj_parm.cgb[5] = np*(601676/22275.0 );
+ proj_parm.cbg[5] = np*(444337/155925.0);
+
+ /* Constants of the projections */
+ /* Transverse Mercator (UTM, ITM, etc) */
+ np = n*n;
+ /* Norm. mer. quad, K&W p.50 (96), p.19 (38b), p.5 (2) */
+ proj_parm.Qn = par.k0/(1 + n) * (1 + np*(1/4.0 + np*(1/64.0 + np/256.0)));
+ /* coef of trig series */
+ /* utg := ell. N, E -> sph. N, E, KW p194 (65) */
+ /* gtu := sph. N, E -> ell. N, E, KW p196 (69) */
+ proj_parm.utg[0] = n*(-0.5 + n*( 2/3.0 + n*(-37/96.0 + n*( 1/360.0 +
+ n*( 81/512.0 + n*(-96199/604800.0))))));
+ proj_parm.gtu[0] = n*( 0.5 + n*(-2/3.0 + n*( 5/16.0 + n*(41/180.0 +
+ n*(-127/288.0 + n*( 7891/37800.0 ))))));
+ proj_parm.utg[1] = np*(-1/48.0 + n*(-1/15.0 + n*(437/1440.0 + n*(-46/105.0 +
+ n*( 1118711/3870720.0)))));
+ proj_parm.gtu[1] = np*(13/48.0 + n*(-3/5.0 + n*(557/1440.0 + n*(281/630.0 +
+ n*(-1983433/1935360.0)))));
+ np *= n;
+ proj_parm.utg[2] = np*(-17/480.0 + n*( 37/840.0 + n*( 209/4480.0 +
+ n*( -5569/90720.0 ))));
+ proj_parm.gtu[2] = np*( 61/240.0 + n*(-103/140.0 + n*(15061/26880.0 +
+ n*(167603/181440.0))));
+ np *= n;
+ proj_parm.utg[3] = np*(-4397/161280.0 + n*( 11/504.0 + n*( 830251/7257600.0)));
+ proj_parm.gtu[3] = np*(49561/161280.0 + n*(-179/168.0 + n*(6601661/7257600.0)));
+ np *= n;
+ proj_parm.utg[4] = np*(-4583/161280.0 + n*( 108847/3991680.0));
+ proj_parm.gtu[4] = np*(34729/80640.0 + n*(-3418889/1995840.0));
+ np *= n;
+ proj_parm.utg[5] = np*(-20648693/638668800.0);
+ proj_parm.gtu[5] = np*(212378941/319334400.0);
+ /* Gaussian latitude value of the origin latitude */
+ Z = gatg(proj_parm.cbg, PROJ_ETMERC_ORDER, par.phi0);
+ /* Origin northing minus true northing at the origin latitude */
+ /* i.e. true northing = N - proj_parm.Zb */
+ proj_parm.Zb = - proj_parm.Qn*(Z + clens(proj_parm.gtu, PROJ_ETMERC_ORDER, 2*Z));
+ }
+
+ }} // namespace detail::etmerc
+ #endif // doxygen
+
+ /*!
+ \brief Extended Transverse Mercator projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ \par Projection parameters
+ - lat_ts: Latitude of true scale
+ - lat_0: Latitude of origin
+ \par Example
+ \image html ex_etmerc.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct etmerc_ellipsoid : public detail::etmerc::base_etmerc_ellipsoid<CalculationType, Parameters>
+ {
+ inline etmerc_ellipsoid(const Parameters& par) : detail::etmerc::base_etmerc_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::etmerc::setup_etmerc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::etmerc, etmerc_ellipsoid, etmerc_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class etmerc_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<etmerc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void etmerc_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("etmerc", new etmerc_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ETMERC_HPP
+
diff --git a/boost/geometry/srs/projections/proj/fahey.hpp b/boost/geometry/srs/projections/proj/fahey.hpp
new file mode 100644
index 0000000000..8ea43ee94b
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/fahey.hpp
@@ -0,0 +1,168 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_FAHEY_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_FAHEY_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct fahey {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace fahey
+ {
+
+ static const double TOL = 1e-6;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_fahey_spheroid : public base_t_fi<base_fahey_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_fahey_spheroid(const Parameters& par)
+ : base_t_fi<base_fahey_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_y = 1.819152 * ( xy_x = tan(0.5 * lp_lat) );
+ xy_x = 0.819152 * lp_lon * asqrt(1 - xy_x * xy_x);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = 2. * atan(xy_y /= 1.819152);
+ lp_lon = fabs(xy_y = 1. - xy_y * xy_y) < TOL ? 0. :
+ xy_x / (0.819152 * sqrt(xy_y));
+ }
+
+ static inline std::string get_name()
+ {
+ return "fahey_spheroid";
+ }
+
+ };
+
+ // Fahey
+ template <typename Parameters>
+ inline void setup_fahey(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::fahey
+ #endif // doxygen
+
+ /*!
+ \brief Fahey projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_fahey.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct fahey_spheroid : public detail::fahey::base_fahey_spheroid<CalculationType, Parameters>
+ {
+ inline fahey_spheroid(const Parameters& par) : detail::fahey::base_fahey_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::fahey::setup_fahey(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::fahey, fahey_spheroid, fahey_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class fahey_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<fahey_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void fahey_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("fahey", new fahey_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_FAHEY_HPP
+
diff --git a/boost/geometry/srs/projections/proj/fouc_s.hpp b/boost/geometry/srs/projections/proj/fouc_s.hpp
new file mode 100644
index 0000000000..0f34593161
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/fouc_s.hpp
@@ -0,0 +1,201 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct fouc_s {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace fouc_s
+ {
+
+ static const int MAX_ITER = 10;
+ static const double LOOP_TOL = 1e-7;
+
+ template <typename T>
+ struct par_fouc_s
+ {
+ T n, n1;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_fouc_s_spheroid : public base_t_fi<base_fouc_s_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_fouc_s<CalculationType> m_proj_parm;
+
+ inline base_fouc_s_spheroid(const Parameters& par)
+ : base_t_fi<base_fouc_s_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType t;
+
+ t = cos(lp_lat);
+ xy_x = lp_lon * t / (this->m_proj_parm.n + this->m_proj_parm.n1 * t);
+ xy_y = this->m_proj_parm.n * lp_lat + this->m_proj_parm.n1 * sin(lp_lat);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType V;
+ int i;
+
+ if (this->m_proj_parm.n) {
+ lp_lat = xy_y;
+ for (i = MAX_ITER; i ; --i) {
+ lp_lat -= V = (this->m_proj_parm.n * lp_lat + this->m_proj_parm.n1 * sin(lp_lat) - xy_y ) /
+ (this->m_proj_parm.n + this->m_proj_parm.n1 * cos(lp_lat));
+ if (fabs(V) < LOOP_TOL)
+ break;
+ }
+ if (!i)
+ lp_lat = xy_y < 0. ? -geometry::math::half_pi<double>() : geometry::math::half_pi<double>();
+ } else
+ lp_lat = aasin(xy_y);
+ V = cos(lp_lat);
+ lp_lon = xy_x * (this->m_proj_parm.n + this->m_proj_parm.n1 * V) / V;
+ }
+
+ static inline std::string get_name()
+ {
+ return "fouc_s_spheroid";
+ }
+
+ };
+
+ // Foucaut Sinusoidal
+ template <typename Parameters, typename T>
+ inline void setup_fouc_s(Parameters& par, par_fouc_s<T>& proj_parm)
+ {
+ proj_parm.n = pj_param(par.params, "dn").f;
+ if (proj_parm.n < 0. || proj_parm.n > 1.)
+ BOOST_THROW_EXCEPTION( projection_exception(-99) );
+ proj_parm.n1 = 1. - proj_parm.n;
+ par.es = 0;
+ }
+
+ }} // namespace detail::fouc_s
+ #endif // doxygen
+
+ /*!
+ \brief Foucaut Sinusoidal projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Projection parameters
+ - n (real)
+ \par Example
+ \image html ex_fouc_s.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct fouc_s_spheroid : public detail::fouc_s::base_fouc_s_spheroid<CalculationType, Parameters>
+ {
+ inline fouc_s_spheroid(const Parameters& par) : detail::fouc_s::base_fouc_s_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::fouc_s::setup_fouc_s(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::fouc_s, fouc_s_spheroid, fouc_s_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class fouc_s_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<fouc_s_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void fouc_s_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("fouc_s", new fouc_s_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP
+
diff --git a/boost/geometry/srs/projections/proj/gall.hpp b/boost/geometry/srs/projections/proj/gall.hpp
new file mode 100644
index 0000000000..fc1ad144d7
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/gall.hpp
@@ -0,0 +1,169 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GALL_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GALL_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct gall {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace gall
+ {
+
+ static const double YF = 1.70710678118654752440;
+ static const double XF = 0.70710678118654752440;
+ static const double RYF = 0.58578643762690495119;
+ static const double RXF = 1.41421356237309504880;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_gall_spheroid : public base_t_fi<base_gall_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_gall_spheroid(const Parameters& par)
+ : base_t_fi<base_gall_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = XF * lp_lon;
+ xy_y = YF * tan(.5 * lp_lat);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lon = RXF * xy_x;
+ lp_lat = 2. * atan(xy_y * RYF);
+ }
+
+ static inline std::string get_name()
+ {
+ return "gall_spheroid";
+ }
+
+ };
+
+ // Gall (Gall Stereographic)
+ template <typename Parameters>
+ inline void setup_gall(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::gall
+ #endif // doxygen
+
+ /*!
+ \brief Gall (Gall Stereographic) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ \par Example
+ \image html ex_gall.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct gall_spheroid : public detail::gall::base_gall_spheroid<CalculationType, Parameters>
+ {
+ inline gall_spheroid(const Parameters& par) : detail::gall::base_gall_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::gall::setup_gall(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gall, gall_spheroid, gall_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class gall_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<gall_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void gall_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("gall", new gall_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GALL_HPP
+
diff --git a/boost/geometry/srs/projections/proj/geocent.hpp b/boost/geometry/srs/projections/proj/geocent.hpp
new file mode 100644
index 0000000000..bfcbb145fa
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/geocent.hpp
@@ -0,0 +1,169 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GEOCENT_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GEOCENT_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Stub projection for geocentric. The transformation isn't
+// really done here since this code is 2D. The real transformation
+// is handled by pj_transform.c.
+// Author: Frank Warmerdam, warmerdam@pobox.com
+// Copyright (c) 2002, Frank Warmerdam
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct geocent {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace geocent
+ {
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_geocent_other : public base_t_fi<base_geocent_other<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_geocent_other(const Parameters& par)
+ : base_t_fi<base_geocent_other<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(forward)
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = lp_lon;
+ xy_y = lp_lat;
+ }
+
+ // INVERSE(inverse)
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y;
+ lp_lon = xy_x;
+ }
+
+ static inline std::string get_name()
+ {
+ return "geocent_other";
+ }
+
+ };
+
+ // Geocentric
+ template <typename Parameters>
+ inline void setup_geocent(Parameters& par)
+ {
+ par.is_geocent = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ }
+
+ }} // namespace detail::geocent
+ #endif // doxygen
+
+ /*!
+ \brief Geocentric projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Example
+ \image html ex_geocent.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct geocent_other : public detail::geocent::base_geocent_other<CalculationType, Parameters>
+ {
+ inline geocent_other(const Parameters& par) : detail::geocent::base_geocent_other<CalculationType, Parameters>(par)
+ {
+ detail::geocent::setup_geocent(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::geocent, geocent_other, geocent_other)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class geocent_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<geocent_other<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void geocent_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("geocent", new geocent_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GEOCENT_HPP
+
diff --git a/boost/geometry/srs/projections/proj/geos.hpp b/boost/geometry/srs/projections/proj/geos.hpp
new file mode 100644
index 0000000000..798f7f6247
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/geos.hpp
@@ -0,0 +1,377 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GEOS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GEOS_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Copyright (c) 2004 Gerald I. Evenden
+// Copyright (c) 2012 Martin Raspaud
+// See also (section 4.4.3.2):
+// http://www.eumetsat.int/en/area4/msg/news/us_doc/cgms_03_26.pdf
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct geos {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace geos
+ {
+ template <typename T>
+ struct par_geos
+ {
+ T h;
+ T radius_p;
+ T radius_p2;
+ T radius_p_inv2;
+ T radius_g;
+ T radius_g_1;
+ T C;
+ std::string sweep_axis;
+ int flip_axis;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_geos_ellipsoid : public base_t_fi<base_geos_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_geos<CalculationType> m_proj_parm;
+
+ inline base_geos_ellipsoid(const Parameters& par)
+ : base_t_fi<base_geos_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType r, Vx, Vy, Vz, tmp;
+
+ /* Calculation of geocentric latitude. */
+ lp_lat = atan (this->m_proj_parm.radius_p2 * tan (lp_lat));
+ /* Calculation of the three components of the vector from satellite to
+ ** position on earth surface (lon,lat).*/
+ r = (this->m_proj_parm.radius_p) / boost::math::hypot(this->m_proj_parm.radius_p * cos (lp_lat), sin (lp_lat));
+ Vx = r * cos (lp_lon) * cos (lp_lat);
+ Vy = r * sin (lp_lon) * cos (lp_lat);
+ Vz = r * sin (lp_lat);
+ /* Check visibility. */
+ if (((this->m_proj_parm.radius_g - Vx) * Vx - Vy * Vy - Vz * Vz * this->m_proj_parm.radius_p_inv2) < 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ /* Calculation based on view angles from satellite. */
+ tmp = this->m_proj_parm.radius_g - Vx;
+ if(this->m_proj_parm.flip_axis)
+ {
+ xy_x = this->m_proj_parm.radius_g_1 * atan (Vy / boost::math::hypot (Vz, tmp));
+ xy_y = this->m_proj_parm.radius_g_1 * atan (Vz / tmp);
+ }
+ else
+ {
+ xy_x = this->m_proj_parm.radius_g_1 * atan (Vy / tmp);
+ xy_y = this->m_proj_parm.radius_g_1 * atan (Vz / boost::math::hypot (Vy, tmp));
+ }
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType Vx, Vy, Vz, a, b, det, k;
+
+ /* Setting three components of vector from satellite to position.*/
+ Vx = -1.0;
+ if(this->m_proj_parm.flip_axis)
+ {
+ Vz = tan (xy_y / this->m_proj_parm.radius_g_1);
+ Vy = tan (xy_x / this->m_proj_parm.radius_g_1) * boost::math::hypot(1.0, Vz);
+ }
+ else
+ {
+ Vy = tan (xy_x / this->m_proj_parm.radius_g_1);
+ Vz = tan (xy_y / this->m_proj_parm.radius_g_1) * boost::math::hypot(1.0, Vy);
+ }
+ /* Calculation of terms in cubic equation and determinant.*/
+ a = Vz / this->m_proj_parm.radius_p;
+ a = Vy * Vy + a * a + Vx * Vx;
+ b = 2 * this->m_proj_parm.radius_g * Vx;
+ if ((det = (b * b) - 4 * a * this->m_proj_parm.C) < 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ /* Calculation of three components of vector from satellite to position.*/
+ k = (-b - sqrt(det)) / (2. * a);
+ Vx = this->m_proj_parm.radius_g + k * Vx;
+ Vy *= k;
+ Vz *= k;
+ /* Calculation of longitude and latitude.*/
+ lp_lon = atan2 (Vy, Vx);
+ lp_lat = atan (Vz * cos (lp_lon) / Vx);
+ lp_lat = atan (this->m_proj_parm.radius_p_inv2 * tan (lp_lat));
+ }
+
+ static inline std::string get_name()
+ {
+ return "geos_ellipsoid";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_geos_spheroid : public base_t_fi<base_geos_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_geos<CalculationType> m_proj_parm;
+
+ inline base_geos_spheroid(const Parameters& par)
+ : base_t_fi<base_geos_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType Vx, Vy, Vz, tmp;
+
+ /* Calculation of the three components of the vector from satellite to
+ ** position on earth surface (lon,lat).*/
+ tmp = cos(lp_lat);
+ Vx = cos (lp_lon) * tmp;
+ Vy = sin (lp_lon) * tmp;
+ Vz = sin (lp_lat);
+ /* Check visibility.*/
+ if (((this->m_proj_parm.radius_g - Vx) * Vx - Vy * Vy - Vz * Vz) < 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ /* Calculation based on view angles from satellite.*/
+ tmp = this->m_proj_parm.radius_g - Vx;
+ if(this->m_proj_parm.flip_axis)
+ {
+ xy_x = this->m_proj_parm.radius_g_1 * atan(Vy / boost::math::hypot(Vz, tmp));
+ xy_y = this->m_proj_parm.radius_g_1 * atan(Vz / tmp);
+ }
+ else
+ {
+ xy_x = this->m_proj_parm.radius_g_1 * atan(Vy / tmp);
+ xy_y = this->m_proj_parm.radius_g_1 * atan(Vz / boost::math::hypot(Vy, tmp));
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType Vx, Vy, Vz, a, b, det, k;
+
+ /* Setting three components of vector from satellite to position.*/
+ Vx = -1.0;
+ if(this->m_proj_parm.flip_axis)
+ {
+ Vz = tan (xy_y / (this->m_proj_parm.radius_g - 1.0));
+ Vy = tan (xy_x / (this->m_proj_parm.radius_g - 1.0)) * sqrt (1.0 + Vz * Vz);
+ }
+ else
+ {
+ Vy = tan (xy_x / (this->m_proj_parm.radius_g - 1.0));
+ Vz = tan (xy_y / (this->m_proj_parm.radius_g - 1.0)) * sqrt (1.0 + Vy * Vy);
+ }
+ /* Calculation of terms in cubic equation and determinant.*/
+ a = Vy * Vy + Vz * Vz + Vx * Vx;
+ b = 2 * this->m_proj_parm.radius_g * Vx;
+ if ((det = (b * b) - 4 * a * this->m_proj_parm.C) < 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ /* Calculation of three components of vector from satellite to position.*/
+ k = (-b - sqrt(det)) / (2 * a);
+ Vx = this->m_proj_parm.radius_g + k * Vx;
+ Vy *= k;
+ Vz *= k;
+ /* Calculation of longitude and latitude.*/
+ lp_lon = atan2 (Vy, Vx);
+ lp_lat = atan (Vz * cos (lp_lon) / Vx);
+ }
+
+ static inline std::string get_name()
+ {
+ return "geos_spheroid";
+ }
+
+ };
+
+ // Geostationary Satellite View
+ template <typename Parameters, typename T>
+ inline void setup_geos(Parameters& par, par_geos<T>& proj_parm)
+ {
+ if ((proj_parm.h = pj_param(par.params, "dh").f) <= 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-30) );
+ if (par.phi0)
+ BOOST_THROW_EXCEPTION( projection_exception(-46) );
+ proj_parm.sweep_axis = pj_param(par.params, "ssweep").s;
+ if (proj_parm.sweep_axis.empty())
+ proj_parm.flip_axis = 0;
+ else {
+ if (proj_parm.sweep_axis[1] != '\0' ||
+ (proj_parm.sweep_axis[0] != 'x' &&
+ proj_parm.sweep_axis[0] != 'y'))
+ BOOST_THROW_EXCEPTION( projection_exception(-49) );
+ if (proj_parm.sweep_axis[0] == 'x')
+ proj_parm.flip_axis = 1;
+ else
+ proj_parm.flip_axis = 0;
+ }
+ proj_parm.radius_g_1 = proj_parm.h / par.a;
+ proj_parm.radius_g = 1. + proj_parm.radius_g_1;
+ proj_parm.C = proj_parm.radius_g * proj_parm.radius_g - 1.0;
+ if (par.es) {
+ proj_parm.radius_p = sqrt (par.one_es);
+ proj_parm.radius_p2 = par.one_es;
+ proj_parm.radius_p_inv2 = par.rone_es;
+ } else {
+ proj_parm.radius_p = proj_parm.radius_p2 = proj_parm.radius_p_inv2 = 1.0;
+ }
+ }
+
+ }} // namespace detail::geos
+ #endif // doxygen
+
+ /*!
+ \brief Geostationary Satellite View projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - h: Height (real)
+ - sweep: Sweep axis ('x' or 'y') (string)
+ \par Example
+ \image html ex_geos.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct geos_ellipsoid : public detail::geos::base_geos_ellipsoid<CalculationType, Parameters>
+ {
+ inline geos_ellipsoid(const Parameters& par) : detail::geos::base_geos_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::geos::setup_geos(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Geostationary Satellite View projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - h: Height (real)
+ - sweep: Sweep axis ('x' or 'y') (string)
+ \par Example
+ \image html ex_geos.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct geos_spheroid : public detail::geos::base_geos_spheroid<CalculationType, Parameters>
+ {
+ inline geos_spheroid(const Parameters& par) : detail::geos::base_geos_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::geos::setup_geos(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::geos, geos_spheroid, geos_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class geos_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<geos_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ else
+ return new base_v_fi<geos_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void geos_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("geos", new geos_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GEOS_HPP
+
diff --git a/boost/geometry/srs/projections/proj/gins8.hpp b/boost/geometry/srs/projections/proj/gins8.hpp
new file mode 100644
index 0000000000..f6c0059b07
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/gins8.hpp
@@ -0,0 +1,170 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GINS8_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GINS8_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct gins8 {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace gins8
+ {
+
+ static const double Cl = 0.000952426;
+ static const double Cp = 0.162388;
+ //static const double C12 = 0.08333333333333333;
+
+ template <typename T>
+ inline T C12() { return 0.083333333333333333333333333333333333; }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_gins8_spheroid : public base_t_f<base_gins8_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_gins8_spheroid(const Parameters& par)
+ : base_t_f<base_gins8_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType C12 = gins8::C12<CalculationType>();
+
+ CalculationType t = lp_lat * lp_lat;
+
+ xy_y = lp_lat * (1. + t * C12);
+ xy_x = lp_lon * (1. - Cp * t);
+ t = lp_lon * lp_lon;
+ xy_x *= (0.87 - Cl * t * t);
+ }
+
+ static inline std::string get_name()
+ {
+ return "gins8_spheroid";
+ }
+
+ };
+
+ // Ginsburg VIII (TsNIIGAiK)
+ template <typename Parameters>
+ inline void setup_gins8(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::gins8
+ #endif // doxygen
+
+ /*!
+ \brief Ginsburg VIII (TsNIIGAiK) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_gins8.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct gins8_spheroid : public detail::gins8::base_gins8_spheroid<CalculationType, Parameters>
+ {
+ inline gins8_spheroid(const Parameters& par) : detail::gins8::base_gins8_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::gins8::setup_gins8(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gins8, gins8_spheroid, gins8_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class gins8_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<gins8_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void gins8_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("gins8", new gins8_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GINS8_HPP
+
diff --git a/boost/geometry/srs/projections/proj/gn_sinu.hpp b/boost/geometry/srs/projections/proj/gn_sinu.hpp
new file mode 100644
index 0000000000..c41b278255
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/gn_sinu.hpp
@@ -0,0 +1,426 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct gn_sinu {};
+ struct sinu {};
+ struct eck6 {};
+ struct mbtfps {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace gn_sinu
+ {
+
+ static const double EPS10 = 1e-10;
+ static const int MAX_ITER = 8;
+ static const double LOOP_TOL = 1e-7;
+
+ template <typename T>
+ struct par_gn_sinu
+ {
+ T en[EN_SIZE];
+ T m, n, C_x, C_y;
+ };
+
+ /* Ellipsoidal Sinusoidal only */
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_gn_sinu_ellipsoid : public base_t_fi<base_gn_sinu_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_gn_sinu<CalculationType> m_proj_parm;
+
+ inline base_gn_sinu_ellipsoid(const Parameters& par)
+ : base_t_fi<base_gn_sinu_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType s, c;
+
+ xy_y = pj_mlfn(lp_lat, s = sin(lp_lat), c = cos(lp_lat), this->m_proj_parm.en);
+ xy_x = lp_lon * c / sqrt(1. - this->m_par.es * s * s);
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType s;
+
+ if ((s = fabs(lp_lat = pj_inv_mlfn(xy_y, this->m_par.es, this->m_proj_parm.en))) < HALFPI) {
+ s = sin(lp_lat);
+ lp_lon = xy_x * sqrt(1. - this->m_par.es * s * s) / cos(lp_lat);
+ } else if ((s - EPS10) < HALFPI)
+ lp_lon = 0.;
+ else
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ }
+ /* General spherical sinusoidals */
+
+ static inline std::string get_name()
+ {
+ return "gn_sinu_ellipsoid";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_gn_sinu_spheroid : public base_t_fi<base_gn_sinu_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_gn_sinu<CalculationType> m_proj_parm;
+
+ inline base_gn_sinu_spheroid(const Parameters& par)
+ : base_t_fi<base_gn_sinu_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ if (!this->m_proj_parm.m)
+ lp_lat = this->m_proj_parm.n != 1. ? aasin(this->m_proj_parm.n * sin(lp_lat)): lp_lat;
+ else {
+ CalculationType k, V;
+ int i;
+
+ k = this->m_proj_parm.n * sin(lp_lat);
+ for (i = MAX_ITER; i ; --i) {
+ lp_lat -= V = (this->m_proj_parm.m * lp_lat + sin(lp_lat) - k) /
+ (this->m_proj_parm.m + cos(lp_lat));
+ if (fabs(V) < LOOP_TOL)
+ break;
+ }
+ if (!i)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ }
+ xy_x = this->m_proj_parm.C_x * lp_lon * (this->m_proj_parm.m + cos(lp_lat));
+ xy_y = this->m_proj_parm.C_y * lp_lat;
+ }
+
+ // INVERSE(s_inverse) sphere
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ xy_y /= this->m_proj_parm.C_y;
+ lp_lat = this->m_proj_parm.m ? aasin((this->m_proj_parm.m * xy_y + sin(xy_y)) / this->m_proj_parm.n) :
+ ( this->m_proj_parm.n != 1. ? aasin(sin(xy_y) / this->m_proj_parm.n) : xy_y );
+ lp_lon = xy_x / (this->m_proj_parm.C_x * (this->m_proj_parm.m + cos(xy_y)));
+ }
+
+ static inline std::string get_name()
+ {
+ return "gn_sinu_spheroid";
+ }
+
+ };
+
+ template <typename Parameters, typename T>
+ inline void setup(Parameters& par, par_gn_sinu<T>& proj_parm)
+ {
+ par.es = 0;
+ proj_parm.C_x = (proj_parm.C_y = sqrt((proj_parm.m + 1.) / proj_parm.n))/(proj_parm.m + 1.);
+ }
+
+
+ // General Sinusoidal Series
+ template <typename Parameters, typename T>
+ inline void setup_gn_sinu(Parameters& par, par_gn_sinu<T>& proj_parm)
+ {
+ if (pj_param(par.params, "tn").i && pj_param(par.params, "tm").i) {
+ proj_parm.n = pj_param(par.params, "dn").f;
+ proj_parm.m = pj_param(par.params, "dm").f;
+ } else
+ BOOST_THROW_EXCEPTION( projection_exception(-99) );
+ setup(par, proj_parm);
+ }
+
+ // Sinusoidal (Sanson-Flamsteed)
+ template <typename Parameters, typename T>
+ inline void setup_sinu(Parameters& par, par_gn_sinu<T>& proj_parm)
+ {
+ if (!pj_enfn(par.es, proj_parm.en))
+ BOOST_THROW_EXCEPTION( projection_exception(0) );
+ if (par.es) {
+ } else {
+ proj_parm.n = 1.;
+ proj_parm.m = 0.;
+ setup(par, proj_parm);
+ }
+ }
+
+ // Eckert VI
+ template <typename Parameters, typename T>
+ inline void setup_eck6(Parameters& par, par_gn_sinu<T>& proj_parm)
+ {
+ proj_parm.m = 1.;
+ proj_parm.n = 2.570796326794896619231321691;
+ setup(par, proj_parm);
+ }
+
+ // McBryde-Thomas Flat-Polar Sinusoidal
+ template <typename Parameters, typename T>
+ inline void setup_mbtfps(Parameters& par, par_gn_sinu<T>& proj_parm)
+ {
+ proj_parm.m = 0.5;
+ proj_parm.n = 1.785398163397448309615660845;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::gn_sinu
+ #endif // doxygen
+
+ /*!
+ \brief General Sinusoidal Series projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Projection parameters
+ - m (real)
+ - n (real)
+ \par Example
+ \image html ex_gn_sinu.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct gn_sinu_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters>
+ {
+ inline gn_sinu_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::gn_sinu::setup_gn_sinu(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Sinusoidal (Sanson-Flamsteed) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_sinu.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct sinu_ellipsoid : public detail::gn_sinu::base_gn_sinu_ellipsoid<CalculationType, Parameters>
+ {
+ inline sinu_ellipsoid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::gn_sinu::setup_sinu(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Sinusoidal (Sanson-Flamsteed) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_sinu.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct sinu_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters>
+ {
+ inline sinu_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::gn_sinu::setup_sinu(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Eckert VI projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_eck6.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct eck6_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters>
+ {
+ inline eck6_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::gn_sinu::setup_eck6(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief McBryde-Thomas Flat-Polar Sinusoidal projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_mbtfps.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct mbtfps_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters>
+ {
+ inline mbtfps_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::gn_sinu::setup_mbtfps(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gn_sinu, gn_sinu_spheroid, gn_sinu_spheroid)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::sinu, sinu_spheroid, sinu_ellipsoid)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::eck6, eck6_spheroid, eck6_spheroid)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mbtfps, mbtfps_spheroid, mbtfps_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class gn_sinu_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<gn_sinu_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class sinu_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<sinu_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ else
+ return new base_v_fi<sinu_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class eck6_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eck6_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class mbtfps_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<mbtfps_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void gn_sinu_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("gn_sinu", new gn_sinu_entry<CalculationType, Parameters>);
+ factory.add_to_factory("sinu", new sinu_entry<CalculationType, Parameters>);
+ factory.add_to_factory("eck6", new eck6_entry<CalculationType, Parameters>);
+ factory.add_to_factory("mbtfps", new mbtfps_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP
+
diff --git a/boost/geometry/srs/projections/proj/gnom.hpp b/boost/geometry/srs/projections/proj/gnom.hpp
new file mode 100644
index 0000000000..d691c136b6
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/gnom.hpp
@@ -0,0 +1,266 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GNOM_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GNOM_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/config.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct gnom {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace gnom
+ {
+
+ static const double EPS10 = 1.e-10;
+ static const int N_POLE = 0;
+ static const int S_POLE = 1;
+ static const int EQUIT = 2;
+ static const int OBLIQ = 3;
+
+ template <typename T>
+ struct par_gnom
+ {
+ T sinph0;
+ T cosph0;
+ int mode;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_gnom_spheroid : public base_t_fi<base_gnom_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_gnom<CalculationType> m_proj_parm;
+
+ inline base_gnom_spheroid(const Parameters& par)
+ : base_t_fi<base_gnom_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType coslam, cosphi, sinphi;
+
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ coslam = cos(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ xy_y = cosphi * coslam;
+ break;
+ case OBLIQ:
+ xy_y = this->m_proj_parm.sinph0 * sinphi + this->m_proj_parm.cosph0 * cosphi * coslam;
+ break;
+ case S_POLE:
+ xy_y = - sinphi;
+ break;
+ case N_POLE:
+ xy_y = sinphi;
+ break;
+ }
+ if (xy_y <= EPS10)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ xy_x = (xy_y = 1. / xy_y) * cosphi * sin(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ xy_y *= sinphi;
+ break;
+ case OBLIQ:
+ xy_y *= this->m_proj_parm.cosph0 * sinphi - this->m_proj_parm.sinph0 * cosphi * coslam;
+ break;
+ case N_POLE:
+ coslam = - coslam;
+ BOOST_FALLTHROUGH;
+ case S_POLE:
+ xy_y *= cosphi * coslam;
+ break;
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType rh, cosz, sinz;
+
+ rh = boost::math::hypot(xy_x, xy_y);
+ sinz = sin(lp_lat = atan(rh));
+ cosz = sqrt(1. - sinz * sinz);
+ if (fabs(rh) <= EPS10) {
+ lp_lat = this->m_par.phi0;
+ lp_lon = 0.;
+ } else {
+ switch (this->m_proj_parm.mode) {
+ case OBLIQ:
+ lp_lat = cosz * this->m_proj_parm.sinph0 + xy_y * sinz * this->m_proj_parm.cosph0 / rh;
+ if (fabs(lp_lat) >= 1.)
+ lp_lat = lp_lat > 0. ? HALFPI : -HALFPI;
+ else
+ lp_lat = asin(lp_lat);
+ xy_y = (cosz - this->m_proj_parm.sinph0 * sin(lp_lat)) * rh;
+ xy_x *= sinz * this->m_proj_parm.cosph0;
+ break;
+ case EQUIT:
+ lp_lat = xy_y * sinz / rh;
+ if (fabs(lp_lat) >= 1.)
+ lp_lat = lp_lat > 0. ? HALFPI : -HALFPI;
+ else
+ lp_lat = asin(lp_lat);
+ xy_y = cosz * rh;
+ xy_x *= sinz;
+ break;
+ case S_POLE:
+ lp_lat -= HALFPI;
+ break;
+ case N_POLE:
+ lp_lat = HALFPI - lp_lat;
+ xy_y = -xy_y;
+ break;
+ }
+ lp_lon = atan2(xy_x, xy_y);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "gnom_spheroid";
+ }
+
+ };
+
+ // Gnomonic
+ template <typename Parameters, typename T>
+ inline void setup_gnom(Parameters& par, par_gnom<T>& proj_parm)
+ {
+ static const T HALFPI = detail::HALFPI<T>();
+
+ if (fabs(fabs(par.phi0) - HALFPI) < EPS10)
+ proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE;
+ else if (fabs(par.phi0) < EPS10)
+ proj_parm.mode = EQUIT;
+ else {
+ proj_parm.mode = OBLIQ;
+ proj_parm.sinph0 = sin(par.phi0);
+ proj_parm.cosph0 = cos(par.phi0);
+ }
+ par.es = 0.;
+ }
+
+ }} // namespace detail::gnom
+ #endif // doxygen
+
+ /*!
+ \brief Gnomonic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ \par Example
+ \image html ex_gnom.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct gnom_spheroid : public detail::gnom::base_gnom_spheroid<CalculationType, Parameters>
+ {
+ inline gnom_spheroid(const Parameters& par) : detail::gnom::base_gnom_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::gnom::setup_gnom(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gnom, gnom_spheroid, gnom_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class gnom_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<gnom_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void gnom_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("gnom", new gnom_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GNOM_HPP
+
diff --git a/boost/geometry/srs/projections/proj/goode.hpp b/boost/geometry/srs/projections/proj/goode.hpp
new file mode 100644
index 0000000000..ef4e5ebeee
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/goode.hpp
@@ -0,0 +1,187 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GOODE_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GOODE_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/proj/gn_sinu.hpp>
+#include <boost/geometry/srs/projections/proj/moll.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct goode {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace goode
+ {
+
+ static const double Y_COR = 0.05280;
+ static const double PHI_LIM = .71093078197902358062;
+
+ template <typename CalculationType, typename Parameters>
+ struct par_goode
+ {
+ sinu_ellipsoid<CalculationType, Parameters> sinu;
+ moll_spheroid<CalculationType, Parameters> moll;
+
+ par_goode(const Parameters& par) : sinu(par), moll(par) {}
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_goode_spheroid : public base_t_fi<base_goode_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_goode<CalculationType, Parameters> m_proj_parm;
+
+ inline base_goode_spheroid(const Parameters& par)
+ : base_t_fi<base_goode_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par), m_proj_parm(par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ if (fabs(lp_lat) <= PHI_LIM)
+ this->m_proj_parm.sinu.fwd(lp_lon, lp_lat, xy_x, xy_y);
+ else {
+ this->m_proj_parm.moll.fwd(lp_lon, lp_lat, xy_x, xy_y);
+ xy_y -= lp_lat >= 0.0 ? Y_COR : -Y_COR;
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ if (fabs(xy_y) <= PHI_LIM)
+ this->m_proj_parm.sinu.inv(xy_x, xy_y, lp_lon, lp_lat);
+ else {
+ xy_y += xy_y >= 0.0 ? Y_COR : -Y_COR;
+ this->m_proj_parm.moll.inv(xy_x, xy_y, lp_lon, lp_lat);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "goode_spheroid";
+ }
+
+ };
+
+ // Goode Homolosine
+ template <typename CalculationType, typename Parameters>
+ inline void setup_goode(Parameters& par, par_goode<CalculationType, Parameters>& /*proj_parm*/)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::goode
+ #endif // doxygen
+
+ /*!
+ \brief Goode Homolosine projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_goode.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct goode_spheroid : public detail::goode::base_goode_spheroid<CalculationType, Parameters>
+ {
+ inline goode_spheroid(const Parameters& par) : detail::goode::base_goode_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::goode::setup_goode(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::goode, goode_spheroid, goode_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class goode_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<goode_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void goode_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("goode", new goode_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GOODE_HPP
+
diff --git a/boost/geometry/srs/projections/proj/gstmerc.hpp b/boost/geometry/srs/projections/proj/gstmerc.hpp
new file mode 100644
index 0000000000..5e3581328e
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/gstmerc.hpp
@@ -0,0 +1,202 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GSTMERC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GSTMERC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_phi2.hpp>
+#include <boost/geometry/srs/projections/impl/pj_tsfn.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct gstmerc {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace gstmerc
+ {
+ template <typename T>
+ struct par_gstmerc
+ {
+ T lamc;
+ T phic;
+ T c;
+ T n1;
+ T n2;
+ T XS;
+ T YS;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_gstmerc_spheroid : public base_t_fi<base_gstmerc_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_gstmerc<CalculationType> m_proj_parm;
+
+ inline base_gstmerc_spheroid(const Parameters& par)
+ : base_t_fi<base_gstmerc_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType L, Ls, sinLs1, Ls1;
+ L= this->m_proj_parm.n1*lp_lon;
+ Ls= this->m_proj_parm.c+this->m_proj_parm.n1*log(pj_tsfn(-1.0*lp_lat,-1.0*sin(lp_lat),this->m_par.e));
+ sinLs1= sin(L)/cosh(Ls);
+ Ls1= log(pj_tsfn(-1.0*asin(sinLs1),0.0,0.0));
+ xy_x= (this->m_proj_parm.XS + this->m_proj_parm.n2*Ls1)*this->m_par.ra;
+ xy_y= (this->m_proj_parm.YS + this->m_proj_parm.n2*atan(sinh(Ls)/cos(L)))*this->m_par.ra;
+ /*fprintf(stderr,"fwd:\nL =%16.13f\nLs =%16.13f\nLs1 =%16.13f\nLP(%16.13f,%16.13f)=XY(%16.4f,%16.4f)\n",L,Ls,Ls1,lp_lon+this->m_par.lam0,lp_lat,(xy_x*this->m_par.a + this->m_par.x0)*this->m_par.to_meter,(xy_y*this->m_par.a + this->m_par.y0)*this->m_par.to_meter);*/
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType L, LC, sinC;
+ L= atan(sinh((xy_x*this->m_par.a - this->m_proj_parm.XS)/this->m_proj_parm.n2)/cos((xy_y*this->m_par.a - this->m_proj_parm.YS)/this->m_proj_parm.n2));
+ sinC= sin((xy_y*this->m_par.a - this->m_proj_parm.YS)/this->m_proj_parm.n2)/cosh((xy_x*this->m_par.a - this->m_proj_parm.XS)/this->m_proj_parm.n2);
+ LC= log(pj_tsfn(-1.0*asin(sinC),0.0,0.0));
+ lp_lon= L/this->m_proj_parm.n1;
+ lp_lat= -1.0*pj_phi2(exp((LC-this->m_proj_parm.c)/this->m_proj_parm.n1),this->m_par.e);
+ /*fprintf(stderr,"inv:\nL =%16.13f\nsinC =%16.13f\nLC =%16.13f\nXY(%16.4f,%16.4f)=LP(%16.13f,%16.13f)\n",L,sinC,LC,((xy_x/this->m_par.ra)+this->m_par.x0)/this->m_par.to_meter,((xy_y/this->m_par.ra)+this->m_par.y0)/this->m_par.to_meter,lp_lon+this->m_par.lam0,lp_lat);*/
+ }
+
+ static inline std::string get_name()
+ {
+ return "gstmerc_spheroid";
+ }
+
+ };
+
+ // Gauss-Schreiber Transverse Mercator (aka Gauss-Laborde Reunion)
+ template <typename Parameters, typename T>
+ inline void setup_gstmerc(Parameters& par, par_gstmerc<T>& proj_parm)
+ {
+ proj_parm.lamc= par.lam0;
+ proj_parm.n1= sqrt(1.0+par.es*pow(cos(par.phi0),4.0)/(1.0-par.es));
+ proj_parm.phic= asin(sin(par.phi0)/proj_parm.n1);
+ proj_parm.c= log(pj_tsfn(-1.0*proj_parm.phic,0.0,0.0))
+ -proj_parm.n1*log(pj_tsfn(-1.0*par.phi0,-1.0*sin(par.phi0),par.e));
+ proj_parm.n2= par.k0*par.a*sqrt(1.0-par.es)/(1.0-par.es*sin(par.phi0)*sin(par.phi0));
+ proj_parm.XS= 0;/* -par.x0 */
+ proj_parm.YS= -1.0*proj_parm.n2*proj_parm.phic;/* -par.y0 */
+ /*fprintf(stderr,"a (m) =%16.4f\ne =%16.13f\nl0(rad)=%16.13f\np0(rad)=%16.13f\nk0 =%16.4f\nX0 (m)=%16.4f\nY0 (m)=%16.4f\n\nlC(rad)=%16.13f\npC(rad)=%16.13f\nc =%16.13f\nn1 =%16.13f\nn2 (m) =%16.4f\nXS (m) =%16.4f\nYS (m) =%16.4f\n", par.a, par.e, par.lam0, par.phi0, par.k0, par.x0, par.y0, proj_parm.lamc, proj_parm.phic, proj_parm.c, proj_parm.n1, proj_parm.n2, proj_parm.XS +par.x0, proj_parm.YS + par.y0);*/
+ }
+
+ }} // namespace detail::gstmerc
+ #endif // doxygen
+
+ /*!
+ \brief Gauss-Schreiber Transverse Mercator (aka Gauss-Laborde Reunion) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_0: Latitude of origin
+ - lon_0: Central meridian
+ - k_0: Scale factor
+ \par Example
+ \image html ex_gstmerc.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct gstmerc_spheroid : public detail::gstmerc::base_gstmerc_spheroid<CalculationType, Parameters>
+ {
+ inline gstmerc_spheroid(const Parameters& par) : detail::gstmerc::base_gstmerc_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::gstmerc::setup_gstmerc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gstmerc, gstmerc_spheroid, gstmerc_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class gstmerc_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<gstmerc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void gstmerc_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("gstmerc", new gstmerc_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GSTMERC_HPP
+
diff --git a/boost/geometry/srs/projections/proj/hammer.hpp b/boost/geometry/srs/projections/proj/hammer.hpp
new file mode 100644
index 0000000000..58707a1499
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/hammer.hpp
@@ -0,0 +1,201 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_HAMMER_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_HAMMER_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct hammer {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace hammer
+ {
+ static const double EPS = 1.0e-10;
+
+ template <typename T>
+ struct par_hammer
+ {
+ T w;
+ T m, rm;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_hammer_spheroid : public base_t_fi<base_hammer_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_hammer<CalculationType> m_proj_parm;
+
+ inline base_hammer_spheroid(const Parameters& par)
+ : base_t_fi<base_hammer_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType cosphi, d;
+
+ d = sqrt(2./(1. + (cosphi = cos(lp_lat)) * cos(lp_lon *= this->m_proj_parm.w)));
+ xy_x = this->m_proj_parm.m * d * cosphi * sin(lp_lon);
+ xy_y = this->m_proj_parm.rm * d * sin(lp_lat);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType z;
+
+ z = sqrt(1. - 0.25*this->m_proj_parm.w*this->m_proj_parm.w*xy_x*xy_x - 0.25*xy_y*xy_y);
+ if (geometry::math::abs(2.*z*z-1.) < EPS) {
+ lp_lon = HUGE_VAL;
+ lp_lat = HUGE_VAL;
+ BOOST_THROW_EXCEPTION( projection_exception(-14) );
+ } else {
+ lp_lon = aatan2(this->m_proj_parm.w * xy_x * z,2. * z * z - 1)/this->m_proj_parm.w;
+ lp_lat = aasin(z * xy_y);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "hammer_spheroid";
+ }
+
+ };
+
+ // Hammer & Eckert-Greifendorff
+ template <typename Parameters, typename T>
+ inline void setup_hammer(Parameters& par, par_hammer<T>& proj_parm)
+ {
+ if (pj_param(par.params, "tW").i) {
+ if ((proj_parm.w = fabs(pj_param(par.params, "dW").f)) <= 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-27) );
+ } else
+ proj_parm.w = .5;
+ if (pj_param(par.params, "tM").i) {
+ if ((proj_parm.m = fabs(pj_param(par.params, "dM").f)) <= 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-27) );
+ } else
+ proj_parm.m = 1.;
+ proj_parm.rm = 1. / proj_parm.m;
+ proj_parm.m /= proj_parm.w;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::hammer
+ #endif // doxygen
+
+ /*!
+ \brief Hammer & Eckert-Greifendorff projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Projection parameters
+ - W (real)
+ - M (real)
+ \par Example
+ \image html ex_hammer.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct hammer_spheroid : public detail::hammer::base_hammer_spheroid<CalculationType, Parameters>
+ {
+ inline hammer_spheroid(const Parameters& par) : detail::hammer::base_hammer_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::hammer::setup_hammer(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::hammer, hammer_spheroid, hammer_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class hammer_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<hammer_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void hammer_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("hammer", new hammer_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_HAMMER_HPP
+
diff --git a/boost/geometry/srs/projections/proj/hatano.hpp b/boost/geometry/srs/projections/proj/hatano.hpp
new file mode 100644
index 0000000000..e37a78196b
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/hatano.hpp
@@ -0,0 +1,211 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_HATANO_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_HATANO_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct hatano {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace hatano
+ {
+
+ static const int NITER = 20;
+ static const double EPS = 1e-7;
+ static const double ONETOL = 1.000001;
+ static const double CN_ = 2.67595;
+ static const double CS_ = 2.43763;
+ static const double RCN = 0.37369906014686373063;
+ static const double RCS = 0.41023453108141924738;
+ static const double FYCN = 1.75859;
+ static const double FYCS = 1.93052;
+ static const double RYCN = 0.56863737426006061674;
+ static const double RYCS = 0.51799515156538134803;
+ static const double FXC = 0.85;
+ static const double RXC = 1.17647058823529411764;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_hatano_spheroid : public base_t_fi<base_hatano_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_hatano_spheroid(const Parameters& par)
+ : base_t_fi<base_hatano_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType th1, c;
+ int i;
+
+ c = sin(lp_lat) * (lp_lat < 0. ? CS_ : CN_);
+ for (i = NITER; i; --i) {
+ lp_lat -= th1 = (lp_lat + sin(lp_lat) - c) / (1. + cos(lp_lat));
+ if (fabs(th1) < EPS) break;
+ }
+ xy_x = FXC * lp_lon * cos(lp_lat *= .5);
+ xy_y = sin(lp_lat) * (lp_lat < 0. ? FYCS : FYCN);
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType th;
+
+ th = xy_y * ( xy_y < 0. ? RYCS : RYCN);
+ if (fabs(th) > 1.) {
+ if (fabs(th) > ONETOL) {
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ } else {
+ th = th > 0. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>();
+ }
+ } else {
+ th = asin(th);
+ }
+
+ lp_lon = RXC * xy_x / cos(th);
+ th += th;
+ lp_lat = (th + sin(th)) * (xy_y < 0. ? RCS : RCN);
+ if (fabs(lp_lat) > 1.) {
+ if (fabs(lp_lat) > ONETOL) {
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ } else {
+ lp_lat = lp_lat > 0. ? geometry::math::half_pi<double>() : - geometry::math::half_pi<double>();
+ }
+ } else {
+ lp_lat = asin(lp_lat);
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "hatano_spheroid";
+ }
+
+ };
+
+ // Hatano Asymmetrical Equal Area
+ template <typename Parameters>
+ inline void setup_hatano(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::hatano
+ #endif // doxygen
+
+ /*!
+ \brief Hatano Asymmetrical Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_hatano.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct hatano_spheroid : public detail::hatano::base_hatano_spheroid<CalculationType, Parameters>
+ {
+ inline hatano_spheroid(const Parameters& par) : detail::hatano::base_hatano_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::hatano::setup_hatano(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::hatano, hatano_spheroid, hatano_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class hatano_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<hatano_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void hatano_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("hatano", new hatano_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_HATANO_HPP
+
diff --git a/boost/geometry/srs/projections/proj/healpix.hpp b/boost/geometry/srs/projections/proj/healpix.hpp
new file mode 100644
index 0000000000..d2f5a8c081
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/healpix.hpp
@@ -0,0 +1,897 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_HEALPIX_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_HEALPIX_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the HEALPix and rHEALPix projections.
+// For background see <http://code.scenzgrid.org/index.php/p/scenzgrid-py/source/tree/master/docs/rhealpix_dggs.pdf>.
+// Authors: Alex Raichev (raichev@cs.auckland.ac.nz)
+// Michael Speth (spethm@landcareresearch.co.nz)
+// Notes: Raichev implemented these projections in Python and
+// Speth translated them into C here.
+// Copyright (c) 2001, Thomas Flemming, tf@ttqv.com
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_auth.hpp>
+#include <boost/geometry/srs/projections/impl/pj_qsfn.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct healpix {};
+ struct rhealpix {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace healpix
+ {
+
+ static const double EPS = 1e-15;
+
+ template <typename T>
+ struct par_healpix
+ {
+ int north_square;
+ int south_square;
+ T qp;
+ T apa[APA_SIZE];
+ };
+
+ /* Matrix for counterclockwise rotation by pi/2: */
+ /* Matrix for counterclockwise rotation by pi: */
+ /* Matrix for counterclockwise rotation by 3*pi/2: */
+ /* Identity matrix */
+ /* IDENT, R1, R2, R3, R1 inverse, R2 inverse, R3 inverse:*/
+ /* Fuzz to handle rounding errors: */
+ template <typename T>
+ struct CapMap
+ {
+ int cn; /* An integer 0--3 indicating the position of the polar cap. */
+ T x, y; /* Coordinates of the pole point (point of most extreme latitude on the polar caps). */
+ enum Region {north, south, equatorial} region;
+ };
+ template <typename T>
+ struct Point
+ {
+ T x, y;
+ };
+ static double rot[7][2][2] = {{{1, 0},{0, 1}}, {{ 0,-1},{ 1, 0}}, {{-1, 0},{ 0,-1}}, {{ 0, 1},{-1, 0}}, {{ 0, 1},{-1, 0}}, {{-1, 0},{ 0,-1}}, {{ 0,-1},{ 1, 0}}};
+
+ /**
+ * Returns the sign of the double.
+ * @param v the parameter whose sign is returned.
+ * @return 1 for positive number, -1 for negative, and 0 for zero.
+ **/
+ template <typename T>
+ inline T pj_sign (T const& v)
+ {
+ return v > 0 ? 1 : (v < 0 ? -1 : 0);
+ }
+ /**
+ * Return the index of the matrix in {{{1, 0},{0, 1}}, {{ 0,-1},{ 1, 0}}, {{-1, 0},{ 0,-1}}, {{ 0, 1},{-1, 0}}, {{ 0, 1},{-1, 0}}, {{-1, 0},{ 0,-1}}, {{ 0,-1},{ 1, 0}}}.
+ * @param index ranges from -3 to 3.
+ */
+ inline int get_rotate_index(int index)
+ {
+ switch(index) {
+ case 0:
+ return 0;
+ case 1:
+ return 1;
+ case 2:
+ return 2;
+ case 3:
+ return 3;
+ case -1:
+ return 4;
+ case -2:
+ return 5;
+ case -3:
+ return 6;
+ }
+ return 0;
+ }
+ /**
+ * Return 1 if point (testx, testy) lies in the interior of the polygon
+ * determined by the vertices in vert, and return 0 otherwise.
+ * See http://paulbourke.net/geometry/polygonmesh/ for more details.
+ * @param nvert the number of vertices in the polygon.
+ * @param vert the (x, y)-coordinates of the polygon's vertices
+ **/
+ template <typename T>
+ inline int pnpoly(int nvert, T vert[][2], T const& testx, T const& testy)
+ {
+ int i, c = 0;
+ int counter = 0;
+ T xinters;
+ Point<T> p1, p2;
+ /* Check for boundrary cases */
+ for (i = 0; i < nvert; i++) {
+ if (testx == vert[i][0] && testy == vert[i][1]) {
+ return 1;
+ }
+ }
+ p1.x = vert[0][0];
+ p1.y = vert[0][1];
+ for (i = 1; i < nvert; i++) {
+ p2.x = vert[i % nvert][0];
+ p2.y = vert[i % nvert][1];
+ if (testy > (std::min)(p1.y, p2.y)) {
+ if (testy <= (std::max)(p1.y, p2.y)) {
+ if (testx <= (std::max)(p1.x, p2.x)) {
+ if (p1.y != p2.y) {
+ xinters = (testy-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
+ if (p1.x == p2.x || testx <= xinters) {
+ counter++;
+ }
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+ if (counter % 2 == 0) {
+ return 0;
+ } else {
+ return 1;
+ }
+ return c;
+ }
+ /**
+ * Return 1 if (x, y) lies in (the interior or boundary of) the image of the
+ * HEALPix projection (in case proj=0) or in the image the rHEALPix projection
+ * (in case proj=1), and return 0 otherwise.
+ * @param north_square the position of the north polar square (rHEALPix only)
+ * @param south_square the position of the south polar square (rHEALPix only)
+ **/
+ template <typename T>
+ inline int in_image(T const& x, T const& y, int proj, int north_square, int south_square)
+ {
+ static const T ONEPI = detail::ONEPI<T>();
+
+ if (proj == 0) {
+ T healpixVertsJit[][2] = {
+ {-1.0*ONEPI- EPS, ONEPI/4.0},
+ {-3.0*ONEPI/4.0, ONEPI/2.0 + EPS},
+ {-1.0*ONEPI/2.0, ONEPI/4.0 + EPS},
+ {-1.0*ONEPI/4.0, ONEPI/2.0 + EPS},
+ {0.0, ONEPI/4.0 + EPS},
+ {ONEPI/4.0, ONEPI/2.0 + EPS},
+ {ONEPI/2.0, ONEPI/4.0 + EPS},
+ {3.0*ONEPI/4.0, ONEPI/2.0 + EPS},
+ {ONEPI+ EPS, ONEPI/4.0},
+ {ONEPI+ EPS, -1.0*ONEPI/4.0},
+ {3.0*ONEPI/4.0, -1.0*ONEPI/2.0 - EPS},
+ {ONEPI/2.0, -1.0*ONEPI/4.0 - EPS},
+ {ONEPI/4.0, -1.0*ONEPI/2.0 - EPS},
+ {0.0, -1.0*ONEPI/4.0 - EPS},
+ {-1.0*ONEPI/4.0, -1.0*ONEPI/2.0 - EPS},
+ {-1.0*ONEPI/2.0, -1.0*ONEPI/4.0 - EPS},
+ {-3.0*ONEPI/4.0, -1.0*ONEPI/2.0 - EPS},
+ {-1.0*ONEPI - EPS, -1.0*ONEPI/4.0}
+ };
+ return pnpoly((int)sizeof(healpixVertsJit)/
+ sizeof(healpixVertsJit[0]), healpixVertsJit, x, y);
+ } else {
+ T rhealpixVertsJit[][2] = {
+ {-1.0*ONEPI - EPS, ONEPI/4.0 + EPS},
+ {-1.0*ONEPI + north_square*ONEPI/2.0- EPS, ONEPI/4.0 + EPS},
+ {-1.0*ONEPI + north_square*ONEPI/2.0- EPS, 3*ONEPI/4.0 + EPS},
+ {-1.0*ONEPI + (north_square + 1.0)*ONEPI/2.0 + EPS, 3*ONEPI/4.0 + EPS},
+ {-1.0*ONEPI + (north_square + 1.0)*ONEPI/2.0 + EPS, ONEPI/4.0 + EPS},
+ {ONEPI + EPS, ONEPI/4.0 + EPS},
+ {ONEPI + EPS, -1.0*ONEPI/4.0 - EPS},
+ {-1.0*ONEPI + (south_square + 1.0)*ONEPI/2.0 + EPS, -1.0*ONEPI/4.0 - EPS},
+ {-1.0*ONEPI + (south_square + 1.0)*ONEPI/2.0 + EPS, -3.0*ONEPI/4.0 - EPS},
+ {-1.0*ONEPI + south_square*ONEPI/2.0 - EPS, -3.0*ONEPI/4.0 - EPS},
+ {-1.0*ONEPI + south_square*ONEPI/2.0 - EPS, -1.0*ONEPI/4.0 - EPS},
+ {-1.0*ONEPI - EPS, -1.0*ONEPI/4.0 - EPS}};
+ return pnpoly((int)sizeof(rhealpixVertsJit)/
+ sizeof(rhealpixVertsJit[0]), rhealpixVertsJit, x, y);
+ }
+ }
+ /**
+ * Return the authalic latitude of latitude alpha (if inverse=0) or
+ * return the approximate latitude of authalic latitude alpha (if inverse=1).
+ * P contains the relavent ellipsoid parameters.
+ **/
+ template <typename Parameters, typename T>
+ inline T auth_lat(const Parameters& par, const par_healpix<T>& proj_parm, T const& alpha, int inverse)
+ {
+ if (inverse == 0) {
+ /* Authalic latitude. */
+ T q = pj_qsfn(sin(alpha), par.e, 1.0 - par.es);
+ T qp = proj_parm.qp;
+ T ratio = q/qp;
+ if (fabsl(ratio) > 1) {
+ /* Rounding error. */
+ ratio = pj_sign(ratio);
+ }
+ return asin(ratio);
+ } else {
+ /* Approximation to inverse authalic latitude. */
+ return pj_authlat(alpha, proj_parm.apa);
+ }
+ }
+ /**
+ * Return the HEALPix projection of the longitude-latitude point lp on
+ * the unit sphere.
+ **/
+ template <typename T>
+ inline void healpix_sphere(T const& lp_lam, T const& lp_phi, T& xy_x, T& xy_y)
+ {
+ static const T ONEPI = detail::ONEPI<T>();
+
+ T lam = lp_lam;
+ T phi = lp_phi;
+ T phi0 = asin(T(2.0)/T(3.0));
+
+ /* equatorial region */
+ if ( fabsl(phi) <= phi0) {
+ xy_x = lam;
+ xy_y = 3.0*ONEPI/8.0*sin(phi);
+ } else {
+ T lamc;
+ T sigma = sqrt(3.0*(1 - fabsl(sin(phi))));
+ T cn = floor(2*lam / ONEPI + 2);
+ if (cn >= 4) {
+ cn = 3;
+ }
+ lamc = -3*ONEPI/4 + (ONEPI/2)*cn;
+ xy_x = lamc + (lam - lamc)*sigma;
+ xy_y = pj_sign(phi)*ONEPI/4*(2 - sigma);
+ }
+ return;
+ }
+ /**
+ * Return the inverse of healpix_sphere().
+ **/
+ template <typename T>
+ inline void healpix_sphere_inverse(T const& xy_x, T const& xy_y, T& lp_lam, T& lp_phi)
+ {
+ static const T ONEPI = detail::ONEPI<T>();
+
+ T x = xy_x;
+ T y = xy_y;
+ T y0 = ONEPI/4.0;
+ /* Equatorial region. */
+ if (fabsl(y) <= y0) {
+ lp_lam = x;
+ lp_phi = asin(8.0*y/(3.0*ONEPI));
+ } else if (fabsl(y) < ONEPI/2.0) {
+ T cn = floor(2.0*x/ONEPI + 2.0);
+ T xc, tau;
+ if (cn >= 4) {
+ cn = 3;
+ }
+ xc = -3.0*ONEPI/4.0 + (ONEPI/2.0)*cn;
+ tau = 2.0 - 4.0*fabsl(y)/ONEPI;
+ lp_lam = xc + (x - xc)/tau;
+ lp_phi = pj_sign(y)*asin(1.0 - pow(tau , 2.0)/3.0);
+ } else {
+ lp_lam = -1.0*ONEPI;
+ lp_phi = pj_sign(y)*ONEPI/2.0;
+ }
+ return;
+ }
+ /**
+ * Return the vector sum a + b, where a and b are 2-dimensional vectors.
+ * @param ret holds a + b.
+ **/
+ template <typename T>
+ inline void vector_add(T a[2], T b[2], T *ret)
+ {
+ int i;
+ for(i = 0; i < 2; i++) {
+ ret[i] = a[i] + b[i];
+ }
+ }
+ /**
+ * Return the vector difference a - b, where a and b are 2-dimensional vectors.
+ * @param ret holds a - b.
+ **/
+ template <typename T>
+ inline void vector_sub(T a[2], T b[2], T*ret)
+ {
+ int i;
+ for(i = 0; i < 2; i++) {
+ ret[i] = a[i] - b[i];
+ }
+ }
+ /**
+ * Return the 2 x 1 matrix product a*b, where a is a 2 x 2 matrix and
+ * b is a 2 x 1 matrix.
+ * @param ret holds a*b.
+ **/
+ template <typename T>
+ inline void dot_product(T a[2][2], T b[2], T *ret)
+ {
+ int i, j;
+ int length = 2;
+ for(i = 0; i < length; i++) {
+ ret[i] = 0;
+ for(j = 0; j < length; j++) {
+ ret[i] += a[i][j]*b[j];
+ }
+ }
+ }
+ /**
+ * Return the number of the polar cap, the pole point coordinates, and
+ * the region that (x, y) lies in.
+ * If inverse=0, then assume (x,y) lies in the image of the HEALPix
+ * projection of the unit sphere.
+ * If inverse=1, then assume (x,y) lies in the image of the
+ * (north_square, south_square)-rHEALPix projection of the unit sphere.
+ **/
+ template <typename T>
+ inline CapMap<T> get_cap(T x, T const& y, int north_square, int south_square,
+ int inverse)
+ {
+ static const T ONEPI = detail::ONEPI<T>();
+
+ CapMap<T> capmap;
+ T c;
+ capmap.x = x;
+ capmap.y = y;
+ if (inverse == 0) {
+ if (y > ONEPI/4.0) {
+ capmap.region = CapMap<T>::north;
+ c = ONEPI/2.0;
+ } else if (y < -1*ONEPI/4.0) {
+ capmap.region = CapMap<T>::south;
+ c = -1*ONEPI/2.0;
+ } else {
+ capmap.region = CapMap<T>::equatorial;
+ capmap.cn = 0;
+ return capmap;
+ }
+ /* polar region */
+ if (x < -1*ONEPI/2.0) {
+ capmap.cn = 0;
+ capmap.x = (-1*3.0*ONEPI/4.0);
+ capmap.y = c;
+ } else if (x >= -1*ONEPI/2.0 && x < 0) {
+ capmap.cn = 1;
+ capmap.x = -1*ONEPI/4.0;
+ capmap.y = c;
+ } else if (x >= 0 && x < ONEPI/2.0) {
+ capmap.cn = 2;
+ capmap.x = ONEPI/4.0;
+ capmap.y = c;
+ } else {
+ capmap.cn = 3;
+ capmap.x = 3.0*ONEPI/4.0;
+ capmap.y = c;
+ }
+ return capmap;
+ } else {
+ T eps;
+ if (y > ONEPI/4.0) {
+ capmap.region = CapMap<T>::north;
+ capmap.x = (-3.0*ONEPI/4.0 + north_square*ONEPI/2.0);
+ capmap.y = ONEPI/2.0;
+ x = x - north_square*ONEPI/2.0;
+ } else if (y < -1*ONEPI/4.0) {
+ capmap.region = CapMap<T>::south;
+ capmap.x = (-3.0*ONEPI/4.0 + south_square*ONEPI/2);
+ capmap.y = -1*ONEPI/2.0;
+ x = x - south_square*ONEPI/2.0;
+ } else {
+ capmap.region = CapMap<T>::equatorial;
+ capmap.cn = 0;
+ return capmap;
+ }
+ /* Polar Region, find the HEALPix polar cap number that
+ x, y moves to when rHEALPix polar square is disassembled. */
+ eps = 1e-15; /* Kludge. Fuzz to avoid some rounding errors. */
+ if (capmap.region == CapMap<T>::north) {
+ if (y >= -1*x - ONEPI/4.0 - eps && y < x + 5.0*ONEPI/4.0 - eps) {
+ capmap.cn = (north_square + 1) % 4;
+ } else if (y > -1*x -1*ONEPI/4.0 + eps && y >= x + 5.0*ONEPI/4.0 - eps) {
+ capmap.cn = (north_square + 2) % 4;
+ } else if (y <= -1*x -1*ONEPI/4.0 + eps && y > x + 5.0*ONEPI/4.0 + eps) {
+ capmap.cn = (north_square + 3) % 4;
+ } else {
+ capmap.cn = north_square;
+ }
+ } else if (capmap.region == CapMap<T>::south) {
+ if (y <= x + ONEPI/4.0 + eps && y > -1*x - 5.0*ONEPI/4 + eps) {
+ capmap.cn = (south_square + 1) % 4;
+ } else if (y < x + ONEPI/4.0 - eps && y <= -1*x - 5.0*ONEPI/4.0 + eps) {
+ capmap.cn = (south_square + 2) % 4;
+ } else if (y >= x + ONEPI/4.0 - eps && y < -1*x - 5.0*ONEPI/4.0 - eps) {
+ capmap.cn = (south_square + 3) % 4;
+ } else {
+ capmap.cn = south_square;
+ }
+ }
+ return capmap;
+ }
+ }
+ /**
+ * Rearrange point (x, y) in the HEALPix projection by
+ * combining the polar caps into two polar squares.
+ * Put the north polar square in position north_square and
+ * the south polar square in position south_square.
+ * If inverse=1, then uncombine the polar caps.
+ * @param north_square integer between 0 and 3.
+ * @param south_square integer between 0 and 3.
+ **/
+ template <typename T>
+ inline void combine_caps(T& xy_x, T& xy_y, int north_square, int south_square,
+ int inverse)
+ {
+ static const T ONEPI = detail::ONEPI<T>();
+
+ T v[2];
+ T a[2];
+ T vector[2];
+ T v_min_c[2];
+ T ret_dot[2];
+ CapMap<T> capmap = get_cap(xy_x, xy_y, north_square, south_square, inverse);
+ if (capmap.region == CapMap<T>::equatorial) {
+ xy_x = capmap.x;
+ xy_y = capmap.y;
+ return;
+ }
+ v[0] = xy_x;
+ v[1] = xy_y;
+ if (inverse == 0) {
+ /* Rotate (xy_x, xy_y) about its polar cap tip and then translate it to
+ north_square or south_square. */
+ int pole = 0;
+ T (*tmpRot)[2];
+ T c[2] = {capmap.x, capmap.y};
+ if (capmap.region == CapMap<T>::north) {
+ pole = north_square;
+ a[0] = (-3.0*ONEPI/4.0 + pole*ONEPI/2);
+ a[1] = (ONEPI/2.0 + pole*0);
+ tmpRot = rot[get_rotate_index(capmap.cn - pole)];
+ vector_sub(v, c, v_min_c);
+ dot_product(tmpRot, v_min_c, ret_dot);
+ vector_add(ret_dot, a, vector);
+ } else {
+ pole = south_square;
+ a[0] = (-3.0*ONEPI/4.0 + pole*ONEPI/2);
+ a[1] = (ONEPI/-2.0 + pole*0);
+ tmpRot = rot[get_rotate_index(-1*(capmap.cn - pole))];
+ vector_sub(v, c, v_min_c);
+ dot_product(tmpRot, v_min_c, ret_dot);
+ vector_add(ret_dot, a, vector);
+ }
+ xy_x = vector[0];
+ xy_y = vector[1];
+ return;
+ } else {
+ /* Inverse function.
+ Unrotate (xy_x, xy_y) and then translate it back. */
+ int pole = 0;
+ T (*tmpRot)[2];
+ T c[2] = {capmap.x, capmap.y};
+ /* disassemble */
+ if (capmap.region == CapMap<T>::north) {
+ pole = north_square;
+ a[0] = (-3.0*ONEPI/4.0 + capmap.cn*ONEPI/2);
+ a[1] = (ONEPI/2.0 + capmap.cn*0);
+ tmpRot = rot[get_rotate_index(-1*(capmap.cn - pole))];
+ vector_sub(v, c, v_min_c);
+ dot_product(tmpRot, v_min_c, ret_dot);
+ vector_add(ret_dot, a, vector);
+ } else {
+ pole = south_square;
+ a[0] = (-3.0*ONEPI/4.0 + capmap.cn*ONEPI/2);
+ a[1] = (ONEPI/-2.0 + capmap.cn*0);
+ tmpRot = rot[get_rotate_index(capmap.cn - pole)];
+ vector_sub(v, c, v_min_c);
+ dot_product(tmpRot, v_min_c, ret_dot);
+ vector_add(ret_dot, a, vector);
+ }
+ xy_x = vector[0];
+ xy_y = vector[1];
+ return;
+ }
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_healpix_ellipsoid : public base_t_fi<base_healpix_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_healpix<CalculationType> m_proj_parm;
+
+ inline base_healpix_ellipsoid(const Parameters& par)
+ : base_t_fi<base_healpix_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_healpix_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 0);
+ return healpix_sphere(lp_lon, lp_lat, xy_x, xy_y);
+ }
+
+ // INVERSE(e_healpix_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ /* Check whether (x, y) lies in the HEALPix image. */
+ if (in_image(xy_x, xy_y, 0, 0, 0) == 0) {
+ lp_lon = HUGE_VAL;
+ lp_lat = HUGE_VAL;
+ BOOST_THROW_EXCEPTION( projection_exception(-15) );
+ }
+ healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat);
+ lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 1);
+ }
+
+ static inline std::string get_name()
+ {
+ return "healpix_ellipsoid";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_healpix_spheroid : public base_t_fi<base_healpix_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_healpix<CalculationType> m_proj_parm;
+
+ inline base_healpix_spheroid(const Parameters& par)
+ : base_t_fi<base_healpix_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_healpix_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ return healpix_sphere(lp_lon, lp_lat, xy_x, xy_y);
+ }
+
+ // INVERSE(s_healpix_inverse) sphere
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ /* Check whether (x, y) lies in the HEALPix image */
+ if (in_image(xy_x, xy_y, 0, 0, 0) == 0) {
+ lp_lon = HUGE_VAL;
+ lp_lat = HUGE_VAL;
+ BOOST_THROW_EXCEPTION( projection_exception(-15) );
+ }
+ return healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat);
+ }
+
+ static inline std::string get_name()
+ {
+ return "healpix_spheroid";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_rhealpix_ellipsoid : public base_t_fi<base_rhealpix_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_healpix<CalculationType> m_proj_parm;
+
+ inline base_rhealpix_ellipsoid(const Parameters& par)
+ : base_t_fi<base_rhealpix_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_rhealpix_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 0);
+ healpix_sphere(lp_lon, lp_lat, xy_x, xy_y);
+ combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 0);
+ }
+
+ // INVERSE(e_rhealpix_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ /* Check whether (x, y) lies in the rHEALPix image. */
+ if (in_image(xy_x, xy_y, 1, this->m_proj_parm.north_square, this->m_proj_parm.south_square) == 0) {
+ lp_lon = HUGE_VAL;
+ lp_lat = HUGE_VAL;
+ BOOST_THROW_EXCEPTION( projection_exception(-15) );
+ }
+ combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 1);
+ healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat);
+ lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 1);
+ }
+
+ static inline std::string get_name()
+ {
+ return "rhealpix_ellipsoid";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_rhealpix_spheroid : public base_t_fi<base_rhealpix_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_healpix<CalculationType> m_proj_parm;
+
+ inline base_rhealpix_spheroid(const Parameters& par)
+ : base_t_fi<base_rhealpix_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_rhealpix_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ healpix_sphere(lp_lon, lp_lat, xy_x, xy_y);
+ combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 0);
+ }
+
+ // INVERSE(s_rhealpix_inverse) sphere
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ /* Check whether (x, y) lies in the rHEALPix image. */
+ if (in_image(xy_x, xy_y, 1, this->m_proj_parm.north_square, this->m_proj_parm.south_square) == 0) {
+ lp_lon = HUGE_VAL;
+ lp_lat = HUGE_VAL;
+ BOOST_THROW_EXCEPTION( projection_exception(-15) );
+ }
+ combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 1);
+ return healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat);
+ }
+
+ static inline std::string get_name()
+ {
+ return "rhealpix_spheroid";
+ }
+
+ };
+
+ // HEALPix
+ template <typename Parameters, typename T>
+ inline void setup_healpix(Parameters& par, par_healpix<T>& proj_parm)
+ {
+ if (par.es) {
+ pj_authset(par.es, proj_parm.apa); /* For auth_lat(). */
+ proj_parm.qp = pj_qsfn(1.0, par.e, par.one_es); /* For auth_lat(). */
+ par.a = par.a*sqrt(0.5*proj_parm.qp); /* Set par.a to authalic radius. */
+ par.ra = 1.0/par.a;
+ } else {
+ }
+ }
+
+ // rHEALPix
+ template <typename Parameters, typename T>
+ inline void setup_rhealpix(Parameters& par, par_healpix<T>& proj_parm)
+ {
+ proj_parm.north_square = pj_param(par.params,"inorth_square").i;
+ proj_parm.south_square = pj_param(par.params,"isouth_square").i;
+ /* Check for valid north_square and south_square inputs. */
+ if (proj_parm.north_square < 0 || proj_parm.north_square > 3) {
+ BOOST_THROW_EXCEPTION( projection_exception(-47) );
+ }
+ if (proj_parm.south_square < 0 || proj_parm.south_square > 3) {
+ BOOST_THROW_EXCEPTION( projection_exception(-47) );
+ }
+ if (par.es) {
+ pj_authset(par.es, proj_parm.apa); /* For auth_lat(). */
+ proj_parm.qp = pj_qsfn(1.0, par.e, par.one_es); /* For auth_lat(). */
+ par.a = par.a*sqrt(0.5*proj_parm.qp); /* Set par.a to authalic radius. */
+ par.ra = 1.0/par.a;
+ } else {
+ }
+ }
+
+ }} // namespace detail::healpix
+ #endif // doxygen
+
+ /*!
+ \brief HEALPix projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_healpix.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct healpix_ellipsoid : public detail::healpix::base_healpix_ellipsoid<CalculationType, Parameters>
+ {
+ inline healpix_ellipsoid(const Parameters& par) : detail::healpix::base_healpix_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::healpix::setup_healpix(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief HEALPix projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_healpix.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct healpix_spheroid : public detail::healpix::base_healpix_spheroid<CalculationType, Parameters>
+ {
+ inline healpix_spheroid(const Parameters& par) : detail::healpix::base_healpix_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::healpix::setup_healpix(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief rHEALPix projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - north_square (integer)
+ - south_square (integer)
+ \par Example
+ \image html ex_rhealpix.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct rhealpix_ellipsoid : public detail::healpix::base_rhealpix_ellipsoid<CalculationType, Parameters>
+ {
+ inline rhealpix_ellipsoid(const Parameters& par) : detail::healpix::base_rhealpix_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::healpix::setup_rhealpix(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief rHEALPix projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - north_square (integer)
+ - south_square (integer)
+ \par Example
+ \image html ex_rhealpix.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct rhealpix_spheroid : public detail::healpix::base_rhealpix_spheroid<CalculationType, Parameters>
+ {
+ inline rhealpix_spheroid(const Parameters& par) : detail::healpix::base_rhealpix_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::healpix::setup_rhealpix(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::healpix, healpix_spheroid, healpix_ellipsoid)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::rhealpix, rhealpix_spheroid, rhealpix_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class healpix_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<healpix_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ else
+ return new base_v_fi<healpix_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class rhealpix_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<rhealpix_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ else
+ return new base_v_fi<rhealpix_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void healpix_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("healpix", new healpix_entry<CalculationType, Parameters>);
+ factory.add_to_factory("rhealpix", new rhealpix_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_HEALPIX_HPP
+
diff --git a/boost/geometry/srs/projections/proj/igh.hpp b/boost/geometry/srs/projections/proj/igh.hpp
new file mode 100644
index 0000000000..219f74239e
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/igh.hpp
@@ -0,0 +1,377 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IGH_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IGH_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/proj/gn_sinu.hpp>
+#include <boost/geometry/srs/projections/proj/moll.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct igh {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace igh
+ {
+
+ template <typename CalculationType, typename Parameters>
+ struct par_igh
+ {
+ boost::shared_ptr<base_v<CalculationType, Parameters> > pj[12];
+ CalculationType dy0;
+ };
+
+ template <typename T>
+ inline T d4044118() { return (T(40) + T(44)/T(60.) + T(11.8)/T(3600.)) * geometry::math::d2r<T>(); } // 40d 44' 11.8" [degrees]
+
+ template <typename T>
+ inline T d10() { return T(10) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T d20() { return T(20) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T d30() { return T(30) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T d40() { return T(40) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T d50() { return T(50) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T d60() { return T(60) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T d80() { return T(80) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T d90() { return T(90) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T d100() { return T(100) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T d140() { return T(140) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T d160() { return T(160) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T d180() { return T(180) * geometry::math::d2r<T>(); }
+
+ static const double EPSLN = 1.e-10; // allow a little 'slack' on zone edge positions
+
+ // Converted from #define SETUP(n, proj, x_0, y_0, lon_0)
+ template <template <typename, typename> class Entry, typename Parameters, typename CalculationType>
+ inline void do_setup(int n, Parameters const& par, par_igh<CalculationType, Parameters>& proj_parm,
+ CalculationType const& x_0, CalculationType const& y_0,
+ CalculationType const& lon_0)
+ {
+ Entry<CalculationType, Parameters> entry;
+ proj_parm.pj[n-1].reset(entry.create_new(par));
+ proj_parm.pj[n-1]->mutable_params().x0 = x_0;
+ proj_parm.pj[n-1]->mutable_params().y0 = y_0;
+ proj_parm.pj[n-1]->mutable_params().lam0 = lon_0;
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_igh_spheroid : public base_t_fi<base_igh_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_igh<CalculationType, Parameters> m_proj_parm;
+
+ inline base_igh_spheroid(const Parameters& par)
+ : base_t_fi<base_igh_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType d4044118 = igh::d4044118<CalculationType>();
+ static const CalculationType d20 = igh::d20<CalculationType>();
+ static const CalculationType d40 = igh::d40<CalculationType>();
+ static const CalculationType d80 = igh::d80<CalculationType>();
+ static const CalculationType d100 = igh::d100<CalculationType>();
+
+ int z;
+ if (lp_lat >= d4044118) { // 1|2
+ z = (lp_lon <= -d40 ? 1: 2);
+ }
+ else if (lp_lat >= 0) { // 3|4
+ z = (lp_lon <= -d40 ? 3: 4);
+ }
+ else if (lp_lat >= -d4044118) { // 5|6|7|8
+ if (lp_lon <= -d100) z = 5; // 5
+ else if (lp_lon <= -d20) z = 6; // 6
+ else if (lp_lon <= d80) z = 7; // 7
+ else z = 8; // 8
+ }
+ else { // 9|10|11|12
+ if (lp_lon <= -d100) z = 9; // 9
+ else if (lp_lon <= -d20) z = 10; // 10
+ else if (lp_lon <= d80) z = 11; // 11
+ else z = 12; // 12
+ }
+
+ lp_lon -= this->m_proj_parm.pj[z-1]->params().lam0;
+ this->m_proj_parm.pj[z-1]->fwd(lp_lon, lp_lat, xy_x, xy_y);
+ xy_x += this->m_proj_parm.pj[z-1]->params().x0;
+ xy_y += this->m_proj_parm.pj[z-1]->params().y0;
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType d4044118 = igh::d4044118<CalculationType>();
+ static const CalculationType d10 = igh::d10<CalculationType>();
+ static const CalculationType d20 = igh::d20<CalculationType>();
+ static const CalculationType d40 = igh::d40<CalculationType>();
+ static const CalculationType d50 = igh::d50<CalculationType>();
+ static const CalculationType d60 = igh::d60<CalculationType>();
+ static const CalculationType d80 = igh::d80<CalculationType>();
+ static const CalculationType d90 = igh::d90<CalculationType>();
+ static const CalculationType d100 = igh::d100<CalculationType>();
+ static const CalculationType d160 = igh::d160<CalculationType>();
+ static const CalculationType d180 = igh::d180<CalculationType>();
+
+ static const CalculationType c2 = 2.0;
+
+ const CalculationType y90 = this->m_proj_parm.dy0 + sqrt(c2); // lt=90 corresponds to y=y0+sqrt(2.0)
+
+ int z = 0;
+ if (xy_y > y90+EPSLN || xy_y < -y90+EPSLN) // 0
+ z = 0;
+ else if (xy_y >= d4044118) // 1|2
+ z = (xy_x <= -d40? 1: 2);
+ else if (xy_y >= 0) // 3|4
+ z = (xy_x <= -d40? 3: 4);
+ else if (xy_y >= -d4044118) { // 5|6|7|8
+ if (xy_x <= -d100) z = 5; // 5
+ else if (xy_x <= -d20) z = 6; // 6
+ else if (xy_x <= d80) z = 7; // 7
+ else z = 8; // 8
+ }
+ else { // 9|10|11|12
+ if (xy_x <= -d100) z = 9; // 9
+ else if (xy_x <= -d20) z = 10; // 10
+ else if (xy_x <= d80) z = 11; // 11
+ else z = 12; // 12
+ }
+
+ if (z)
+ {
+ int ok = 0;
+
+ xy_x -= this->m_proj_parm.pj[z-1]->params().x0;
+ xy_y -= this->m_proj_parm.pj[z-1]->params().y0;
+ this->m_proj_parm.pj[z-1]->inv(xy_x, xy_y, lp_lon, lp_lat);
+ lp_lon += this->m_proj_parm.pj[z-1]->params().lam0;
+
+ switch (z) {
+ case 1: ok = (lp_lon >= -d180-EPSLN && lp_lon <= -d40+EPSLN) ||
+ ((lp_lon >= -d40-EPSLN && lp_lon <= -d10+EPSLN) &&
+ (lp_lat >= d60-EPSLN && lp_lat <= d90+EPSLN)); break;
+ case 2: ok = (lp_lon >= -d40-EPSLN && lp_lon <= d180+EPSLN) ||
+ ((lp_lon >= -d180-EPSLN && lp_lon <= -d160+EPSLN) &&
+ (lp_lat >= d50-EPSLN && lp_lat <= d90+EPSLN)) ||
+ ((lp_lon >= -d50-EPSLN && lp_lon <= -d40+EPSLN) &&
+ (lp_lat >= d60-EPSLN && lp_lat <= d90+EPSLN)); break;
+ case 3: ok = (lp_lon >= -d180-EPSLN && lp_lon <= -d40+EPSLN); break;
+ case 4: ok = (lp_lon >= -d40-EPSLN && lp_lon <= d180+EPSLN); break;
+ case 5: ok = (lp_lon >= -d180-EPSLN && lp_lon <= -d100+EPSLN); break;
+ case 6: ok = (lp_lon >= -d100-EPSLN && lp_lon <= -d20+EPSLN); break;
+ case 7: ok = (lp_lon >= -d20-EPSLN && lp_lon <= d80+EPSLN); break;
+ case 8: ok = (lp_lon >= d80-EPSLN && lp_lon <= d180+EPSLN); break;
+ case 9: ok = (lp_lon >= -d180-EPSLN && lp_lon <= -d100+EPSLN); break;
+ case 10: ok = (lp_lon >= -d100-EPSLN && lp_lon <= -d20+EPSLN); break;
+ case 11: ok = (lp_lon >= -d20-EPSLN && lp_lon <= d80+EPSLN); break;
+ case 12: ok = (lp_lon >= d80-EPSLN && lp_lon <= d180+EPSLN); break;
+ }
+
+ z = (!ok? 0: z); // projectable?
+ }
+ // if (!z) pj_errno = -15; // invalid x or y
+ if (!z) lp_lon = HUGE_VAL;
+ if (!z) lp_lat = HUGE_VAL;
+ }
+
+ static inline std::string get_name()
+ {
+ return "igh_spheroid";
+ }
+
+ };
+
+ // Interrupted Goode Homolosine
+ template <typename CalculationType, typename Parameters>
+ inline void setup_igh(Parameters& par, par_igh<CalculationType, Parameters>& proj_parm)
+ {
+ static const CalculationType d0 = 0;
+ static const CalculationType d4044118 = igh::d4044118<CalculationType>();
+ static const CalculationType d20 = igh::d20<CalculationType>();
+ static const CalculationType d30 = igh::d30<CalculationType>();
+ static const CalculationType d60 = igh::d60<CalculationType>();
+ static const CalculationType d100 = igh::d100<CalculationType>();
+ static const CalculationType d140 = igh::d140<CalculationType>();
+ static const CalculationType d160 = igh::d160<CalculationType>();
+
+ /*
+ Zones:
+
+ -180 -40 180
+ +--------------+-------------------------+ Zones 1,2,9,10,11 & 12:
+ |1 |2 | Mollweide projection
+ | | |
+ +--------------+-------------------------+ Zones 3,4,5,6,7 & 8:
+ |3 |4 | Sinusoidal projection
+ | | |
+ 0 +-------+------+-+-----------+-----------+
+ |5 |6 |7 |8 |
+ | | | | |
+ +-------+--------+-----------+-----------+
+ |9 |10 |11 |12 |
+ | | | | |
+ +-------+--------+-----------+-----------+
+ -180 -100 -20 80 180
+ */
+
+
+ CalculationType lp_lam = 0, lp_phi = d4044118;
+ CalculationType xy1_x, xy1_y;
+ CalculationType xy3_x, xy3_y;
+
+ // sinusoidal zones
+ do_setup<sinu_entry>(3, par, proj_parm, -d100, d0, -d100);
+ do_setup<sinu_entry>(4, par, proj_parm, d30, d0, d30);
+ do_setup<sinu_entry>(5, par, proj_parm, -d160, d0, -d160);
+ do_setup<sinu_entry>(6, par, proj_parm, -d60, d0, -d60);
+ do_setup<sinu_entry>(7, par, proj_parm, d20, d0, d20);
+ do_setup<sinu_entry>(8, par, proj_parm, d140, d0, d140);
+
+ // mollweide zones
+ do_setup<moll_entry>(1, par, proj_parm, -d100, d0, -d100);
+
+ // y0 ?
+ proj_parm.pj[0]->fwd(lp_lam, lp_phi, xy1_x, xy1_y); // zone 1
+ proj_parm.pj[2]->fwd(lp_lam, lp_phi, xy3_x, xy3_y); // zone 3
+ // y0 + xy1_y = xy3_y for lt = 40d44'11.8"
+ proj_parm.dy0 = xy3_y - xy1_y;
+
+ proj_parm.pj[0]->mutable_params().y0 = proj_parm.dy0;
+
+ // mollweide zones (cont'd)
+ do_setup<moll_entry>( 2, par, proj_parm, d30, proj_parm.dy0, d30);
+ do_setup<moll_entry>( 9, par, proj_parm, -d160, -proj_parm.dy0, -d160);
+ do_setup<moll_entry>(10, par, proj_parm, -d60, -proj_parm.dy0, -d60);
+ do_setup<moll_entry>(11, par, proj_parm, d20, -proj_parm.dy0, d20);
+ do_setup<moll_entry>(12, par, proj_parm, d140, -proj_parm.dy0, d140);
+
+ par.es = 0.;
+ }
+
+ }} // namespace detail::igh
+ #endif // doxygen
+
+ /*!
+ \brief Interrupted Goode Homolosine projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_igh.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct igh_spheroid : public detail::igh::base_igh_spheroid<CalculationType, Parameters>
+ {
+ inline igh_spheroid(const Parameters& par) : detail::igh::base_igh_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::igh::setup_igh(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::igh, igh_spheroid, igh_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class igh_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<igh_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void igh_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("igh", new igh_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IGH_HPP
+
diff --git a/boost/geometry/srs/projections/proj/imw_p.hpp b/boost/geometry/srs/projections/proj/imw_p.hpp
new file mode 100644
index 0000000000..1a7fe9e915
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/imw_p.hpp
@@ -0,0 +1,320 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct imw_p {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace imw_p
+ {
+
+ static const double TOL = 1e-10;
+ static const double EPS = 1e-10;
+
+ template <typename T>
+ struct XY { T x, y; }; // specific for IMW_P
+
+ template <typename T>
+ struct par_imw_p
+ {
+ T P, Pp, Q, Qp, R_1, R_2, sphi_1, sphi_2, C2;
+ T phi_1, phi_2, lam_1;
+ T en[EN_SIZE];
+ int mode; /* = 0, phi_1 and phi_2 != 0, = 1, phi_1 = 0, = -1 phi_2 = 0 */
+ };
+
+ template <typename Parameters, typename T>
+ inline int
+ phi12(Parameters& par, par_imw_p<T>& proj_parm, T *del, T *sig)
+ {
+ int err = 0;
+
+ if (!pj_param(par.params, "tlat_1").i ||
+ !pj_param(par.params, "tlat_2").i) {
+ err = -41;
+ } else {
+ proj_parm.phi_1 = pj_param(par.params, "rlat_1").f;
+ proj_parm.phi_2 = pj_param(par.params, "rlat_2").f;
+ *del = 0.5 * (proj_parm.phi_2 - proj_parm.phi_1);
+ *sig = 0.5 * (proj_parm.phi_2 + proj_parm.phi_1);
+ err = (fabs(*del) < EPS || fabs(*sig) < EPS) ? -42 : 0;
+ }
+ return err;
+ }
+ template <typename Parameters, typename T>
+ inline XY<T>
+ loc_for(T const& lp_lam, T const& lp_phi, Parameters const& par, par_imw_p<T> const& proj_parm, T *yc)
+ {
+ XY<T> xy;
+
+ if (! lp_phi) {
+ xy.x = lp_lam;
+ xy.y = 0.;
+ } else {
+ T xa, ya, xb, yb, xc, D, B, m, sp, t, R, C;
+
+ sp = sin(lp_phi);
+ m = pj_mlfn(lp_phi, sp, cos(lp_phi), proj_parm.en);
+ xa = proj_parm.Pp + proj_parm.Qp * m;
+ ya = proj_parm.P + proj_parm.Q * m;
+ R = 1. / (tan(lp_phi) * sqrt(1. - par.es * sp * sp));
+ C = sqrt(R * R - xa * xa);
+ if (lp_phi < 0.) C = - C;
+ C += ya - R;
+ if (proj_parm.mode < 0) {
+ xb = lp_lam;
+ yb = proj_parm.C2;
+ } else {
+ t = lp_lam * proj_parm.sphi_2;
+ xb = proj_parm.R_2 * sin(t);
+ yb = proj_parm.C2 + proj_parm.R_2 * (1. - cos(t));
+ }
+ if (proj_parm.mode > 0) {
+ xc = lp_lam;
+ *yc = 0.;
+ } else {
+ t = lp_lam * proj_parm.sphi_1;
+ xc = proj_parm.R_1 * sin(t);
+ *yc = proj_parm.R_1 * (1. - cos(t));
+ }
+ D = (xb - xc)/(yb - *yc);
+ B = xc + D * (C + R - *yc);
+ xy.x = D * sqrt(R * R * (1 + D * D) - B * B);
+ if (lp_phi > 0)
+ xy.x = - xy.x;
+ xy.x = (B + xy.x) / (1. + D * D);
+ xy.y = sqrt(R * R - xy.x * xy.x);
+ if (lp_phi > 0)
+ xy.y = - xy.y;
+ xy.y += C + R;
+ }
+ return (xy);
+ }
+ template <typename Parameters, typename T>
+ inline void
+ xy(Parameters const& par, par_imw_p<T> const& proj_parm, T const& phi, T *x, T *y, T *sp, T *R)
+ {
+ T F;
+
+ *sp = sin(phi);
+ *R = 1./(tan(phi) * sqrt(1. - par.es * *sp * *sp ));
+ F = proj_parm.lam_1 * *sp;
+ *y = *R * (1 - cos(F));
+ *x = *R * sin(F);
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_imw_p_ellipsoid : public base_t_fi<base_imw_p_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_imw_p<CalculationType> m_proj_parm;
+
+ inline base_imw_p_ellipsoid(const Parameters& par)
+ : base_t_fi<base_imw_p_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType yc = 0;
+ XY<CalculationType> xy = loc_for(lp_lon, lp_lat, this->m_par, m_proj_parm, &yc);
+ xy_x = xy.x; xy_y = xy.y;
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ XY<CalculationType> t;
+ CalculationType yc = 0;
+
+ lp_lat = this->m_proj_parm.phi_2;
+ lp_lon = xy_x / cos(lp_lat);
+ do {
+ t = loc_for(lp_lon, lp_lat, this->m_par, m_proj_parm, &yc);
+ lp_lat = ((lp_lat - this->m_proj_parm.phi_1) * (xy_y - yc) / (t.y - yc)) + this->m_proj_parm.phi_1;
+ lp_lon = lp_lon * xy_x / t.x;
+ } while (fabs(t.x - xy_x) > TOL || fabs(t.y - xy_y) > TOL);
+ }
+
+ static inline std::string get_name()
+ {
+ return "imw_p_ellipsoid";
+ }
+
+ };
+
+ // International Map of the World Polyconic
+ template <typename Parameters, typename T>
+ inline void setup_imw_p(Parameters& par, par_imw_p<T>& proj_parm)
+ {
+ T del, sig, s, t, x1, x2, T2, y1, m1, m2, y2;
+ int i;
+
+ if (!pj_enfn(par.es, proj_parm.en))
+ BOOST_THROW_EXCEPTION( projection_exception(0) );
+ if( (i = phi12(par, proj_parm, &del, &sig)) != 0)
+ BOOST_THROW_EXCEPTION( projection_exception(i) );
+ if (proj_parm.phi_2 < proj_parm.phi_1) { /* make sure proj_parm.phi_1 most southerly */
+ del = proj_parm.phi_1;
+ proj_parm.phi_1 = proj_parm.phi_2;
+ proj_parm.phi_2 = del;
+ }
+ if (pj_param(par.params, "tlon_1").i)
+ proj_parm.lam_1 = pj_param(par.params, "rlon_1").f;
+ else { /* use predefined based upon latitude */
+ sig = fabs(sig * geometry::math::r2d<T>());
+ if (sig <= 60) sig = 2.;
+ else if (sig <= 76) sig = 4.;
+ else sig = 8.;
+ proj_parm.lam_1 = sig * geometry::math::d2r<T>();
+ }
+ proj_parm.mode = 0;
+ if (proj_parm.phi_1) xy(par, proj_parm, proj_parm.phi_1, &x1, &y1, &proj_parm.sphi_1, &proj_parm.R_1);
+ else {
+ proj_parm.mode = 1;
+ y1 = 0.;
+ x1 = proj_parm.lam_1;
+ }
+ if (proj_parm.phi_2) xy(par, proj_parm, proj_parm.phi_2, &x2, &T2, &proj_parm.sphi_2, &proj_parm.R_2);
+ else {
+ proj_parm.mode = -1;
+ T2 = 0.;
+ x2 = proj_parm.lam_1;
+ }
+ m1 = pj_mlfn(proj_parm.phi_1, proj_parm.sphi_1, cos(proj_parm.phi_1), proj_parm.en);
+ m2 = pj_mlfn(proj_parm.phi_2, proj_parm.sphi_2, cos(proj_parm.phi_2), proj_parm.en);
+ t = m2 - m1;
+ s = x2 - x1;
+ y2 = sqrt(t * t - s * s) + y1;
+ proj_parm.C2 = y2 - T2;
+ t = 1. / t;
+ proj_parm.P = (m2 * y1 - m1 * y2) * t;
+ proj_parm.Q = (y2 - y1) * t;
+ proj_parm.Pp = (m2 * x1 - m1 * x2) * t;
+ proj_parm.Qp = (x2 - x1) * t;
+ }
+
+ }} // namespace detail::imw_p
+ #endif // doxygen
+
+ /*!
+ \brief International Map of the World Polyconic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Mod. Polyconic
+ - Ellipsoid
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel
+ - lat_2: Latitude of second standard parallel
+ - lon_1 (degrees)
+ \par Example
+ \image html ex_imw_p.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct imw_p_ellipsoid : public detail::imw_p::base_imw_p_ellipsoid<CalculationType, Parameters>
+ {
+ inline imw_p_ellipsoid(const Parameters& par) : detail::imw_p::base_imw_p_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::imw_p::setup_imw_p(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::imw_p, imw_p_ellipsoid, imw_p_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class imw_p_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<imw_p_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void imw_p_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("imw_p", new imw_p_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP
+
diff --git a/boost/geometry/srs/projections/proj/isea.hpp b/boost/geometry/srs/projections/proj/isea.hpp
new file mode 100644
index 0000000000..4cffbc430f
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/isea.hpp
@@ -0,0 +1,1311 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ISEA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ISEA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// This code was entirely written by Nathan Wagner
+// and is in the public domain.
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <sstream>
+
+#include <boost/core/ignore_unused.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct isea {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace isea
+ {
+
+ static const double E = 52.62263186;
+ static const double F = 10.81231696;
+ //static const double DEG60 = 1.04719755119659774614;
+ //static const double DEG120 = 2.09439510239319549229;
+ //static const double DEG72 = 1.25663706143591729537;
+ //static const double DEG90 = 1.57079632679489661922;
+ //static const double DEG144 = 2.51327412287183459075;
+ //static const double DEG36 = 0.62831853071795864768;
+ //static const double DEG108 = 1.88495559215387594306;
+ //static const double DEG180 = geometry::math::pi<double>();
+ static const double ISEA_SCALE = 0.8301572857837594396028083;
+ static const double V_LAT = 0.46364760899944494524;
+ static const double E_RAD = 0.91843818702186776133;
+ static const double F_RAD = 0.18871053072122403508;
+ static const double TABLE_G = 0.6615845383;
+ static const double TABLE_H = 0.1909830056;
+ static const double RPRIME = 0.91038328153090290025;
+ static const double PRECISION = 0.0000000000005;
+ static const double ISEA_STD_LAT = 1.01722196792335072101;
+ static const double ISEA_STD_LON = .19634954084936207740;
+
+ template <typename T>
+ inline T DEG30() { return T(30) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T DEG60() { return T(60) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T DEG120() { return T(120) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T DEG72() { return T(72) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T DEG90() { return geometry::math::half_pi<T>(); }
+ template <typename T>
+ inline T DEG144() { return T(144) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T DEG36() { return T(36) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T DEG108() { return T(108) * geometry::math::d2r<T>(); }
+ template <typename T>
+ inline T DEG180() { return geometry::math::pi<T>(); }
+
+ inline bool DOWNTRI(int tri) { return (((tri - 1) / 5) % 2 == 1); }
+
+ /*
+ * Proj 4 provides its own entry points into
+ * the code, so none of the library functions
+ * need to be global
+ */
+
+ struct hex {
+ int iso;
+ int x, y, z;
+ };
+
+ /* y *must* be positive down as the xy /iso conversion assumes this */
+ inline
+ int hex_xy(struct hex *h) {
+ if (!h->iso) return 1;
+ if (h->x >= 0) {
+ h->y = -h->y - (h->x+1)/2;
+ } else {
+ /* need to round toward -inf, not toward zero, so x-1 */
+ h->y = -h->y - h->x/2;
+ }
+ h->iso = 0;
+
+ return 1;
+ }
+
+ inline
+ int hex_iso(struct hex *h) {
+ if (h->iso) return 1;
+
+ if (h->x >= 0) {
+ h->y = (-h->y - (h->x+1)/2);
+ } else {
+ /* need to round toward -inf, not toward zero, so x-1 */
+ h->y = (-h->y - (h->x)/2);
+ }
+
+ h->z = -h->x - h->y;
+ h->iso = 1;
+ return 1;
+ }
+
+ template <typename T>
+ inline
+ int hexbin2(T const& width, T x, T y,
+ int *i, int *j) {
+ T z, rx, ry, rz;
+ T abs_dx, abs_dy, abs_dz;
+ int ix, iy, iz, s;
+ struct hex h;
+
+ x = x / cos(DEG30<T>()); /* rotated X coord */
+ y = y - x / 2.0; /* adjustment for rotated X */
+
+ /* adjust for actual hexwidth */
+ x /= width;
+ y /= width;
+
+ z = -x - y;
+
+ rx = floor(x + 0.5);
+ ix = (int)rx;
+ ry = floor(y + 0.5);
+ iy = (int)ry;
+ rz = floor(z + 0.5);
+ iz = (int)rz;
+
+ s = ix + iy + iz;
+
+ if (s) {
+ abs_dx = fabs(rx - x);
+ abs_dy = fabs(ry - y);
+ abs_dz = fabs(rz - z);
+
+ if (abs_dx >= abs_dy && abs_dx >= abs_dz) {
+ ix -= s;
+ } else if (abs_dy >= abs_dx && abs_dy >= abs_dz) {
+ iy -= s;
+ } else {
+ iz -= s;
+ }
+ }
+ h.x = ix;
+ h.y = iy;
+ h.z = iz;
+ h.iso = 1;
+
+ hex_xy(&h);
+ *i = h.x;
+ *j = h.y;
+ return ix * 100 + iy;
+ }
+
+ enum isea_poly { ISEA_NONE, ISEA_ICOSAHEDRON = 20 };
+ enum isea_topology { ISEA_HEXAGON=6, ISEA_TRIANGLE=3, ISEA_DIAMOND=4 };
+ enum isea_address_form { ISEA_GEO, ISEA_Q2DI, ISEA_SEQNUM, ISEA_INTERLEAVE,
+ ISEA_PLANE, ISEA_Q2DD, ISEA_PROJTRI, ISEA_VERTEX2DD, ISEA_HEX
+ };
+
+ template <typename T>
+ struct isea_dgg {
+ int polyhedron; /* ignored, icosahedron */
+ T o_lat, o_lon, o_az; /* orientation, radians */
+ int pole; /* true if standard snyder */
+ int topology; /* ignored, hexagon */
+ int aperture; /* valid values depend on partitioning method */
+ int resolution;
+ T radius; /* radius of the earth in meters, ignored 1.0 */
+ int output; /* an isea_address_form */
+ int triangle; /* triangle of last transformed point */
+ int quad; /* quad of last transformed point */
+ unsigned long serial;
+ };
+
+ template <typename T>
+ struct isea_pt {
+ T x, y;
+ };
+
+ template <typename T>
+ struct isea_geo {
+ T lon, lat;
+ };
+
+ template <typename T>
+ struct isea_address {
+ int type; /* enum isea_address_form */
+ int number;
+ T x,y; /* or i,j or lon,lat depending on type */
+ };
+
+ /* ENDINC */
+
+ enum snyder_polyhedron {
+ SNYDER_POLY_HEXAGON, SNYDER_POLY_PENTAGON,
+ SNYDER_POLY_TETRAHEDRON, SNYDER_POLY_CUBE,
+ SNYDER_POLY_OCTAHEDRON, SNYDER_POLY_DODECAHEDRON,
+ SNYDER_POLY_ICOSAHEDRON
+ };
+
+ template <typename T>
+ struct snyder_constants {
+ T g, G, theta, ea_w, ea_a, ea_b, g_w, g_a, g_b;
+ };
+
+ template <typename T>
+ inline const snyder_constants<T> * constants()
+ {
+ /* TODO put these in radians to avoid a later conversion */
+ static snyder_constants<T> result[] = {
+ {23.80018260, 62.15458023, 60.0, 3.75, 1.033, 0.968, 5.09, 1.195, 1.0},
+ {20.07675127, 55.69063953, 54.0, 2.65, 1.030, 0.983, 3.59, 1.141, 1.027},
+ {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {37.37736814, 36.0, 30.0, 17.27, 1.163, 0.860, 13.14, 1.584, 1.0}
+ };
+ return result;
+ }
+
+
+ /* sqrt(5)/M_PI */
+
+ /* 26.565051177 degrees */
+
+
+ template <typename T>
+ inline const isea_geo<T> * vertex()
+ {
+ static isea_geo<T> result[] = {
+ {0.0, DEG90<T>()},
+ {DEG180<T>(), V_LAT},
+ {-DEG108<T>(), V_LAT},
+ {-DEG36<T>(), V_LAT},
+ {DEG36<T>(), V_LAT},
+ {DEG108<T>(), V_LAT},
+ {-DEG144<T>(), -V_LAT},
+ {-DEG72<T>(), -V_LAT},
+ {0.0, -V_LAT},
+ {DEG72<T>(), -V_LAT},
+ {DEG144<T>(), -V_LAT},
+ {0.0, -DEG90<T>()}
+ };
+ return result;
+ }
+
+ /* TODO make an isea_pt array of the vertices as well */
+
+ static int tri_v1[] = {0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 2, 3, 4, 5, 1, 11, 11, 11, 11, 11};
+
+ /* 52.62263186 */
+
+ /* 10.81231696 */
+
+ /* triangle Centers */
+ template <typename T>
+ inline const isea_geo<T> * icostriangles()
+ {
+ static isea_geo<T> result[] = {
+ {0.0, 0.0},
+ {-DEG144<T>(), E_RAD},
+ {-DEG72<T>(), E_RAD},
+ {0.0, E_RAD},
+ {DEG72<T>(), E_RAD},
+ {DEG144<T>(), E_RAD},
+ {-DEG144<T>(), F_RAD},
+ {-DEG72<T>(), F_RAD},
+ {0.0, F_RAD},
+ {DEG72<T>(), F_RAD},
+ {DEG144<T>(), F_RAD},
+ {-DEG108<T>(), -F_RAD},
+ {-DEG36<T>(), -F_RAD},
+ {DEG36<T>(), -F_RAD},
+ {DEG108<T>(), -F_RAD},
+ {DEG180<T>(), -F_RAD},
+ {-DEG108<T>(), -E_RAD},
+ {-DEG36<T>(), -E_RAD},
+ {DEG36<T>(), -E_RAD},
+ {DEG108<T>(), -E_RAD},
+ {DEG180<T>(), -E_RAD},
+ };
+ return result;
+ }
+
+ template <typename T>
+ inline T az_adjustment(int triangle)
+ {
+ T adj;
+
+ isea_geo<T> v;
+ isea_geo<T> c;
+
+ v = vertex<T>()[tri_v1[triangle]];
+ c = icostriangles<T>()[triangle];
+
+ /* TODO looks like the adjustment is always either 0 or 180 */
+ /* at least if you pick your vertex carefully */
+ adj = atan2(cos(v.lat) * sin(v.lon - c.lon),
+ cos(c.lat) * sin(v.lat)
+ - sin(c.lat) * cos(v.lat) * cos(v.lon - c.lon));
+ return adj;
+ }
+
+ /* R tan(g) sin(60) */
+
+ /* H = 0.25 R tan g = */
+
+
+ template <typename T>
+ inline isea_pt<T> isea_triangle_xy(int triangle)
+ {
+ isea_pt<T> c;
+ T Rprime = 0.91038328153090290025;
+
+ triangle = (triangle - 1) % 20;
+
+ c.x = TABLE_G * ((triangle % 5) - 2) * 2.0;
+ if (triangle > 9) {
+ c.x += TABLE_G;
+ }
+ switch (triangle / 5) {
+ case 0:
+ c.y = 5.0 * TABLE_H;
+ break;
+ case 1:
+ c.y = TABLE_H;
+ break;
+ case 2:
+ c.y = -TABLE_H;
+ break;
+ case 3:
+ c.y = -5.0 * TABLE_H;
+ break;
+ default:
+ /* should be impossible */
+ BOOST_THROW_EXCEPTION( projection_exception() );
+ };
+ c.x *= Rprime;
+ c.y *= Rprime;
+
+ return c;
+ }
+
+ /* snyder eq 14 */
+ template <typename T>
+ inline T sph_azimuth(T const& f_lon, T const& f_lat, T const& t_lon, T const& t_lat)
+ {
+ T az;
+
+ az = atan2(cos(t_lat) * sin(t_lon - f_lon),
+ cos(f_lat) * sin(t_lat)
+ - sin(f_lat) * cos(t_lat) * cos(t_lon - f_lon)
+ );
+ return az;
+ }
+
+ /* coord needs to be in radians */
+ template <typename T>
+ inline int isea_snyder_forward(isea_geo<T> * ll, isea_pt<T> * out)
+ {
+ int i;
+
+ /*
+ * spherical distance from center of polygon face to any of its
+ * vertexes on the globe
+ */
+ T g;
+
+ /*
+ * spherical angle between radius vector to center and adjacent edge
+ * of spherical polygon on the globe
+ */
+ T G;
+
+ /*
+ * plane angle between radius vector to center and adjacent edge of
+ * plane polygon
+ */
+ T theta;
+
+ /* additional variables from snyder */
+ T q, Rprime, H, Ag, Azprime, Az, dprime, f, rho,
+ x, y;
+
+ /* variables used to store intermediate results */
+ T cot_theta, tan_g, az_offset;
+
+ /* how many multiples of 60 degrees we adjust the azimuth */
+ int Az_adjust_multiples;
+
+ snyder_constants<T> c;
+
+ /*
+ * TODO by locality of reference, start by trying the same triangle
+ * as last time
+ */
+
+ /* TODO put these constants in as radians to begin with */
+ c = constants<T>()[SNYDER_POLY_ICOSAHEDRON];
+ theta = c.theta * geometry::math::d2r<T>();
+ g = c.g * geometry::math::d2r<T>();
+ G = c.G * geometry::math::d2r<T>();
+
+ for (i = 1; i <= 20; i++) {
+ T z;
+ isea_geo<T> center;
+
+ center = icostriangles<T>()[i];
+
+ /* step 1 */
+ #if 0
+ z = sph_distance(center.lon, center.lat, ll->lon, ll->lat);
+ #else
+ z = acos(sin(center.lat) * sin(ll->lat)
+ + cos(center.lat) * cos(ll->lat) * cos(ll->lon - center.lon));
+ #endif
+
+ /* not on this triangle */
+ if (z > g + 0.000005) { /* TODO DBL_EPSILON */
+ continue;
+ }
+ Az = sph_azimuth(ll->lon, ll->lat, center.lon, center.lat);
+
+ Az = atan2(cos(ll->lat) * sin(ll->lon - center.lon),
+ cos(center.lat) * sin(ll->lat)
+ - sin(center.lat) * cos(ll->lat) * cos(ll->lon - center.lon)
+ );
+
+ /* step 2 */
+
+ /* This calculates "some" vertex coordinate */
+ az_offset = az_adjustment<T>(i);
+
+ Az -= az_offset;
+
+ /* TODO I don't know why we do this. It's not in snyder */
+ /* maybe because we should have picked a better vertex */
+ if (Az < 0.0) {
+ Az += geometry::math::two_pi<T>();
+ }
+ /*
+ * adjust Az for the point to fall within the range of 0 to
+ * 2(90 - theta) or 60 degrees for the hexagon, by
+ * and therefore 120 degrees for the triangle
+ * of the icosahedron
+ * subtracting or adding multiples of 60 degrees to Az and
+ * recording the amount of adjustment
+ */
+
+ Az_adjust_multiples = 0;
+ while (Az < 0.0) {
+ Az += DEG120<T>();
+ Az_adjust_multiples--;
+ }
+ while (Az > DEG120<T>() + DBL_EPSILON) {
+ Az -= DEG120<T>();
+ Az_adjust_multiples++;
+ }
+
+ /* step 3 */
+ cot_theta = 1.0 / tan(theta);
+ tan_g = tan(g); /* TODO this is a constant */
+
+ /* Calculate q from eq 9. */
+ /* TODO cot_theta is cot(30) */
+ q = atan2(tan_g, cos(Az) + sin(Az) * cot_theta);
+
+ /* not in this triangle */
+ if (z > q + 0.000005) {
+ continue;
+ }
+ /* step 4 */
+
+ /* Apply equations 5-8 and 10-12 in order */
+
+ /* eq 5 */
+ /* Rprime = 0.9449322893 * R; */
+ /* R' in the paper is for the truncated */
+ Rprime = 0.91038328153090290025;
+
+ /* eq 6 */
+ H = acos(sin(Az) * sin(G) * cos(g) - cos(Az) * cos(G));
+
+ /* eq 7 */
+ /* Ag = (Az + G + H - DEG180) * M_PI * R * R / DEG180; */
+ Ag = Az + G + H - DEG180<T>();
+
+ /* eq 8 */
+ Azprime = atan2(2.0 * Ag, Rprime * Rprime * tan_g * tan_g - 2.0 * Ag * cot_theta);
+
+ /* eq 10 */
+ /* cot(theta) = 1.73205080756887729355 */
+ dprime = Rprime * tan_g / (cos(Azprime) + sin(Azprime) * cot_theta);
+
+ /* eq 11 */
+ f = dprime / (2.0 * Rprime * sin(q / 2.0));
+
+ /* eq 12 */
+ rho = 2.0 * Rprime * f * sin(z / 2.0);
+
+ /*
+ * add back the same 60 degree multiple adjustment from step
+ * 2 to Azprime
+ */
+
+ Azprime += DEG120<T>() * Az_adjust_multiples;
+
+ /* calculate rectangular coordinates */
+
+ x = rho * sin(Azprime);
+ y = rho * cos(Azprime);
+
+ /*
+ * TODO
+ * translate coordinates to the origin for the particular
+ * hexagon on the flattened polyhedral map plot
+ */
+
+ out->x = x;
+ out->y = y;
+
+ return i;
+ }
+
+ /*
+ * should be impossible, this implies that the coordinate is not on
+ * any triangle
+ */
+
+ //fprintf(stderr, "impossible transform: %f %f is not on any triangle\n",
+ // ll->lon * geometry::math::r2d<double>(), ll->lat * geometry::math::r2d<double>());
+ std::stringstream ss;
+ ss << "impossible transform: " << ll->lon * geometry::math::r2d<T>()
+ << " " << ll->lat * geometry::math::r2d<T>() << " is not on any triangle.";
+
+ BOOST_THROW_EXCEPTION( projection_exception(ss.str()) );
+
+ /* not reached */
+ return 0; /* supresses a warning */
+ }
+
+ /*
+ * return the new coordinates of any point in orginal coordinate system.
+ * Define a point (newNPold) in orginal coordinate system as the North Pole in
+ * new coordinate system, and the great circle connect the original and new
+ * North Pole as the lon0 longitude in new coordinate system, given any point
+ * in orginal coordinate system, this function return the new coordinates.
+ */
+
+
+ /* formula from Snyder, Map Projections: A working manual, p31 */
+ /*
+ * old north pole at np in new coordinates
+ * could be simplified a bit with fewer intermediates
+ *
+ * TODO take a result pointer
+ */
+ template <typename T>
+ inline isea_geo<T> snyder_ctran(isea_geo<T> * np, isea_geo<T> * pt)
+ {
+ isea_geo<T> npt;
+ T alpha, phi, lambda, lambda0, beta, lambdap, phip;
+ T sin_phip;
+ T lp_b; /* lambda prime minus beta */
+ T cos_p, sin_a;
+
+ phi = pt->lat;
+ lambda = pt->lon;
+ alpha = np->lat;
+ beta = np->lon;
+ lambda0 = beta;
+
+ cos_p = cos(phi);
+ sin_a = sin(alpha);
+
+ /* mpawm 5-7 */
+ sin_phip = sin_a * sin(phi) - cos(alpha) * cos_p * cos(lambda - lambda0);
+
+ /* mpawm 5-8b */
+
+ /* use the two argument form so we end up in the right quadrant */
+ lp_b = atan2(cos_p * sin(lambda - lambda0),
+ (sin_a * cos_p * cos(lambda - lambda0) + cos(alpha) * sin(phi)));
+
+ lambdap = lp_b + beta;
+
+ /* normalize longitude */
+ /* TODO can we just do a modulus ? */
+ lambdap = fmod(lambdap, geometry::math::two_pi<T>());
+ while (lambdap > geometry::math::pi<T>())
+ lambdap -= geometry::math::two_pi<T>();
+ while (lambdap < -geometry::math::pi<T>())
+ lambdap += geometry::math::two_pi<T>();
+
+ phip = asin(sin_phip);
+
+ npt.lat = phip;
+ npt.lon = lambdap;
+
+ return npt;
+ }
+
+ template <typename T>
+ inline isea_geo<T> isea_ctran(isea_geo<T> * np, isea_geo<T> * pt, T const& lon0)
+ {
+ isea_geo<T> npt;
+
+ np->lon += geometry::math::pi<T>();
+ npt = snyder_ctran(np, pt);
+ np->lon -= geometry::math::pi<T>();
+
+ npt.lon -= (geometry::math::pi<T>() - lon0 + np->lon);
+
+ /*
+ * snyder is down tri 3, isea is along side of tri1 from vertex 0 to
+ * vertex 1 these are 180 degrees apart
+ */
+ npt.lon += geometry::math::pi<T>();
+ /* normalize longitude */
+ npt.lon = fmod(npt.lon, geometry::math::two_pi<T>());
+ while (npt.lon > geometry::math::pi<T>())
+ npt.lon -= geometry::math::two_pi<T>();
+ while (npt.lon < -geometry::math::pi<T>())
+ npt.lon += geometry::math::two_pi<T>();
+
+ return npt;
+ }
+
+ /* in radians */
+
+ /* fuller's at 5.2454 west, 2.3009 N, adjacent at 7.46658 deg */
+
+ template <typename T>
+ inline int isea_grid_init(isea_dgg<T> * g)
+ {
+ if (!g)
+ return 0;
+
+ g->polyhedron = 20;
+ g->o_lat = ISEA_STD_LAT;
+ g->o_lon = ISEA_STD_LON;
+ g->o_az = 0.0;
+ g->aperture = 4;
+ g->resolution = 6;
+ g->radius = 1.0;
+ g->topology = 6;
+
+ return 1;
+ }
+
+ template <typename T>
+ inline int isea_orient_isea(isea_dgg<T> * g)
+ {
+ if (!g)
+ return 0;
+ g->o_lat = ISEA_STD_LAT;
+ g->o_lon = ISEA_STD_LON;
+ g->o_az = 0.0;
+ return 1;
+ }
+
+ template <typename T>
+ inline int isea_orient_pole(isea_dgg<T> * g)
+ {
+ if (!g)
+ return 0;
+ g->o_lat = geometry::math::half_pi<T>();
+ g->o_lon = 0.0;
+ g->o_az = 0;
+ return 1;
+ }
+
+ template <typename T>
+ inline int isea_transform(isea_dgg<T> * g, isea_geo<T> * in,
+ isea_pt<T> * out)
+ {
+ isea_geo<T> i, pole;
+ int tri;
+
+ pole.lat = g->o_lat;
+ pole.lon = g->o_lon;
+
+ i = isea_ctran(&pole, in, g->o_az);
+
+ tri = isea_snyder_forward(&i, out);
+ out->x *= g->radius;
+ out->y *= g->radius;
+ g->triangle = tri;
+
+ return tri;
+ }
+
+
+ template <typename T>
+ inline void isea_rotate(isea_pt<T> * pt, T const& degrees)
+ {
+ T rad;
+
+ T x, y;
+
+ rad = -degrees * geometry::math::d2r<T>();
+ while (rad >= geometry::math::two_pi<T>()) rad -= geometry::math::two_pi<T>();
+ while (rad <= -geometry::math::two_pi<T>()) rad += geometry::math::two_pi<T>();
+
+ x = pt->x * cos(rad) + pt->y * sin(rad);
+ y = -pt->x * sin(rad) + pt->y * cos(rad);
+
+ pt->x = x;
+ pt->y = y;
+ }
+
+ template <typename T>
+ inline int isea_tri_plane(int tri, isea_pt<T> *pt, T const& radius)
+ {
+ isea_pt<T> tc; /* center of triangle */
+
+ if (DOWNTRI(tri)) {
+ isea_rotate(pt, 180.0);
+ }
+ tc = isea_triangle_xy<T>(tri);
+ tc.x *= radius;
+ tc.y *= radius;
+ pt->x += tc.x;
+ pt->y += tc.y;
+
+ return tri;
+ }
+
+ /* convert projected triangle coords to quad xy coords, return quad number */
+ template <typename T>
+ inline int isea_ptdd(int tri, isea_pt<T> *pt)
+ {
+ int downtri, quad;
+
+ downtri = (((tri - 1) / 5) % 2 == 1);
+ boost::ignore_unused(downtri);
+ quad = ((tri - 1) % 5) + ((tri - 1) / 10) * 5 + 1;
+
+ isea_rotate(pt, downtri ? 240.0 : 60.0);
+ if (downtri) {
+ pt->x += 0.5;
+ /* pt->y += cos(30.0 * M_PI / 180.0); */
+ pt->y += .86602540378443864672;
+ }
+ return quad;
+ }
+
+ template <typename T>
+ inline int isea_dddi_ap3odd(isea_dgg<T> *g, int quad, isea_pt<T> *pt, isea_pt<T> *di)
+ {
+ isea_pt<T> v;
+ T hexwidth;
+ T sidelength; /* in hexes */
+ int d, i;
+ int maxcoord;
+ hex h;
+
+ /* This is the number of hexes from apex to base of a triangle */
+ sidelength = (pow(2.0, g->resolution) + 1.0) / 2.0;
+
+ /* apex to base is cos(30deg) */
+ hexwidth = cos(geometry::math::pi<T>() / 6.0) / sidelength;
+
+ /* TODO I think sidelength is always x.5, so
+ * (int)sidelength * 2 + 1 might be just as good
+ */
+ maxcoord = (int) (sidelength * 2.0 + 0.5);
+
+ v = *pt;
+ hexbin2(hexwidth, v.x, v.y, &h.x, &h.y);
+ h.iso = 0;
+ hex_iso(&h);
+
+ d = h.x - h.z;
+ i = h.x + h.y + h.y;
+
+ /*
+ * you want to test for max coords for the next quad in the same
+ * "row" first to get the case where both are max
+ */
+ if (quad <= 5) {
+ if (d == 0 && i == maxcoord) {
+ /* north pole */
+ quad = 0;
+ d = 0;
+ i = 0;
+ } else if (i == maxcoord) {
+ /* upper right in next quad */
+ quad += 1;
+ if (quad == 6)
+ quad = 1;
+ i = maxcoord - d;
+ d = 0;
+ } else if (d == maxcoord) {
+ /* lower right in quad to lower right */
+ quad += 5;
+ d = 0;
+ }
+ } else if (quad >= 6) {
+ if (i == 0 && d == maxcoord) {
+ /* south pole */
+ quad = 11;
+ d = 0;
+ i = 0;
+ } else if (d == maxcoord) {
+ /* lower right in next quad */
+ quad += 1;
+ if (quad == 11)
+ quad = 6;
+ d = maxcoord - i;
+ i = 0;
+ } else if (i == maxcoord) {
+ /* upper right in quad to upper right */
+ quad = (quad - 4) % 5;
+ i = 0;
+ }
+ }
+
+ di->x = d;
+ di->y = i;
+
+ g->quad = quad;
+ return quad;
+ }
+
+ template <typename T>
+ inline int isea_dddi(isea_dgg<T> *g, int quad, isea_pt<T> *pt, isea_pt<T> *di)
+ {
+ isea_pt<T> v;
+ T hexwidth;
+ int sidelength; /* in hexes */
+ hex h;
+
+ if (g->aperture == 3 && g->resolution % 2 != 0) {
+ return isea_dddi_ap3odd(g, quad, pt, di);
+ }
+ /* todo might want to do this as an iterated loop */
+ if (g->aperture >0) {
+ sidelength = (int) (pow(T(g->aperture), T(g->resolution / 2.0)) + 0.5);
+ } else {
+ sidelength = g->resolution;
+ }
+
+ hexwidth = 1.0 / sidelength;
+
+ v = *pt;
+ isea_rotate(&v, -30.0);
+ hexbin2(hexwidth, v.x, v.y, &h.x, &h.y);
+ h.iso = 0;
+ hex_iso(&h);
+
+ /* we may actually be on another quad */
+ if (quad <= 5) {
+ if (h.x == 0 && h.z == -sidelength) {
+ /* north pole */
+ quad = 0;
+ h.z = 0;
+ h.y = 0;
+ h.x = 0;
+ } else if (h.z == -sidelength) {
+ quad = quad + 1;
+ if (quad == 6)
+ quad = 1;
+ h.y = sidelength - h.x;
+ h.z = h.x - sidelength;
+ h.x = 0;
+ } else if (h.x == sidelength) {
+ quad += 5;
+ h.y = -h.z;
+ h.x = 0;
+ }
+ } else if (quad >= 6) {
+ if (h.z == 0 && h.x == sidelength) {
+ /* south pole */
+ quad = 11;
+ h.x = 0;
+ h.y = 0;
+ h.z = 0;
+ } else if (h.x == sidelength) {
+ quad = quad + 1;
+ if (quad == 11)
+ quad = 6;
+ h.x = h.y + sidelength;
+ h.y = 0;
+ h.z = -h.x;
+ } else if (h.y == -sidelength) {
+ quad -= 4;
+ h.y = 0;
+ h.z = -h.x;
+ }
+ }
+ di->x = h.x;
+ di->y = -h.z;
+
+ g->quad = quad;
+ return quad;
+ }
+
+ template <typename T>
+ inline int isea_ptdi(isea_dgg<T> *g, int tri, isea_pt<T> *pt,
+ isea_pt<T> *di)
+ {
+ isea_pt<T> v;
+ int quad;
+
+ v = *pt;
+ quad = isea_ptdd(tri, &v);
+ quad = isea_dddi(g, quad, &v, di);
+ return quad;
+ }
+
+ /* q2di to seqnum */
+ template <typename T>
+ inline int isea_disn(isea_dgg<T> *g, int quad, isea_pt<T> *di)
+ {
+ int sidelength;
+ int sn, height;
+ int hexes;
+
+ if (quad == 0) {
+ g->serial = 1;
+ return g->serial;
+ }
+ /* hexes in a quad */
+ hexes = (int) (pow(T(g->aperture), T(g->resolution)) + 0.5);
+ if (quad == 11) {
+ g->serial = 1 + 10 * hexes + 1;
+ return g->serial;
+ }
+ if (g->aperture == 3 && g->resolution % 2 == 1) {
+ height = (int) (pow(T(g->aperture), T((g->resolution - 1) / 2.0)));
+ sn = ((int) di->x) * height;
+ sn += ((int) di->y) / height;
+ sn += (quad - 1) * hexes;
+ sn += 2;
+ } else {
+ sidelength = (int) (pow(T(g->aperture), T(g->resolution / 2.0)) + 0.5);
+ sn = (int) ((quad - 1) * hexes + sidelength * di->x + di->y + 2);
+ }
+
+ g->serial = sn;
+ return sn;
+ }
+
+ /* TODO just encode the quad in the d or i coordinate
+ * quad is 0-11, which can be four bits.
+ * d' = d << 4 + q, d = d' >> 4, q = d' & 0xf
+ */
+ /* convert a q2di to global hex coord */
+ template <typename T>
+ inline int isea_hex(isea_dgg<T> *g, int tri, isea_pt<T> *pt,
+ isea_pt<T> *hex)
+ {
+ isea_pt<T> v;
+#ifdef BOOST_GEOMETRY_PROJECTIONS_FIXME
+ int sidelength;
+ int d, i, x, y;
+#endif // BOOST_GEOMETRY_PROJECTIONS_FIXME
+ int quad;
+
+ quad = isea_ptdi(g, tri, pt, &v);
+
+ hex->x = ((int)v.x << 4) + quad;
+ hex->y = v.y;
+
+ return 1;
+#ifdef BOOST_GEOMETRY_PROJECTIONS_FIXME
+ d = (int)v.x;
+ i = (int)v.y;
+
+ /* Aperture 3 odd resolutions */
+ if (g->aperture == 3 && g->resolution % 2 != 0) {
+ int offset = (int)(pow(T(3.0), T(g->resolution - 1)) + 0.5);
+
+ d += offset * ((g->quad-1) % 5);
+ i += offset * ((g->quad-1) % 5);
+
+ if (quad == 0) {
+ d = 0;
+ i = offset;
+ } else if (quad == 11) {
+ d = 2 * offset;
+ i = 0;
+ } else if (quad > 5) {
+ d += offset;
+ }
+
+ x = (2*d - i) /3;
+ y = (2*i - d) /3;
+
+ hex->x = x + offset / 3;
+ hex->y = y + 2 * offset / 3;
+ return 1;
+ }
+
+ /* aperture 3 even resolutions and aperture 4 */
+ sidelength = (int) (pow(T(g->aperture), T(g->resolution / 2.0)) + 0.5);
+ if (g->quad == 0) {
+ hex->x = 0;
+ hex->y = sidelength;
+ } else if (g->quad == 11) {
+ hex->x = sidelength * 2;
+ hex->y = 0;
+ } else {
+ hex->x = d + sidelength * ((g->quad-1) % 5);
+ if (g->quad > 5) hex->x += sidelength;
+ hex->y = i + sidelength * ((g->quad-1) % 5);
+ }
+
+ return 1;
+#endif // BOOST_GEOMETRY_PROJECTIONS_FIXME
+ }
+
+ template <typename T>
+ inline isea_pt<T> isea_forward(isea_dgg<T> *g, isea_geo<T> *in)
+ {
+ int tri, downtri;
+ isea_pt<T> out, coord;
+
+ tri = isea_transform(g, in, &out);
+
+ downtri = (((tri - 1) / 5) % 2 == 1);
+ boost::ignore_unused(downtri);
+
+ if (g->output == ISEA_PLANE) {
+ isea_tri_plane(tri, &out, g->radius);
+ return out;
+ }
+
+ /* convert to isea standard triangle size */
+ out.x = out.x / g->radius * ISEA_SCALE;
+ out.y = out.y / g->radius * ISEA_SCALE;
+ out.x += 0.5;
+ out.y += 2.0 * .14433756729740644112;
+
+ switch (g->output) {
+ case ISEA_PROJTRI:
+ /* nothing to do, already in projected triangle */
+ break;
+ case ISEA_VERTEX2DD:
+ g->quad = isea_ptdd(tri, &out);
+ break;
+ case ISEA_Q2DD:
+ /* Same as above, we just don't print as much */
+ g->quad = isea_ptdd(tri, &out);
+ break;
+ case ISEA_Q2DI:
+ g->quad = isea_ptdi(g, tri, &out, &coord);
+ return coord;
+ break;
+ case ISEA_SEQNUM:
+ isea_ptdi(g, tri, &out, &coord);
+ /* disn will set g->serial */
+ isea_disn(g, g->quad, &coord);
+ return coord;
+ break;
+ case ISEA_HEX:
+ isea_hex(g, tri, &out, &coord);
+ return coord;
+ break;
+ }
+
+ return out;
+ }
+ /*
+ * Proj 4 integration code follows
+ */
+
+ template <typename T>
+ struct par_isea
+ {
+ isea_dgg<T> dgg;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_isea_spheroid : public base_t_f<base_isea_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_isea<CalculationType> m_proj_parm;
+
+ inline base_isea_spheroid(const Parameters& par)
+ : base_t_f<base_isea_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward)
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ isea_pt<CalculationType> out;
+ isea_geo<CalculationType> in;
+
+ in.lon = lp_lon;
+ in.lat = lp_lat;
+
+ isea_dgg<CalculationType> copy = this->m_proj_parm.dgg;
+ out = isea_forward(&copy, &in);
+
+ xy_x = out.x;
+ xy_y = out.y;
+ }
+
+ static inline std::string get_name()
+ {
+ return "isea_spheroid";
+ }
+
+ };
+
+ // Icosahedral Snyder Equal Area
+ template <typename Parameters, typename T>
+ inline void setup_isea(Parameters& par, par_isea<T>& proj_parm)
+ {
+ std::string opt;
+
+ isea_grid_init(&proj_parm.dgg);
+
+ proj_parm.dgg.output = ISEA_PLANE;
+ /* proj_parm.dgg.radius = par.a; / * otherwise defaults to 1 */
+ /* calling library will scale, I think */
+
+ opt = pj_param(par.params, "sorient").s;
+ if (! opt.empty()) {
+ if (opt == std::string("isea")) {
+ isea_orient_isea(&proj_parm.dgg);
+ } else if (opt == std::string("pole")) {
+ isea_orient_pole(&proj_parm.dgg);
+ } else {
+ BOOST_THROW_EXCEPTION( projection_exception(-34) );
+ }
+ }
+
+ if (pj_param(par.params, "tazi").i) {
+ proj_parm.dgg.o_az = pj_param(par.params, "razi").f;
+ }
+
+ if (pj_param(par.params, "tlon_0").i) {
+ proj_parm.dgg.o_lon = pj_param(par.params, "rlon_0").f;
+ }
+
+ if (pj_param(par.params, "tlat_0").i) {
+ proj_parm.dgg.o_lat = pj_param(par.params, "rlat_0").f;
+ }
+
+ if (pj_param(par.params, "taperture").i) {
+ proj_parm.dgg.aperture = pj_param(par.params, "iaperture").i;
+ }
+
+ if (pj_param(par.params, "tresolution").i) {
+ proj_parm.dgg.resolution = pj_param(par.params, "iresolution").i;
+ }
+
+ opt = pj_param(par.params, "smode").s;
+ if (! opt.empty()) {
+ if (opt == std::string("plane")) {
+ proj_parm.dgg.output = ISEA_PLANE;
+ } else if (opt == std::string("di")) {
+ proj_parm.dgg.output = ISEA_Q2DI;
+ }
+ else if (opt == std::string("dd")) {
+ proj_parm.dgg.output = ISEA_Q2DD;
+ }
+ else if (opt == std::string("hex")) {
+ proj_parm.dgg.output = ISEA_HEX;
+ }
+ else {
+ /* TODO verify error code. Possibly eliminate magic */
+ BOOST_THROW_EXCEPTION( projection_exception(-34) );
+ }
+ }
+
+ if (pj_param(par.params, "trescale").i) {
+ proj_parm.dgg.radius = ISEA_SCALE;
+ }
+
+ if (pj_param(par.params, "tresolution").i) {
+ proj_parm.dgg.resolution = pj_param(par.params, "iresolution").i;
+ } else {
+ proj_parm.dgg.resolution = 4;
+ }
+
+ if (pj_param(par.params, "taperture").i) {
+ proj_parm.dgg.aperture = pj_param(par.params, "iaperture").i;
+ } else {
+ proj_parm.dgg.aperture = 3;
+ }
+ }
+
+ }} // namespace detail::isea
+ #endif // doxygen
+
+ /*!
+ \brief Icosahedral Snyder Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Spheroid
+ \par Projection parameters
+ - orient (string)
+ - azi: Azimuth (or Gamma) (degrees)
+ - lon_0: Central meridian (degrees)
+ - lat_0: Latitude of origin (degrees)
+ - aperture (integer)
+ - resolution (integer)
+ - mode (string)
+ - rescale
+ \par Example
+ \image html ex_isea.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct isea_spheroid : public detail::isea::base_isea_spheroid<CalculationType, Parameters>
+ {
+ inline isea_spheroid(const Parameters& par) : detail::isea::base_isea_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::isea::setup_isea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::isea, isea_spheroid, isea_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class isea_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<isea_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void isea_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("isea", new isea_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ISEA_HPP
+
diff --git a/boost/geometry/srs/projections/proj/krovak.hpp b/boost/geometry/srs/projections/proj/krovak.hpp
new file mode 100644
index 0000000000..09c24772ed
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/krovak.hpp
@@ -0,0 +1,360 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_KROVAK_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_KROVAK_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Implementation of the krovak (Krovak) projection.
+// Definition: http://www.ihsenergy.com/epsg/guid7.html#1.4.3
+// Author: Thomas Flemming, tf@ttqv.com
+// Copyright (c) 2001, Thomas Flemming, tf@ttqv.com
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct krovak {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace krovak
+ {
+ template <typename T>
+ struct par_krovak
+ {
+ T C_x;
+ };
+
+ /**
+ NOTES: According to EPSG the full Krovak projection method should have
+ the following parameters. Within PROJ.4 the azimuth, and pseudo
+ standard parallel are hardcoded in the algorithm and can't be
+ altered from outside. The others all have defaults to match the
+ common usage with Krovak projection.
+
+ lat_0 = latitude of centre of the projection
+
+ lon_0 = longitude of centre of the projection
+
+ ** = azimuth (true) of the centre line passing through the centre of the projection
+
+ ** = latitude of pseudo standard parallel
+
+ k = scale factor on the pseudo standard parallel
+
+ x_0 = False Easting of the centre of the projection at the apex of the cone
+
+ y_0 = False Northing of the centre of the projection at the apex of the cone
+
+ **/
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_krovak_ellipsoid : public base_t_fi<base_krovak_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_krovak<CalculationType> m_proj_parm;
+
+ inline base_krovak_ellipsoid(const Parameters& par)
+ : base_t_fi<base_krovak_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ /* calculate xy from lat/lon */
+
+ /* Constants, identical to inverse transform function */
+ CalculationType s45, s90, e2, e, alfa, uq, u0, g, k, k1, n0, ro0, ad, a, s0, n;
+ CalculationType gfi, u, fi0, deltav, s, d, eps, ro;
+
+
+ s45 = 0.785398163397448; /* 45 DEG */
+ s90 = 2 * s45;
+ fi0 = this->m_par.phi0; /* Latitude of projection centre 49 DEG 30' */
+
+ /* Ellipsoid is used as Parameter in for.c and inv.c, therefore a must
+ be set to 1 here.
+ Ellipsoid Bessel 1841 a = 6377397.155m 1/f = 299.1528128,
+ e2=0.006674372230614;
+ */
+ a = 1; /* 6377397.155; */
+ /* e2 = this->m_par.es;*/ /* 0.006674372230614; */
+ e2 = 0.006674372230614;
+ e = sqrt(e2);
+
+ alfa = sqrt(1. + (e2 * pow(cos(fi0), 4)) / (1. - e2));
+
+ uq = 1.04216856380474; /* DU(2, 59, 42, 42.69689) */
+ u0 = asin(sin(fi0) / alfa);
+ g = pow( (1. + e * sin(fi0)) / (1. - e * sin(fi0)) , alfa * e / 2. );
+
+ k = tan( u0 / 2. + s45) / pow (tan(fi0 / 2. + s45) , alfa) * g;
+
+ k1 = this->m_par.k0;
+ n0 = a * sqrt(1. - e2) / (1. - e2 * pow(sin(fi0), 2));
+ s0 = 1.37008346281555; /* Latitude of pseudo standard parallel 78 DEG 30'00" N */
+ n = sin(s0);
+ ro0 = k1 * n0 / tan(s0);
+ ad = s90 - uq;
+
+ /* Transformation */
+
+ gfi =pow ( ((1. + e * sin(lp_lat)) /
+ (1. - e * sin(lp_lat))) , (alfa * e / 2.));
+
+ u= 2. * (atan(k * pow( tan(lp_lat / 2. + s45), alfa) / gfi)-s45);
+
+ deltav = - lp_lon * alfa;
+
+ s = asin(cos(ad) * sin(u) + sin(ad) * cos(u) * cos(deltav));
+ d = asin(cos(u) * sin(deltav) / cos(s));
+ eps = n * d;
+ ro = ro0 * pow(tan(s0 / 2. + s45) , n) / pow(tan(s / 2. + s45) , n) ;
+
+ /* x and y are reverted! */
+ xy_y = ro * cos(eps) / a;
+ xy_x = ro * sin(eps) / a;
+
+ if( !pj_param(this->m_par.params, "tczech").i )
+ {
+ xy_y *= -1.0;
+ xy_x *= -1.0;
+ }
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ /* calculate lat/lon from xy */
+
+ /* Constants, identisch wie in der Umkehrfunktion */
+ CalculationType s45, s90, fi0, e2, e, alfa, uq, u0, g, k, k1, n0, ro0, ad, a, s0, n;
+ CalculationType u, deltav, s, d, eps, ro, fi1, xy0;
+ int ok;
+
+ s45 = 0.785398163397448; /* 45 DEG */
+ s90 = 2 * s45;
+ fi0 = this->m_par.phi0; /* Latitude of projection centre 49 DEG 30' */
+
+
+ /* Ellipsoid is used as Parameter in for.c and inv.c, therefore a must
+ be set to 1 here.
+ Ellipsoid Bessel 1841 a = 6377397.155m 1/f = 299.1528128,
+ e2=0.006674372230614;
+ */
+ a = 1; /* 6377397.155; */
+ /* e2 = this->m_par.es; */ /* 0.006674372230614; */
+ e2 = 0.006674372230614;
+ e = sqrt(e2);
+
+ alfa = sqrt(1. + (e2 * pow(cos(fi0), 4)) / (1. - e2));
+ uq = 1.04216856380474; /* DU(2, 59, 42, 42.69689) */
+ u0 = asin(sin(fi0) / alfa);
+ g = pow( (1. + e * sin(fi0)) / (1. - e * sin(fi0)) , alfa * e / 2. );
+
+ k = tan( u0 / 2. + s45) / pow (tan(fi0 / 2. + s45) , alfa) * g;
+
+ k1 = this->m_par.k0;
+ n0 = a * sqrt(1. - e2) / (1. - e2 * pow(sin(fi0), 2));
+ s0 = 1.37008346281555; /* Latitude of pseudo standard parallel 78 DEG 30'00" N */
+ n = sin(s0);
+ ro0 = k1 * n0 / tan(s0);
+ ad = s90 - uq;
+
+
+ /* Transformation */
+ /* revert y, x*/
+ xy0=xy_x;
+ xy_x=xy_y;
+ xy_y=xy0;
+
+ if( !pj_param(this->m_par.params, "tczech").i )
+ {
+ xy_x *= -1.0;
+ xy_y *= -1.0;
+ }
+
+ ro = sqrt(xy_x * xy_x + xy_y * xy_y);
+ eps = atan2(xy_y, xy_x);
+ d = eps / sin(s0);
+ s = 2. * (atan( pow(ro0 / ro, 1. / n) * tan(s0 / 2. + s45)) - s45);
+
+ u = asin(cos(ad) * sin(s) - sin(ad) * cos(s) * cos(d));
+ deltav = asin(cos(s) * sin(d) / cos(u));
+
+ lp_lon = this->m_par.lam0 - deltav / alfa;
+
+ /* ITERATION FOR lp_lat */
+ fi1 = u;
+
+ ok = 0;
+ do
+ {
+ lp_lat = 2. * ( atan( pow( k, -1. / alfa) *
+ pow( tan(u / 2. + s45) , 1. / alfa) *
+ pow( (1. + e * sin(fi1)) / (1. - e * sin(fi1)) , e / 2.)
+ ) - s45);
+
+ if (fabs(fi1 - lp_lat) < 0.000000000000001) ok=1;
+ fi1 = lp_lat;
+
+ }
+ while (ok==0);
+
+ lp_lon -= this->m_par.lam0;
+ }
+
+ static inline std::string get_name()
+ {
+ return "krovak_ellipsoid";
+ }
+
+ };
+
+ // Krovak
+ template <typename Parameters, typename T>
+ inline void setup_krovak(Parameters& par, par_krovak<T>& proj_parm)
+ {
+ T ts;
+ /* read some Parameters,
+ * here Latitude Truescale */
+
+ ts = pj_param(par.params, "rlat_ts").f;
+ proj_parm.C_x = ts;
+
+ /* we want Bessel as fixed ellipsoid */
+ par.a = 6377397.155;
+ par.e = sqrt(par.es = 0.006674372230614);
+
+ /* if latitude of projection center is not set, use 49d30'N */
+ if (!pj_param(par.params, "tlat_0").i)
+ par.phi0 = 0.863937979737193;
+
+ /* if center long is not set use 42d30'E of Ferro - 17d40' for Ferro */
+ /* that will correspond to using longitudes relative to greenwich */
+ /* as input and output, instead of lat/long relative to Ferro */
+ if (!pj_param(par.params, "tlon_0").i)
+ par.lam0 = 0.7417649320975901 - 0.308341501185665;
+
+ /* if scale not set default to 0.9999 */
+ if (!pj_param(par.params, "tk").i)
+ par.k0 = 0.9999;
+
+ /* always the same */
+ }
+
+ }} // namespace detail::krovak
+ #endif // doxygen
+
+ /*!
+ \brief Krovak projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Ellipsoid
+ \par Projection parameters
+ - lat_ts: Latitude of true scale (degrees)
+ - lat_0: Latitude of origin
+ - lon_0: Central meridian
+ - k: Scale factor on the pseudo standard parallel
+ \par Example
+ \image html ex_krovak.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct krovak_ellipsoid : public detail::krovak::base_krovak_ellipsoid<CalculationType, Parameters>
+ {
+ inline krovak_ellipsoid(const Parameters& par) : detail::krovak::base_krovak_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::krovak::setup_krovak(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::krovak, krovak_ellipsoid, krovak_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class krovak_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<krovak_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void krovak_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("krovak", new krovak_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_KROVAK_HPP
+
diff --git a/boost/geometry/srs/projections/proj/labrd.hpp b/boost/geometry/srs/projections/proj/labrd.hpp
new file mode 100644
index 0000000000..0a51689308
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/labrd.hpp
@@ -0,0 +1,269 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LABRD_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LABRD_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct labrd {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace labrd
+ {
+ static const double EPS = 1.e-10;
+
+ template <typename T>
+ struct par_labrd
+ {
+ T Az, kRg, p0s, A, C, Ca, Cb, Cc, Cd;
+ int rot;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_labrd_ellipsoid : public base_t_fi<base_labrd_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_labrd<CalculationType> m_proj_parm;
+
+ inline base_labrd_ellipsoid(const Parameters& par)
+ : base_t_fi<base_labrd_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward)
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType FORTPI = detail::FORTPI<CalculationType>();
+
+ CalculationType V1, V2, ps, sinps, cosps, sinps2, cosps2, I1, I2, I3, I4, I5, I6,
+ x2, y2, t;
+
+ V1 = this->m_proj_parm.A * log( tan(FORTPI + .5 * lp_lat) );
+ t = this->m_par.e * sin(lp_lat);
+ V2 = .5 * this->m_par.e * this->m_proj_parm.A * log ((1. + t)/(1. - t));
+ ps = 2. * (atan(exp(V1 - V2 + this->m_proj_parm.C)) - FORTPI);
+ I1 = ps - this->m_proj_parm.p0s;
+ cosps = cos(ps); cosps2 = cosps * cosps;
+ sinps = sin(ps); sinps2 = sinps * sinps;
+ I4 = this->m_proj_parm.A * cosps;
+ I2 = .5 * this->m_proj_parm.A * I4 * sinps;
+ I3 = I2 * this->m_proj_parm.A * this->m_proj_parm.A * (5. * cosps2 - sinps2) / 12.;
+ I6 = I4 * this->m_proj_parm.A * this->m_proj_parm.A;
+ I5 = I6 * (cosps2 - sinps2) / 6.;
+ I6 *= this->m_proj_parm.A * this->m_proj_parm.A *
+ (5. * cosps2 * cosps2 + sinps2 * (sinps2 - 18. * cosps2)) / 120.;
+ t = lp_lon * lp_lon;
+ xy_x = this->m_proj_parm.kRg * lp_lon * (I4 + t * (I5 + t * I6));
+ xy_y = this->m_proj_parm.kRg * (I1 + t * (I2 + t * I3));
+ x2 = xy_x * xy_x;
+ y2 = xy_y * xy_y;
+ V1 = 3. * xy_x * y2 - xy_x * x2;
+ V2 = xy_y * y2 - 3. * x2 * xy_y;
+ xy_x += this->m_proj_parm.Ca * V1 + this->m_proj_parm.Cb * V2;
+ xy_y += this->m_proj_parm.Ca * V2 - this->m_proj_parm.Cb * V1;
+ }
+
+ // INVERSE(e_inverse) ellipsoid & spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType FORTPI = detail::FORTPI<CalculationType>();
+
+ CalculationType x2, y2, V1, V2, V3, V4, t, t2, ps, pe, tpe, s,
+ I7, I8, I9, I10, I11, d, Re;
+ int i;
+
+ x2 = xy_x * xy_x;
+ y2 = xy_y * xy_y;
+ V1 = 3. * xy_x * y2 - xy_x * x2;
+ V2 = xy_y * y2 - 3. * x2 * xy_y;
+ V3 = xy_x * (5. * y2 * y2 + x2 * (-10. * y2 + x2 ));
+ V4 = xy_y * (5. * x2 * x2 + y2 * (-10. * x2 + y2 ));
+ xy_x += - this->m_proj_parm.Ca * V1 - this->m_proj_parm.Cb * V2 + this->m_proj_parm.Cc * V3 + this->m_proj_parm.Cd * V4;
+ xy_y += this->m_proj_parm.Cb * V1 - this->m_proj_parm.Ca * V2 - this->m_proj_parm.Cd * V3 + this->m_proj_parm.Cc * V4;
+ ps = this->m_proj_parm.p0s + xy_y / this->m_proj_parm.kRg;
+ pe = ps + this->m_par.phi0 - this->m_proj_parm.p0s;
+ for ( i = 20; i; --i) {
+ V1 = this->m_proj_parm.A * log(tan(FORTPI + .5 * pe));
+ tpe = this->m_par.e * sin(pe);
+ V2 = .5 * this->m_par.e * this->m_proj_parm.A * log((1. + tpe)/(1. - tpe));
+ t = ps - 2. * (atan(exp(V1 - V2 + this->m_proj_parm.C)) - FORTPI);
+ pe += t;
+ if (fabs(t) < EPS)
+ break;
+ }
+ /*
+ if (!i) {
+ } else {
+ }
+ */
+ t = this->m_par.e * sin(pe);
+ t = 1. - t * t;
+ Re = this->m_par.one_es / ( t * sqrt(t) );
+ t = tan(ps);
+ t2 = t * t;
+ s = this->m_proj_parm.kRg * this->m_proj_parm.kRg;
+ d = Re * this->m_par.k0 * this->m_proj_parm.kRg;
+ I7 = t / (2. * d);
+ I8 = t * (5. + 3. * t2) / (24. * d * s);
+ d = cos(ps) * this->m_proj_parm.kRg * this->m_proj_parm.A;
+ I9 = 1. / d;
+ d *= s;
+ I10 = (1. + 2. * t2) / (6. * d);
+ I11 = (5. + t2 * (28. + 24. * t2)) / (120. * d * s);
+ x2 = xy_x * xy_x;
+ lp_lat = pe + x2 * (-I7 + I8 * x2);
+ lp_lon = xy_x * (I9 + x2 * (-I10 + x2 * I11));
+ }
+
+ static inline std::string get_name()
+ {
+ return "labrd_ellipsoid";
+ }
+
+ };
+
+ // Laborde
+ template <typename Parameters, typename T>
+ inline void setup_labrd(Parameters& par, par_labrd<T>& proj_parm)
+ {
+ static const T FORTPI = detail::FORTPI<T>();
+
+ T Az, sinp, R, N, t;
+
+ proj_parm.rot = pj_param(par.params, "bno_rot").i == 0;
+ Az = pj_param(par.params, "razi").f;
+ sinp = sin(par.phi0);
+ t = 1. - par.es * sinp * sinp;
+ N = 1. / sqrt(t);
+ R = par.one_es * N / t;
+ proj_parm.kRg = par.k0 * sqrt( N * R );
+ proj_parm.p0s = atan( sqrt(R / N) * tan(par.phi0) );
+ proj_parm.A = sinp / sin(proj_parm.p0s);
+ t = par.e * sinp;
+ proj_parm.C = .5 * par.e * proj_parm.A * log((1. + t)/(1. - t)) +
+ - proj_parm.A * log( tan(FORTPI + .5 * par.phi0))
+ + log( tan(FORTPI + .5 * proj_parm.p0s));
+ t = Az + Az;
+ proj_parm.Ca = (1. - cos(t)) * ( proj_parm.Cb = 1. / (12. * proj_parm.kRg * proj_parm.kRg) );
+ proj_parm.Cb *= sin(t);
+ proj_parm.Cc = 3. * (proj_parm.Ca * proj_parm.Ca - proj_parm.Cb * proj_parm.Cb);
+ proj_parm.Cd = 6. * proj_parm.Ca * proj_parm.Cb;
+ }
+
+ }} // namespace detail::labrd
+ #endif // doxygen
+
+ /*!
+ \brief Laborde projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Special for Madagascar
+ \par Projection parameters
+ - no_rot: No rotation (boolean)
+ - azi: Azimuth (or Gamma) (degrees)
+ \par Example
+ \image html ex_labrd.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct labrd_ellipsoid : public detail::labrd::base_labrd_ellipsoid<CalculationType, Parameters>
+ {
+ inline labrd_ellipsoid(const Parameters& par) : detail::labrd::base_labrd_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::labrd::setup_labrd(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::labrd, labrd_ellipsoid, labrd_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class labrd_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<labrd_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void labrd_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("labrd", new labrd_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LABRD_HPP
+
diff --git a/boost/geometry/srs/projections/proj/laea.hpp b/boost/geometry/srs/projections/proj/laea.hpp
new file mode 100644
index 0000000000..757d2b7ff0
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/laea.hpp
@@ -0,0 +1,447 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LAEA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LAEA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/config.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_auth.hpp>
+#include <boost/geometry/srs/projections/impl/pj_qsfn.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct laea {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace laea
+ {
+ static const double EPS10 = 1.e-10;
+ static const int NITER = 20;
+ static const double CONV = 1.e-10;
+ static const int N_POLE = 0;
+ static const int S_POLE = 1;
+ static const int EQUIT = 2;
+ static const int OBLIQ = 3;
+
+ template <typename T>
+ struct par_laea
+ {
+ T sinb1;
+ T cosb1;
+ T xmf;
+ T ymf;
+ T mmf;
+ T qp;
+ T dd;
+ T rq;
+ T apa[APA_SIZE];
+ int mode;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_laea_ellipsoid : public base_t_fi<base_laea_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_laea<CalculationType> m_proj_parm;
+
+ inline base_laea_ellipsoid(const Parameters& par)
+ : base_t_fi<base_laea_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType coslam, sinlam, sinphi, q, sinb=0.0, cosb=0.0, b=0.0;
+
+ coslam = cos(lp_lon);
+ sinlam = sin(lp_lon);
+ sinphi = sin(lp_lat);
+ q = pj_qsfn(sinphi, this->m_par.e, this->m_par.one_es);
+ if (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT) {
+ sinb = q / this->m_proj_parm.qp;
+ cosb = sqrt(1. - sinb * sinb);
+ }
+ switch (this->m_proj_parm.mode) {
+ case OBLIQ:
+ b = 1. + this->m_proj_parm.sinb1 * sinb + this->m_proj_parm.cosb1 * cosb * coslam;
+ break;
+ case EQUIT:
+ b = 1. + cosb * coslam;
+ break;
+ case N_POLE:
+ b = HALFPI + lp_lat;
+ q = this->m_proj_parm.qp - q;
+ break;
+ case S_POLE:
+ b = lp_lat - HALFPI;
+ q = this->m_proj_parm.qp + q;
+ break;
+ }
+ if (fabs(b) < EPS10)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ switch (this->m_proj_parm.mode) {
+ case OBLIQ:
+ xy_y = this->m_proj_parm.ymf * ( b = sqrt(2. / b) )
+ * (this->m_proj_parm.cosb1 * sinb - this->m_proj_parm.sinb1 * cosb * coslam);
+ goto eqcon;
+ break;
+ case EQUIT:
+ xy_y = (b = sqrt(2. / (1. + cosb * coslam))) * sinb * this->m_proj_parm.ymf;
+ eqcon:
+ xy_x = this->m_proj_parm.xmf * b * cosb * sinlam;
+ break;
+ case N_POLE:
+ case S_POLE:
+ if (q >= 0.) {
+ xy_x = (b = sqrt(q)) * sinlam;
+ xy_y = coslam * (this->m_proj_parm.mode == S_POLE ? b : -b);
+ } else
+ xy_x = xy_y = 0.;
+ break;
+ }
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType cCe, sCe, q, rho, ab=0.0;
+
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ case OBLIQ:
+ if ((rho = boost::math::hypot(xy_x /= this->m_proj_parm.dd, xy_y *= this->m_proj_parm.dd)) < EPS10) {
+ lp_lon = 0.;
+ lp_lat = this->m_par.phi0;
+ return;
+ }
+ cCe = cos(sCe = 2. * asin(.5 * rho / this->m_proj_parm.rq));
+ xy_x *= (sCe = sin(sCe));
+ if (this->m_proj_parm.mode == OBLIQ) {
+ q = this->m_proj_parm.qp * (ab = cCe * this->m_proj_parm.sinb1 + xy_y * sCe * this->m_proj_parm.cosb1 / rho);
+ xy_y = rho * this->m_proj_parm.cosb1 * cCe - xy_y * this->m_proj_parm.sinb1 * sCe;
+ } else {
+ q = this->m_proj_parm.qp * (ab = xy_y * sCe / rho);
+ xy_y = rho * cCe;
+ }
+ break;
+ case N_POLE:
+ xy_y = -xy_y;
+ BOOST_FALLTHROUGH;
+ case S_POLE:
+ if (!(q = (xy_x * xy_x + xy_y * xy_y)) ) {
+ lp_lon = 0.;
+ lp_lat = this->m_par.phi0;
+ return;
+ }
+ /*
+ q = this->m_proj_parm.qp - q;
+ */
+ ab = 1. - q / this->m_proj_parm.qp;
+ if (this->m_proj_parm.mode == S_POLE)
+ ab = - ab;
+ break;
+ }
+ lp_lon = atan2(xy_x, xy_y);
+ lp_lat = pj_authlat(asin(ab), this->m_proj_parm.apa);
+ }
+
+ static inline std::string get_name()
+ {
+ return "laea_ellipsoid";
+ }
+
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_laea_spheroid : public base_t_fi<base_laea_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_laea<CalculationType> m_proj_parm;
+
+ inline base_laea_spheroid(const Parameters& par)
+ : base_t_fi<base_laea_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType FORTPI = detail::FORTPI<CalculationType>();
+
+ CalculationType coslam, cosphi, sinphi;
+
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ coslam = cos(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ xy_y = 1. + cosphi * coslam;
+ goto oblcon;
+ case OBLIQ:
+ xy_y = 1. + this->m_proj_parm.sinb1 * sinphi + this->m_proj_parm.cosb1 * cosphi * coslam;
+ oblcon:
+ if (xy_y <= EPS10)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ xy_x = (xy_y = sqrt(2. / xy_y)) * cosphi * sin(lp_lon);
+ xy_y *= this->m_proj_parm.mode == EQUIT ? sinphi :
+ this->m_proj_parm.cosb1 * sinphi - this->m_proj_parm.sinb1 * cosphi * coslam;
+ break;
+ case N_POLE:
+ coslam = -coslam;
+ BOOST_FALLTHROUGH;
+ case S_POLE:
+ if (fabs(lp_lat + this->m_par.phi0) < EPS10)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ xy_y = FORTPI - lp_lat * .5;
+ xy_y = 2. * (this->m_proj_parm.mode == S_POLE ? cos(xy_y) : sin(xy_y));
+ xy_x = xy_y * sin(lp_lon);
+ xy_y *= coslam;
+ break;
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType cosz=0.0, rh, sinz=0.0;
+
+ rh = boost::math::hypot(xy_x, xy_y);
+ if ((lp_lat = rh * .5 ) > 1.)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ lp_lat = 2. * asin(lp_lat);
+ if (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT) {
+ sinz = sin(lp_lat);
+ cosz = cos(lp_lat);
+ }
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ lp_lat = fabs(rh) <= EPS10 ? 0. : asin(xy_y * sinz / rh);
+ xy_x *= sinz;
+ xy_y = cosz * rh;
+ break;
+ case OBLIQ:
+ lp_lat = fabs(rh) <= EPS10 ? this->m_par.phi0 :
+ asin(cosz * this->m_proj_parm.sinb1 + xy_y * sinz * this->m_proj_parm.cosb1 / rh);
+ xy_x *= sinz * this->m_proj_parm.cosb1;
+ xy_y = (cosz - sin(lp_lat) * this->m_proj_parm.sinb1) * rh;
+ break;
+ case N_POLE:
+ xy_y = -xy_y;
+ lp_lat = HALFPI - lp_lat;
+ break;
+ case S_POLE:
+ lp_lat -= HALFPI;
+ break;
+ }
+ lp_lon = (xy_y == 0. && (this->m_proj_parm.mode == EQUIT || this->m_proj_parm.mode == OBLIQ)) ?
+ 0. : atan2(xy_x, xy_y);
+ }
+
+ static inline std::string get_name()
+ {
+ return "laea_spheroid";
+ }
+
+ };
+
+ // Lambert Azimuthal Equal Area
+ template <typename Parameters, typename T>
+ inline void setup_laea(Parameters& par, par_laea<T>& proj_parm)
+ {
+ static const T HALFPI = detail::HALFPI<T>();
+
+ T t;
+
+ if (fabs((t = fabs(par.phi0)) - HALFPI) < EPS10)
+ proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE;
+ else if (fabs(t) < EPS10)
+ proj_parm.mode = EQUIT;
+ else
+ proj_parm.mode = OBLIQ;
+ if (par.es) {
+ double sinphi;
+
+ par.e = sqrt(par.es);
+ proj_parm.qp = pj_qsfn(1., par.e, par.one_es);
+ proj_parm.mmf = .5 / (1. - par.es);
+ pj_authset(par.es, proj_parm.apa);
+ switch (proj_parm.mode) {
+ case N_POLE:
+ case S_POLE:
+ proj_parm.dd = 1.;
+ break;
+ case EQUIT:
+ proj_parm.dd = 1. / (proj_parm.rq = sqrt(.5 * proj_parm.qp));
+ proj_parm.xmf = 1.;
+ proj_parm.ymf = .5 * proj_parm.qp;
+ break;
+ case OBLIQ:
+ proj_parm.rq = sqrt(.5 * proj_parm.qp);
+ sinphi = sin(par.phi0);
+ proj_parm.sinb1 = pj_qsfn(sinphi, par.e, par.one_es) / proj_parm.qp;
+ proj_parm.cosb1 = sqrt(1. - proj_parm.sinb1 * proj_parm.sinb1);
+ proj_parm.dd = cos(par.phi0) / (sqrt(1. - par.es * sinphi * sinphi) *
+ proj_parm.rq * proj_parm.cosb1);
+ proj_parm.ymf = (proj_parm.xmf = proj_parm.rq) / proj_parm.dd;
+ proj_parm.xmf *= proj_parm.dd;
+ break;
+ }
+ } else {
+ if (proj_parm.mode == OBLIQ) {
+ proj_parm.sinb1 = sin(par.phi0);
+ proj_parm.cosb1 = cos(par.phi0);
+ }
+ }
+ }
+
+ }} // namespace laea
+ #endif // doxygen
+
+ /*!
+ \brief Lambert Azimuthal Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_laea.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct laea_ellipsoid : public detail::laea::base_laea_ellipsoid<CalculationType, Parameters>
+ {
+ inline laea_ellipsoid(const Parameters& par) : detail::laea::base_laea_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::laea::setup_laea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Lambert Azimuthal Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_laea.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct laea_spheroid : public detail::laea::base_laea_spheroid<CalculationType, Parameters>
+ {
+ inline laea_spheroid(const Parameters& par) : detail::laea::base_laea_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::laea::setup_laea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::laea, laea_spheroid, laea_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class laea_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<laea_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ else
+ return new base_v_fi<laea_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void laea_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("laea", new laea_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LAEA_HPP
+
diff --git a/boost/geometry/srs/projections/proj/lagrng.hpp b/boost/geometry/srs/projections/proj/lagrng.hpp
new file mode 100644
index 0000000000..8ed5c1389e
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/lagrng.hpp
@@ -0,0 +1,195 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct lagrng {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace lagrng
+ {
+
+ static const double TOL = 1e-10;
+
+ template <typename T>
+ struct par_lagrng
+ {
+ T hrw;
+ T rw;
+ T a1;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_lagrng_spheroid : public base_t_f<base_lagrng_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_lagrng<CalculationType> m_proj_parm;
+
+ inline base_lagrng_spheroid(const Parameters& par)
+ : base_t_f<base_lagrng_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType v, c;
+
+ if (fabs(fabs(lp_lat) - HALFPI) < TOL) {
+ xy_x = 0;
+ xy_y = lp_lat < 0 ? -2. : 2.;
+ } else {
+ lp_lat = sin(lp_lat);
+ v = this->m_proj_parm.a1 * pow((1. + lp_lat)/(1. - lp_lat), this->m_proj_parm.hrw);
+ if ((c = 0.5 * (v + 1./v) + cos(lp_lon *= this->m_proj_parm.rw)) < TOL)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ xy_x = 2. * sin(lp_lon) / c;
+ xy_y = (v - 1./v) / c;
+ }
+ }
+
+ static inline std::string get_name()
+ {
+ return "lagrng_spheroid";
+ }
+
+ };
+
+ // Lagrange
+ template <typename Parameters, typename T>
+ inline void setup_lagrng(Parameters& par, par_lagrng<T>& proj_parm)
+ {
+ T phi1;
+
+ if ((proj_parm.rw = pj_param(par.params, "dW").f) <= 0)
+ BOOST_THROW_EXCEPTION( projection_exception(-27) );
+ proj_parm.hrw = 0.5 * (proj_parm.rw = 1. / proj_parm.rw);
+ phi1 = pj_param(par.params, "rlat_1").f;
+ if (fabs(fabs(phi1 = sin(phi1)) - 1.) < TOL)
+ BOOST_THROW_EXCEPTION( projection_exception(-22) );
+ proj_parm.a1 = pow((1. - phi1)/(1. + phi1), proj_parm.hrw);
+ par.es = 0.;
+ }
+
+ }} // namespace detail::lagrng
+ #endif // doxygen
+
+ /*!
+ \brief Lagrange projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Projection parameters
+ - W (real)
+ - lat_1: Latitude of first standard parallel (degrees)
+ \par Example
+ \image html ex_lagrng.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct lagrng_spheroid : public detail::lagrng::base_lagrng_spheroid<CalculationType, Parameters>
+ {
+ inline lagrng_spheroid(const Parameters& par) : detail::lagrng::base_lagrng_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::lagrng::setup_lagrng(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lagrng, lagrng_spheroid, lagrng_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class lagrng_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<lagrng_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void lagrng_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("lagrng", new lagrng_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP
+
diff --git a/boost/geometry/srs/projections/proj/larr.hpp b/boost/geometry/srs/projections/proj/larr.hpp
new file mode 100644
index 0000000000..2b2735c0dd
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/larr.hpp
@@ -0,0 +1,164 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LARR_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LARR_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct larr {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace larr
+ {
+
+ //static const double SIXTH = .16666666666666666;
+
+ template <typename T>
+ inline T SIXTH() { return .16666666666666666666666666666666; }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_larr_spheroid : public base_t_f<base_larr_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_larr_spheroid(const Parameters& par)
+ : base_t_f<base_larr_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType SIXTH = larr::SIXTH<CalculationType>();
+
+ xy_x = 0.5 * lp_lon * (1. + sqrt(cos(lp_lat)));
+ xy_y = lp_lat / (cos(0.5 * lp_lat) * cos(SIXTH * lp_lon));
+ }
+
+ static inline std::string get_name()
+ {
+ return "larr_spheroid";
+ }
+
+ };
+
+ // Larrivee
+ template <typename Parameters>
+ inline void setup_larr(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::larr
+ #endif // doxygen
+
+ /*!
+ \brief Larrivee projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_larr.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct larr_spheroid : public detail::larr::base_larr_spheroid<CalculationType, Parameters>
+ {
+ inline larr_spheroid(const Parameters& par) : detail::larr::base_larr_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::larr::setup_larr(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::larr, larr_spheroid, larr_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class larr_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<larr_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void larr_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("larr", new larr_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LARR_HPP
+
diff --git a/boost/geometry/srs/projections/proj/lask.hpp b/boost/geometry/srs/projections/proj/lask.hpp
new file mode 100644
index 0000000000..9ee1a95efe
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/lask.hpp
@@ -0,0 +1,173 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LASK_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LASK_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct lask {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace lask
+ {
+
+ static const double a10 = 0.975534;
+ static const double a12 = -0.119161;
+ static const double a32 = -0.0143059;
+ static const double a14 = -0.0547009;
+ static const double b01 = 1.00384;
+ static const double b21 = 0.0802894;
+ static const double b03 = 0.0998909;
+ static const double b41 = 0.000199025;
+ static const double b23 = -0.0285500;
+ static const double b05 = -0.0491032;
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_lask_spheroid : public base_t_f<base_lask_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_lask_spheroid(const Parameters& par)
+ : base_t_f<base_lask_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) sphere
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType l2, p2;
+
+ l2 = lp_lon * lp_lon;
+ p2 = lp_lat * lp_lat;
+ xy_x = lp_lon * (a10 + p2 * (a12 + l2 * a32 + p2 * a14));
+ xy_y = lp_lat * (b01 + l2 * (b21 + p2 * b23 + l2 * b41) +
+ p2 * (b03 + p2 * b05));
+ }
+
+ static inline std::string get_name()
+ {
+ return "lask_spheroid";
+ }
+
+ };
+
+ // Laskowski
+ template <typename Parameters>
+ inline void setup_lask(Parameters& par)
+ {
+ par.es = 0.;
+ }
+
+ }} // namespace detail::lask
+ #endif // doxygen
+
+ /*!
+ \brief Laskowski projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_lask.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct lask_spheroid : public detail::lask::base_lask_spheroid<CalculationType, Parameters>
+ {
+ inline lask_spheroid(const Parameters& par) : detail::lask::base_lask_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::lask::setup_lask(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lask, lask_spheroid, lask_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class lask_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<lask_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void lask_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("lask", new lask_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LASK_HPP
+
diff --git a/boost/geometry/srs/projections/proj/latlong.hpp b/boost/geometry/srs/projections/proj/latlong.hpp
new file mode 100644
index 0000000000..e806381f2d
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/latlong.hpp
@@ -0,0 +1,292 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LATLONG_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LATLONG_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Purpose: Stub projection implementation for lat/long coordinates. We
+// don't actually change the coordinates, but we want proj=latlong
+// to act sort of like a projection.
+// Author: Frank Warmerdam, warmerdam@pobox.com
+// Copyright (c) 2000, Frank Warmerdam
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct lonlat {};
+ struct latlon {};
+ struct latlong {};
+ struct longlat {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace latlong
+ {
+
+ /* very loosely based upon DMA code by Bradford W. Drew */
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_latlong_other : public base_t_fi<base_latlong_other<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+
+ inline base_latlong_other(const Parameters& par)
+ : base_t_fi<base_latlong_other<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(forward)
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = lp_lon / this->m_par.a;
+ xy_y = lp_lat / this->m_par.a;
+ }
+
+ // INVERSE(inverse)
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y * this->m_par.a;
+ lp_lon = xy_x * this->m_par.a;
+ }
+
+ static inline std::string get_name()
+ {
+ return "latlong_other";
+ }
+
+ };
+
+ // Lat/long (Geodetic)
+ template <typename Parameters>
+ inline void setup_lonlat(Parameters& par)
+ {
+ par.is_latlong = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ }
+
+ // Lat/long (Geodetic alias)
+ template <typename Parameters>
+ inline void setup_latlon(Parameters& par)
+ {
+ par.is_latlong = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ }
+
+ // Lat/long (Geodetic alias)
+ template <typename Parameters>
+ inline void setup_latlong(Parameters& par)
+ {
+ par.is_latlong = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ }
+
+ // Lat/long (Geodetic alias)
+ template <typename Parameters>
+ inline void setup_longlat(Parameters& par)
+ {
+ par.is_latlong = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ }
+
+ }} // namespace detail::latlong
+ #endif // doxygen
+
+ /*!
+ \brief Lat/long (Geodetic) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Example
+ \image html ex_lonlat.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct lonlat_other : public detail::latlong::base_latlong_other<CalculationType, Parameters>
+ {
+ inline lonlat_other(const Parameters& par) : detail::latlong::base_latlong_other<CalculationType, Parameters>(par)
+ {
+ detail::latlong::setup_lonlat(this->m_par);
+ }
+ };
+
+ /*!
+ \brief Lat/long (Geodetic alias) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Example
+ \image html ex_latlon.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct latlon_other : public detail::latlong::base_latlong_other<CalculationType, Parameters>
+ {
+ inline latlon_other(const Parameters& par) : detail::latlong::base_latlong_other<CalculationType, Parameters>(par)
+ {
+ detail::latlong::setup_latlon(this->m_par);
+ }
+ };
+
+ /*!
+ \brief Lat/long (Geodetic alias) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Example
+ \image html ex_latlong.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct latlong_other : public detail::latlong::base_latlong_other<CalculationType, Parameters>
+ {
+ inline latlong_other(const Parameters& par) : detail::latlong::base_latlong_other<CalculationType, Parameters>(par)
+ {
+ detail::latlong::setup_latlong(this->m_par);
+ }
+ };
+
+ /*!
+ \brief Lat/long (Geodetic alias) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Example
+ \image html ex_longlat.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct longlat_other : public detail::latlong::base_latlong_other<CalculationType, Parameters>
+ {
+ inline longlat_other(const Parameters& par) : detail::latlong::base_latlong_other<CalculationType, Parameters>(par)
+ {
+ detail::latlong::setup_longlat(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lonlat, lonlat_other, lonlat_other)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::latlon, latlon_other, latlon_other)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::latlong, latlong_other, latlong_other)
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::longlat, longlat_other, longlat_other)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class lonlat_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<lonlat_other<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class latlon_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<latlon_other<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class latlong_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<latlong_other<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ class longlat_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<longlat_other<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void latlong_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("lonlat", new lonlat_entry<CalculationType, Parameters>);
+ factory.add_to_factory("latlon", new latlon_entry<CalculationType, Parameters>);
+ factory.add_to_factory("latlong", new latlong_entry<CalculationType, Parameters>);
+ factory.add_to_factory("longlat", new longlat_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LATLONG_HPP
+
diff --git a/boost/geometry/srs/projections/proj/lcc.hpp b/boost/geometry/srs/projections/proj/lcc.hpp
new file mode 100644
index 0000000000..609c08491c
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/lcc.hpp
@@ -0,0 +1,282 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LCC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LCC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_msfn.hpp>
+#include <boost/geometry/srs/projections/impl/pj_phi2.hpp>
+#include <boost/geometry/srs/projections/impl/pj_tsfn.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct lcc {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace lcc
+ {
+ static const double EPS10 = 1.e-10;
+
+ template <typename T>
+ struct par_lcc
+ {
+ T phi1;
+ T phi2;
+ T n;
+ T rho0;
+ T c;
+ int ellips;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_lcc_ellipsoid : public base_t_fi<base_lcc_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_lcc<CalculationType> m_proj_parm;
+
+ inline base_lcc_ellipsoid(const Parameters& par)
+ : base_t_fi<base_lcc_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid & spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType FORTPI = detail::FORTPI<CalculationType>();
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType rho;
+ if (fabs(fabs(lp_lat) - HALFPI) < EPS10) {
+ if ((lp_lat * this->m_proj_parm.n) <= 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ rho = 0.;
+ } else
+ rho = this->m_proj_parm.c * (this->m_proj_parm.ellips ? pow(pj_tsfn(lp_lat, sin(lp_lat),
+ this->m_par.e), this->m_proj_parm.n) : pow(tan(FORTPI + .5 * lp_lat), -this->m_proj_parm.n));
+ xy_x = this->m_par.k0 * (rho * sin( lp_lon *= this->m_proj_parm.n ) );
+ xy_y = this->m_par.k0 * (this->m_proj_parm.rho0 - rho * cos(lp_lon) );
+ }
+
+ // INVERSE(e_inverse) ellipsoid & spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType rho;
+ xy_x /= this->m_par.k0;
+ xy_y /= this->m_par.k0;
+ if( (rho = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.rho0 - xy_y)) != 0.0) {
+ if (this->m_proj_parm.n < 0.) {
+ rho = -rho;
+ xy_x = -xy_x;
+ xy_y = -xy_y;
+ }
+ if (this->m_proj_parm.ellips) {
+ if ((lp_lat = pj_phi2(pow(rho / this->m_proj_parm.c, 1./this->m_proj_parm.n), this->m_par.e))
+ == HUGE_VAL)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ } else
+ lp_lat = 2. * atan(pow(this->m_proj_parm.c / rho, 1./this->m_proj_parm.n)) - HALFPI;
+ lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n;
+ } else {
+ lp_lon = 0.;
+ lp_lat = this->m_proj_parm.n > 0. ? HALFPI : -HALFPI;
+ }
+ }
+
+ // SPECIAL(fac)
+ #ifdef SPECIAL_FACTORS_NOT_CONVERTED
+ inline void fac(Geographic lp, Factors &fac) const
+ {
+ static const CalculationType FORTPI = detail::FORTPI<CalculationType>();
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ CalculationType rho;
+ if (fabs(fabs(lp_lat) - HALFPI) < EPS10) {
+ if ((lp_lat * this->m_proj_parm.n) <= 0.) return;
+ rho = 0.;
+ } else
+ rho = this->m_proj_parm.c * (this->m_proj_parm.ellips ? pow(pj_tsfn(lp_lat, sin(lp_lat),
+ this->m_par.e), this->m_proj_parm.n) : pow(tan(FORTPI + .5 * lp_lat), -this->m_proj_parm.n));
+ this->m_fac.code |= IS_ANAL_HK + IS_ANAL_CONV;
+ this->m_fac.k = this->m_fac.h = this->m_par.k0 * this->m_proj_parm.n * rho /
+ pj_msfn(sin(lp_lat), cos(lp_lat), this->m_par.es);
+ this->m_fac.conv = - this->m_proj_parm.n * lp_lon;
+ }
+ #endif
+
+ static inline std::string get_name()
+ {
+ return "lcc_ellipsoid";
+ }
+
+ };
+
+ // Lambert Conformal Conic
+ template <typename Parameters, typename T>
+ inline void setup_lcc(Parameters& par, par_lcc<T>& proj_parm)
+ {
+ static const T FORTPI = detail::FORTPI<T>();
+ static const T HALFPI = detail::HALFPI<T>();
+
+ T cosphi, sinphi;
+ int secant;
+
+ proj_parm.phi1 = pj_param(par.params, "rlat_1").f;
+ if (pj_param(par.params, "tlat_2").i)
+ proj_parm.phi2 = pj_param(par.params, "rlat_2").f;
+ else {
+ proj_parm.phi2 = proj_parm.phi1;
+ if (!pj_param(par.params, "tlat_0").i)
+ par.phi0 = proj_parm.phi1;
+ }
+ if (fabs(proj_parm.phi1 + proj_parm.phi2) < EPS10)
+ BOOST_THROW_EXCEPTION( projection_exception(-21) );
+ proj_parm.n = sinphi = sin(proj_parm.phi1);
+ cosphi = cos(proj_parm.phi1);
+ secant = fabs(proj_parm.phi1 - proj_parm.phi2) >= EPS10;
+ if( (proj_parm.ellips = (par.es != 0.)) ) {
+ double ml1, m1;
+
+ par.e = sqrt(par.es);
+ m1 = pj_msfn(sinphi, cosphi, par.es);
+ ml1 = pj_tsfn(proj_parm.phi1, sinphi, par.e);
+ if (secant) { /* secant cone */
+ proj_parm.n = log(m1 /
+ pj_msfn(sinphi = sin(proj_parm.phi2), cos(proj_parm.phi2), par.es));
+ proj_parm.n /= log(ml1 / pj_tsfn(proj_parm.phi2, sinphi, par.e));
+ }
+ proj_parm.c = (proj_parm.rho0 = m1 * pow(ml1, -proj_parm.n) / proj_parm.n);
+ proj_parm.rho0 *= (fabs(fabs(par.phi0) - HALFPI) < EPS10) ? 0. :
+ pow(pj_tsfn(par.phi0, sin(par.phi0), par.e), proj_parm.n);
+ } else {
+ if (secant)
+ proj_parm.n = log(cosphi / cos(proj_parm.phi2)) /
+ log(tan(FORTPI + .5 * proj_parm.phi2) /
+ tan(FORTPI + .5 * proj_parm.phi1));
+ proj_parm.c = cosphi * pow(tan(FORTPI + .5 * proj_parm.phi1), proj_parm.n) / proj_parm.n;
+ proj_parm.rho0 = (fabs(fabs(par.phi0) - HALFPI) < EPS10) ? 0. :
+ proj_parm.c * pow(tan(FORTPI + .5 * par.phi0), -proj_parm.n);
+ }
+ }
+
+ }} // namespace detail::lcc
+ #endif // doxygen
+
+ /*!
+ \brief Lambert Conformal Conic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ - lat_2: Latitude of second standard parallel (degrees)
+ - lat_0: Latitude of origin
+ \par Example
+ \image html ex_lcc.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct lcc_ellipsoid : public detail::lcc::base_lcc_ellipsoid<CalculationType, Parameters>
+ {
+ inline lcc_ellipsoid(const Parameters& par) : detail::lcc::base_lcc_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::lcc::setup_lcc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lcc, lcc_ellipsoid, lcc_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class lcc_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<lcc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void lcc_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("lcc", new lcc_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LCC_HPP
+
diff --git a/boost/geometry/srs/projections/proj/lcca.hpp b/boost/geometry/srs/projections/proj/lcca.hpp
new file mode 100644
index 0000000000..a1a2069d8f
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/lcca.hpp
@@ -0,0 +1,231 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LCCA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LCCA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/core/ignore_unused.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct lcca {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace lcca
+ {
+
+ static const int MAX_ITER = 10;
+ static const double DEL_TOL = 1e-12;
+
+ template <typename T>
+ struct par_lcca
+ {
+ T en[EN_SIZE];
+ T r0, l, M0;
+ T C;
+ };
+
+ template <typename T> /* func to compute dr */
+ inline T fS(T const& S, T const& C)
+ {
+ return(S * ( 1. + S * S * C));
+ }
+
+ template <typename T> /* deriv of fs */
+ inline T fSp(T const& S, T const& C)
+ {
+ return(1. + 3.* S * S * C);
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_lcca_ellipsoid : public base_t_fi<base_lcca_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_lcca<CalculationType> m_proj_parm;
+
+ inline base_lcca_ellipsoid(const Parameters& par)
+ : base_t_fi<base_lcca_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ CalculationType S, r, dr;
+
+ S = pj_mlfn(lp_lat, sin(lp_lat), cos(lp_lat), this->m_proj_parm.en) - this->m_proj_parm.M0;
+ dr = fS(S, this->m_proj_parm.C);
+ r = this->m_proj_parm.r0 - dr;
+ xy_x = this->m_par.k0 * (r * sin( lp_lon *= this->m_proj_parm.l ) );
+ xy_y = this->m_par.k0 * (this->m_proj_parm.r0 - r * cos(lp_lon) );
+ }
+
+ // INVERSE(e_inverse) ellipsoid & spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ CalculationType theta, dr, S, dif;
+ int i;
+
+ xy_x /= this->m_par.k0;
+ xy_y /= this->m_par.k0;
+ theta = atan2(xy_x , this->m_proj_parm.r0 - xy_y);
+ dr = xy_y - xy_x * tan(0.5 * theta);
+ lp_lon = theta / this->m_proj_parm.l;
+ S = dr;
+ for (i = MAX_ITER; i ; --i) {
+ S -= (dif = (fS(S, this->m_proj_parm.C) - dr) / fSp(S, this->m_proj_parm.C));
+ if (fabs(dif) < DEL_TOL) break;
+ }
+ if (!i)
+ BOOST_THROW_EXCEPTION( projection_exception(-20) );
+ lp_lat = pj_inv_mlfn(S + this->m_proj_parm.M0, this->m_par.es, this->m_proj_parm.en);
+ }
+
+ static inline std::string get_name()
+ {
+ return "lcca_ellipsoid";
+ }
+
+ };
+
+ // Lambert Conformal Conic Alternative
+ template <typename Parameters, typename T>
+ inline void setup_lcca(Parameters& par, par_lcca<T>& proj_parm)
+ {
+ T s2p0, N0, R0, tan0, tan20;
+
+ if (!pj_enfn(par.es, proj_parm.en))
+ BOOST_THROW_EXCEPTION( projection_exception(0) );
+ if (!pj_param(par.params, "tlat_0").i)
+ BOOST_THROW_EXCEPTION( projection_exception(50) );
+ if (par.phi0 == 0.)
+ BOOST_THROW_EXCEPTION( projection_exception(51) );
+ proj_parm.l = sin(par.phi0);
+ proj_parm.M0 = pj_mlfn(par.phi0, proj_parm.l, cos(par.phi0), proj_parm.en);
+ s2p0 = proj_parm.l * proj_parm.l;
+ R0 = 1. / (1. - par.es * s2p0);
+ N0 = sqrt(R0);
+ R0 *= par.one_es * N0;
+ tan0 = tan(par.phi0);
+ tan20 = tan0 * tan0;
+ proj_parm.r0 = N0 / tan0;
+ proj_parm.C = 1. / (6. * R0 * N0);
+ boost::ignore_unused(tan20);
+ }
+
+ }} // namespace detail::lcca
+ #endif // doxygen
+
+ /*!
+ \brief Lambert Conformal Conic Alternative projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lat_0: Latitude of origin
+ \par Example
+ \image html ex_lcca.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct lcca_ellipsoid : public detail::lcca::base_lcca_ellipsoid<CalculationType, Parameters>
+ {
+ inline lcca_ellipsoid(const Parameters& par) : detail::lcca::base_lcca_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::lcca::setup_lcca(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lcca, lcca_ellipsoid, lcca_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class lcca_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<lcca_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void lcca_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("lcca", new lcca_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LCCA_HPP
+
diff --git a/boost/geometry/srs/projections/proj/loxim.hpp b/boost/geometry/srs/projections/proj/loxim.hpp
new file mode 100644
index 0000000000..f88eb4ca6e
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/loxim.hpp
@@ -0,0 +1,205 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct loxim {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace loxim
+ {
+ static const double EPS = 1e-8;
+
+ template <typename T>
+ struct par_loxim
+ {
+ T phi1;
+ T cosphi1;
+ T tanphi1;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_loxim_spheroid : public base_t_fi<base_loxim_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_loxim<CalculationType> m_proj_parm;
+
+ inline base_loxim_spheroid(const Parameters& par)
+ : base_t_fi<base_loxim_spheroid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(s_forward) spheroid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType FORTPI = detail::FORTPI<CalculationType>();
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ xy_y = lp_lat - this->m_proj_parm.phi1;
+ if (fabs(xy_y) < EPS)
+ xy_x = lp_lon * this->m_proj_parm.cosphi1;
+ else {
+ xy_x = FORTPI + 0.5 * lp_lat;
+ if (fabs(xy_x) < EPS || fabs(fabs(xy_x) - HALFPI) < EPS)
+ xy_x = 0.;
+ else
+ xy_x = lp_lon * xy_y / log( tan(xy_x) / this->m_proj_parm.tanphi1 );
+ }
+ }
+
+ // INVERSE(s_inverse) spheroid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType FORTPI = detail::FORTPI<CalculationType>();
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ lp_lat = xy_y + this->m_proj_parm.phi1;
+ if (fabs(xy_y) < EPS)
+ lp_lon = xy_x / this->m_proj_parm.cosphi1;
+ else
+ if (fabs( lp_lon = FORTPI + 0.5 * lp_lat ) < EPS ||
+ fabs(fabs(lp_lon) - HALFPI) < EPS)
+ lp_lon = 0.;
+ else
+ lp_lon = xy_x * log( tan(lp_lon) / this->m_proj_parm.tanphi1 ) / xy_y ;
+ }
+
+ static inline std::string get_name()
+ {
+ return "loxim_spheroid";
+ }
+
+ };
+
+ // Loximuthal
+ template <typename Parameters, typename T>
+ inline void setup_loxim(Parameters& par, par_loxim<T>& proj_parm)
+ {
+ static const T FORTPI = detail::FORTPI<T>();
+
+ proj_parm.phi1 = pj_param(par.params, "rlat_1").f;
+ if ((proj_parm.cosphi1 = cos(proj_parm.phi1)) < EPS)
+ BOOST_THROW_EXCEPTION( projection_exception(-22) );
+ proj_parm.tanphi1 = tan(FORTPI + 0.5 * proj_parm.phi1);
+ par.es = 0.;
+ }
+
+ }} // namespace detail::loxim
+ #endif // doxygen
+
+ /*!
+ \brief Loximuthal projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Projection parameters
+ - lat_1: Latitude of first standard parallel (degrees)
+ \par Example
+ \image html ex_loxim.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct loxim_spheroid : public detail::loxim::base_loxim_spheroid<CalculationType, Parameters>
+ {
+ inline loxim_spheroid(const Parameters& par) : detail::loxim::base_loxim_spheroid<CalculationType, Parameters>(par)
+ {
+ detail::loxim::setup_loxim(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::loxim, loxim_spheroid, loxim_spheroid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class loxim_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<loxim_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void loxim_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("loxim", new loxim_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP
+
diff --git a/boost/geometry/srs/projections/proj/lsat.hpp b/boost/geometry/srs/projections/proj/lsat.hpp
new file mode 100644
index 0000000000..d305339d5b
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/lsat.hpp
@@ -0,0 +1,341 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels
+
+// Last updated version of proj: 4.9.1
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/srs/projections/impl/base_static.hpp>
+#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/srs/projections/impl/projects.hpp>
+#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
+#include <boost/geometry/srs/projections/impl/aasincos.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace srs { namespace par4
+{
+ struct lsat {};
+
+}} //namespace srs::par4
+
+namespace projections
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace lsat
+ {
+ static const double TOL = 1e-7;
+ //static const double PI_HALFPI = 4.71238898038468985766;
+ //static const double TWOPI_HALFPI = 7.85398163397448309610;
+
+ template <typename T>
+ struct par_lsat
+ {
+ T a2, a4, b, c1, c3;
+ T q, t, u, w, p22, sa, ca, xj, rlm, rlm2;
+ };
+
+ /* based upon Snyder and Linck, USGS-NMD */
+ template <typename T>
+ inline void
+ seraz0(T lam, T const& mult, par_lsat<T>& proj_parm)
+ {
+ T sdsq, h, s, fc, sd, sq, d__1;
+
+ lam *= geometry::math::d2r<T>();
+ sd = sin(lam);
+ sdsq = sd * sd;
+ s = proj_parm.p22 * proj_parm.sa * cos(lam) * sqrt((1. + proj_parm.t * sdsq) / ((
+ 1. + proj_parm.w * sdsq) * (1. + proj_parm.q * sdsq)));
+ d__1 = 1. + proj_parm.q * sdsq;
+ h = sqrt((1. + proj_parm.q * sdsq) / (1. + proj_parm.w * sdsq)) * ((1. +
+ proj_parm.w * sdsq) / (d__1 * d__1) - proj_parm.p22 * proj_parm.ca);
+ sq = sqrt(proj_parm.xj * proj_parm.xj + s * s);
+ proj_parm.b += fc = mult * (h * proj_parm.xj - s * s) / sq;
+ proj_parm.a2 += fc * cos(lam + lam);
+ proj_parm.a4 += fc * cos(lam * 4.);
+ fc = mult * s * (h + proj_parm.xj) / sq;
+ proj_parm.c1 += fc * cos(lam);
+ proj_parm.c3 += fc * cos(lam * 3.);
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename CalculationType, typename Parameters>
+ struct base_lsat_ellipsoid : public base_t_fi<base_lsat_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>
+ {
+
+ typedef CalculationType geographic_type;
+ typedef CalculationType cartesian_type;
+
+ par_lsat<CalculationType> m_proj_parm;
+
+ inline base_lsat_ellipsoid(const Parameters& par)
+ : base_t_fi<base_lsat_ellipsoid<CalculationType, Parameters>,
+ CalculationType, Parameters>(*this, par) {}
+
+ // FORWARD(e_forward) ellipsoid
+ // Project coordinates from geographic (lon, lat) to cartesian (x, y)
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ static const CalculationType FORTPI = detail::FORTPI<CalculationType>();
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+ static const CalculationType PI_HALFPI = detail::PI_HALFPI<CalculationType>();
+ static const CalculationType TWOPI_HALFPI = detail::TWOPI_HALFPI<CalculationType>();
+
+ int l, nn;
+ CalculationType lamt, xlam, sdsq, c, d, s, lamdp, phidp, lampp, tanph,
+ lamtp, cl, sd, sp, fac, sav, tanphi;
+
+ if (lp_lat > HALFPI)
+ lp_lat = HALFPI;
+ else if (lp_lat < -HALFPI)
+ lp_lat = -HALFPI;
+ lampp = lp_lat >= 0. ? HALFPI : PI_HALFPI;
+ tanphi = tan(lp_lat);
+ for (nn = 0;;) {
+ sav = lampp;
+ lamtp = lp_lon + this->m_proj_parm.p22 * lampp;
+ cl = cos(lamtp);
+ if (fabs(cl) < TOL)
+ lamtp -= TOL;
+ fac = lampp - sin(lampp) * (cl < 0. ? -HALFPI : HALFPI);
+ for (l = 50; l; --l) {
+ lamt = lp_lon + this->m_proj_parm.p22 * sav;
+ if (fabs(c = cos(lamt)) < TOL)
+ lamt -= TOL;
+ xlam = (this->m_par.one_es * tanphi * this->m_proj_parm.sa + sin(lamt) * this->m_proj_parm.ca) / c;
+ lamdp = atan(xlam) + fac;
+ if (fabs(fabs(sav) - fabs(lamdp)) < TOL)
+ break;
+ sav = lamdp;
+ }
+ if (!l || ++nn >= 3 || (lamdp > this->m_proj_parm.rlm && lamdp < this->m_proj_parm.rlm2))
+ break;
+ if (lamdp <= this->m_proj_parm.rlm)
+ lampp = TWOPI_HALFPI;
+ else if (lamdp >= this->m_proj_parm.rlm2)
+ lampp = HALFPI;
+ }
+ if (l) {
+ sp = sin(lp_lat);
+ phidp = aasin((this->m_par.one_es * this->m_proj_parm.ca * sp - this->m_proj_parm.sa * cos(lp_lat) *
+ sin(lamt)) / sqrt(1. - this->m_par.es * sp * sp));
+ tanph = log(tan(FORTPI + .5 * phidp));
+ sd = sin(lamdp);
+ sdsq = sd * sd;
+ s = this->m_proj_parm.p22 * this->m_proj_parm.sa * cos(lamdp) * sqrt((1. + this->m_proj_parm.t * sdsq)
+ / ((1. + this->m_proj_parm.w * sdsq) * (1. + this->m_proj_parm.q * sdsq)));
+ d = sqrt(this->m_proj_parm.xj * this->m_proj_parm.xj + s * s);
+ xy_x = this->m_proj_parm.b * lamdp + this->m_proj_parm.a2 * sin(2. * lamdp) + this->m_proj_parm.a4 *
+ sin(lamdp * 4.) - tanph * s / d;
+ xy_y = this->m_proj_parm.c1 * sd + this->m_proj_parm.c3 * sin(lamdp * 3.) + tanph * this->m_proj_parm.xj / d;
+ } else
+ xy_x = xy_y = HUGE_VAL;
+ }
+
+ // INVERSE(e_inverse) ellipsoid
+ // Project coordinates from cartesian (x, y) to geographic (lon, lat)
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ static const CalculationType FORTPI = detail::FORTPI<CalculationType>();
+ static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
+
+ int nn;
+ CalculationType lamt, sdsq, s, lamdp, phidp, sppsq, dd, sd, sl, fac, scl, sav, spp;
+
+ lamdp = xy_x / this->m_proj_parm.b;
+ nn = 50;
+ do {
+ sav = lamdp;
+ sd = sin(lamdp);
+ sdsq = sd * sd;
+ s = this->m_proj_parm.p22 * this->m_proj_parm.sa * cos(lamdp) * sqrt((1. + this->m_proj_parm.t * sdsq)
+ / ((1. + this->m_proj_parm.w * sdsq) * (1. + this->m_proj_parm.q * sdsq)));
+ lamdp = xy_x + xy_y * s / this->m_proj_parm.xj - this->m_proj_parm.a2 * sin(
+ 2. * lamdp) - this->m_proj_parm.a4 * sin(lamdp * 4.) - s / this->m_proj_parm.xj * (
+ this->m_proj_parm.c1 * sin(lamdp) + this->m_proj_parm.c3 * sin(lamdp * 3.));
+ lamdp /= this->m_proj_parm.b;
+ } while (fabs(lamdp - sav) >= TOL && --nn);
+ sl = sin(lamdp);
+ fac = exp(sqrt(1. + s * s / this->m_proj_parm.xj / this->m_proj_parm.xj) * (xy_y -
+ this->m_proj_parm.c1 * sl - this->m_proj_parm.c3 * sin(lamdp * 3.)));
+ phidp = 2. * (atan(fac) - FORTPI);
+ dd = sl * sl;
+ if (fabs(cos(lamdp)) < TOL)
+ lamdp -= TOL;
+ spp = sin(phidp);
+ sppsq = spp * spp;
+ lamt = atan(((1. - sppsq * this->m_par.rone_es) * tan(lamdp) *
+ this->m_proj_parm.ca - spp * this->m_proj_parm.sa * sqrt((1. + this->m_proj_parm.q * dd) * (
+ 1. - sppsq) - sppsq * this->m_proj_parm.u) / cos(lamdp)) / (1. - sppsq
+ * (1. + this->m_proj_parm.u)));
+ sl = lamt >= 0. ? 1. : -1.;
+ scl = cos(lamdp) >= 0. ? 1. : -1;
+ lamt -= HALFPI * (1. - scl) * sl;
+ lp_lon = lamt - this->m_proj_parm.p22 * lamdp;
+ if (fabs(this->m_proj_parm.sa) < TOL)
+ lp_lat = aasin(spp / sqrt(this->m_par.one_es * this->m_par.one_es + this->m_par.es * sppsq));
+ else
+ lp_lat = atan((tan(lamdp) * cos(lamt) - this->m_proj_parm.ca * sin(lamt)) /
+ (this->m_par.one_es * this->m_proj_parm.sa));
+ }
+
+ static inline std::string get_name()
+ {
+ return "lsat_ellipsoid";
+ }
+
+ };
+
+ // Space oblique for LANDSAT
+ template <typename Parameters, typename T>
+ inline void setup_lsat(Parameters& par, par_lsat<T>& proj_parm)
+ {
+ int land, path;
+ T lam, alf, esc, ess;
+
+ land = pj_param(par.params, "ilsat").i;
+ if (land <= 0 || land > 5)
+ BOOST_THROW_EXCEPTION( projection_exception(-28) );
+ path = pj_param(par.params, "ipath").i;
+ if (path <= 0 || path > (land <= 3 ? 251 : 233))
+ BOOST_THROW_EXCEPTION( projection_exception(-29) );
+ if (land <= 3) {
+ par.lam0 = geometry::math::d2r<T>() * 128.87 - geometry::math::two_pi<T>() / 251. * path;
+ proj_parm.p22 = 103.2669323;
+ alf = geometry::math::d2r<T>() * 99.092;
+ } else {
+ par.lam0 = geometry::math::d2r<T>() * 129.3 - geometry::math::two_pi<T>() / 233. * path;
+ proj_parm.p22 = 98.8841202;
+ alf = geometry::math::d2r<T>() * 98.2;
+ }
+ proj_parm.p22 /= 1440.;
+ proj_parm.sa = sin(alf);
+ proj_parm.ca = cos(alf);
+ if (fabs(proj_parm.ca) < 1e-9)
+ proj_parm.ca = 1e-9;
+ esc = par.es * proj_parm.ca * proj_parm.ca;
+ ess = par.es * proj_parm.sa * proj_parm.sa;
+ proj_parm.w = (1. - esc) * par.rone_es;
+ proj_parm.w = proj_parm.w * proj_parm.w - 1.;
+ proj_parm.q = ess * par.rone_es;
+ proj_parm.t = ess * (2. - par.es) * par.rone_es * par.rone_es;
+ proj_parm.u = esc * par.rone_es;
+ proj_parm.xj = par.one_es * par.one_es * par.one_es;
+ proj_parm.rlm = geometry::math::pi<T>() * (1. / 248. + .5161290322580645);
+ proj_parm.rlm2 = proj_parm.rlm + geometry::math::two_pi<T>();
+ proj_parm.a2 = proj_parm.a4 = proj_parm.b = proj_parm.c1 = proj_parm.c3 = 0.;
+ seraz0(0., 1., proj_parm);
+ for (lam = 9.; lam <= 81.0001; lam += 18.)
+ seraz0(lam, 4., proj_parm);
+ for (lam = 18; lam <= 72.0001; lam += 18.)
+ seraz0(lam, 2., proj_parm);
+ seraz0(90., 1., proj_parm);
+ proj_parm.a2 /= 30.;
+ proj_parm.a4 /= 60.;
+ proj_parm.b /= 30.;
+ proj_parm.c1 /= 15.;
+ proj_parm.c3 /= 45.;
+ }
+
+ }} // namespace detail::lsat
+ #endif // doxygen
+
+ /*!
+ \brief Space oblique for LANDSAT projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Projection parameters
+ - lsat (integer)
+ - path (integer)
+ \par Example
+ \image html ex_lsat.gif
+ */
+ template <typename CalculationType, typename Parameters>
+ struct lsat_ellipsoid : public detail::lsat::base_lsat_ellipsoid<CalculationType, Parameters>
+ {
+ inline lsat_ellipsoid(const Parameters& par) : detail::lsat::base_lsat_ellipsoid<CalculationType, Parameters>(par)
+ {
+ detail::lsat::setup_lsat(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Static projection
+ BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lsat, lsat_ellipsoid, lsat_ellipsoid)
+
+ // Factory entry(s)
+ template <typename CalculationType, typename Parameters>
+ class lsat_entry : public detail::factory_entry<CalculationType, Parameters>
+ {
+ public :
+ virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<lsat_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par);
+ }
+ };
+
+ template <typename CalculationType, typename Parameters>
+ inline void lsat_init(detail::base_factory<CalculationType, Parameters>& factory)
+ {
+ factory.add_to_factory("lsat", new lsat_entry<CalculationType, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+} // namespace projections
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP
+
diff --git a/boost/geometry/srs/projections/proj/mbt_fps.hpp b/boost/geometry/srs/projections/proj/mbt_fps.hpp
new file mode 100644
index 0000000000..3823725f1c
--- /dev/null
+++ b/boost/geometry/srs/projections/proj/mbt_fps.hpp
@@ -0,0 +1,194 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_MBT_FPS_HPP