diff options
Diffstat (limited to 'boost/geometry/srs/projections/proj')
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(©, &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 +#define BOOST_GEOMETRY_PROJECTIONS_MBT_FPS_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 mbt_fps {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace mbt_fps + { + + static const int MAX_ITER = 10; + static const double LOOP_TOL = 1e-7; + static const double C1 = 0.45503; + static const double C2 = 1.36509; + static const double C3 = 1.41546; + static const double C_x = 0.22248; + static const double C_y = 1.44492; + //static const double C1_2 = 0.33333333333333333333333333; + + template <typename T> + inline T C1_2() { return detail::THIRD<T>(); } + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_mbt_fps_spheroid : public base_t_fi<base_mbt_fps_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_mbt_fps_spheroid(const Parameters& par) + : base_t_fi<base_mbt_fps_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_2 = mbt_fps::C1_2<CalculationType>(); + + CalculationType k, V, t; + int i; + + k = C3 * sin(lp_lat); + for (i = MAX_ITER; i ; --i) { + t = lp_lat / C2; + lp_lat -= V = (C1 * sin(t) + sin(lp_lat) - k) / + (C1_2 * cos(t) + cos(lp_lat)); + if (fabs(V) < LOOP_TOL) + break; + } + t = lp_lat / C2; + xy_x = C_x * lp_lon * (1. + 3. * cos(lp_lat)/cos(t) ); + xy_y = C_y * sin(t); + } + + // 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; + + lp_lat = C2 * (t = aasin(xy_y / C_y)); + lp_lon = xy_x / (C_x * (1. + 3. * cos(lp_lat)/cos(t))); + lp_lat = aasin((C1 * sin(t) + sin(lp_lat)) / C3); + } + + static inline std::string get_name() + { + return "mbt_fps_spheroid"; + } + + }; + + // McBryde-Thomas Flat-Pole Sine (No. 2) + template <typename Parameters> + inline void setup_mbt_fps(Parameters& par) + { + par.es = 0; + } + + }} // namespace detail::mbt_fps + #endif // doxygen + + /*! + \brief McBryde-Thomas Flat-Pole Sine (No. 2) 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_mbt_fps.gif + */ + template <typename CalculationType, typename Parameters> + struct mbt_fps_spheroid : public detail::mbt_fps::base_mbt_fps_spheroid<CalculationType, Parameters> + { + inline mbt_fps_spheroid(const Parameters& par) : detail::mbt_fps::base_mbt_fps_spheroid<CalculationType, Parameters>(par) + { + detail::mbt_fps::setup_mbt_fps(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mbt_fps, mbt_fps_spheroid, mbt_fps_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class mbt_fps_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<mbt_fps_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void mbt_fps_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("mbt_fps", new mbt_fps_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_MBT_FPS_HPP + diff --git a/boost/geometry/srs/projections/proj/mbtfpp.hpp b/boost/geometry/srs/projections/proj/mbtfpp.hpp new file mode 100644 index 0000000000..123d1e4b02 --- /dev/null +++ b/boost/geometry/srs/projections/proj/mbtfpp.hpp @@ -0,0 +1,199 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_MBTFPP_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MBTFPP_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 mbtfpp {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace mbtfpp + { + + static const double CS_ = .95257934441568037152; + static const double FXC = .92582009977255146156; + static const double FYC = 3.40168025708304504493; + //static const double C23 = .66666666666666666666; + //static const double C13 = .33333333333333333333; + static const double ONEEPS = 1.0000001; + + template <typename T> + inline T C23() { return detail::TWOTHIRD<T>(); } + template <typename T> + inline T C13() { return detail::THIRD<T>(); } + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_mbtfpp_spheroid : public base_t_fi<base_mbtfpp_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_mbtfpp_spheroid(const Parameters& par) + : base_t_fi<base_mbtfpp_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 C23 = mbtfpp::C23<CalculationType>(); + static const CalculationType C13 = mbtfpp::C13<CalculationType>(); + + lp_lat = asin(CS_ * sin(lp_lat)); + xy_x = FXC * lp_lon * (2. * cos(C23 * lp_lat) - 1.); + xy_y = FYC * sin(C13 * 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 HALFPI = detail::HALFPI<CalculationType>(); + static const CalculationType C23 = mbtfpp::C23<CalculationType>(); + + lp_lat = xy_y / FYC; + 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); + lp_lon = xy_x / ( FXC * (2. * cos(C23 * (lp_lat *= 3.)) - 1.) ); + if (fabs(lp_lat = sin(lp_lat) / CS_) >= 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); + } + + static inline std::string get_name() + { + return "mbtfpp_spheroid"; + } + + }; + + // McBride-Thomas Flat-Polar Parabolic + template <typename Parameters> + inline void setup_mbtfpp(Parameters& par) + { + par.es = 0.; + } + + }} // namespace detail::mbtfpp + #endif // doxygen + + /*! + \brief McBride-Thomas Flat-Polar Parabolic 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_mbtfpp.gif + */ + template <typename CalculationType, typename Parameters> + struct mbtfpp_spheroid : public detail::mbtfpp::base_mbtfpp_spheroid<CalculationType, Parameters> + { + inline mbtfpp_spheroid(const Parameters& par) : detail::mbtfpp::base_mbtfpp_spheroid<CalculationType, Parameters>(par) + { + detail::mbtfpp::setup_mbtfpp(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mbtfpp, mbtfpp_spheroid, mbtfpp_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class mbtfpp_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<mbtfpp_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void mbtfpp_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("mbtfpp", new mbtfpp_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_MBTFPP_HPP + diff --git a/boost/geometry/srs/projections/proj/mbtfpq.hpp b/boost/geometry/srs/projections/proj/mbtfpq.hpp new file mode 100644 index 0000000000..b4eeb34d5a --- /dev/null +++ b/boost/geometry/srs/projections/proj/mbtfpq.hpp @@ -0,0 +1,208 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_MBTFPQ_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MBTFPQ_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 mbtfpq {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace mbtfpq + { + + static const int NITER = 20; + static const double EPS = 1e-7; + static const double ONETOL = 1.000001; + static const double C = 1.70710678118654752440; + static const double RC = 0.58578643762690495119; + static const double FYC = 1.87475828462269495505; + static const double RYC = 0.53340209679417701685; + static const double FXC = 0.31245971410378249250; + static const double RXC = 3.20041258076506210122; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_mbtfpq_spheroid : public base_t_fi<base_mbtfpq_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_mbtfpq_spheroid(const Parameters& par) + : base_t_fi<base_mbtfpq_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 = C * sin(lp_lat); + for (i = NITER; i; --i) { + lp_lat -= th1 = (sin(.5*lp_lat) + sin(lp_lat) - c) / + (.5*cos(.5*lp_lat) + cos(lp_lat)); + if (fabs(th1) < EPS) break; + } + xy_x = FXC * lp_lon * (1.0 + 2. * cos(lp_lat)/cos(0.5 * lp_lat)); + xy_y = FYC * sin(0.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 + { + static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); + static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + + CalculationType t; + + lp_lat = RYC * xy_y; + if (fabs(lp_lat) > 1.) { + if (fabs(lp_lat) > ONETOL) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + else if (lp_lat < 0.) { + t = -1.; lp_lat = -ONEPI; + } else { + t = 1.; lp_lat = ONEPI; + } + } else + lp_lat = 2. * asin(t = lp_lat); + lp_lon = RXC * xy_x / (1. + 2. * cos(lp_lat)/cos(0.5 * lp_lat)); + lp_lat = RC * (t + sin(lp_lat)); + if (fabs(lp_lat) > 1.) + if (fabs(lp_lat) > ONETOL) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + else + lp_lat = lp_lat < 0. ? -HALFPI : HALFPI; + else + lp_lat = asin(lp_lat); + } + + static inline std::string get_name() + { + return "mbtfpq_spheroid"; + } + + }; + + // McBryde-Thomas Flat-Polar Quartic + template <typename Parameters> + inline void setup_mbtfpq(Parameters& par) + { + par.es = 0.; + } + + }} // namespace detail::mbtfpq + #endif // doxygen + + /*! + \brief McBryde-Thomas Flat-Polar Quartic 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_mbtfpq.gif + */ + template <typename CalculationType, typename Parameters> + struct mbtfpq_spheroid : public detail::mbtfpq::base_mbtfpq_spheroid<CalculationType, Parameters> + { + inline mbtfpq_spheroid(const Parameters& par) : detail::mbtfpq::base_mbtfpq_spheroid<CalculationType, Parameters>(par) + { + detail::mbtfpq::setup_mbtfpq(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mbtfpq, mbtfpq_spheroid, mbtfpq_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class mbtfpq_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<mbtfpq_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void mbtfpq_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("mbtfpq", new mbtfpq_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_MBTFPQ_HPP + diff --git a/boost/geometry/srs/projections/proj/merc.hpp b/boost/geometry/srs/projections/proj/merc.hpp new file mode 100644 index 0000000000..ac34aee33e --- /dev/null +++ b/boost/geometry/srs/projections/proj/merc.hpp @@ -0,0 +1,267 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_MERC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MERC_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_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 merc {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace merc + { + + static const double EPS10 = 1.e-10; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_merc_ellipsoid : public base_t_fi<base_merc_ellipsoid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_merc_ellipsoid(const Parameters& par) + : base_t_fi<base_merc_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>(); + + if (fabs(fabs(lp_lat) - HALFPI) <= EPS10) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + xy_x = this->m_par.k0 * lp_lon; + xy_y = - this->m_par.k0 * log(pj_tsfn(lp_lat, sin(lp_lat), this->m_par.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 + { + if ((lp_lat = pj_phi2(exp(- xy_y / this->m_par.k0), this->m_par.e)) == HUGE_VAL) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + lp_lon = xy_x / this->m_par.k0; + } + + static inline std::string get_name() + { + return "merc_ellipsoid"; + } + + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_merc_spheroid : public base_t_fi<base_merc_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_merc_spheroid(const Parameters& par) + : base_t_fi<base_merc_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 FORTPI = detail::FORTPI<CalculationType>(); + + if (fabs(fabs(lp_lat) - HALFPI) <= EPS10) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + xy_x = this->m_par.k0 * lp_lon; + xy_y = this->m_par.k0 * log(tan(FORTPI + .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 + { + static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + + lp_lat = HALFPI - 2. * atan(exp(-xy_y / this->m_par.k0)); + lp_lon = xy_x / this->m_par.k0; + } + + static inline std::string get_name() + { + return "merc_spheroid"; + } + + }; + + // Mercator + template <typename Parameters> + inline void setup_merc(Parameters& par) + { + typedef typename Parameters::type calc_t; + static const calc_t HALFPI = detail::HALFPI<calc_t>(); + + calc_t phits=0.0; + int is_phits; + + if( (is_phits = pj_param(par.params, "tlat_ts").i) ) { + phits = fabs(pj_param(par.params, "rlat_ts").f); + if (phits >= HALFPI) + BOOST_THROW_EXCEPTION( projection_exception(-24) ); + } + if (par.es) { /* ellipsoid */ + if (is_phits) + par.k0 = pj_msfn(sin(phits), cos(phits), par.es); + } else { /* sphere */ + if (is_phits) + par.k0 = cos(phits); + } + } + + }} // namespace detail::merc + #endif // doxygen + + /*! + \brief Mercator 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_merc.gif + */ + template <typename CalculationType, typename Parameters> + struct merc_ellipsoid : public detail::merc::base_merc_ellipsoid<CalculationType, Parameters> + { + inline merc_ellipsoid(const Parameters& par) : detail::merc::base_merc_ellipsoid<CalculationType, Parameters>(par) + { + detail::merc::setup_merc(this->m_par); + } + }; + + /*! + \brief Mercator 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_merc.gif + */ + template <typename CalculationType, typename Parameters> + struct merc_spheroid : public detail::merc::base_merc_spheroid<CalculationType, Parameters> + { + inline merc_spheroid(const Parameters& par) : detail::merc::base_merc_spheroid<CalculationType, Parameters>(par) + { + detail::merc::setup_merc(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::merc, merc_spheroid, merc_ellipsoid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class merc_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<merc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + else + return new base_v_fi<merc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void merc_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("merc", new merc_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_MERC_HPP + diff --git a/boost/geometry/srs/projections/proj/mill.hpp b/boost/geometry/srs/projections/proj/mill.hpp new file mode 100644 index 0000000000..1d3d4a01d2 --- /dev/null +++ b/boost/geometry/srs/projections/proj/mill.hpp @@ -0,0 +1,167 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_MILL_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MILL_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 mill {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace mill + { + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_mill_spheroid : public base_t_fi<base_mill_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_mill_spheroid(const Parameters& par) + : base_t_fi<base_mill_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>(); + + xy_x = lp_lon; + xy_y = log(tan(FORTPI + lp_lat * .4)) * 1.25; + } + + // 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>(); + + lp_lon = xy_x; + lp_lat = 2.5 * (atan(exp(.8 * xy_y)) - FORTPI); + } + + static inline std::string get_name() + { + return "mill_spheroid"; + } + + }; + + // Miller Cylindrical + template <typename Parameters> + inline void setup_mill(Parameters& par) + { + par.es = 0.; + } + + }} // namespace detail::mill + #endif // doxygen + + /*! + \brief Miller 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_mill.gif + */ + template <typename CalculationType, typename Parameters> + struct mill_spheroid : public detail::mill::base_mill_spheroid<CalculationType, Parameters> + { + inline mill_spheroid(const Parameters& par) : detail::mill::base_mill_spheroid<CalculationType, Parameters>(par) + { + detail::mill::setup_mill(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mill, mill_spheroid, mill_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class mill_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<mill_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void mill_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("mill", new mill_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_MILL_HPP + diff --git a/boost/geometry/srs/projections/proj/mod_ster.hpp b/boost/geometry/srs/projections/proj/mod_ster.hpp new file mode 100644 index 0000000000..8a50a275f9 --- /dev/null +++ b/boost/geometry/srs/projections/proj/mod_ster.hpp @@ -0,0 +1,522 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MOD_STER_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/aasincos.hpp> +#include <boost/geometry/srs/projections/impl/pj_zpoly1.hpp> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct mil_os {}; + struct lee_os {}; + struct gs48 {}; + struct alsk {}; + struct gs50 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace mod_ster + { + + static const double EPSLN = 1e-10; + + template <typename T> + struct par_mod_ster + { + COMPLEX<T> *zcoeff; + T cchio, schio; + int n; + }; + + /* based upon Snyder and Linck, USGS-NMD */ + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_mod_ster_ellipsoid : public base_t_fi<base_mod_ster_ellipsoid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_mod_ster<CalculationType> m_proj_parm; + + inline base_mod_ster_ellipsoid(const Parameters& par) + : base_t_fi<base_mod_ster_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 sinlon, coslon, esphi, chi, schi, cchi, s; + COMPLEX<CalculationType> p; + + sinlon = sin(lp_lon); + coslon = cos(lp_lon); + esphi = this->m_par.e * sin(lp_lat); + chi = 2. * atan(tan((HALFPI + lp_lat) * .5) * + pow((1. - esphi) / (1. + esphi), this->m_par.e * .5)) - HALFPI; + schi = sin(chi); + cchi = cos(chi); + s = 2. / (1. + this->m_proj_parm.schio * schi + this->m_proj_parm.cchio * cchi * coslon); + p.r = s * cchi * sinlon; + p.i = s * (this->m_proj_parm.cchio * schi - this->m_proj_parm.schio * cchi * coslon); + p = pj_zpoly1(p, this->m_proj_parm.zcoeff, this->m_proj_parm.n); + xy_x = p.r; + xy_y = p.i; + } + + // 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>(); + + int nn; + COMPLEX<CalculationType> p, fxy, fpxy, dp; + CalculationType den, rh = 0, z, sinz = 0, cosz = 0, chi, phi = 0, dphi, esphi; + + p.r = xy_x; + p.i = xy_y; + for (nn = 20; nn ;--nn) { + fxy = pj_zpolyd1(p, this->m_proj_parm.zcoeff, this->m_proj_parm.n, &fpxy); + fxy.r -= xy_x; + fxy.i -= xy_y; + den = fpxy.r * fpxy.r + fpxy.i * fpxy.i; + dp.r = -(fxy.r * fpxy.r + fxy.i * fpxy.i) / den; + dp.i = -(fxy.i * fpxy.r - fxy.r * fpxy.i) / den; + p.r += dp.r; + p.i += dp.i; + if ((fabs(dp.r) + fabs(dp.i)) <= EPSLN) + break; + } + if (nn) { + rh = boost::math::hypot(p.r, p.i); + z = 2. * atan(.5 * rh); + sinz = sin(z); + cosz = cos(z); + lp_lon = this->m_par.lam0; + if (fabs(rh) <= EPSLN) { + lp_lat = this->m_par.phi0; + return; + } + chi = aasin(cosz * this->m_proj_parm.schio + p.i * sinz * this->m_proj_parm.cchio / rh); + phi = chi; + for (nn = 20; nn ;--nn) { + esphi = this->m_par.e * sin(phi); + dphi = 2. * atan(tan((HALFPI + chi) * .5) * + pow((1. + esphi) / (1. - esphi), this->m_par.e * .5)) - HALFPI - phi; + phi += dphi; + if (fabs(dphi) <= EPSLN) + break; + } + } + if (nn) { + lp_lat = phi; + lp_lon = atan2(p.r * sinz, rh * this->m_proj_parm.cchio * cosz - p.i * + this->m_proj_parm.schio * sinz); + } else + lp_lon = lp_lat = HUGE_VAL; + } + + static inline std::string get_name() + { + return "mod_ster_ellipsoid"; + } + + }; + + template <typename Parameters, typename T> + inline void setup(Parameters& par, par_mod_ster<T>& proj_parm) /* general initialization */ + { + T esphi, chio; + + if (par.es) { + esphi = par.e * sin(par.phi0); + chio = 2. * atan(tan((geometry::math::half_pi<T>() + par.phi0) * .5) * + pow((1. - esphi) / (1. + esphi), par.e * .5)) - geometry::math::half_pi<T>(); + } else + chio = par.phi0; + proj_parm.schio = sin(chio); + proj_parm.cchio = cos(chio); + } + + + // Miller Oblated Stereographic + template <typename Parameters, typename T> + inline void setup_mil_os(Parameters& par, par_mod_ster<T>& proj_parm) + { + static COMPLEX<T> /* Miller Oblated Stereographic */ + AB[] = { + {0.924500, 0.}, + {0., 0.}, + {0.019430, 0.} + }; + + proj_parm.n = 2; + par.lam0 = geometry::math::d2r<T>() * 20.; + par.phi0 = geometry::math::d2r<T>() * 18.; + proj_parm.zcoeff = AB; + par.es = 0.; + setup(par, proj_parm); + } + + // Lee Oblated Stereographic + template <typename Parameters, typename T> + inline void setup_lee_os(Parameters& par, par_mod_ster<T>& proj_parm) + { + static COMPLEX<T> /* Lee Oblated Stereographic */ + AB[] = { + {0.721316, 0.}, + {0., 0.}, + {-0.0088162, -0.00617325} + }; + + proj_parm.n = 2; + par.lam0 = geometry::math::d2r<T>() * -165.; + par.phi0 = geometry::math::d2r<T>() * -10.; + proj_parm.zcoeff = AB; + par.es = 0.; + setup(par, proj_parm); + } + + // Mod. Stererographics of 48 U.S. + template <typename Parameters, typename T> + inline void setup_gs48(Parameters& par, par_mod_ster<T>& proj_parm) + { + static COMPLEX<T> /* 48 United States */ + AB[] = { + {0.98879, 0.}, + {0., 0.}, + {-0.050909, 0.}, + {0., 0.}, + {0.075528, 0.} + }; + + proj_parm.n = 4; + par.lam0 = geometry::math::d2r<T>() * -96.; + par.phi0 = geometry::math::d2r<T>() * -39.; + proj_parm.zcoeff = AB; + par.es = 0.; + par.a = 6370997.; + setup(par, proj_parm); + } + + // Mod. Stererographics of Alaska + template <typename Parameters, typename T> + inline void setup_alsk(Parameters& par, par_mod_ster<T>& proj_parm) + { + static COMPLEX<T> + ABe[] = { /* Alaska ellipsoid */ + {.9945303, 0.}, + {.0052083, -.0027404}, + {.0072721, .0048181}, + {-.0151089, -.1932526}, + {.0642675, -.1381226}, + {.3582802, -.2884586}}, + ABs[] = { /* Alaska sphere */ + {.9972523, 0.}, + {.0052513, -.0041175}, + {.0074606, .0048125}, + {-.0153783, -.1968253}, + {.0636871, -.1408027}, + {.3660976, -.2937382} + }; + + proj_parm.n = 5; + par.lam0 = geometry::math::d2r<T>() * -152.; + par.phi0 = geometry::math::d2r<T>() * 64.; + if (par.es) { /* fixed ellipsoid/sphere */ + proj_parm.zcoeff = ABe; + par.a = 6378206.4; + par.e = sqrt(par.es = 0.00676866); + } else { + proj_parm.zcoeff = ABs; + par.a = 6370997.; + } + setup(par, proj_parm); + } + + // Mod. Stererographics of 50 U.S. + template <typename Parameters, typename T> + inline void setup_gs50(Parameters& par, par_mod_ster<T>& proj_parm) + { + static COMPLEX<T> + ABe[] = { /* GS50 ellipsoid */ + {.9827497, 0.}, + {.0210669, .0053804}, + {-.1031415, -.0571664}, + {-.0323337, -.0322847}, + {.0502303, .1211983}, + {.0251805, .0895678}, + {-.0012315, -.1416121}, + {.0072202, -.1317091}, + {-.0194029, .0759677}, + {-.0210072, .0834037} + }, + ABs[] = { /* GS50 sphere */ + {.9842990, 0.}, + {.0211642, .0037608}, + {-.1036018, -.0575102}, + {-.0329095, -.0320119}, + {.0499471, .1223335}, + {.0260460, .0899805}, + {.0007388, -.1435792}, + {.0075848, -.1334108}, + {-.0216473, .0776645}, + {-.0225161, .0853673} + }; + + proj_parm.n = 9; + par.lam0 = geometry::math::d2r<T>() * -120.; + par.phi0 = geometry::math::d2r<T>() * 45.; + if (par.es) { /* fixed ellipsoid/sphere */ + proj_parm.zcoeff = ABe; + par.a = 6378206.4; + par.e = sqrt(par.es = 0.00676866); + } else { + proj_parm.zcoeff = ABs; + par.a = 6370997.; + } + setup(par, proj_parm); + } + + }} // namespace detail::mod_ster + #endif // doxygen + + /*! + \brief Miller Oblated Stereographic projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Azimuthal (mod) + \par Example + \image html ex_mil_os.gif + */ + template <typename CalculationType, typename Parameters> + struct mil_os_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters> + { + inline mil_os_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par) + { + detail::mod_ster::setup_mil_os(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Lee Oblated Stereographic projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Azimuthal (mod) + \par Example + \image html ex_lee_os.gif + */ + template <typename CalculationType, typename Parameters> + struct lee_os_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters> + { + inline lee_os_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par) + { + detail::mod_ster::setup_lee_os(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Mod. Stererographics of 48 U.S. projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Azimuthal (mod) + \par Example + \image html ex_gs48.gif + */ + template <typename CalculationType, typename Parameters> + struct gs48_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters> + { + inline gs48_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par) + { + detail::mod_ster::setup_gs48(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Mod. Stererographics of Alaska projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Azimuthal (mod) + \par Example + \image html ex_alsk.gif + */ + template <typename CalculationType, typename Parameters> + struct alsk_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters> + { + inline alsk_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par) + { + detail::mod_ster::setup_alsk(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Mod. Stererographics of 50 U.S. projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Azimuthal (mod) + \par Example + \image html ex_gs50.gif + */ + template <typename CalculationType, typename Parameters> + struct gs50_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters> + { + inline gs50_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<CalculationType, Parameters>(par) + { + detail::mod_ster::setup_gs50(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mil_os, mil_os_ellipsoid, mil_os_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::lee_os, lee_os_ellipsoid, lee_os_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gs48, gs48_ellipsoid, gs48_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::alsk, alsk_ellipsoid, alsk_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::gs50, gs50_ellipsoid, gs50_ellipsoid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class mil_os_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<mil_os_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class lee_os_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<lee_os_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class gs48_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<gs48_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class alsk_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<alsk_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class gs50_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<gs50_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void mod_ster_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("mil_os", new mil_os_entry<CalculationType, Parameters>); + factory.add_to_factory("lee_os", new lee_os_entry<CalculationType, Parameters>); + factory.add_to_factory("gs48", new gs48_entry<CalculationType, Parameters>); + factory.add_to_factory("alsk", new alsk_entry<CalculationType, Parameters>); + factory.add_to_factory("gs50", new gs50_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP + diff --git a/boost/geometry/srs/projections/proj/moll.hpp b/boost/geometry/srs/projections/proj/moll.hpp new file mode 100644 index 0000000000..6f02c7dea0 --- /dev/null +++ b/boost/geometry/srs/projections/proj/moll.hpp @@ -0,0 +1,294 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_MOLL_HPP +#define BOOST_GEOMETRY_PROJECTIONS_MOLL_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 moll {}; + struct wag4 {}; + struct wag5 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace moll + { + + static const int MAX_ITER = 10; + static const double LOOP_TOL = 1e-7; + + template <typename T> + struct par_moll + { + T C_x, C_y, C_p; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_moll_spheroid : public base_t_fi<base_moll_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_moll<CalculationType> m_proj_parm; + + inline base_moll_spheroid(const Parameters& par) + : base_t_fi<base_moll_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 k, V; + int i; + + k = this->m_proj_parm.C_p * sin(lp_lat); + for (i = MAX_ITER; i ; --i) { + lp_lat -= V = (lp_lat + sin(lp_lat) - k) / + (1. + cos(lp_lat)); + if (fabs(V) < LOOP_TOL) + break; + } + if (!i) + lp_lat = (lp_lat < 0.) ? -HALFPI : HALFPI; + else + lp_lat *= 0.5; + xy_x = this->m_proj_parm.C_x * lp_lon * cos(lp_lat); + xy_y = this->m_proj_parm.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 + { + lp_lat = aasin(xy_y / this->m_proj_parm.C_y); + lp_lon = xy_x / (this->m_proj_parm.C_x * cos(lp_lat)); + lp_lat += lp_lat; + lp_lat = aasin((lp_lat + sin(lp_lat)) / this->m_proj_parm.C_p); + } + + static inline std::string get_name() + { + return "moll_spheroid"; + } + + }; + + template <typename Parameters, typename T> + inline void setup(Parameters& par, par_moll<T>& proj_parm, T const& p) + { + T r, sp, p2 = p + p; + + par.es = 0; + sp = sin(p); + r = sqrt(geometry::math::two_pi<T>() * sp / (p2 + sin(p2))); + proj_parm.C_x = 2. * r / geometry::math::pi<T>(); + proj_parm.C_y = r / sp; + proj_parm.C_p = p2 + sin(p2); + } + + + // Mollweide + template <typename Parameters, typename T> + inline void setup_moll(Parameters& par, par_moll<T>& proj_parm) + { + setup(par, proj_parm, geometry::math::half_pi<T>()); + } + + // Wagner IV + template <typename Parameters, typename T> + inline void setup_wag4(Parameters& par, par_moll<T>& proj_parm) + { + setup(par, proj_parm, geometry::math::pi<T>()/3.); + } + + // Wagner V + template <typename Parameters, typename T> + inline void setup_wag5(Parameters& par, par_moll<T>& proj_parm) + { + par.es = 0; + proj_parm.C_x = 0.90977; + proj_parm.C_y = 1.65014; + proj_parm.C_p = 3.00896; + } + + }} // namespace detail::moll + #endif // doxygen + + /*! + \brief Mollweide 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_moll.gif + */ + template <typename CalculationType, typename Parameters> + struct moll_spheroid : public detail::moll::base_moll_spheroid<CalculationType, Parameters> + { + inline moll_spheroid(const Parameters& par) : detail::moll::base_moll_spheroid<CalculationType, Parameters>(par) + { + detail::moll::setup_moll(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Wagner 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_wag4.gif + */ + template <typename CalculationType, typename Parameters> + struct wag4_spheroid : public detail::moll::base_moll_spheroid<CalculationType, Parameters> + { + inline wag4_spheroid(const Parameters& par) : detail::moll::base_moll_spheroid<CalculationType, Parameters>(par) + { + detail::moll::setup_wag4(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Wagner 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_wag5.gif + */ + template <typename CalculationType, typename Parameters> + struct wag5_spheroid : public detail::moll::base_moll_spheroid<CalculationType, Parameters> + { + inline wag5_spheroid(const Parameters& par) : detail::moll::base_moll_spheroid<CalculationType, Parameters>(par) + { + detail::moll::setup_wag5(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::moll, moll_spheroid, moll_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wag4, wag4_spheroid, wag4_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wag5, wag5_spheroid, wag5_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class moll_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<moll_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class wag4_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<wag4_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class wag5_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<wag5_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void moll_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("moll", new moll_entry<CalculationType, Parameters>); + factory.add_to_factory("wag4", new wag4_entry<CalculationType, Parameters>); + factory.add_to_factory("wag5", new wag5_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_MOLL_HPP + diff --git a/boost/geometry/srs/projections/proj/natearth.hpp b/boost/geometry/srs/projections/proj/natearth.hpp new file mode 100644 index 0000000000..dcd259d9d1 --- /dev/null +++ b/boost/geometry/srs/projections/proj/natearth.hpp @@ -0,0 +1,228 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_NATEARTH_HPP +#define BOOST_GEOMETRY_PROJECTIONS_NATEARTH_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: + +// The Natural Earth projection was designed by Tom Patterson, US National Park +// Service, in 2007, using Flex Projector. The shape of the original projection +// was defined at every 5 degrees and piece-wise cubic spline interpolation was +// used to compute the complete graticule. +// The code here uses polynomial functions instead of cubic splines and +// is therefore much simpler to program. The polynomial approximation was +// developed by Bojan Savric, in collaboration with Tom Patterson and Bernhard +// Jenny, Institute of Cartography, ETH Zurich. It slightly deviates from +// Patterson's original projection by adding additional curvature to meridians +// where they meet the horizontal pole line. This improvement is by intention +// and designed in collaboration with Tom Patterson. +// Port to PROJ.4 by Bernhard Jenny, 6 June 2011 + +// 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 natearth {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace natearth + { + + static const double A0 = 0.8707; + static const double A1 = -0.131979; + static const double A2 = -0.013791; + static const double A3 = 0.003971; + static const double A4 = -0.001529; + static const double B0 = 1.007226; + static const double B1 = 0.015085; + static const double B2 = -0.044475; + static const double B3 = 0.028874; + static const double B4 = -0.005916; + static const double C0 = B0; + static const double C1 = (3 * B1); + static const double C2 = (7 * B2); + static const double C3 = (9 * B3); + static const double C4 = (11 * B4); + static const double EPS = 1e-11; + //static const double MAX_Y = (0.8707 * 0.52 * geometry::math::pi<double>()); + + template <typename T> + inline T MAX_Y() { return (0.8707 * 0.52 * detail::ONEPI<T>()); } + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_natearth_spheroid : public base_t_fi<base_natearth_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_natearth_spheroid(const Parameters& par) + : base_t_fi<base_natearth_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 phi2, phi4; + + phi2 = lp_lat * lp_lat; + phi4 = phi2 * phi2; + xy_x = lp_lon * (A0 + phi2 * (A1 + phi2 * (A2 + phi4 * phi2 * (A3 + phi2 * A4)))); + xy_y = lp_lat * (B0 + phi2 * (B1 + phi4 * (B2 + B3 * phi2 + B4 * phi4))); + } + + // 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 MAX_Y = natearth::MAX_Y<CalculationType>(); + + CalculationType yc, tol, y2, y4, f, fder; + + /* make sure y is inside valid range */ + if (xy_y > MAX_Y) { + xy_y = MAX_Y; + } else if (xy_y < -MAX_Y) { + xy_y = -MAX_Y; + } + + /* latitude */ + yc = xy_y; + for (;;) { /* Newton-Raphson */ + y2 = yc * yc; + y4 = y2 * y2; + f = (yc * (B0 + y2 * (B1 + y4 * (B2 + B3 * y2 + B4 * y4)))) - xy_y; + fder = C0 + y2 * (C1 + y4 * (C2 + C3 * y2 + C4 * y4)); + yc -= tol = f / fder; + if (fabs(tol) < EPS) { + break; + } + } + lp_lat = yc; + + /* longitude */ + y2 = yc * yc; + lp_lon = xy_x / (A0 + y2 * (A1 + y2 * (A2 + y2 * y2 * y2 * (A3 + y2 * A4)))); + } + + static inline std::string get_name() + { + return "natearth_spheroid"; + } + + }; + + // Natural Earth + template <typename Parameters> + inline void setup_natearth(Parameters& par) + { + par.es = 0; + } + + }} // namespace detail::natearth + #endif // doxygen + + /*! + \brief Natural Earth 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_natearth.gif + */ + template <typename CalculationType, typename Parameters> + struct natearth_spheroid : public detail::natearth::base_natearth_spheroid<CalculationType, Parameters> + { + inline natearth_spheroid(const Parameters& par) : detail::natearth::base_natearth_spheroid<CalculationType, Parameters>(par) + { + detail::natearth::setup_natearth(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::natearth, natearth_spheroid, natearth_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class natearth_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<natearth_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void natearth_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("natearth", new natearth_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_NATEARTH_HPP + diff --git a/boost/geometry/srs/projections/proj/nell.hpp b/boost/geometry/srs/projections/proj/nell.hpp new file mode 100644 index 0000000000..351a4101f7 --- /dev/null +++ b/boost/geometry/srs/projections/proj/nell.hpp @@ -0,0 +1,180 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_NELL_HPP +#define BOOST_GEOMETRY_PROJECTIONS_NELL_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 nell {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace nell + { + + static const int MAX_ITER = 10; + static const double LOOP_TOL = 1e-7; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_nell_spheroid : public base_t_fi<base_nell_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_nell_spheroid(const Parameters& par) + : base_t_fi<base_nell_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 k, V; + int i; + + k = 2. * sin(lp_lat); + V = lp_lat * lp_lat; + lp_lat *= 1.00371 + V * (-0.0935382 + V * -0.011412); + for (i = MAX_ITER; i ; --i) { + lp_lat -= V = (lp_lat + sin(lp_lat) - k) / + (1. + cos(lp_lat)); + if (fabs(V) < LOOP_TOL) + break; + } + xy_x = 0.5 * lp_lon * (1. + cos(lp_lat)); + xy_y = 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 = 2. * xy_x / (1. + cos(xy_y)); + lp_lat = aasin(0.5 * (xy_y + sin(xy_y))); + } + + static inline std::string get_name() + { + return "nell_spheroid"; + } + + }; + + // Nell + template <typename Parameters> + inline void setup_nell(Parameters& par) + { + par.es = 0; + } + + }} // namespace detail::nell + #endif // doxygen + + /*! + \brief Nell 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_nell.gif + */ + template <typename CalculationType, typename Parameters> + struct nell_spheroid : public detail::nell::base_nell_spheroid<CalculationType, Parameters> + { + inline nell_spheroid(const Parameters& par) : detail::nell::base_nell_spheroid<CalculationType, Parameters>(par) + { + detail::nell::setup_nell(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::nell, nell_spheroid, nell_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class nell_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<nell_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void nell_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("nell", new nell_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_NELL_HPP + diff --git a/boost/geometry/srs/projections/proj/nell_h.hpp b/boost/geometry/srs/projections/proj/nell_h.hpp new file mode 100644 index 0000000000..05de9e263e --- /dev/null +++ b/boost/geometry/srs/projections/proj/nell_h.hpp @@ -0,0 +1,184 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_NELL_H_HPP +#define BOOST_GEOMETRY_PROJECTIONS_NELL_H_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 nell_h {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace nell_h + { + + static const int NITER = 9; + static const double EPS = 1e-7; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_nell_h_spheroid : public base_t_fi<base_nell_h_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_nell_h_spheroid(const Parameters& par) + : base_t_fi<base_nell_h_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 = 0.5 * lp_lon * (1. + cos(lp_lat)); + xy_y = 2.0 * (lp_lat - tan(0.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 + { + static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + + CalculationType V, c, p; + int i; + + p = 0.5 * xy_y; + for (i = NITER; i ; --i) { + c = cos(0.5 * lp_lat); + lp_lat -= V = (lp_lat - tan(lp_lat/2) - p)/(1. - 0.5/(c*c)); + if (fabs(V) < EPS) + break; + } + if (!i) { + lp_lat = p < 0. ? -HALFPI : HALFPI; + lp_lon = 2. * xy_x; + } else + lp_lon = 2. * xy_x / (1. + cos(lp_lat)); + } + + static inline std::string get_name() + { + return "nell_h_spheroid"; + } + + }; + + // Nell-Hammer + template <typename Parameters> + inline void setup_nell_h(Parameters& par) + { + par.es = 0.; + } + + }} // namespace detail::nell_h + #endif // doxygen + + /*! + \brief Nell-Hammer 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_nell_h.gif + */ + template <typename CalculationType, typename Parameters> + struct nell_h_spheroid : public detail::nell_h::base_nell_h_spheroid<CalculationType, Parameters> + { + inline nell_h_spheroid(const Parameters& par) : detail::nell_h::base_nell_h_spheroid<CalculationType, Parameters>(par) + { + detail::nell_h::setup_nell_h(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::nell_h, nell_h_spheroid, nell_h_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class nell_h_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<nell_h_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void nell_h_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("nell_h", new nell_h_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_NELL_H_HPP + diff --git a/boost/geometry/srs/projections/proj/nocol.hpp b/boost/geometry/srs/projections/proj/nocol.hpp new file mode 100644 index 0000000000..ef2e95a843 --- /dev/null +++ b/boost/geometry/srs/projections/proj/nocol.hpp @@ -0,0 +1,190 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_NOCOL_HPP +#define BOOST_GEOMETRY_PROJECTIONS_NOCOL_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 nicol {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace nocol + { + + static const double EPS = 1e-10; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_nocol_spheroid : public base_t_f<base_nocol_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_nocol_spheroid(const Parameters& par) + : base_t_f<base_nocol_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(lp_lon) < EPS) { + xy_x = 0; + xy_y = lp_lat; + } else if (fabs(lp_lat) < EPS) { + xy_x = lp_lon; + xy_y = 0.; + } else if (fabs(fabs(lp_lon) - HALFPI) < EPS) { + xy_x = lp_lon * cos(lp_lat); + xy_y = HALFPI * sin(lp_lat); + } else if (fabs(fabs(lp_lat) - HALFPI) < EPS) { + xy_x = 0; + xy_y = lp_lat; + } else { + CalculationType tb, c, d, m, n, r2, sp; + + tb = HALFPI / lp_lon - lp_lon / HALFPI; + c = lp_lat / HALFPI; + d = (1 - c * c)/((sp = sin(lp_lat)) - c); + r2 = tb / d; + r2 *= r2; + m = (tb * sp / d - 0.5 * tb)/(1. + r2); + n = (sp / r2 + 0.5 * d)/(1. + 1./r2); + xy_x = cos(lp_lat); + xy_x = sqrt(m * m + xy_x * xy_x / (1. + r2)); + xy_x = HALFPI * ( m + (lp_lon < 0. ? -xy_x : xy_x)); + xy_y = sqrt(n * n - (sp * sp / r2 + d * sp - 1.) / + (1. + 1./r2)); + xy_y = HALFPI * ( n + (lp_lat < 0. ? xy_y : -xy_y )); + } + } + + static inline std::string get_name() + { + return "nocol_spheroid"; + } + + }; + + // Nicolosi Globular + template <typename Parameters> + inline void setup_nicol(Parameters& par) + { + par.es = 0.; + } + + }} // namespace detail::nocol + #endif // doxygen + + /*! + \brief Nicolosi 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_nicol.gif + */ + template <typename CalculationType, typename Parameters> + struct nicol_spheroid : public detail::nocol::base_nocol_spheroid<CalculationType, Parameters> + { + inline nicol_spheroid(const Parameters& par) : detail::nocol::base_nocol_spheroid<CalculationType, Parameters>(par) + { + detail::nocol::setup_nicol(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::nicol, nicol_spheroid, nicol_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class nicol_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_f<nicol_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void nocol_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("nicol", new nicol_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_NOCOL_HPP + diff --git a/boost/geometry/srs/projections/proj/nsper.hpp b/boost/geometry/srs/projections/proj/nsper.hpp new file mode 100644 index 0000000000..85576bf963 --- /dev/null +++ b/boost/geometry/srs/projections/proj/nsper.hpp @@ -0,0 +1,355 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_NSPER_HPP +#define BOOST_GEOMETRY_PROJECTIONS_NSPER_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 nsper {}; + struct tpers {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace nsper + { + + 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_nsper + { + T height; + T sinph0; + T cosph0; + T p; + T rp; + T pn1; + T pfact; + T h; + T cg; + T sg; + T sw; + T cw; + int mode; + int tilt; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_nsper_spheroid : public base_t_fi<base_nsper_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_nsper<CalculationType> m_proj_parm; + + inline base_nsper_spheroid(const Parameters& par) + : base_t_fi<base_nsper_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 OBLIQ: + xy_y = this->m_proj_parm.sinph0 * sinphi + this->m_proj_parm.cosph0 * cosphi * coslam; + break; + case EQUIT: + xy_y = cosphi * coslam; + break; + case S_POLE: + xy_y = - sinphi; + break; + case N_POLE: + xy_y = sinphi; + break; + } + if (xy_y < this->m_proj_parm.rp) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + xy_y = this->m_proj_parm.pn1 / (this->m_proj_parm.p - xy_y); + xy_x = xy_y * cosphi * sin(lp_lon); + switch (this->m_proj_parm.mode) { + case OBLIQ: + xy_y *= (this->m_proj_parm.cosph0 * sinphi - + this->m_proj_parm.sinph0 * cosphi * coslam); + break; + case EQUIT: + xy_y *= sinphi; + break; + case N_POLE: + coslam = - coslam; + BOOST_FALLTHROUGH; + case S_POLE: + xy_y *= cosphi * coslam; + break; + } + if (this->m_proj_parm.tilt) { + CalculationType yt, ba; + + yt = xy_y * this->m_proj_parm.cg + xy_x * this->m_proj_parm.sg; + ba = 1. / (yt * this->m_proj_parm.sw * this->m_proj_parm.h + this->m_proj_parm.cw); + xy_x = (xy_x * this->m_proj_parm.cg - xy_y * this->m_proj_parm.sg) * this->m_proj_parm.cw * ba; + xy_y = yt * ba; + } + } + + // 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 rh, cosz, sinz; + + if (this->m_proj_parm.tilt) { + CalculationType bm, bq, yt; + + yt = 1./(this->m_proj_parm.pn1 - xy_y * this->m_proj_parm.sw); + bm = this->m_proj_parm.pn1 * xy_x * yt; + bq = this->m_proj_parm.pn1 * xy_y * this->m_proj_parm.cw * yt; + xy_x = bm * this->m_proj_parm.cg + bq * this->m_proj_parm.sg; + xy_y = bq * this->m_proj_parm.cg - bm * this->m_proj_parm.sg; + } + rh = boost::math::hypot(xy_x, xy_y); + if ((sinz = 1. - rh * rh * this->m_proj_parm.pfact) < 0.) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + sinz = (this->m_proj_parm.p - sqrt(sinz)) / (this->m_proj_parm.pn1 / rh + rh / this->m_proj_parm.pn1); + cosz = sqrt(1. - sinz * sinz); + if (fabs(rh) <= EPS10) { + lp_lon = 0.; + lp_lat = this->m_par.phi0; + } else { + switch (this->m_proj_parm.mode) { + case OBLIQ: + lp_lat = asin(cosz * this->m_proj_parm.sinph0 + xy_y * sinz * this->m_proj_parm.cosph0 / rh); + 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 = asin(xy_y * sinz / rh); + xy_y = cosz * rh; + xy_x *= sinz; + break; + case N_POLE: + lp_lat = asin(cosz); + xy_y = -xy_y; + break; + case S_POLE: + lp_lat = - asin(cosz); + break; + } + lp_lon = atan2(xy_x, xy_y); + } + } + + static inline std::string get_name() + { + return "nsper_spheroid"; + } + + }; + + template <typename Parameters, typename T> + inline void setup(Parameters& par, par_nsper<T>& proj_parm) + { + if ((proj_parm.height = pj_param(par.params, "dh").f) <= 0.) + BOOST_THROW_EXCEPTION( projection_exception(-30) ); + if (fabs(fabs(par.phi0) - geometry::math::half_pi<T>()) < 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); + } + proj_parm.pn1 = proj_parm.height / par.a; /* normalize by radius */ + proj_parm.p = 1. + proj_parm.pn1; + proj_parm.rp = 1. / proj_parm.p; + proj_parm.h = 1. / proj_parm.pn1; + proj_parm.pfact = (proj_parm.p + 1.) * proj_parm.h; + par.es = 0.; + } + + + // Near-sided perspective + template <typename Parameters, typename T> + inline void setup_nsper(Parameters& par, par_nsper<T>& proj_parm) + { + proj_parm.tilt = 0; + setup(par, proj_parm); + } + + // Tilted perspective + template <typename Parameters, typename T> + inline void setup_tpers(Parameters& par, par_nsper<T>& proj_parm) + { + T omega, gamma; + + omega = pj_param(par.params, "dtilt").f * geometry::math::d2r<T>(); + gamma = pj_param(par.params, "dazi").f * geometry::math::d2r<T>(); + proj_parm.tilt = 1; + proj_parm.cg = cos(gamma); proj_parm.sg = sin(gamma); + proj_parm.cw = cos(omega); proj_parm.sw = sin(omega); + setup(par, proj_parm); + } + + }} // namespace detail::nsper + #endif // doxygen + + /*! + \brief Near-sided perspective projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Azimuthal + - Spheroid + \par Projection parameters + - h: Height + \par Example + \image html ex_nsper.gif + */ + template <typename CalculationType, typename Parameters> + struct nsper_spheroid : public detail::nsper::base_nsper_spheroid<CalculationType, Parameters> + { + inline nsper_spheroid(const Parameters& par) : detail::nsper::base_nsper_spheroid<CalculationType, Parameters>(par) + { + detail::nsper::setup_nsper(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Tilted perspective projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Azimuthal + - Spheroid + \par Projection parameters + - tilt: Tilt, or Omega (real) + - azi: Azimuth (or Gamma) (real) + - h: Height + \par Example + \image html ex_tpers.gif + */ + template <typename CalculationType, typename Parameters> + struct tpers_spheroid : public detail::nsper::base_nsper_spheroid<CalculationType, Parameters> + { + inline tpers_spheroid(const Parameters& par) : detail::nsper::base_nsper_spheroid<CalculationType, Parameters>(par) + { + detail::nsper::setup_tpers(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::nsper, nsper_spheroid, nsper_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::tpers, tpers_spheroid, tpers_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class nsper_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<nsper_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class tpers_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<tpers_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void nsper_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("nsper", new nsper_entry<CalculationType, Parameters>); + factory.add_to_factory("tpers", new tpers_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_NSPER_HPP + diff --git a/boost/geometry/srs/projections/proj/nzmg.hpp b/boost/geometry/srs/projections/proj/nzmg.hpp new file mode 100644 index 0000000000..067eece27a --- /dev/null +++ b/boost/geometry/srs/projections/proj/nzmg.hpp @@ -0,0 +1,255 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_NZMG_HPP +#define BOOST_GEOMETRY_PROJECTIONS_NZMG_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 nzmg (New Zealand Map Grid) projection. +// Very loosely based upon DMA code by Bradford W. Drew +// 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/impl/pj_zpoly1.hpp> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct nzmg {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace nzmg + { + + static const double EPSLN = 1e-10; + //static const double SEC5_TO_RAD = 0.4848136811095359935899141023; + //static const double RAD_TO_SEC5 = 2.062648062470963551564733573; + static const int Nbf = 5; + static const int Ntpsi = 9; + static const int Ntphi = 8; + + template <typename T> + inline T SEC5_TO_RAD() { return 0.4848136811095359935899141023; } + template <typename T> + inline T RAD_TO_SEC5() { return 2.062648062470963551564733573; } + + template <typename T> + inline const COMPLEX<T> * bf() + { + static const COMPLEX<T> result[] = { + {.7557853228, 0.0}, + {.249204646, .003371507}, + {-.001541739, .041058560}, + {-.10162907, .01727609}, + {-.26623489, -.36249218}, + {-.6870983, -1.1651967} + }; + return result; + } + + template <typename T> + inline const T * tphi() + { + static const T result[] = { 1.5627014243, .5185406398, -.03333098, -.1052906, -.0368594, + .007317, .01220, .00394, -.0013 }; + return result; + } + template <typename T> + inline const T * tpsi() + { + static const T result[] = { .6399175073, -.1358797613, .063294409, -.02526853, .0117879, + -.0055161, .0026906, -.001333, .00067, -.00034 }; + return result; + } + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_nzmg_ellipsoid : public base_t_fi<base_nzmg_ellipsoid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_nzmg_ellipsoid(const Parameters& par) + : base_t_fi<base_nzmg_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 RAD_TO_SEC5 = nzmg::RAD_TO_SEC5<CalculationType>(); + + COMPLEX<CalculationType> p; + const CalculationType * C; + int i; + + lp_lat = (lp_lat - this->m_par.phi0) * RAD_TO_SEC5; + for (p.r = *(C = tpsi<CalculationType>() + (i = Ntpsi)); i ; --i) + p.r = *--C + lp_lat * p.r; + p.r *= lp_lat; + p.i = lp_lon; + p = pj_zpoly1(p, bf<CalculationType>(), Nbf); + xy_x = p.i; + xy_y = p.r; + } + + // 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 SEC5_TO_RAD = nzmg::SEC5_TO_RAD<CalculationType>(); + + int nn, i; + COMPLEX<CalculationType> p, f, fp, dp; + CalculationType den; + const CalculationType* C; + + p.r = xy_y; + p.i = xy_x; + for (nn = 20; nn ;--nn) { + f = pj_zpolyd1(p, bf<CalculationType>(), Nbf, &fp); + f.r -= xy_y; + f.i -= xy_x; + den = fp.r * fp.r + fp.i * fp.i; + p.r += dp.r = -(f.r * fp.r + f.i * fp.i) / den; + p.i += dp.i = -(f.i * fp.r - f.r * fp.i) / den; + if ((fabs(dp.r) + fabs(dp.i)) <= EPSLN) + break; + } + if (nn) { + lp_lon = p.i; + for (lp_lat = *(C = tphi<CalculationType>() + (i = Ntphi)); i ; --i) + lp_lat = *--C + p.r * lp_lat; + lp_lat = this->m_par.phi0 + p.r * lp_lat * SEC5_TO_RAD; + } else + lp_lon = lp_lat = HUGE_VAL; + } + + static inline std::string get_name() + { + return "nzmg_ellipsoid"; + } + + }; + + // New Zealand Map Grid + template <typename Parameters> + inline void setup_nzmg(Parameters& par) + { + typedef typename Parameters::type calc_t; + + /* force to International major axis */ + par.ra = 1. / (par.a = 6378388.0); + par.lam0 = geometry::math::d2r<calc_t>() * 173.; + par.phi0 = geometry::math::d2r<calc_t>() * -41.; + par.x0 = 2510000.; + par.y0 = 6023150.; + } + + }} // namespace detail::nzmg + #endif // doxygen + + /*! + \brief New Zealand Map Grid projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Fixed Earth + \par Example + \image html ex_nzmg.gif + */ + template <typename CalculationType, typename Parameters> + struct nzmg_ellipsoid : public detail::nzmg::base_nzmg_ellipsoid<CalculationType, Parameters> + { + inline nzmg_ellipsoid(const Parameters& par) : detail::nzmg::base_nzmg_ellipsoid<CalculationType, Parameters>(par) + { + detail::nzmg::setup_nzmg(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::nzmg, nzmg_ellipsoid, nzmg_ellipsoid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class nzmg_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<nzmg_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void nzmg_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("nzmg", new nzmg_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_NZMG_HPP + diff --git a/boost/geometry/srs/projections/proj/ob_tran.hpp b/boost/geometry/srs/projections/proj/ob_tran.hpp new file mode 100644 index 0000000000..ae74cc27d2 --- /dev/null +++ b/boost/geometry/srs/projections/proj/ob_tran.hpp @@ -0,0 +1,575 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP +#define BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_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/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/impl/aasincos.hpp> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + //struct ob_tran_oblique {}; + //struct ob_tran_transverse {}; + struct ob_tran {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { + + // fwd declaration needed below + template <typename CalculationType> + inline detail::base_v<CalculationType, parameters<CalculationType> >* + create_new(parameters<CalculationType> const& parameters); + + } // namespace detail + + namespace detail { namespace ob_tran + { + + static const double TOL = 1e-10; + + template <typename Parameters> + inline Parameters o_proj_parameters(Parameters const& par) + { + Parameters pj; + + /* get name of projection to be translated */ + pj.name = pj_param(par.params, "so_proj").s; + /* copy existing header into new */ + pj.params = par.params; + pj.over = par.over; + pj.geoc = par.geoc; + pj.a = par.a; + pj.es = par.es; + pj.ra = par.ra; + pj.lam0 = par.lam0; + pj.phi0 = par.phi0; + pj.x0 = par.x0; + pj.y0 = par.y0; + pj.k0 = par.k0; + /* force spherical earth */ + pj.one_es = pj.rone_es = 1.; + pj.es = pj.e = 0.; + + return pj; + } + + template <typename CalculationType, typename Parameters> + struct par_ob_tran + { + par_ob_tran(Parameters const& par) + : link(projections::detail::create_new(o_proj_parameters(par))) + { + if (! link.get()) + BOOST_THROW_EXCEPTION( projection_exception(-26) ); + } + + template <typename T> + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const + { + link->fwd(lp_lon, lp_lat, xy_x, xy_y); + } + + template <typename T> + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const + { + link->inv(xy_x, xy_y, lp_lon, lp_lat); + } + + boost::shared_ptr<base_v<CalculationType, Parameters> > link; + CalculationType lamp; + CalculationType cphip, sphip; + }; + + template <typename StaticParameters, typename CalculationType, typename Parameters> + struct par_ob_tran_static + { + typedef typename srs::par4::detail::pick_o_proj_tag + < + StaticParameters + >::type o_proj_tag; + + typedef typename projections::detail::static_projection_type + < + o_proj_tag, + srs_sphere_tag, // force spherical + StaticParameters, + CalculationType, + Parameters + >::type projection_type; + + par_ob_tran_static(Parameters const& par) + : link(o_proj_parameters(par)) + {} + + template <typename T> + inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const + { + link.fwd(lp_lon, lp_lat, xy_x, xy_y); + } + + template <typename T> + inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const + { + link.inv(xy_x, xy_y, lp_lon, lp_lat); + } + + projection_type link; + CalculationType lamp; + CalculationType cphip, sphip; + }; + + template <typename T, typename Par> + inline void o_forward(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y, Par const& proj_parm) + { + T coslam, sinphi, cosphi; + + coslam = cos(lp_lon); + sinphi = sin(lp_lat); + cosphi = cos(lp_lat); + lp_lon = adjlon(aatan2(cosphi * sin(lp_lon), proj_parm.sphip * cosphi * coslam + + proj_parm.cphip * sinphi) + proj_parm.lamp); + lp_lat = aasin(proj_parm.sphip * sinphi - proj_parm.cphip * cosphi * coslam); + + proj_parm.fwd(lp_lon, lp_lat, xy_x, xy_y); + } + + template <typename T, typename Par> + inline void o_inverse(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat, Par const& proj_parm) + { + T coslam, sinphi, cosphi; + + proj_parm.inv(xy_x, xy_y, lp_lon, lp_lat); + if (lp_lon != HUGE_VAL) { + coslam = cos(lp_lon -= proj_parm.lamp); + sinphi = sin(lp_lat); + cosphi = cos(lp_lat); + lp_lat = aasin(proj_parm.sphip * sinphi + proj_parm.cphip * cosphi * coslam); + lp_lon = aatan2(cosphi * sin(lp_lon), proj_parm.sphip * cosphi * coslam - + proj_parm.cphip * sinphi); + } + } + + template <typename T, typename Par> + inline void t_forward(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y, Par const& proj_parm) + { + T cosphi, coslam; + + cosphi = cos(lp_lat); + coslam = cos(lp_lon); + lp_lon = adjlon(aatan2(cosphi * sin(lp_lon), sin(lp_lat)) + proj_parm.lamp); + lp_lat = aasin(- cosphi * coslam); + proj_parm.fwd(lp_lon, lp_lat, xy_x, xy_y); + } + + template <typename T, typename Par> + inline void t_inverse(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat, Par const& proj_parm) + { + T cosphi, t; + + proj_parm.inv(xy_x, xy_y, lp_lon, lp_lat); + if (lp_lon != HUGE_VAL) { + cosphi = cos(lp_lat); + t = lp_lon - proj_parm.lamp; + lp_lon = aatan2(cosphi * sin(t), - sin(lp_lat)); + lp_lat = aasin(cosphi * cos(t)); + } + } + + // General Oblique Transformation + template <typename CalculationType, typename Parameters, typename ProjParameters> + inline CalculationType setup_ob_tran(Parameters & par, ProjParameters& proj_parm) + { + static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + + CalculationType phip; + + par.es = 0.; /* force to spherical */ + + // proj_parm.link should be created at this point + + if (pj_param(par.params, "to_alpha").i) { + CalculationType lamc, phic, alpha; + + lamc = pj_param(par.params, "ro_lon_c").f; + phic = pj_param(par.params, "ro_lat_c").f; + alpha = pj_param(par.params, "ro_alpha").f; + /* + if (fabs(phic) <= TOL || + fabs(fabs(phic) - HALFPI) <= TOL || + fabs(fabs(alpha) - HALFPI) <= TOL) + */ + if (fabs(fabs(phic) - HALFPI) <= TOL) + BOOST_THROW_EXCEPTION( projection_exception(-32) ); + proj_parm.lamp = lamc + aatan2(-cos(alpha), -sin(alpha) * sin(phic)); + phip = aasin(cos(phic) * sin(alpha)); + } else if (pj_param(par.params, "to_lat_p").i) { /* specified new pole */ + proj_parm.lamp = pj_param(par.params, "ro_lon_p").f; + phip = pj_param(par.params, "ro_lat_p").f; + } else { /* specified new "equator" points */ + CalculationType lam1, lam2, phi1, phi2, con; + + lam1 = pj_param(par.params, "ro_lon_1").f; + phi1 = pj_param(par.params, "ro_lat_1").f; + lam2 = pj_param(par.params, "ro_lon_2").f; + phi2 = pj_param(par.params, "ro_lat_2").f; + if (fabs(phi1 - phi2) <= TOL || + (con = fabs(phi1)) <= TOL || + fabs(con - HALFPI) <= TOL || + fabs(fabs(phi2) - HALFPI) <= TOL) + BOOST_THROW_EXCEPTION( projection_exception(-33) ); + proj_parm.lamp = atan2(cos(phi1) * sin(phi2) * cos(lam1) - + sin(phi1) * cos(phi2) * cos(lam2), + sin(phi1) * cos(phi2) * sin(lam2) - + cos(phi1) * sin(phi2) * sin(lam1)); + phip = atan(-cos(proj_parm.lamp - lam1) / tan(phi1)); + } + if (fabs(phip) > TOL) { /* oblique */ + proj_parm.cphip = cos(phip); + proj_parm.sphip = sin(phip); + } else { /* transverse */ + } + // return phip to choose model + return phip; + } + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_ob_tran_oblique : public base_t_fi<base_ob_tran_oblique<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_ob_tran<CalculationType, Parameters> m_proj_parm; + + inline base_ob_tran_oblique(Parameters const& par, + par_ob_tran<CalculationType, Parameters> const& proj_parm) + : base_t_fi + < + base_ob_tran_oblique<CalculationType, Parameters>, CalculationType, Parameters + >(*this, par) + , m_proj_parm(proj_parm) + {} + + // FORWARD(o_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 + { + o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm); + } + + // INVERSE(o_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 + { + o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm); + } + + static inline std::string get_name() + { + return "ob_tran_oblique"; + } + + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_ob_tran_transverse : public base_t_fi<base_ob_tran_transverse<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_ob_tran<CalculationType, Parameters> m_proj_parm; + + inline base_ob_tran_transverse(Parameters const& par, + par_ob_tran<CalculationType, Parameters> const& proj_parm) + : base_t_fi + < + base_ob_tran_transverse<CalculationType, Parameters>, CalculationType, Parameters + >(*this, par) + , m_proj_parm(proj_parm) + {} + + // FORWARD(t_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 + { + t_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm); + } + + // INVERSE(t_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 + { + t_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm); + } + + static inline std::string get_name() + { + return "ob_tran_transverse"; + } + + }; + + // template class, using CRTP to implement forward/inverse + template <typename StaticParameters, typename CalculationType, typename Parameters> + struct base_ob_tran_static : public base_t_fi<base_ob_tran_static<StaticParameters, CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_ob_tran_static<StaticParameters, CalculationType, Parameters> m_proj_parm; + bool m_is_oblique; + + inline base_ob_tran_static(Parameters const& par) + : base_t_fi<base_ob_tran_static<StaticParameters, CalculationType, Parameters>, CalculationType, Parameters>(*this, par) + , m_proj_parm(par) + {} + + // FORWARD(o_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 (m_is_oblique) { + o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm); + } else { + t_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm); + } + } + + // INVERSE(o_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 (m_is_oblique) { + o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm); + } else { + t_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm); + } + } + + static inline std::string get_name() + { + return "ob_tran"; + } + + }; + + }} // namespace detail::ob_tran + #endif // doxygen + + /*! + \brief General Oblique Transformation 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 + - o_proj (string) + - Plus projection parameters + - o_lat_p (degrees) + - o_lon_p (degrees) + - New pole + - o_alpha: Alpha (degrees) + - o_lon_c (degrees) + - o_lat_c (degrees) + - o_lon_1 (degrees) + - o_lat_1: Latitude of first standard parallel (degrees) + - o_lon_2 (degrees) + - o_lat_2: Latitude of second standard parallel (degrees) + \par Example + \image html ex_ob_tran.gif + */ + template <typename CalculationType, typename Parameters> + struct ob_tran_oblique : public detail::ob_tran::base_ob_tran_oblique<CalculationType, Parameters> + { + inline ob_tran_oblique(Parameters const& par, + detail::ob_tran::par_ob_tran<CalculationType, Parameters> const& proj_parm) + : detail::ob_tran::base_ob_tran_oblique<CalculationType, Parameters>(par, proj_parm) + { + // already done + //detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief General Oblique Transformation 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 + - o_proj (string) + - Plus projection parameters + - o_lat_p (degrees) + - o_lon_p (degrees) + - New pole + - o_alpha: Alpha (degrees) + - o_lon_c (degrees) + - o_lat_c (degrees) + - o_lon_1 (degrees) + - o_lat_1: Latitude of first standard parallel (degrees) + - o_lon_2 (degrees) + - o_lat_2: Latitude of second standard parallel (degrees) + \par Example + \image html ex_ob_tran.gif + */ + template <typename CalculationType, typename Parameters> + struct ob_tran_transverse : public detail::ob_tran::base_ob_tran_transverse<CalculationType, Parameters> + { + inline ob_tran_transverse(Parameters const& par, + detail::ob_tran::par_ob_tran<CalculationType, Parameters> const& proj_parm) + : detail::ob_tran::base_ob_tran_transverse<CalculationType, Parameters>(par, proj_parm) + { + // already done + //detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief General Oblique Transformation 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 + - o_proj (string) + - Plus projection parameters + - o_lat_p (degrees) + - o_lon_p (degrees) + - New pole + - o_alpha: Alpha (degrees) + - o_lon_c (degrees) + - o_lat_c (degrees) + - o_lon_1 (degrees) + - o_lat_1: Latitude of first standard parallel (degrees) + - o_lon_2 (degrees) + - o_lat_2: Latitude of second standard parallel (degrees) + \par Example + \image html ex_ob_tran.gif + */ + template <typename StaticParameters, typename CalculationType, typename Parameters> + struct ob_tran_static : public detail::ob_tran::base_ob_tran_static<StaticParameters, CalculationType, Parameters> + { + inline ob_tran_static(const Parameters& par) + : detail::ob_tran::base_ob_tran_static<StaticParameters, CalculationType, Parameters>(par) + { + CalculationType phip = detail::ob_tran::setup_ob_tran<CalculationType>(this->m_par, this->m_proj_parm); + this->m_is_oblique = fabs(phip) > detail::ob_tran::TOL; + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + template <typename BGP, typename CT, typename P> + struct static_projection_type<srs::par4::ob_tran, srs_sphere_tag, BGP, CT, P> + { + typedef ob_tran_static<BGP, CT, P> type; + }; + template <typename BGP, typename CT, typename P> + struct static_projection_type<srs::par4::ob_tran, srs_spheroid_tag, BGP, CT, P> + { + typedef ob_tran_static<BGP, CT, P> type; + }; + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class ob_tran_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + Parameters params = par; + detail::ob_tran::par_ob_tran<CalculationType, Parameters> proj_parm(params); + CalculationType phip = detail::ob_tran::setup_ob_tran<CalculationType>(params, proj_parm); + + if (fabs(phip) > detail::ob_tran::TOL) + return new base_v_fi<ob_tran_oblique<CalculationType, Parameters>, CalculationType, Parameters>(params, proj_parm); + else + return new base_v_fi<ob_tran_transverse<CalculationType, Parameters>, CalculationType, Parameters>(params, proj_parm); + } + }; + + template <typename CalculationType, typename Parameters> + inline void ob_tran_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("ob_tran", new ob_tran_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP + diff --git a/boost/geometry/srs/projections/proj/ocea.hpp b/boost/geometry/srs/projections/proj/ocea.hpp new file mode 100644 index 0000000000..4b8da5be6e --- /dev/null +++ b/boost/geometry/srs/projections/proj/ocea.hpp @@ -0,0 +1,231 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_OCEA_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 ocea {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace ocea + { + template <typename T> + struct par_ocea + { + T rok; + T rtk; + T sinphi; + T cosphi; + T singam; + T cosgam; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_ocea_spheroid : public base_t_fi<base_ocea_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_ocea<CalculationType> m_proj_parm; + + inline base_ocea_spheroid(const Parameters& par) + : base_t_fi<base_ocea_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 ONEPI = detail::ONEPI<CalculationType>(); + + CalculationType t; + + xy_y = sin(lp_lon); + /* + xy_x = atan2((tan(lp_lat) * this->m_proj_parm.cosphi + this->m_proj_parm.sinphi * xy_y) , cos(lp_lon)); + */ + t = cos(lp_lon); + xy_x = atan((tan(lp_lat) * this->m_proj_parm.cosphi + this->m_proj_parm.sinphi * xy_y) / t); + if (t < 0.) + xy_x += ONEPI; + xy_x *= this->m_proj_parm.rtk; + xy_y = this->m_proj_parm.rok * (this->m_proj_parm.sinphi * sin(lp_lat) - this->m_proj_parm.cosphi * cos(lp_lat) * 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 + { + CalculationType t, s; + + xy_y /= this->m_proj_parm.rok; + xy_x /= this->m_proj_parm.rtk; + t = sqrt(1. - xy_y * xy_y); + lp_lat = asin(xy_y * this->m_proj_parm.sinphi + t * this->m_proj_parm.cosphi * (s = sin(xy_x))); + lp_lon = atan2(t * this->m_proj_parm.sinphi * s - xy_y * this->m_proj_parm.cosphi, + t * cos(xy_x)); + } + + static inline std::string get_name() + { + return "ocea_spheroid"; + } + + }; + + // Oblique Cylindrical Equal Area + template <typename Parameters, typename T> + inline void setup_ocea(Parameters& par, par_ocea<T>& proj_parm) + { + static const T HALFPI = detail::HALFPI<T>(); + + T phi_0=0.0, phi_1, phi_2, lam_1, lam_2, lonz, alpha; + + proj_parm.rok = 1. / par.k0; + proj_parm.rtk = par.k0; + if ( pj_param(par.params, "talpha").i) { + alpha = pj_param(par.params, "ralpha").f; + lonz = pj_param(par.params, "rlonc").f; + proj_parm.singam = atan(-cos(alpha)/(-sin(phi_0) * sin(alpha))) + lonz; + proj_parm.sinphi = asin(cos(phi_0) * sin(alpha)); + } else { + phi_1 = pj_param(par.params, "rlat_1").f; + phi_2 = pj_param(par.params, "rlat_2").f; + lam_1 = pj_param(par.params, "rlon_1").f; + lam_2 = pj_param(par.params, "rlon_2").f; + proj_parm.singam = atan2(cos(phi_1) * sin(phi_2) * cos(lam_1) - + sin(phi_1) * cos(phi_2) * cos(lam_2), + sin(phi_1) * cos(phi_2) * sin(lam_2) - + cos(phi_1) * sin(phi_2) * sin(lam_1) ); + if (lam_1 == -HALFPI) + proj_parm.singam = -proj_parm.singam; + proj_parm.sinphi = atan(-cos(proj_parm.singam - lam_1) / tan(phi_1)); + } + par.lam0 = proj_parm.singam + HALFPI; + proj_parm.cosphi = cos(proj_parm.sinphi); + proj_parm.sinphi = sin(proj_parm.sinphi); + proj_parm.cosgam = cos(proj_parm.singam); + proj_parm.singam = sin(proj_parm.singam); + par.es = 0.; + } + + }} // namespace detail::ocea + #endif // doxygen + + /*! + \brief Oblique Cylindrical Equal Area 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 + - lonc: Longitude (only used if alpha (or gamma) is specified) (degrees) + - alpha: Alpha (degrees) + - lat_1: Latitude of first standard parallel (degrees) + - lat_2: Latitude of second standard parallel (degrees) + - lon_1 (degrees) + - lon_2 (degrees) + \par Example + \image html ex_ocea.gif + */ + template <typename CalculationType, typename Parameters> + struct ocea_spheroid : public detail::ocea::base_ocea_spheroid<CalculationType, Parameters> + { + inline ocea_spheroid(const Parameters& par) : detail::ocea::base_ocea_spheroid<CalculationType, Parameters>(par) + { + detail::ocea::setup_ocea(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::ocea, ocea_spheroid, ocea_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class ocea_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<ocea_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void ocea_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("ocea", new ocea_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP + diff --git a/boost/geometry/srs/projections/proj/oea.hpp b/boost/geometry/srs/projections/proj/oea.hpp new file mode 100644 index 0000000000..469a41a2d5 --- /dev/null +++ b/boost/geometry/srs/projections/proj/oea.hpp @@ -0,0 +1,214 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_OEA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_OEA_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/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> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct oea {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace oea + { + template <typename T> + struct par_oea + { + T theta; + T m, n; + T two_r_m, two_r_n, rm, rn, hm, hn; + T cp0, sp0; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_oea_spheroid : public base_t_fi<base_oea_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_oea<CalculationType> m_proj_parm; + + inline base_oea_spheroid(const Parameters& par) + : base_t_fi<base_oea_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 Az, M, N, cp, sp, cl, shz; + + cp = cos(lp_lat); + sp = sin(lp_lat); + cl = cos(lp_lon); + Az = aatan2(cp * sin(lp_lon), this->m_proj_parm.cp0 * sp - this->m_proj_parm.sp0 * cp * cl) + this->m_proj_parm.theta; + shz = sin(0.5 * aacos(this->m_proj_parm.sp0 * sp + this->m_proj_parm.cp0 * cp * cl)); + M = aasin(shz * sin(Az)); + N = aasin(shz * cos(Az) * cos(M) / cos(M * this->m_proj_parm.two_r_m)); + xy_y = this->m_proj_parm.n * sin(N * this->m_proj_parm.two_r_n); + xy_x = this->m_proj_parm.m * sin(M * this->m_proj_parm.two_r_m) * cos(N) / cos(N * this->m_proj_parm.two_r_n); + } + + // 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 + { + CalculationType N, M, xp, yp, z, Az, cz, sz, cAz; + + N = this->m_proj_parm.hn * aasin(xy_y * this->m_proj_parm.rn); + M = this->m_proj_parm.hm * aasin(xy_x * this->m_proj_parm.rm * cos(N * this->m_proj_parm.two_r_n) / cos(N)); + xp = 2. * sin(M); + yp = 2. * sin(N) * cos(M * this->m_proj_parm.two_r_m) / cos(M); + cAz = cos(Az = aatan2(xp, yp) - this->m_proj_parm.theta); + z = 2. * aasin(0.5 * boost::math::hypot(xp, yp)); + sz = sin(z); + cz = cos(z); + lp_lat = aasin(this->m_proj_parm.sp0 * cz + this->m_proj_parm.cp0 * sz * cAz); + lp_lon = aatan2(sz * sin(Az), + this->m_proj_parm.cp0 * cz - this->m_proj_parm.sp0 * sz * cAz); + } + + static inline std::string get_name() + { + return "oea_spheroid"; + } + + }; + + // Oblated Equal Area + template <typename Parameters, typename T> + inline void setup_oea(Parameters& par, par_oea<T>& proj_parm) + { + if (((proj_parm.n = pj_param(par.params, "dn").f) <= 0.) || + ((proj_parm.m = pj_param(par.params, "dm").f) <= 0.)) + BOOST_THROW_EXCEPTION( projection_exception(-39) ); + else { + proj_parm.theta = pj_param(par.params, "rtheta").f; + proj_parm.sp0 = sin(par.phi0); + proj_parm.cp0 = cos(par.phi0); + proj_parm.rn = 1./ proj_parm.n; + proj_parm.rm = 1./ proj_parm.m; + proj_parm.two_r_n = 2. * proj_parm.rn; + proj_parm.two_r_m = 2. * proj_parm.rm; + proj_parm.hm = 0.5 * proj_parm.m; + proj_parm.hn = 0.5 * proj_parm.n; + par.es = 0.; + } + } + + }} // namespace detail::oea + #endif // doxygen + + /*! + \brief Oblated Equal Area 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 + - n (real) + - m (real) + - theta: Theta (degrees) + \par Example + \image html ex_oea.gif + */ + template <typename CalculationType, typename Parameters> + struct oea_spheroid : public detail::oea::base_oea_spheroid<CalculationType, Parameters> + { + inline oea_spheroid(const Parameters& par) : detail::oea::base_oea_spheroid<CalculationType, Parameters>(par) + { + detail::oea::setup_oea(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::oea, oea_spheroid, oea_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class oea_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<oea_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void oea_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("oea", new oea_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_OEA_HPP + diff --git a/boost/geometry/srs/projections/proj/omerc.hpp b/boost/geometry/srs/projections/proj/omerc.hpp new file mode 100644 index 0000000000..4da6871d13 --- /dev/null +++ b/boost/geometry/srs/projections/proj/omerc.hpp @@ -0,0 +1,354 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_OMERC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_OMERC_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) 2003, 2006 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/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_phi2.hpp> +#include <boost/geometry/srs/projections/impl/pj_tsfn.hpp> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct omerc {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace omerc + { + static const double TOL = 1.e-7; + static const double EPS = 1.e-10; + + template <typename T> + struct par_omerc + { + T A, B, E, AB, ArB, BrA, rB, singam, cosgam, sinrot, cosrot; + T v_pole_n, v_pole_s, u_0; + int no_rot; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_omerc_ellipsoid : public base_t_fi<base_omerc_ellipsoid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_omerc<CalculationType> m_proj_parm; + + inline base_omerc_ellipsoid(const Parameters& par) + : base_t_fi<base_omerc_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 Q, S, T, U, V, temp, u, v; + + if (fabs(fabs(lp_lat) - HALFPI) > EPS) { + Q = this->m_proj_parm.E / pow(pj_tsfn(lp_lat, sin(lp_lat), this->m_par.e), this->m_proj_parm.B); + temp = 1. / Q; + S = .5 * (Q - temp); + T = .5 * (Q + temp); + V = sin(this->m_proj_parm.B * lp_lon); + U = (S * this->m_proj_parm.singam - V * this->m_proj_parm.cosgam) / T; + if (fabs(fabs(U) - 1.0) < EPS) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + v = 0.5 * this->m_proj_parm.ArB * log((1. - U)/(1. + U)); + temp = cos(this->m_proj_parm.B * lp_lon); + if(fabs(temp) < TOL) { + u = this->m_proj_parm.A * lp_lon; + } else { + u = this->m_proj_parm.ArB * atan2((S * this->m_proj_parm.cosgam + V * this->m_proj_parm.singam), temp); + } + } else { + v = lp_lat > 0 ? this->m_proj_parm.v_pole_n : this->m_proj_parm.v_pole_s; + u = this->m_proj_parm.ArB * lp_lat; + } + if (this->m_proj_parm.no_rot) { + xy_x = u; + xy_y = v; + } else { + u -= this->m_proj_parm.u_0; + xy_x = v * this->m_proj_parm.cosrot + u * this->m_proj_parm.sinrot; + xy_y = u * this->m_proj_parm.cosrot - v * this->m_proj_parm.sinrot; + } + } + + // 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 u, v, Qp, Sp, Tp, Vp, Up; + + if (this->m_proj_parm.no_rot) { + v = xy_y; + u = xy_x; + } else { + v = xy_x * this->m_proj_parm.cosrot - xy_y * this->m_proj_parm.sinrot; + u = xy_y * this->m_proj_parm.cosrot + xy_x * this->m_proj_parm.sinrot + this->m_proj_parm.u_0; + } + Qp = exp(- this->m_proj_parm.BrA * v); + Sp = .5 * (Qp - 1. / Qp); + Tp = .5 * (Qp + 1. / Qp); + Vp = sin(this->m_proj_parm.BrA * u); + Up = (Vp * this->m_proj_parm.cosgam + Sp * this->m_proj_parm.singam) / Tp; + if (fabs(fabs(Up) - 1.) < EPS) { + lp_lon = 0.; + lp_lat = Up < 0. ? -HALFPI : HALFPI; + } else { + lp_lat = this->m_proj_parm.E / sqrt((1. + Up) / (1. - Up)); + if ((lp_lat = pj_phi2(pow(lp_lat, 1. / this->m_proj_parm.B), this->m_par.e)) == HUGE_VAL) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + lp_lon = - this->m_proj_parm.rB * atan2((Sp * this->m_proj_parm.cosgam - + Vp * this->m_proj_parm.singam), cos(this->m_proj_parm.BrA * u)); + } + } + + static inline std::string get_name() + { + return "omerc_ellipsoid"; + } + + }; + + // Oblique Mercator + template <typename Parameters, typename T> + inline void setup_omerc(Parameters& par, par_omerc<T>& proj_parm) + { + static const T FORTPI = detail::FORTPI<T>(); + static const T HALFPI = detail::HALFPI<T>(); + static const T ONEPI = detail::ONEPI<T>(); + static const T TWOPI = detail::TWOPI<T>(); + + T con, com, cosph0, D, F, H, L, sinph0, p, J, gamma=0, + gamma0, lamc=0, lam1=0, lam2=0, phi1=0, phi2=0, alpha_c=0.0; + int alp, gam, no_off = 0; + + proj_parm.no_rot = pj_param(par.params, "tno_rot").i; + if ((alp = pj_param(par.params, "talpha").i) != 0) + alpha_c = pj_param(par.params, "ralpha").f; + if ((gam = pj_param(par.params, "tgamma").i) != 0) + gamma = pj_param(par.params, "rgamma").f; + if (alp || gam) { + lamc = pj_param(par.params, "rlonc").f; + no_off = + /* For libproj4 compatability */ + pj_param(par.params, "tno_off").i + /* for backward compatibility */ + || pj_param(par.params, "tno_uoff").i; + if( no_off ) + { + /* Mark the parameter as used, so that the pj_get_def() return them */ + pj_param(par.params, "sno_uoff"); + pj_param(par.params, "sno_off"); + } + } else { + lam1 = pj_param(par.params, "rlon_1").f; + phi1 = pj_param(par.params, "rlat_1").f; + lam2 = pj_param(par.params, "rlon_2").f; + phi2 = pj_param(par.params, "rlat_2").f; + if (fabs(phi1 - phi2) <= TOL || + (con = fabs(phi1)) <= TOL || + fabs(con - HALFPI) <= TOL || + fabs(fabs(par.phi0) - HALFPI) <= TOL || + fabs(fabs(phi2) - HALFPI) <= TOL) + BOOST_THROW_EXCEPTION( projection_exception(-33) ); + } + com = sqrt(par.one_es); + if (fabs(par.phi0) > EPS) { + sinph0 = sin(par.phi0); + cosph0 = cos(par.phi0); + con = 1. - par.es * sinph0 * sinph0; + proj_parm.B = cosph0 * cosph0; + proj_parm.B = sqrt(1. + par.es * proj_parm.B * proj_parm.B / par.one_es); + proj_parm.A = proj_parm.B * par.k0 * com / con; + D = proj_parm.B * com / (cosph0 * sqrt(con)); + if ((F = D * D - 1.) <= 0.) + F = 0.; + else { + F = sqrt(F); + if (par.phi0 < 0.) + F = -F; + } + proj_parm.E = F += D; + proj_parm.E *= pow(pj_tsfn(par.phi0, sinph0, par.e), proj_parm.B); + } else { + proj_parm.B = 1. / com; + proj_parm.A = par.k0; + proj_parm.E = D = F = 1.; + } + if (alp || gam) { + if (alp) { + gamma0 = asin(sin(alpha_c) / D); + if (!gam) + gamma = alpha_c; + } else + alpha_c = asin(D*sin(gamma0 = gamma)); + if ((con = fabs(alpha_c)) <= TOL || + fabs(con - ONEPI) <= TOL || + fabs(fabs(par.phi0) - HALFPI) <= TOL) + BOOST_THROW_EXCEPTION( projection_exception(-32) ); + par.lam0 = lamc - asin(.5 * (F - 1. / F) * + tan(gamma0)) / proj_parm.B; + } else { + H = pow(pj_tsfn(phi1, sin(phi1), par.e), proj_parm.B); + L = pow(pj_tsfn(phi2, sin(phi2), par.e), proj_parm.B); + F = proj_parm.E / H; + p = (L - H) / (L + H); + J = proj_parm.E * proj_parm.E; + J = (J - L * H) / (J + L * H); + if ((con = lam1 - lam2) < -ONEPI) + lam2 -= TWOPI; + else if (con > ONEPI) + lam2 += TWOPI; + par.lam0 = adjlon(.5 * (lam1 + lam2) - atan( + J * tan(.5 * proj_parm.B * (lam1 - lam2)) / p) / proj_parm.B); + gamma0 = atan(2. * sin(proj_parm.B * adjlon(lam1 - par.lam0)) / + (F - 1. / F)); + gamma = alpha_c = asin(D * sin(gamma0)); + } + proj_parm.singam = sin(gamma0); + proj_parm.cosgam = cos(gamma0); + proj_parm.sinrot = sin(gamma); + proj_parm.cosrot = cos(gamma); + proj_parm.BrA = 1. / (proj_parm.ArB = proj_parm.A * (proj_parm.rB = 1. / proj_parm.B)); + proj_parm.AB = proj_parm.A * proj_parm.B; + if (no_off) + proj_parm.u_0 = 0; + else { + proj_parm.u_0 = fabs(proj_parm.ArB * atan2(sqrt(D * D - 1.), cos(alpha_c))); + if (par.phi0 < 0.) + proj_parm.u_0 = - proj_parm.u_0; + } + F = 0.5 * gamma0; + proj_parm.v_pole_n = proj_parm.ArB * log(tan(FORTPI - F)); + proj_parm.v_pole_s = proj_parm.ArB * log(tan(FORTPI + F)); + } + + }} // namespace detail::omerc + #endif // doxygen + + /*! + \brief Oblique Mercator 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 + - no_rot: No rotation + - alpha: Alpha (degrees) + - gamma: Gamma (degrees) + - no_off: Only for compatibility with libproj, proj4 (string) + - lonc: Longitude (only used if alpha (or gamma) is specified) (degrees) + - lon_1 (degrees) + - lat_1: Latitude of first standard parallel (degrees) + - lon_2 (degrees) + - lat_2: Latitude of second standard parallel (degrees) + - no_uoff (string) + \par Example + \image html ex_omerc.gif + */ + template <typename CalculationType, typename Parameters> + struct omerc_ellipsoid : public detail::omerc::base_omerc_ellipsoid<CalculationType, Parameters> + { + inline omerc_ellipsoid(const Parameters& par) : detail::omerc::base_omerc_ellipsoid<CalculationType, Parameters>(par) + { + detail::omerc::setup_omerc(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::omerc, omerc_ellipsoid, omerc_ellipsoid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class omerc_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<omerc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void omerc_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("omerc", new omerc_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_OMERC_HPP + diff --git a/boost/geometry/srs/projections/proj/ortho.hpp b/boost/geometry/srs/projections/proj/ortho.hpp new file mode 100644 index 0000000000..4510f9dab9 --- /dev/null +++ b/boost/geometry/srs/projections/proj/ortho.hpp @@ -0,0 +1,257 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_ORTHO_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ORTHO_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 ortho {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace ortho + { + + 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_ortho + { + T sinph0; + T cosph0; + int mode; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_ortho_spheroid : public base_t_fi<base_ortho_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_ortho<CalculationType> m_proj_parm; + + inline base_ortho_spheroid(const Parameters& par) + : base_t_fi<base_ortho_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 coslam, cosphi, sinphi; + + cosphi = cos(lp_lat); + coslam = cos(lp_lon); + switch (this->m_proj_parm.mode) { + case EQUIT: + if (cosphi * coslam < - EPS10) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + xy_y = sin(lp_lat); + break; + case OBLIQ: + if (this->m_proj_parm.sinph0 * (sinphi = sin(lp_lat)) + + this->m_proj_parm.cosph0 * cosphi * coslam < - EPS10) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + 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: + if (fabs(lp_lat - this->m_par.phi0) - EPS10 > HALFPI) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + xy_y = cosphi * coslam; + break; + } + xy_x = cosphi * sin(lp_lon); + } + + // 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, cosc, sinc; + + if ((sinc = (rh = boost::math::hypot(xy_x, xy_y))) > 1.) { + if ((sinc - 1.) > EPS10) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + sinc = 1.; + } + cosc = sqrt(1. - sinc * sinc); /* in this range OK */ + if (fabs(rh) <= EPS10) { + lp_lat = this->m_par.phi0; + lp_lon = 0.0; + } else { + switch (this->m_proj_parm.mode) { + case N_POLE: + xy_y = -xy_y; + lp_lat = acos(sinc); + break; + case S_POLE: + lp_lat = - acos(sinc); + break; + case EQUIT: + lp_lat = xy_y * sinc / rh; + xy_x *= sinc; + xy_y = cosc * rh; + goto sinchk; + case OBLIQ: + lp_lat = cosc * this->m_proj_parm.sinph0 + xy_y * sinc * this->m_proj_parm.cosph0 /rh; + xy_y = (cosc - this->m_proj_parm.sinph0 * lp_lat) * rh; + xy_x *= sinc * this->m_proj_parm.cosph0; + sinchk: + if (fabs(lp_lat) >= 1.) + lp_lat = lp_lat < 0. ? -HALFPI : HALFPI; + else + lp_lat = asin(lp_lat); + break; + } + lp_lon = (xy_y == 0. && (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT)) + ? (xy_x == 0. ? 0. : xy_x < 0. ? -HALFPI : HALFPI) + : atan2(xy_x, xy_y); + } + } + + static inline std::string get_name() + { + return "ortho_spheroid"; + } + + }; + + // Orthographic + template <typename Parameters, typename T> + inline void setup_ortho(Parameters& par, par_ortho<T>& proj_parm) + { + if (fabs(fabs(par.phi0) - geometry::math::half_pi<T>()) <= EPS10) + proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE; + else if (fabs(par.phi0) > EPS10) { + proj_parm.mode = OBLIQ; + proj_parm.sinph0 = sin(par.phi0); + proj_parm.cosph0 = cos(par.phi0); + } else + proj_parm.mode = EQUIT; + par.es = 0.; + } + + }} // namespace detail::ortho + #endif // doxygen + + /*! + \brief Orthographic 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_ortho.gif + */ + template <typename CalculationType, typename Parameters> + struct ortho_spheroid : public detail::ortho::base_ortho_spheroid<CalculationType, Parameters> + { + inline ortho_spheroid(const Parameters& par) : detail::ortho::base_ortho_spheroid<CalculationType, Parameters>(par) + { + detail::ortho::setup_ortho(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::ortho, ortho_spheroid, ortho_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class ortho_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<ortho_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void ortho_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("ortho", new ortho_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_ORTHO_HPP + diff --git a/boost/geometry/srs/projections/proj/poly.hpp b/boost/geometry/srs/projections/proj/poly.hpp new file mode 100644 index 0000000000..ff97ecadec --- /dev/null +++ b/boost/geometry/srs/projections/proj/poly.hpp @@ -0,0 +1,311 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_POLY_HPP +#define BOOST_GEOMETRY_PROJECTIONS_POLY_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> +#include <boost/geometry/srs/projections/impl/pj_msfn.hpp> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct poly {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace poly + { + + static const double TOL = 1e-10; + static const double CONV = 1e-10; + static const int N_ITER = 10; + static const int I_ITER = 20; + static const double ITOL = 1.e-12; + + template <typename T> + struct par_poly + { + T ml0; + T en[EN_SIZE]; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_poly_ellipsoid : public base_t_fi<base_poly_ellipsoid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_poly<CalculationType> m_proj_parm; + + inline base_poly_ellipsoid(const Parameters& par) + : base_t_fi<base_poly_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 ms, sp, cp; + + if (fabs(lp_lat) <= TOL) { xy_x = lp_lon; xy_y = -this->m_proj_parm.ml0; } + else { + sp = sin(lp_lat); + ms = fabs(cp = cos(lp_lat)) > TOL ? pj_msfn(sp, cp, this->m_par.es) / sp : 0.; + xy_x = ms * sin(lp_lon *= sp); + xy_y = (pj_mlfn(lp_lat, sp, cp, this->m_proj_parm.en) - this->m_proj_parm.ml0) + ms * (1. - cos(lp_lon)); + } + } + + // 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_y += this->m_proj_parm.ml0; + if (fabs(xy_y) <= TOL) { + lp_lon = xy_x; + lp_lat = 0.; + } else { + CalculationType r, c, sp, cp, s2ph, ml, mlb, mlp, dPhi; + int i; + + r = xy_y * xy_y + xy_x * xy_x; + for (lp_lat = xy_y, i = I_ITER; i ; --i) { + sp = sin(lp_lat); + s2ph = sp * ( cp = cos(lp_lat)); + if (fabs(cp) < ITOL) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + c = sp * (mlp = sqrt(1. - this->m_par.es * sp * sp)) / cp; + ml = pj_mlfn(lp_lat, sp, cp, this->m_proj_parm.en); + mlb = ml * ml + r; + mlp = this->m_par.one_es / (mlp * mlp * mlp); + lp_lat += ( dPhi = + ( ml + ml + c * mlb - 2. * xy_y * (c * ml + 1.) ) / ( + this->m_par.es * s2ph * (mlb - 2. * xy_y * ml) / c + + 2.* (xy_y - ml) * (c * mlp - 1. / s2ph) - mlp - mlp )); + if (fabs(dPhi) <= ITOL) + break; + } + if (!i) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + c = sin(lp_lat); + lp_lon = asin(xy_x * tan(lp_lat) * sqrt(1. - this->m_par.es * c * c)) / sin(lp_lat); + } + } + + static inline std::string get_name() + { + return "poly_ellipsoid"; + } + + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_poly_spheroid : public base_t_fi<base_poly_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_poly<CalculationType> m_proj_parm; + + inline base_poly_spheroid(const Parameters& par) + : base_t_fi<base_poly_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 cot, E; + + if (fabs(lp_lat) <= TOL) { + xy_x = lp_lon; + xy_y = this->m_proj_parm.ml0; + } else { + cot = 1. / tan(lp_lat); + xy_x = sin(E = lp_lon * sin(lp_lat)) * cot; + xy_y = lp_lat - this->m_par.phi0 + cot * (1. - cos(E)); + } + } + + // 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 B, dphi, tp; + int i; + + if (fabs(xy_y = this->m_par.phi0 + xy_y) <= TOL) { + lp_lon = xy_x; + lp_lat = 0.; + } else { + lp_lat = xy_y; + B = xy_x * xy_x + xy_y * xy_y; + i = N_ITER; + do { + tp = tan(lp_lat); + lp_lat -= (dphi = (xy_y * (lp_lat * tp + 1.) - lp_lat - + .5 * ( lp_lat * lp_lat + B) * tp) / + ((lp_lat - xy_y) / tp - 1.)); + } while (fabs(dphi) > CONV && --i); + if (! i) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + lp_lon = asin(xy_x * tan(lp_lat)) / sin(lp_lat); + } + } + + static inline std::string get_name() + { + return "poly_spheroid"; + } + + }; + + // Polyconic (American) + template <typename Parameters, typename T> + inline void setup_poly(Parameters& par, par_poly<T>& proj_parm) + { + if (par.es) { + if (!pj_enfn(par.es, proj_parm.en)) + BOOST_THROW_EXCEPTION( projection_exception(0) ); + proj_parm.ml0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en); + } else { + proj_parm.ml0 = -par.phi0; + } + } + + }} // namespace detail::poly + #endif // doxygen + + /*! + \brief Polyconic (American) projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Conic + - Spheroid + - Ellipsoid + \par Example + \image html ex_poly.gif + */ + template <typename CalculationType, typename Parameters> + struct poly_ellipsoid : public detail::poly::base_poly_ellipsoid<CalculationType, Parameters> + { + inline poly_ellipsoid(const Parameters& par) : detail::poly::base_poly_ellipsoid<CalculationType, Parameters>(par) + { + detail::poly::setup_poly(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Polyconic (American) projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Conic + - Spheroid + - Ellipsoid + \par Example + \image html ex_poly.gif + */ + template <typename CalculationType, typename Parameters> + struct poly_spheroid : public detail::poly::base_poly_spheroid<CalculationType, Parameters> + { + inline poly_spheroid(const Parameters& par) : detail::poly::base_poly_spheroid<CalculationType, Parameters>(par) + { + detail::poly::setup_poly(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::poly, poly_spheroid, poly_ellipsoid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class poly_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<poly_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + else + return new base_v_fi<poly_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void poly_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("poly", new poly_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_POLY_HPP + diff --git a/boost/geometry/srs/projections/proj/putp2.hpp b/boost/geometry/srs/projections/proj/putp2.hpp new file mode 100644 index 0000000000..458ee81aa3 --- /dev/null +++ b/boost/geometry/srs/projections/proj/putp2.hpp @@ -0,0 +1,193 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP2_HPP +#define BOOST_GEOMETRY_PROJECTIONS_PUTP2_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 putp2 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace putp2 + { + + static const double C_x = 1.89490; + static const double C_y = 1.71848; + static const double C_p = 0.6141848493043784; + static const double EPS = 1e-10; + static const int NITER = 10; + //static const double PI_DIV_3 = 1.0471975511965977; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_putp2_spheroid : public base_t_fi<base_putp2_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_putp2_spheroid(const Parameters& par) + : base_t_fi<base_putp2_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 PI_DIV_3 = detail::PI_DIV_3<CalculationType>(); + + CalculationType p, c, s, V; + int i; + + p = C_p * sin(lp_lat); + s = lp_lat * lp_lat; + lp_lat *= 0.615709 + s * ( 0.00909953 + s * 0.0046292 ); + for (i = NITER; i ; --i) { + c = cos(lp_lat); + s = sin(lp_lat); + lp_lat -= V = (lp_lat + s * (c - 1.) - p) / + (1. + c * (c - 1.) - s * s); + if (fabs(V) < EPS) + break; + } + if (!i) + lp_lat = lp_lat < 0 ? - PI_DIV_3 : PI_DIV_3; + xy_x = C_x * lp_lon * (cos(lp_lat) - 0.5); + 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 * ((c = cos(lp_lat)) - 0.5)); + lp_lat = aasin((lp_lat + sin(lp_lat) * (c - 1.)) / C_p); + } + + static inline std::string get_name() + { + return "putp2_spheroid"; + } + + }; + + // Putnins P2 + template <typename Parameters> + inline void setup_putp2(Parameters& par) + { + par.es = 0.; + } + + }} // namespace detail::putp2 + #endif // doxygen + + /*! + \brief Putnins P2 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_putp2.gif + */ + template <typename CalculationType, typename Parameters> + struct putp2_spheroid : public detail::putp2::base_putp2_spheroid<CalculationType, Parameters> + { + inline putp2_spheroid(const Parameters& par) : detail::putp2::base_putp2_spheroid<CalculationType, Parameters>(par) + { + detail::putp2::setup_putp2(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp2, putp2_spheroid, putp2_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class putp2_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<putp2_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void putp2_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("putp2", new putp2_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP2_HPP + diff --git a/boost/geometry/srs/projections/proj/putp3.hpp b/boost/geometry/srs/projections/proj/putp3.hpp new file mode 100644 index 0000000000..91150082b8 --- /dev/null +++ b/boost/geometry/srs/projections/proj/putp3.hpp @@ -0,0 +1,227 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP3_HPP +#define BOOST_GEOMETRY_PROJECTIONS_PUTP3_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> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct putp3 {}; + struct putp3p {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace putp3 + { + + static const double C = 0.79788456; + static const double RPISQ = 0.1013211836; + + template <typename T> + struct par_putp3 + { + T A; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_putp3_spheroid : public base_t_fi<base_putp3_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_putp3<CalculationType> m_proj_parm; + + inline base_putp3_spheroid(const Parameters& par) + : base_t_fi<base_putp3_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 = C * lp_lon * (1. - this->m_proj_parm.A * lp_lat * lp_lat); + xy_y = C * 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 / C; + lp_lon = xy_x / (C * (1. - this->m_proj_parm.A * lp_lat * lp_lat)); + } + + static inline std::string get_name() + { + return "putp3_spheroid"; + } + + }; + + template <typename Parameters, typename T> + inline void setup(Parameters& par, par_putp3<T>& proj_parm) + { + boost::ignore_unused(proj_parm); + par.es = 0.; + } + + + // Putnins P3 + template <typename Parameters, typename T> + inline void setup_putp3(Parameters& par, par_putp3<T>& proj_parm) + { + proj_parm.A = 4. * RPISQ; + setup(par, proj_parm); + } + + // Putnins P3' + template <typename Parameters, typename T> + inline void setup_putp3p(Parameters& par, par_putp3<T>& proj_parm) + { + proj_parm.A = 2. * RPISQ; + setup(par, proj_parm); + } + + }} // namespace detail::putp3 + #endif // doxygen + + /*! + \brief Putnins P3 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_putp3.gif + */ + template <typename CalculationType, typename Parameters> + struct putp3_spheroid : public detail::putp3::base_putp3_spheroid<CalculationType, Parameters> + { + inline putp3_spheroid(const Parameters& par) : detail::putp3::base_putp3_spheroid<CalculationType, Parameters>(par) + { + detail::putp3::setup_putp3(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Putnins P3' 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_putp3p.gif + */ + template <typename CalculationType, typename Parameters> + struct putp3p_spheroid : public detail::putp3::base_putp3_spheroid<CalculationType, Parameters> + { + inline putp3p_spheroid(const Parameters& par) : detail::putp3::base_putp3_spheroid<CalculationType, Parameters>(par) + { + detail::putp3::setup_putp3p(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp3, putp3_spheroid, putp3_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp3p, putp3p_spheroid, putp3p_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class putp3_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<putp3_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class putp3p_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<putp3p_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void putp3_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("putp3", new putp3_entry<CalculationType, Parameters>); + factory.add_to_factory("putp3p", new putp3p_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP3_HPP + diff --git a/boost/geometry/srs/projections/proj/putp4p.hpp b/boost/geometry/srs/projections/proj/putp4p.hpp new file mode 100644 index 0000000000..4252b37141 --- /dev/null +++ b/boost/geometry/srs/projections/proj/putp4p.hpp @@ -0,0 +1,231 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP4P_HPP +#define BOOST_GEOMETRY_PROJECTIONS_PUTP4P_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 putp4p {}; + struct weren {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace putp4p + { + template <typename T> + struct par_putp4p + { + T C_x, C_y; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_putp4p_spheroid : public base_t_fi<base_putp4p_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_putp4p<CalculationType> m_proj_parm; + + inline base_putp4p_spheroid(const Parameters& par) + : base_t_fi<base_putp4p_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 + { + lp_lat = aasin(0.883883476 * sin(lp_lat)); + xy_x = this->m_proj_parm.C_x * lp_lon * cos(lp_lat); + xy_x /= cos(lp_lat *= 0.333333333333333); + xy_y = this->m_proj_parm.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 + { + lp_lat = aasin(xy_y / this->m_proj_parm.C_y); + lp_lon = xy_x * cos(lp_lat) / this->m_proj_parm.C_x; + lp_lat *= 3.; + lp_lon /= cos(lp_lat); + lp_lat = aasin(1.13137085 * sin(lp_lat)); + } + + static inline std::string get_name() + { + return "putp4p_spheroid"; + } + + }; + + template <typename Parameters, typename T> + inline void setup(Parameters& par, par_putp4p<T>& proj_parm) + { + boost::ignore_unused(proj_parm); + par.es = 0.; + } + + + // Putnins P4' + template <typename Parameters, typename T> + inline void setup_putp4p(Parameters& par, par_putp4p<T>& proj_parm) + { + proj_parm.C_x = 0.874038744; + proj_parm.C_y = 3.883251825; + setup(par, proj_parm); + } + + // Werenskiold I + template <typename Parameters, typename T> + inline void setup_weren(Parameters& par, par_putp4p<T>& proj_parm) + { + proj_parm.C_x = 1.; + proj_parm.C_y = 4.442882938; + setup(par, proj_parm); + } + + }} // namespace detail::putp4p + #endif // doxygen + + /*! + \brief 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_putp4p.gif + */ + template <typename CalculationType, typename Parameters> + struct putp4p_spheroid : public detail::putp4p::base_putp4p_spheroid<CalculationType, Parameters> + { + inline putp4p_spheroid(const Parameters& par) : detail::putp4p::base_putp4p_spheroid<CalculationType, Parameters>(par) + { + detail::putp4p::setup_putp4p(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Werenskiold 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_weren.gif + */ + template <typename CalculationType, typename Parameters> + struct weren_spheroid : public detail::putp4p::base_putp4p_spheroid<CalculationType, Parameters> + { + inline weren_spheroid(const Parameters& par) : detail::putp4p::base_putp4p_spheroid<CalculationType, Parameters>(par) + { + detail::putp4p::setup_weren(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp4p, putp4p_spheroid, putp4p_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::weren, weren_spheroid, weren_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class putp4p_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<putp4p_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class weren_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<weren_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void putp4p_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("putp4p", new putp4p_entry<CalculationType, Parameters>); + factory.add_to_factory("weren", new weren_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP4P_HPP + diff --git a/boost/geometry/srs/projections/proj/putp5.hpp b/boost/geometry/srs/projections/proj/putp5.hpp new file mode 100644 index 0000000000..652dca5231 --- /dev/null +++ b/boost/geometry/srs/projections/proj/putp5.hpp @@ -0,0 +1,229 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP5_HPP +#define BOOST_GEOMETRY_PROJECTIONS_PUTP5_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> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct putp5 {}; + struct putp5p {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace putp5 + { + + static const double C = 1.01346; + static const double D = 1.2158542; + + template <typename T> + struct par_putp5 + { + T A, B; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_putp5_spheroid : public base_t_fi<base_putp5_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_putp5<CalculationType> m_proj_parm; + + inline base_putp5_spheroid(const Parameters& par) + : base_t_fi<base_putp5_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 = C * lp_lon * (this->m_proj_parm.A - this->m_proj_parm.B * sqrt(1. + D * lp_lat * lp_lat)); + xy_y = C * 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 / C; + lp_lon = xy_x / (C * (this->m_proj_parm.A - this->m_proj_parm.B * sqrt(1. + D * lp_lat * lp_lat))); + } + + static inline std::string get_name() + { + return "putp5_spheroid"; + } + + }; + + template <typename Parameters, typename T> + inline void setup(Parameters& par, par_putp5<T>& proj_parm) + { + boost::ignore_unused(proj_parm); + par.es = 0.; + } + + + // Putnins P5 + template <typename Parameters, typename T> + inline void setup_putp5(Parameters& par, par_putp5<T>& proj_parm) + { + proj_parm.A = 2.; + proj_parm.B = 1.; + setup(par, proj_parm); + } + + // Putnins P5' + template <typename Parameters, typename T> + inline void setup_putp5p(Parameters& par, par_putp5<T>& proj_parm) + { + proj_parm.A = 1.5; + proj_parm.B = 0.5; + setup(par, proj_parm); + } + + }} // namespace detail::putp5 + #endif // doxygen + + /*! + \brief Putnins P5 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_putp5.gif + */ + template <typename CalculationType, typename Parameters> + struct putp5_spheroid : public detail::putp5::base_putp5_spheroid<CalculationType, Parameters> + { + inline putp5_spheroid(const Parameters& par) : detail::putp5::base_putp5_spheroid<CalculationType, Parameters>(par) + { + detail::putp5::setup_putp5(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Putnins P5' 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_putp5p.gif + */ + template <typename CalculationType, typename Parameters> + struct putp5p_spheroid : public detail::putp5::base_putp5_spheroid<CalculationType, Parameters> + { + inline putp5p_spheroid(const Parameters& par) : detail::putp5::base_putp5_spheroid<CalculationType, Parameters>(par) + { + detail::putp5::setup_putp5p(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp5, putp5_spheroid, putp5_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp5p, putp5p_spheroid, putp5p_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class putp5_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<putp5_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class putp5p_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<putp5p_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void putp5_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("putp5", new putp5_entry<CalculationType, Parameters>); + factory.add_to_factory("putp5p", new putp5p_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP5_HPP + diff --git a/boost/geometry/srs/projections/proj/putp6.hpp b/boost/geometry/srs/projections/proj/putp6.hpp new file mode 100644 index 0000000000..2dff641717 --- /dev/null +++ b/boost/geometry/srs/projections/proj/putp6.hpp @@ -0,0 +1,255 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP6_HPP +#define BOOST_GEOMETRY_PROJECTIONS_PUTP6_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 putp6 {}; + struct putp6p {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace putp6 + { + + static const double EPS = 1e-10; + static const int NITER = 10; + static const double CON_POLE = 1.732050807568877; + + template <typename T> + struct par_putp6 + { + T C_x, C_y, A, B, D; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_putp6_spheroid : public base_t_fi<base_putp6_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_putp6<CalculationType> m_proj_parm; + + inline base_putp6_spheroid(const Parameters& par) + : base_t_fi<base_putp6_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, r, V; + int i; + + p = this->m_proj_parm.B * sin(lp_lat); + lp_lat *= 1.10265779; + for (i = NITER; i ; --i) { + r = sqrt(1. + lp_lat * lp_lat); + lp_lat -= V = ( (this->m_proj_parm.A - r) * lp_lat - log(lp_lat + r) - p ) / + (this->m_proj_parm.A - 2. * r); + if (fabs(V) < EPS) + break; + } + if (!i) + lp_lat = p < 0. ? -CON_POLE : CON_POLE; + xy_x = this->m_proj_parm.C_x * lp_lon * (this->m_proj_parm.D - sqrt(1. + lp_lat * lp_lat)); + xy_y = this->m_proj_parm.C_y * 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 r; + + lp_lat = xy_y / this->m_proj_parm.C_y; + r = sqrt(1. + lp_lat * lp_lat); + lp_lon = xy_x / (this->m_proj_parm.C_x * (this->m_proj_parm.D - r)); + lp_lat = aasin(( (this->m_proj_parm.A - r) * lp_lat - log(lp_lat + r) ) / this->m_proj_parm.B); + } + + static inline std::string get_name() + { + return "putp6_spheroid"; + } + + }; + + template <typename Parameters, typename T> + inline void setup(Parameters& par, par_putp6<T>& proj_parm) + { + boost::ignore_unused(proj_parm); + par.es = 0.; + } + + + // Putnins P6 + template <typename Parameters, typename T> + inline void setup_putp6(Parameters& par, par_putp6<T>& proj_parm) + { + proj_parm.C_x = 1.01346; + proj_parm.C_y = 0.91910; + proj_parm.A = 4.; + proj_parm.B = 2.1471437182129378784; + proj_parm.D = 2.; + setup(par, proj_parm); + } + + // Putnins P6' + template <typename Parameters, typename T> + inline void setup_putp6p(Parameters& par, par_putp6<T>& proj_parm) + { + proj_parm.C_x = 0.44329; + proj_parm.C_y = 0.80404; + proj_parm.A = 6.; + proj_parm.B = 5.61125; + proj_parm.D = 3.; + setup(par, proj_parm); + } + + }} // namespace detail::putp6 + #endif // doxygen + + /*! + \brief Putnins P6 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_putp6.gif + */ + template <typename CalculationType, typename Parameters> + struct putp6_spheroid : public detail::putp6::base_putp6_spheroid<CalculationType, Parameters> + { + inline putp6_spheroid(const Parameters& par) : detail::putp6::base_putp6_spheroid<CalculationType, Parameters>(par) + { + detail::putp6::setup_putp6(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Putnins P6' 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_putp6p.gif + */ + template <typename CalculationType, typename Parameters> + struct putp6p_spheroid : public detail::putp6::base_putp6_spheroid<CalculationType, Parameters> + { + inline putp6p_spheroid(const Parameters& par) : detail::putp6::base_putp6_spheroid<CalculationType, Parameters>(par) + { + detail::putp6::setup_putp6p(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp6, putp6_spheroid, putp6_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::putp6p, putp6p_spheroid, putp6p_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class putp6_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<putp6_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class putp6p_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<putp6p_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void putp6_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("putp6", new putp6_entry<CalculationType, Parameters>); + factory.add_to_factory("putp6p", new putp6p_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP6_HPP + diff --git a/boost/geometry/srs/projections/proj/qsc.hpp b/boost/geometry/srs/projections/proj/qsc.hpp new file mode 100644 index 0000000000..4cccc29f8b --- /dev/null +++ b/boost/geometry/srs/projections/proj/qsc.hpp @@ -0,0 +1,539 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_QSC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_QSC_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: + +// This implements the Quadrilateralized Spherical Cube (QSC) projection. +// Copyright (c) 2011, 2012 Martin Lambers <marlam@marlam.de> +// The QSC projection was introduced in: +// [OL76] +// E.M. O'Neill and R.E. Laubscher, "Extended Studies of a Quadrilateralized +// Spherical Cube Earth Data Base", Naval Environmental Prediction Research +// Facility Tech. Report NEPRF 3-76 (CSC), May 1976. +// The preceding shift from an ellipsoid to a sphere, which allows to apply +// this projection to ellipsoids as used in the Ellipsoidal Cube Map model, +// is described in +// [LK12] +// M. Lambers and A. Kolb, "Ellipsoidal Cube Maps for Accurate Rendering of +// Planetary-Scale Terrain Data", Proc. Pacfic Graphics (Short Papers), Sep. +// 2012 +// You have to choose one of the following projection centers, +// corresponding to the centers of the six cube faces: +// phi0 = 0.0, lam0 = 0.0 ("front" face) +// phi0 = 0.0, lam0 = 90.0 ("right" face) +// phi0 = 0.0, lam0 = 180.0 ("back" face) +// phi0 = 0.0, lam0 = -90.0 ("left" face) +// phi0 = 90.0 ("top" face) +// phi0 = -90.0 ("bottom" face) +// Other projection centers will not work! +// In the projection code below, each cube face is handled differently. +// See the computation of the face parameter in the ENTRY0(qsc) function +// and the handling of different face values (FACE_*) in the forward and +// inverse projections. +// Furthermore, the projection is originally only defined for theta angles +// between (-1/4 * PI) and (+1/4 * PI) on the current cube face. This area +// of definition is named AREA_0 in the projection code below. The other +// three areas of a cube face are handled by rotation of AREA_0. + +// 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 qsc {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace qsc + { + static const double EPS10 = 1.e-10; + static const int FACE_FRONT = 0; + static const int FACE_RIGHT = 1; + static const int FACE_BACK = 2; + static const int FACE_LEFT = 3; + static const int FACE_TOP = 4; + static const int FACE_BOTTOM = 5; + static const int AREA_0 = 0; + static const int AREA_1 = 1; + static const int AREA_2 = 2; + static const int AREA_3 = 3; + + template <typename T> + struct par_qsc + { + int face; + T a_squared; + T b; + T one_minus_f; + T one_minus_f_squared; + }; + + /* The six cube faces. */ + + /* The four areas on a cube face. AREA_0 is the area of definition, + * the other three areas are counted counterclockwise. */ + + /* Helper function for forward projection: compute the theta angle + * and determine the area number. */ + template <typename T> + inline T qsc_fwd_equat_face_theta(T const& phi, T const& y, T const& x, int *area) + { + static const T FORTPI = detail::FORTPI<T>(); + static const T HALFPI = detail::HALFPI<T>(); + static const T ONEPI = detail::ONEPI<T>(); + + T theta; + if (phi < EPS10) { + *area = AREA_0; + theta = 0.0; + } else { + theta = atan2(y, x); + if (fabs(theta) <= FORTPI) { + *area = AREA_0; + } else if (theta > FORTPI && theta <= HALFPI + FORTPI) { + *area = AREA_1; + theta -= HALFPI; + } else if (theta > HALFPI + FORTPI || theta <= -(HALFPI + FORTPI)) { + *area = AREA_2; + theta = (theta >= 0.0 ? theta - ONEPI : theta + ONEPI); + } else { + *area = AREA_3; + theta += HALFPI; + } + } + return (theta); + } + + /* Helper function: shift the longitude. */ + template <typename T> + inline T qsc_shift_lon_origin(T const& lon, T const& offset) + { + static const T ONEPI = detail::ONEPI<T>(); + static const T TWOPI = detail::TWOPI<T>(); + + T slon = lon + offset; + if (slon < -ONEPI) { + slon += TWOPI; + } else if (slon > +ONEPI) { + slon -= TWOPI; + } + return slon; + } + + /* Forward projection, ellipsoid */ + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_qsc_ellipsoid : public base_t_fi<base_qsc_ellipsoid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_qsc<CalculationType> m_proj_parm; + + inline base_qsc_ellipsoid(const Parameters& par) + : base_t_fi<base_qsc_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>(); + static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); + + CalculationType lat, lon; + CalculationType sinlat, coslat; + CalculationType sinlon, coslon; + CalculationType q = 0.0, r = 0.0, s = 0.0; + CalculationType theta, phi; + CalculationType t, mu, nu; + int area; + + /* Convert the geodetic latitude to a geocentric latitude. + * This corresponds to the shift from the ellipsoid to the sphere + * described in [LK12]. */ + if (this->m_par.es) { + lat = atan(this->m_proj_parm.one_minus_f_squared * tan(lp_lat)); + } else { + lat = lp_lat; + } + + /* Convert the input lat, lon into theta, phi as used by QSC. + * This depends on the cube face and the area on it. + * For the top and bottom face, we can compute theta and phi + * directly from phi, lam. For the other faces, we must use + * unit sphere cartesian coordinates as an intermediate step. */ + lon = lp_lon; + if (this->m_proj_parm.face != FACE_TOP && this->m_proj_parm.face != FACE_BOTTOM) { + if (this->m_proj_parm.face == FACE_RIGHT) { + lon = qsc_shift_lon_origin(lon, +HALFPI); + } else if (this->m_proj_parm.face == FACE_BACK) { + lon = qsc_shift_lon_origin(lon, +ONEPI); + } else if (this->m_proj_parm.face == FACE_LEFT) { + lon = qsc_shift_lon_origin(lon, -HALFPI); + } + sinlat = sin(lat); + coslat = cos(lat); + sinlon = sin(lon); + coslon = cos(lon); + q = coslat * coslon; + r = coslat * sinlon; + s = sinlat; + } + if (this->m_proj_parm.face == FACE_FRONT) { + phi = acos(q); + theta = qsc_fwd_equat_face_theta(phi, s, r, &area); + } else if (this->m_proj_parm.face == FACE_RIGHT) { + phi = acos(r); + theta = qsc_fwd_equat_face_theta(phi, s, -q, &area); + } else if (this->m_proj_parm.face == FACE_BACK) { + phi = acos(-q); + theta = qsc_fwd_equat_face_theta(phi, s, -r, &area); + } else if (this->m_proj_parm.face == FACE_LEFT) { + phi = acos(-r); + theta = qsc_fwd_equat_face_theta(phi, s, q, &area); + } else if (this->m_proj_parm.face == FACE_TOP) { + phi = HALFPI - lat; + if (lon >= FORTPI && lon <= HALFPI + FORTPI) { + area = AREA_0; + theta = lon - HALFPI; + } else if (lon > HALFPI + FORTPI || lon <= -(HALFPI + FORTPI)) { + area = AREA_1; + theta = (lon > 0.0 ? lon - ONEPI : lon + ONEPI); + } else if (lon > -(HALFPI + FORTPI) && lon <= -FORTPI) { + area = AREA_2; + theta = lon + HALFPI; + } else { + area = AREA_3; + theta = lon; + } + } else /* this->m_proj_parm.face == FACE_BOTTOM */ { + phi = HALFPI + lat; + if (lon >= FORTPI && lon <= HALFPI + FORTPI) { + area = AREA_0; + theta = -lon + HALFPI; + } else if (lon < FORTPI && lon >= -FORTPI) { + area = AREA_1; + theta = -lon; + } else if (lon < -FORTPI && lon >= -(HALFPI + FORTPI)) { + area = AREA_2; + theta = -lon - HALFPI; + } else { + area = AREA_3; + theta = (lon > 0.0 ? -lon + ONEPI : -lon - ONEPI); + } + } + + /* Compute mu and nu for the area of definition. + * For mu, see Eq. (3-21) in [OL76], but note the typos: + * compare with Eq. (3-14). For nu, see Eq. (3-38). */ + mu = atan((12.0 / ONEPI) * (theta + acos(sin(theta) * cos(FORTPI)) - HALFPI)); + t = sqrt((1.0 - cos(phi)) / (cos(mu) * cos(mu)) / (1.0 - cos(atan(1.0 / cos(theta))))); + /* nu = atan(t); We don't really need nu, just t, see below. */ + + /* Apply the result to the real area. */ + if (area == AREA_1) { + mu += HALFPI; + } else if (area == AREA_2) { + mu += ONEPI; + } else if (area == AREA_3) { + mu += HALFPI + ONEPI; + } + + /* Now compute x, y from mu and nu */ + /* t = tan(nu); */ + xy_x = t * cos(mu); + xy_y = t * sin(mu); + boost::ignore_unused(nu); + } + /* Inverse projection, ellipsoid */ + + // INVERSE(e_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 + { + static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const CalculationType ONEPI = detail::ONEPI<CalculationType>(); + + CalculationType mu, nu, cosmu, tannu; + CalculationType tantheta, theta, cosphi, phi; + CalculationType t; + int area; + + /* Convert the input x, y to the mu and nu angles as used by QSC. + * This depends on the area of the cube face. */ + nu = atan(sqrt(xy_x * xy_x + xy_y * xy_y)); + mu = atan2(xy_y, xy_x); + if (xy_x >= 0.0 && xy_x >= fabs(xy_y)) { + area = AREA_0; + } else if (xy_y >= 0.0 && xy_y >= fabs(xy_x)) { + area = AREA_1; + mu -= HALFPI; + } else if (xy_x < 0.0 && -xy_x >= fabs(xy_y)) { + area = AREA_2; + mu = (mu < 0.0 ? mu + ONEPI : mu - ONEPI); + } else { + area = AREA_3; + mu += HALFPI; + } + + /* Compute phi and theta for the area of definition. + * The inverse projection is not described in the original paper, but some + * good hints can be found here (as of 2011-12-14): + * http://fits.gsfc.nasa.gov/fitsbits/saf.93/saf.9302 + * (search for "Message-Id: <9302181759.AA25477 at fits.cv.nrao.edu>") */ + t = (ONEPI / 12.0) * tan(mu); + tantheta = sin(t) / (cos(t) - (1.0 / sqrt(2.0))); + theta = atan(tantheta); + cosmu = cos(mu); + tannu = tan(nu); + cosphi = 1.0 - cosmu * cosmu * tannu * tannu * (1.0 - cos(atan(1.0 / cos(theta)))); + if (cosphi < -1.0) { + cosphi = -1.0; + } else if (cosphi > +1.0) { + cosphi = +1.0; + } + + /* Apply the result to the real area on the cube face. + * For the top and bottom face, we can compute phi and lam directly. + * For the other faces, we must use unit sphere cartesian coordinates + * as an intermediate step. */ + if (this->m_proj_parm.face == FACE_TOP) { + phi = acos(cosphi); + lp_lat = HALFPI - phi; + if (area == AREA_0) { + lp_lon = theta + HALFPI; + } else if (area == AREA_1) { + lp_lon = (theta < 0.0 ? theta + ONEPI : theta - ONEPI); + } else if (area == AREA_2) { + lp_lon = theta - HALFPI; + } else /* area == AREA_3 */ { + lp_lon = theta; + } + } else if (this->m_proj_parm.face == FACE_BOTTOM) { + phi = acos(cosphi); + lp_lat = phi - HALFPI; + if (area == AREA_0) { + lp_lon = -theta + HALFPI; + } else if (area == AREA_1) { + lp_lon = -theta; + } else if (area == AREA_2) { + lp_lon = -theta - HALFPI; + } else /* area == AREA_3 */ { + lp_lon = (theta < 0.0 ? -theta - ONEPI : -theta + ONEPI); + } + } else { + /* Compute phi and lam via cartesian unit sphere coordinates. */ + CalculationType q, r, s, t; + q = cosphi; + t = q * q; + if (t >= 1.0) { + s = 0.0; + } else { + s = sqrt(1.0 - t) * sin(theta); + } + t += s * s; + if (t >= 1.0) { + r = 0.0; + } else { + r = sqrt(1.0 - t); + } + /* Rotate q,r,s into the correct area. */ + if (area == AREA_1) { + t = r; + r = -s; + s = t; + } else if (area == AREA_2) { + r = -r; + s = -s; + } else if (area == AREA_3) { + t = r; + r = s; + s = -t; + } + /* Rotate q,r,s into the correct cube face. */ + if (this->m_proj_parm.face == FACE_RIGHT) { + t = q; + q = -r; + r = t; + } else if (this->m_proj_parm.face == FACE_BACK) { + q = -q; + r = -r; + } else if (this->m_proj_parm.face == FACE_LEFT) { + t = q; + q = r; + r = -t; + } + /* Now compute phi and lam from the unit sphere coordinates. */ + lp_lat = acos(-s) - HALFPI; + lp_lon = atan2(r, q); + if (this->m_proj_parm.face == FACE_RIGHT) { + lp_lon = qsc_shift_lon_origin(lp_lon, -HALFPI); + } else if (this->m_proj_parm.face == FACE_BACK) { + lp_lon = qsc_shift_lon_origin(lp_lon, -ONEPI); + } else if (this->m_proj_parm.face == FACE_LEFT) { + lp_lon = qsc_shift_lon_origin(lp_lon, +HALFPI); + } + } + + /* Apply the shift from the sphere to the ellipsoid as described + * in [LK12]. */ + if (this->m_par.es) { + int invert_sign; + CalculationType tanphi, xa; + invert_sign = (lp_lat < 0.0 ? 1 : 0); + tanphi = tan(lp_lat); + xa = this->m_proj_parm.b / sqrt(tanphi * tanphi + this->m_proj_parm.one_minus_f_squared); + lp_lat = atan(sqrt(this->m_par.a * this->m_par.a - xa * xa) / (this->m_proj_parm.one_minus_f * xa)); + if (invert_sign) { + lp_lat = -lp_lat; + } + } + } + + static inline std::string get_name() + { + return "qsc_ellipsoid"; + } + + }; + + // Quadrilateralized Spherical Cube + template <typename Parameters, typename T> + inline void setup_qsc(Parameters& par, par_qsc<T>& proj_parm) + { + static const T FORTPI = detail::FORTPI<T>(); + static const T HALFPI = detail::HALFPI<T>(); + + /* Determine the cube face from the center of projection. */ + if (par.phi0 >= HALFPI - FORTPI / 2.0) { + proj_parm.face = FACE_TOP; + } else if (par.phi0 <= -(HALFPI - FORTPI / 2.0)) { + proj_parm.face = FACE_BOTTOM; + } else if (fabs(par.lam0) <= FORTPI) { + proj_parm.face = FACE_FRONT; + } else if (fabs(par.lam0) <= HALFPI + FORTPI) { + proj_parm.face = (par.lam0 > 0.0 ? FACE_RIGHT : FACE_LEFT); + } else { + proj_parm.face = FACE_BACK; + } + /* Fill in useful values for the ellipsoid <-> sphere shift + * described in [LK12]. */ + if (par.es) { + proj_parm.a_squared = par.a * par.a; + proj_parm.b = par.a * sqrt(1.0 - par.es); + proj_parm.one_minus_f = 1.0 - (par.a - proj_parm.b) / par.a; + proj_parm.one_minus_f_squared = proj_parm.one_minus_f * proj_parm.one_minus_f; + } + } + + }} // namespace detail::qsc + #endif // doxygen + + /*! + \brief Quadrilateralized Spherical Cube 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_qsc.gif + */ + template <typename CalculationType, typename Parameters> + struct qsc_ellipsoid : public detail::qsc::base_qsc_ellipsoid<CalculationType, Parameters> + { + inline qsc_ellipsoid(const Parameters& par) : detail::qsc::base_qsc_ellipsoid<CalculationType, Parameters>(par) + { + detail::qsc::setup_qsc(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::qsc, qsc_ellipsoid, qsc_ellipsoid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class qsc_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<qsc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void qsc_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("qsc", new qsc_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_QSC_HPP + diff --git a/boost/geometry/srs/projections/proj/robin.hpp b/boost/geometry/srs/projections/proj/robin.hpp new file mode 100644 index 0000000000..52acb58e41 --- /dev/null +++ b/boost/geometry/srs/projections/proj/robin.hpp @@ -0,0 +1,298 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_ROBIN_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ROBIN_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/function_overloads.hpp> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct robin {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace robin + { + + static const double FXC = 0.8487; + static const double FYC = 1.3523; + static const double C1 = 11.45915590261646417544; + static const double RC1 = 0.08726646259971647884; + static const int NODES = 18; + static const double ONEEPS = 1.000001; + static const double EPS = 1e-8; + + /* + note: following terms based upon 5 deg. intervals in degrees. + + Some background on these coefficients is available at: + + http://article.gmane.org/gmane.comp.gis.proj-4.devel/6039 + http://trac.osgeo.org/proj/ticket/113 + */ + + template <typename T> + struct COEFS { + T c0, c1, c2, c3; + }; + + template <typename T> + inline const COEFS<T> * X() + { + static const COEFS<T> result[] = { + {1.0, 2.2199e-17, -7.15515e-05, 3.1103e-06}, + {0.9986, -0.000482243, -2.4897e-05, -1.3309e-06}, + {0.9954, -0.00083103, -4.48605e-05, -9.86701e-07}, + {0.99, -0.00135364, -5.9661e-05, 3.6777e-06}, + {0.9822, -0.00167442, -4.49547e-06, -5.72411e-06}, + {0.973, -0.00214868, -9.03571e-05, 1.8736e-08}, + {0.96, -0.00305085, -9.00761e-05, 1.64917e-06}, + {0.9427, -0.00382792, -6.53386e-05, -2.6154e-06}, + {0.9216, -0.00467746, -0.00010457, 4.81243e-06}, + {0.8962, -0.00536223, -3.23831e-05, -5.43432e-06}, + {0.8679, -0.00609363, -0.000113898, 3.32484e-06}, + {0.835, -0.00698325, -6.40253e-05, 9.34959e-07}, + {0.7986, -0.00755338, -5.00009e-05, 9.35324e-07}, + {0.7597, -0.00798324, -3.5971e-05, -2.27626e-06}, + {0.7186, -0.00851367, -7.01149e-05, -8.6303e-06}, + {0.6732, -0.00986209, -0.000199569, 1.91974e-05}, + {0.6213, -0.010418, 8.83923e-05, 6.24051e-06}, + {0.5722, -0.00906601, 0.000182, 6.24051e-06}, + {0.5322, -0.00677797, 0.000275608, 6.24051e-06} + }; + return result; + } + + template <typename T> + inline const COEFS<T> * Y() + { + static const COEFS<T> result[] = { + {-5.20417e-18, 0.0124, 1.21431e-18, -8.45284e-11}, + {0.062, 0.0124, -1.26793e-09, 4.22642e-10}, + {0.124, 0.0124, 5.07171e-09, -1.60604e-09}, + {0.186, 0.0123999, -1.90189e-08, 6.00152e-09}, + {0.248, 0.0124002, 7.10039e-08, -2.24e-08}, + {0.31, 0.0123992, -2.64997e-07, 8.35986e-08}, + {0.372, 0.0124029, 9.88983e-07, -3.11994e-07}, + {0.434, 0.0123893, -3.69093e-06, -4.35621e-07}, + {0.4958, 0.0123198, -1.02252e-05, -3.45523e-07}, + {0.5571, 0.0121916, -1.54081e-05, -5.82288e-07}, + {0.6176, 0.0119938, -2.41424e-05, -5.25327e-07}, + {0.6769, 0.011713, -3.20223e-05, -5.16405e-07}, + {0.7346, 0.0113541, -3.97684e-05, -6.09052e-07}, + {0.7903, 0.0109107, -4.89042e-05, -1.04739e-06}, + {0.8435, 0.0103431, -6.4615e-05, -1.40374e-09}, + {0.8936, 0.00969686, -6.4636e-05, -8.547e-06}, + {0.9394, 0.00840947, -0.000192841, -4.2106e-06}, + {0.9761, 0.00616527, -0.000256, -4.2106e-06}, + {1.0, 0.00328947, -0.000319159, -4.2106e-06} + }; + return result; + } + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_robin_spheroid : public base_t_fi<base_robin_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_robin_spheroid(const Parameters& par) + : base_t_fi<base_robin_spheroid<CalculationType, Parameters>, + CalculationType, Parameters>(*this, par) {} + + template <typename T> + inline T V(COEFS<T> const& C, T const& z) const + { return (C.c0 + z * (C.c1 + z * (C.c2 + z * C.c3))); } + template <typename T> + inline T DV(COEFS<T> const& C, T const& z) const + { return (C.c1 + z * (C.c2 + C.c2 + z * 3. * C.c3)); } + + // 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 + { + int i; + CalculationType dphi; + + i = int_floor((dphi = fabs(lp_lat)) * C1); + if (i < 0) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (i >= NODES) i = NODES - 1; + dphi = geometry::math::r2d<CalculationType>() * (dphi - RC1 * i); + xy_x = V(X<CalculationType>()[i], dphi) * FXC * lp_lon; + xy_y = V(Y<CalculationType>()[i], dphi) * FYC; + 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>(); + const COEFS<CalculationType> * X = robin::X<CalculationType>(); + const COEFS<CalculationType> * Y = robin::Y<CalculationType>(); + + int i; + CalculationType t, t1; + COEFS<CalculationType> T; + + lp_lon = xy_x / FXC; + lp_lat = fabs(xy_y / FYC); + if (lp_lat >= 1.) { /* simple pathologic cases */ + if (lp_lat > ONEEPS) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + else { + lp_lat = xy_y < 0. ? -HALFPI : HALFPI; + lp_lon /= X[NODES].c0; + } + } else { /* general problem */ + /* in Y space, reduce to table interval */ + i = int_floor(lp_lat * NODES); + if( i < 0 || i >= NODES ) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + for (;;) { + if (Y[i].c0 > lp_lat) --i; + else if (Y[i+1].c0 <= lp_lat) ++i; + else break; + } + T = Y[i]; + /* first guess, linear interp */ + t = 5. * (lp_lat - T.c0)/(Y[i+1].c0 - T.c0); + /* make into root */ + T.c0 -= lp_lat; + for (;;) { /* Newton-Raphson reduction */ + t -= t1 = V(T,t) / DV(T,t); + if (fabs(t1) < EPS) + break; + } + lp_lat = (5 * i + t) * geometry::math::d2r<CalculationType>(); + if (xy_y < 0.) lp_lat = -lp_lat; + lp_lon /= V(X[i], t); + } + } + + static inline std::string get_name() + { + return "robin_spheroid"; + } + + }; + + // Robinson + template <typename Parameters> + inline void setup_robin(Parameters& par) + { + par.es = 0.; + } + + }} // namespace detail::robin + #endif // doxygen + + /*! + \brief Robinson 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_robin.gif + */ + template <typename CalculationType, typename Parameters> + struct robin_spheroid : public detail::robin::base_robin_spheroid<CalculationType, Parameters> + { + inline robin_spheroid(const Parameters& par) : detail::robin::base_robin_spheroid<CalculationType, Parameters>(par) + { + detail::robin::setup_robin(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::robin, robin_spheroid, robin_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class robin_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<robin_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void robin_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("robin", new robin_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_ROBIN_HPP + diff --git a/boost/geometry/srs/projections/proj/rouss.hpp b/boost/geometry/srs/projections/proj/rouss.hpp new file mode 100644 index 0000000000..edad904799 --- /dev/null +++ b/boost/geometry/srs/projections/proj/rouss.hpp @@ -0,0 +1,241 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_ROUSS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_ROUSS_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) 2003, 2006 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/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/proj_mdist.hpp> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct rouss {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace rouss + { + template <typename T> + struct par_rouss + { + T s0; + T A1, A2, A3, A4, A5, A6; + T B1, B2, B3, B4, B5, B6, B7, B8; + T C1, C2, C3, C4, C5, C6, C7, C8; + T D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11; + MDIST<T> en; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_rouss_ellipsoid : public base_t_fi<base_rouss_ellipsoid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_rouss<CalculationType> m_proj_parm; + + inline base_rouss_ellipsoid(const Parameters& par) + : base_t_fi<base_rouss_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, al, cp, sp, al2, s2; + + cp = cos(lp_lat); + sp = sin(lp_lat); + s = proj_mdist(lp_lat, sp, cp, this->m_proj_parm.en) - this->m_proj_parm.s0; + s2 = s * s; + al = lp_lon * cp / sqrt(1. - this->m_par.es * sp * sp); + al2 = al * al; + xy_x = this->m_par.k0 * al*(1.+s2*(this->m_proj_parm.A1+s2*this->m_proj_parm.A4)-al2*(this->m_proj_parm.A2+s*this->m_proj_parm.A3+s2*this->m_proj_parm.A5 + +al2*this->m_proj_parm.A6)); + xy_y = this->m_par.k0 * (al2*(this->m_proj_parm.B1+al2*this->m_proj_parm.B4)+ + s*(1.+al2*(this->m_proj_parm.B3-al2*this->m_proj_parm.B6)+s2*(this->m_proj_parm.B2+s2*this->m_proj_parm.B8)+ + s*al2*(this->m_proj_parm.B5+s*this->m_proj_parm.B7))); + } + + // 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 s, al, x = xy_x / this->m_par.k0, y = xy_y / this->m_par.k0, x2, y2;; + + x2 = x * x; + y2 = y * y; + al = x*(1.-this->m_proj_parm.C1*y2+x2*(this->m_proj_parm.C2+this->m_proj_parm.C3*y-this->m_proj_parm.C4*x2+this->m_proj_parm.C5*y2-this->m_proj_parm.C7*x2*y) + +y2*(this->m_proj_parm.C6*y2-this->m_proj_parm.C8*x2*y)); + s = this->m_proj_parm.s0 + y*(1.+y2*(-this->m_proj_parm.D2+this->m_proj_parm.D8*y2))+ + x2*(-this->m_proj_parm.D1+y*(-this->m_proj_parm.D3+y*(-this->m_proj_parm.D5+y*(-this->m_proj_parm.D7+y*this->m_proj_parm.D11)))+ + x2*(this->m_proj_parm.D4+y*(this->m_proj_parm.D6+y*this->m_proj_parm.D10)-x2*this->m_proj_parm.D9)); + lp_lat=proj_inv_mdist(s, this->m_proj_parm.en); + s = sin(lp_lat); + lp_lon=al * sqrt(1. - this->m_par.es * s * s)/cos(lp_lat); + } + + static inline std::string get_name() + { + return "rouss_ellipsoid"; + } + + }; + + // Roussilhe Stereographic + template <typename Parameters, typename T> + inline void setup_rouss(Parameters& par, par_rouss<T>& proj_parm) + { + T N0, es2, t, t2, R_R0_2, R_R0_4; + + if (!proj_mdist_ini(par.es, proj_parm.en)) + BOOST_THROW_EXCEPTION( projection_exception(0) ); + es2 = sin(par.phi0); + proj_parm.s0 = proj_mdist(par.phi0, es2, cos(par.phi0), proj_parm.en); + t = 1. - (es2 = par.es * es2 * es2); + N0 = 1./sqrt(t); + R_R0_2 = t * t / par.one_es; + R_R0_4 = R_R0_2 * R_R0_2; + t = tan(par.phi0); + t2 = t * t; + proj_parm.C1 = proj_parm.A1 = R_R0_2 / 4.; + proj_parm.C2 = proj_parm.A2 = R_R0_2 * (2 * t2 - 1. - 2. * es2) / 12.; + proj_parm.A3 = R_R0_2 * t * (1. + 4. * t2)/ ( 12. * N0); + proj_parm.A4 = R_R0_4 / 24.; + proj_parm.A5 = R_R0_4 * ( -1. + t2 * (11. + 12. * t2))/24.; + proj_parm.A6 = R_R0_4 * ( -2. + t2 * (11. - 2. * t2))/240.; + proj_parm.B1 = t / (2. * N0); + proj_parm.B2 = R_R0_2 / 12.; + proj_parm.B3 = R_R0_2 * (1. + 2. * t2 - 2. * es2)/4.; + proj_parm.B4 = R_R0_2 * t * (2. - t2)/(24. * N0); + proj_parm.B5 = R_R0_2 * t * (5. + 4.* t2)/(8. * N0); + proj_parm.B6 = R_R0_4 * (-2. + t2 * (-5. + 6. * t2))/48.; + proj_parm.B7 = R_R0_4 * (5. + t2 * (19. + 12. * t2))/24.; + proj_parm.B8 = R_R0_4 / 120.; + proj_parm.C3 = R_R0_2 * t * (1. + t2)/(3. * N0); + proj_parm.C4 = R_R0_4 * (-3. + t2 * (34. + 22. * t2))/240.; + proj_parm.C5 = R_R0_4 * (4. + t2 * (13. + 12. * t2))/24.; + proj_parm.C6 = R_R0_4 / 16.; + proj_parm.C7 = R_R0_4 * t * (11. + t2 * (33. + t2 * 16.))/(48. * N0); + proj_parm.C8 = R_R0_4 * t * (1. + t2 * 4.)/(36. * N0); + proj_parm.D1 = t / (2. * N0); + proj_parm.D2 = R_R0_2 / 12.; + proj_parm.D3 = R_R0_2 * (2 * t2 + 1. - 2. * es2) / 4.; + proj_parm.D4 = R_R0_2 * t * (1. + t2)/(8. * N0); + proj_parm.D5 = R_R0_2 * t * (1. + t2 * 2.)/(4. * N0); + proj_parm.D6 = R_R0_4 * (1. + t2 * (6. + t2 * 6.))/16.; + proj_parm.D7 = R_R0_4 * t2 * (3. + t2 * 4.)/8.; + proj_parm.D8 = R_R0_4 / 80.; + proj_parm.D9 = R_R0_4 * t * (-21. + t2 * (178. - t2 * 26.))/720.; + proj_parm.D10 = R_R0_4 * t * (29. + t2 * (86. + t2 * 48.))/(96. * N0); + proj_parm.D11 = R_R0_4 * t * (37. + t2 * 44.)/(96. * N0); + } + + }} // namespace detail::rouss + #endif // doxygen + + /*! + \brief Roussilhe Stereographic projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Azimuthal + - Ellipsoid + \par Example + \image html ex_rouss.gif + */ + template <typename CalculationType, typename Parameters> + struct rouss_ellipsoid : public detail::rouss::base_rouss_ellipsoid<CalculationType, Parameters> + { + inline rouss_ellipsoid(const Parameters& par) : detail::rouss::base_rouss_ellipsoid<CalculationType, Parameters>(par) + { + detail::rouss::setup_rouss(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::rouss, rouss_ellipsoid, rouss_ellipsoid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class rouss_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<rouss_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void rouss_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("rouss", new rouss_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_ROUSS_HPP + diff --git a/boost/geometry/srs/projections/proj/rpoly.hpp b/boost/geometry/srs/projections/proj/rpoly.hpp new file mode 100644 index 0000000000..fcb9f1043b --- /dev/null +++ b/boost/geometry/srs/projections/proj/rpoly.hpp @@ -0,0 +1,187 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_RPOLY_HPP +#define BOOST_GEOMETRY_PROJECTIONS_RPOLY_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 rpoly {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace rpoly + { + + static const double EPS = 1e-9; + + template <typename T> + struct par_rpoly + { + T phi1; + T fxa; + T fxb; + int mode; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_rpoly_spheroid : public base_t_f<base_rpoly_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_rpoly<CalculationType> m_proj_parm; + + inline base_rpoly_spheroid(const Parameters& par) + : base_t_f<base_rpoly_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 fa; + + if (this->m_proj_parm.mode) + fa = tan(lp_lon * this->m_proj_parm.fxb) * this->m_proj_parm.fxa; + else + fa = 0.5 * lp_lon; + if (fabs(lp_lat) < EPS) { + xy_x = fa + fa; + xy_y = - this->m_par.phi0; + } else { + xy_y = 1. / tan(lp_lat); + xy_x = sin(fa = 2. * atan(fa * sin(lp_lat))) * xy_y; + xy_y = lp_lat - this->m_par.phi0 + (1. - cos(fa)) * xy_y; + } + } + + static inline std::string get_name() + { + return "rpoly_spheroid"; + } + + }; + + // Rectangular Polyconic + template <typename Parameters, typename T> + inline void setup_rpoly(Parameters& par, par_rpoly<T>& proj_parm) + { + if ((proj_parm.mode = (proj_parm.phi1 = fabs(pj_param(par.params, "rlat_ts").f)) > EPS)) { + proj_parm.fxb = 0.5 * sin(proj_parm.phi1); + proj_parm.fxa = 0.5 / proj_parm.fxb; + } + par.es = 0.; + } + + }} // namespace detail::rpoly + #endif // doxygen + + /*! + \brief Rectangular Polyconic projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Conic + - Spheroid + - no inverse + \par Projection parameters + - lat_ts: Latitude of true scale (degrees) + \par Example + \image html ex_rpoly.gif + */ + template <typename CalculationType, typename Parameters> + struct rpoly_spheroid : public detail::rpoly::base_rpoly_spheroid<CalculationType, Parameters> + { + inline rpoly_spheroid(const Parameters& par) : detail::rpoly::base_rpoly_spheroid<CalculationType, Parameters>(par) + { + detail::rpoly::setup_rpoly(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::rpoly, rpoly_spheroid, rpoly_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class rpoly_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_f<rpoly_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void rpoly_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("rpoly", new rpoly_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_RPOLY_HPP + diff --git a/boost/geometry/srs/projections/proj/sconics.hpp b/boost/geometry/srs/projections/proj/sconics.hpp new file mode 100644 index 0000000000..b5f97fa542 --- /dev/null +++ b/boost/geometry/srs/projections/proj/sconics.hpp @@ -0,0 +1,570 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_SCONICS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_SCONICS_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 euler {}; + struct murd1 {}; + struct murd2 {}; + struct murd3 {}; + struct pconic {}; + struct tissot {}; + struct vitk1 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace sconics + { + + static const int EULER = 0; + static const int MURD1 = 1; + static const int MURD2 = 2; + static const int MURD3 = 3; + static const int PCONIC = 4; + static const int TISSOT = 5; + static const int VITK1 = 6; + static const double EPS10 = 1.e-10; + static const double EPS = 1e-10; + + template <typename T> + struct par_sconics + { + T n; + T rho_c; + T rho_0; + T sig; + T c1, c2; + int type; + }; + + /* get common factors for simple conics */ + template <typename Parameters, typename T> + inline int phi12(Parameters& par, par_sconics<T>& proj_parm, T *del) + { + T p1, p2; + int err = 0; + + if (!pj_param(par.params, "tlat_1").i || + !pj_param(par.params, "tlat_2").i) { + err = -41; + } else { + p1 = pj_param(par.params, "rlat_1").f; + p2 = pj_param(par.params, "rlat_2").f; + *del = 0.5 * (p2 - p1); + proj_parm.sig = 0.5 * (p2 + p1); + err = (fabs(*del) < EPS || fabs(proj_parm.sig) < EPS) ? -42 : 0; + *del = *del; + } + return err; + } + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_sconics_spheroid : public base_t_fi<base_sconics_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_sconics<CalculationType> m_proj_parm; + + inline base_sconics_spheroid(const Parameters& par) + : base_t_fi<base_sconics_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 rho; + + switch (this->m_proj_parm.type) { + case MURD2: + rho = this->m_proj_parm.rho_c + tan(this->m_proj_parm.sig - lp_lat); + break; + case PCONIC: + rho = this->m_proj_parm.c2 * (this->m_proj_parm.c1 - tan(lp_lat - this->m_proj_parm.sig)); + break; + default: + rho = this->m_proj_parm.rho_c - lp_lat; + break; + } + xy_x = rho * sin( lp_lon *= this->m_proj_parm.n ); + xy_y = this->m_proj_parm.rho_0 - rho * cos(lp_lon); + } + + // INVERSE(s_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 rho; + + rho = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.rho_0 - xy_y); + if (this->m_proj_parm.n < 0.) { + rho = - rho; + xy_x = - xy_x; + xy_y = - xy_y; + } + lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n; + switch (this->m_proj_parm.type) { + case PCONIC: + lp_lat = atan(this->m_proj_parm.c1 - rho / this->m_proj_parm.c2) + this->m_proj_parm.sig; + break; + case MURD2: + lp_lat = this->m_proj_parm.sig - atan(rho - this->m_proj_parm.rho_c); + break; + default: + lp_lat = this->m_proj_parm.rho_c - rho; + } + } + + static inline std::string get_name() + { + return "sconics_spheroid"; + } + + }; + + template <typename Parameters, typename T> + inline void setup(Parameters& par, par_sconics<T>& proj_parm) + { + static const T HALFPI = detail::HALFPI<T>(); + + T del, cs; + int i; + + if( (i = phi12(par, proj_parm, &del)) ) + BOOST_THROW_EXCEPTION( projection_exception(i) ); + switch (proj_parm.type) { + case TISSOT: + proj_parm.n = sin(proj_parm.sig); + cs = cos(del); + proj_parm.rho_c = proj_parm.n / cs + cs / proj_parm.n; + proj_parm.rho_0 = sqrt((proj_parm.rho_c - 2 * sin(par.phi0))/proj_parm.n); + break; + case MURD1: + proj_parm.rho_c = sin(del)/(del * tan(proj_parm.sig)) + proj_parm.sig; + proj_parm.rho_0 = proj_parm.rho_c - par.phi0; + proj_parm.n = sin(proj_parm.sig); + break; + case MURD2: + proj_parm.rho_c = (cs = sqrt(cos(del))) / tan(proj_parm.sig); + proj_parm.rho_0 = proj_parm.rho_c + tan(proj_parm.sig - par.phi0); + proj_parm.n = sin(proj_parm.sig) * cs; + break; + case MURD3: + proj_parm.rho_c = del / (tan(proj_parm.sig) * tan(del)) + proj_parm.sig; + proj_parm.rho_0 = proj_parm.rho_c - par.phi0; + proj_parm.n = sin(proj_parm.sig) * sin(del) * tan(del) / (del * del); + break; + case EULER: + proj_parm.n = sin(proj_parm.sig) * sin(del) / del; + del *= 0.5; + proj_parm.rho_c = del / (tan(del) * tan(proj_parm.sig)) + proj_parm.sig; + proj_parm.rho_0 = proj_parm.rho_c - par.phi0; + break; + case PCONIC: + proj_parm.n = sin(proj_parm.sig); + proj_parm.c2 = cos(del); + proj_parm.c1 = 1./tan(proj_parm.sig); + if (fabs(del = par.phi0 - proj_parm.sig) - EPS10 >= HALFPI) + BOOST_THROW_EXCEPTION( projection_exception(-43) ); + proj_parm.rho_0 = proj_parm.c2 * (proj_parm.c1 - tan(del)); + break; + case VITK1: + proj_parm.n = (cs = tan(del)) * sin(proj_parm.sig) / del; + proj_parm.rho_c = del / (cs * tan(proj_parm.sig)) + proj_parm.sig; + proj_parm.rho_0 = proj_parm.rho_c - par.phi0; + break; + } + par.es = 0; + } + + + // Tissot + template <typename Parameters, typename T> + inline void setup_tissot(Parameters& par, par_sconics<T>& proj_parm) + { + proj_parm.type = TISSOT; + setup(par, proj_parm); + } + + // Murdoch I + template <typename Parameters, typename T> + inline void setup_murd1(Parameters& par, par_sconics<T>& proj_parm) + { + proj_parm.type = MURD1; + setup(par, proj_parm); + } + + // Murdoch II + template <typename Parameters, typename T> + inline void setup_murd2(Parameters& par, par_sconics<T>& proj_parm) + { + proj_parm.type = MURD2; + setup(par, proj_parm); + } + + // Murdoch III + template <typename Parameters, typename T> + inline void setup_murd3(Parameters& par, par_sconics<T>& proj_parm) + { + proj_parm.type = MURD3; + setup(par, proj_parm); + } + + // Euler + template <typename Parameters, typename T> + inline void setup_euler(Parameters& par, par_sconics<T>& proj_parm) + { + proj_parm.type = EULER; + setup(par, proj_parm); + } + + // Perspective Conic + template <typename Parameters, typename T> + inline void setup_pconic(Parameters& par, par_sconics<T>& proj_parm) + { + proj_parm.type = PCONIC; + setup(par, proj_parm); + } + + // Vitkovsky I + template <typename Parameters, typename T> + inline void setup_vitk1(Parameters& par, par_sconics<T>& proj_parm) + { + proj_parm.type = VITK1; + setup(par, proj_parm); + } + + }} // namespace detail::sconics + #endif // doxygen + + /*! + \brief Tissot 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 + - lat_1: Latitude of first standard parallel + - lat_2: Latitude of second standard parallel + \par Example + \image html ex_tissot.gif + */ + template <typename CalculationType, typename Parameters> + struct tissot_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + { + inline tissot_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + { + detail::sconics::setup_tissot(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Murdoch I 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 + - lat_1: Latitude of first standard parallel + - lat_2: Latitude of second standard parallel + \par Example + \image html ex_murd1.gif + */ + template <typename CalculationType, typename Parameters> + struct murd1_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + { + inline murd1_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + { + detail::sconics::setup_murd1(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Murdoch II 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 + - lat_1: Latitude of first standard parallel + - lat_2: Latitude of second standard parallel + \par Example + \image html ex_murd2.gif + */ + template <typename CalculationType, typename Parameters> + struct murd2_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + { + inline murd2_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + { + detail::sconics::setup_murd2(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Murdoch III 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 + - lat_1: Latitude of first standard parallel + - lat_2: Latitude of second standard parallel + \par Example + \image html ex_murd3.gif + */ + template <typename CalculationType, typename Parameters> + struct murd3_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + { + inline murd3_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + { + detail::sconics::setup_murd3(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Euler 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 + - lat_1: Latitude of first standard parallel + - lat_2: Latitude of second standard parallel + \par Example + \image html ex_euler.gif + */ + template <typename CalculationType, typename Parameters> + struct euler_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + { + inline euler_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + { + detail::sconics::setup_euler(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Perspective Conic 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 + - lat_1: Latitude of first standard parallel + - lat_2: Latitude of second standard parallel + \par Example + \image html ex_pconic.gif + */ + template <typename CalculationType, typename Parameters> + struct pconic_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + { + inline pconic_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + { + detail::sconics::setup_pconic(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Vitkovsky I 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 + - lat_1: Latitude of first standard parallel + - lat_2: Latitude of second standard parallel + \par Example + \image html ex_vitk1.gif + */ + template <typename CalculationType, typename Parameters> + struct vitk1_spheroid : public detail::sconics::base_sconics_spheroid<CalculationType, Parameters> + { + inline vitk1_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<CalculationType, Parameters>(par) + { + detail::sconics::setup_vitk1(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::euler, euler_spheroid, euler_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::murd1, murd1_spheroid, murd1_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::murd2, murd2_spheroid, murd2_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::murd3, murd3_spheroid, murd3_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::pconic, pconic_spheroid, pconic_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::tissot, tissot_spheroid, tissot_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::vitk1, vitk1_spheroid, vitk1_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class tissot_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<tissot_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class murd1_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<murd1_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class murd2_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<murd2_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class murd3_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<murd3_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class euler_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<euler_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class pconic_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<pconic_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class vitk1_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<vitk1_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void sconics_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("tissot", new tissot_entry<CalculationType, Parameters>); + factory.add_to_factory("murd1", new murd1_entry<CalculationType, Parameters>); + factory.add_to_factory("murd2", new murd2_entry<CalculationType, Parameters>); + factory.add_to_factory("murd3", new murd3_entry<CalculationType, Parameters>); + factory.add_to_factory("euler", new euler_entry<CalculationType, Parameters>); + factory.add_to_factory("pconic", new pconic_entry<CalculationType, Parameters>); + factory.add_to_factory("vitk1", new vitk1_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_SCONICS_HPP + diff --git a/boost/geometry/srs/projections/proj/somerc.hpp b/boost/geometry/srs/projections/proj/somerc.hpp new file mode 100644 index 0000000000..e67d09719e --- /dev/null +++ b/boost/geometry/srs/projections/proj/somerc.hpp @@ -0,0 +1,227 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_SOMERC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_SOMERC_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 somerc {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace somerc + { + static const double EPS = 1.e-10; + static const int NITER = 6; + + template <typename T> + struct par_somerc + { + T K, c, hlf_e, kR, cosp0, sinp0; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_somerc_ellipsoid : public base_t_fi<base_somerc_ellipsoid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_somerc<CalculationType> m_proj_parm; + + inline base_somerc_ellipsoid(const Parameters& par) + : base_t_fi<base_somerc_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>(); + static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + + CalculationType phip, lamp, phipp, lampp, sp, cp; + + sp = this->m_par.e * sin(lp_lat); + phip = 2.* atan( exp( this->m_proj_parm.c * ( + log(tan(FORTPI + 0.5 * lp_lat)) - this->m_proj_parm.hlf_e * log((1. + sp)/(1. - sp))) + + this->m_proj_parm.K)) - HALFPI; + lamp = this->m_proj_parm.c * lp_lon; + cp = cos(phip); + phipp = aasin(this->m_proj_parm.cosp0 * sin(phip) - this->m_proj_parm.sinp0 * cp * cos(lamp)); + lampp = aasin(cp * sin(lamp) / cos(phipp)); + xy_x = this->m_proj_parm.kR * lampp; + xy_y = this->m_proj_parm.kR * log(tan(FORTPI + 0.5 * phipp)); + } + + // 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 phip, lamp, phipp, lampp, cp, esp, con, delp; + int i; + + phipp = 2. * (atan(exp(xy_y / this->m_proj_parm.kR)) - FORTPI); + lampp = xy_x / this->m_proj_parm.kR; + cp = cos(phipp); + phip = aasin(this->m_proj_parm.cosp0 * sin(phipp) + this->m_proj_parm.sinp0 * cp * cos(lampp)); + lamp = aasin(cp * sin(lampp) / cos(phip)); + con = (this->m_proj_parm.K - log(tan(FORTPI + 0.5 * phip)))/this->m_proj_parm.c; + for (i = NITER; i ; --i) { + esp = this->m_par.e * sin(phip); + delp = (con + log(tan(FORTPI + 0.5 * phip)) - this->m_proj_parm.hlf_e * + log((1. + esp)/(1. - esp)) ) * + (1. - esp * esp) * cos(phip) * this->m_par.rone_es; + phip -= delp; + if (fabs(delp) < EPS) + break; + } + if (i) { + lp_lat = phip; + lp_lon = lamp / this->m_proj_parm.c; + } else + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + } + + static inline std::string get_name() + { + return "somerc_ellipsoid"; + } + + }; + + // Swiss. Obl. Mercator + template <typename Parameters, typename T> + inline void setup_somerc(Parameters& par, par_somerc<T>& proj_parm) + { + static const T FORTPI = detail::FORTPI<T>(); + + T cp, phip0, sp; + + proj_parm.hlf_e = 0.5 * par.e; + cp = cos(par.phi0); + cp *= cp; + proj_parm.c = sqrt(1 + par.es * cp * cp * par.rone_es); + sp = sin(par.phi0); + proj_parm.cosp0 = cos( phip0 = aasin(proj_parm.sinp0 = sp / proj_parm.c) ); + sp *= par.e; + proj_parm.K = log(tan(FORTPI + 0.5 * phip0)) - proj_parm.c * ( + log(tan(FORTPI + 0.5 * par.phi0)) - proj_parm.hlf_e * + log((1. + sp) / (1. - sp))); + proj_parm.kR = par.k0 * sqrt(par.one_es) / (1. - sp * sp); + } + + }} // namespace detail::somerc + #endif // doxygen + + /*! + \brief Swiss. Obl. Mercator projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Cylindrical + - Ellipsoid + - For CH1903 + \par Example + \image html ex_somerc.gif + */ + template <typename CalculationType, typename Parameters> + struct somerc_ellipsoid : public detail::somerc::base_somerc_ellipsoid<CalculationType, Parameters> + { + inline somerc_ellipsoid(const Parameters& par) : detail::somerc::base_somerc_ellipsoid<CalculationType, Parameters>(par) + { + detail::somerc::setup_somerc(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::somerc, somerc_ellipsoid, somerc_ellipsoid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class somerc_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<somerc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void somerc_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("somerc", new somerc_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_SOMERC_HPP + diff --git a/boost/geometry/srs/projections/proj/stere.hpp b/boost/geometry/srs/projections/proj/stere.hpp new file mode 100644 index 0000000000..9278902e34 --- /dev/null +++ b/boost/geometry/srs/projections/proj/stere.hpp @@ -0,0 +1,545 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_STERE_HPP +#define BOOST_GEOMETRY_PROJECTIONS_STERE_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_tsfn.hpp> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct stere {}; + struct ups {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace stere + { + static const double EPS10 = 1.e-10; + static const double TOL = 1.e-8; + static const int NITER = 8; + static const double CONV = 1.e-10; + static const int S_POLE = 0; + static const int N_POLE = 1; + static const int OBLIQ = 2; + static const int EQUIT = 3; + + template <typename T> + struct par_stere + { + T phits; + T sinX1; + T cosX1; + T akm1; + int mode; + }; + + template <typename T> + inline T ssfn_(T const& phit, T sinphi, T const& eccen) + { + sinphi *= eccen; + return (tan (.5 * (geometry::math::half_pi<T>() + phit)) * + pow((1. - sinphi) / (1. + sinphi), .5 * eccen)); + } + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_stere_ellipsoid : public base_t_fi<base_stere_ellipsoid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_stere<CalculationType> m_proj_parm; + + inline base_stere_ellipsoid(const Parameters& par) + : base_t_fi<base_stere_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, sinX=0.0, cosX=0.0, X, A, sinphi; + + coslam = cos(lp_lon); + sinlam = sin(lp_lon); + sinphi = sin(lp_lat); + if (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT) { + sinX = sin(X = 2. * atan(ssfn_(lp_lat, sinphi, this->m_par.e)) - HALFPI); + cosX = cos(X); + } + switch (this->m_proj_parm.mode) { + case OBLIQ: + A = this->m_proj_parm.akm1 / (this->m_proj_parm.cosX1 * (1. + this->m_proj_parm.sinX1 * sinX + + this->m_proj_parm.cosX1 * cosX * coslam)); + xy_y = A * (this->m_proj_parm.cosX1 * sinX - this->m_proj_parm.sinX1 * cosX * coslam); + goto xmul; + case EQUIT: + A = this->m_proj_parm.akm1 / (1. + cosX * coslam); + xy_y = A * sinX; + xmul: + xy_x = A * cosX; + break; + case S_POLE: + lp_lat = -lp_lat; + coslam = - coslam; + sinphi = -sinphi; + BOOST_FALLTHROUGH; + case N_POLE: + xy_x = this->m_proj_parm.akm1 * pj_tsfn(lp_lat, sinphi, this->m_par.e); + xy_y = - xy_x * coslam; + break; + } + xy_x = xy_x * sinlam; + } + + // 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 cosphi, sinphi, tp=0.0, phi_l=0.0, rho, halfe=0.0, halfpi=0.0; + int i; + + rho = boost::math::hypot(xy_x, xy_y); + switch (this->m_proj_parm.mode) { + case OBLIQ: + case EQUIT: + cosphi = cos( tp = 2. * atan2(rho * this->m_proj_parm.cosX1 , this->m_proj_parm.akm1) ); + sinphi = sin(tp); + if( rho == 0.0 ) + phi_l = asin(cosphi * this->m_proj_parm.sinX1); + else + phi_l = asin(cosphi * this->m_proj_parm.sinX1 + (xy_y * sinphi * this->m_proj_parm.cosX1 / rho)); + + tp = tan(.5 * (HALFPI + phi_l)); + xy_x *= sinphi; + xy_y = rho * this->m_proj_parm.cosX1 * cosphi - xy_y * this->m_proj_parm.sinX1* sinphi; + halfpi = HALFPI; + halfe = .5 * this->m_par.e; + break; + case N_POLE: + xy_y = -xy_y; + BOOST_FALLTHROUGH; + case S_POLE: + phi_l = HALFPI - 2. * atan(tp = - rho / this->m_proj_parm.akm1); + halfpi = -HALFPI; + halfe = -.5 * this->m_par.e; + break; + } + for (i = NITER; i--; phi_l = lp_lat) { + sinphi = this->m_par.e * sin(phi_l); + lp_lat = 2. * atan(tp * pow((1.+sinphi)/(1.-sinphi), halfe)) - halfpi; + if (fabs(phi_l - lp_lat) < CONV) { + if (this->m_proj_parm.mode == S_POLE) + lp_lat = -lp_lat; + lp_lon = (xy_x == 0. && xy_y == 0.) ? 0. : atan2(xy_x, xy_y); + return; + } + } + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + } + + static inline std::string get_name() + { + return "stere_ellipsoid"; + } + + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_stere_spheroid : public base_t_fi<base_stere_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_stere<CalculationType> m_proj_parm; + + inline base_stere_spheroid(const Parameters& par) + : base_t_fi<base_stere_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>(); + + CalculationType sinphi, cosphi, coslam, sinlam; + + sinphi = sin(lp_lat); + cosphi = cos(lp_lat); + coslam = cos(lp_lon); + sinlam = sin(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.sinX1 * sinphi + this->m_proj_parm.cosX1 * cosphi * coslam; + oblcon: + if (xy_y <= EPS10) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + xy_x = (xy_y = this->m_proj_parm.akm1 / xy_y) * cosphi * sinlam; + xy_y *= (this->m_proj_parm.mode == EQUIT) ? sinphi : + this->m_proj_parm.cosX1 * sinphi - this->m_proj_parm.sinX1 * cosphi * coslam; + break; + case N_POLE: + coslam = - coslam; + lp_lat = - lp_lat; + BOOST_FALLTHROUGH; + case S_POLE: + if (fabs(lp_lat - HALFPI) < TOL) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + xy_x = sinlam * ( xy_y = this->m_proj_parm.akm1 * tan(FORTPI + .5 * lp_lat) ); + 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 + { + CalculationType c, rh, sinc, cosc; + + sinc = sin(c = 2. * atan((rh = boost::math::hypot(xy_x, xy_y)) / this->m_proj_parm.akm1)); + cosc = cos(c); + lp_lon = 0.; + switch (this->m_proj_parm.mode) { + case EQUIT: + if (fabs(rh) <= EPS10) + lp_lat = 0.; + else + lp_lat = asin(xy_y * sinc / rh); + if (cosc != 0. || xy_x != 0.) + lp_lon = atan2(xy_x * sinc, cosc * rh); + break; + case OBLIQ: + if (fabs(rh) <= EPS10) + lp_lat = this->m_par.phi0; + else + lp_lat = asin(cosc * this->m_proj_parm.sinX1 + xy_y * sinc * this->m_proj_parm.cosX1 / rh); + if ((c = cosc - this->m_proj_parm.sinX1 * sin(lp_lat)) != 0. || xy_x != 0.) + lp_lon = atan2(xy_x * sinc * this->m_proj_parm.cosX1, c * rh); + break; + case N_POLE: + xy_y = -xy_y; + BOOST_FALLTHROUGH; + case S_POLE: + if (fabs(rh) <= EPS10) + lp_lat = this->m_par.phi0; + else + lp_lat = asin(this->m_proj_parm.mode == S_POLE ? - cosc : cosc); + lp_lon = (xy_x == 0. && xy_y == 0.) ? 0. : atan2(xy_x, xy_y); + break; + } + } + + static inline std::string get_name() + { + return "stere_spheroid"; + } + + }; + + template <typename Parameters, typename T> + inline void setup(Parameters& par, par_stere<T>& proj_parm) /* general initialization */ + { + static const T FORTPI = detail::FORTPI<T>(); + 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 + proj_parm.mode = t > EPS10 ? OBLIQ : EQUIT; + proj_parm.phits = fabs(proj_parm.phits); + if (par.es != 0.0) { + T X; + + switch (proj_parm.mode) { + case N_POLE: + case S_POLE: + if (fabs(proj_parm.phits - HALFPI) < EPS10) + proj_parm.akm1 = 2. * par.k0 / + sqrt(pow(1+par.e,1+par.e)*pow(1-par.e,1-par.e)); + else { + proj_parm.akm1 = cos(proj_parm.phits) / + pj_tsfn(proj_parm.phits, t = sin(proj_parm.phits), par.e); + t *= par.e; + proj_parm.akm1 /= sqrt(1. - t * t); + } + break; + case EQUIT: + //proj_parm.akm1 = 2. * par.k0; + //break; + case OBLIQ: + t = sin(par.phi0); + X = 2. * atan(ssfn_(par.phi0, t, par.e)) - HALFPI; + t *= par.e; + proj_parm.akm1 = 2. * par.k0 * cos(par.phi0) / sqrt(1. - t * t); + proj_parm.sinX1 = sin(X); + proj_parm.cosX1 = cos(X); + break; + } + } else { + switch (proj_parm.mode) { + case OBLIQ: + proj_parm.sinX1 = sin(par.phi0); + proj_parm.cosX1 = cos(par.phi0); + BOOST_FALLTHROUGH; + case EQUIT: + proj_parm.akm1 = 2. * par.k0; + break; + case S_POLE: + case N_POLE: + proj_parm.akm1 = fabs(proj_parm.phits - HALFPI) >= EPS10 ? + cos(proj_parm.phits) / tan(FORTPI - .5 * proj_parm.phits) : + 2. * par.k0 ; + break; + } + } + } + + + // Stereographic + template <typename Parameters, typename T> + inline void setup_stere(Parameters& par, par_stere<T>& proj_parm) + { + static const T HALFPI = detail::HALFPI<T>(); + + proj_parm.phits = pj_param(par.params, "tlat_ts").i ? + pj_param(par.params, "rlat_ts").f : HALFPI; + setup(par, proj_parm); + } + + // Universal Polar Stereographic + template <typename Parameters, typename T> + inline void setup_ups(Parameters& par, par_stere<T>& proj_parm) + { + static const T HALFPI = detail::HALFPI<T>(); + + /* International Ellipsoid */ + par.phi0 = pj_param(par.params, "bsouth").i ? -HALFPI: HALFPI; + if (!par.es) + BOOST_THROW_EXCEPTION( projection_exception(-34) ); + par.k0 = .994; + par.x0 = 2000000.; + par.y0 = 2000000.; + proj_parm.phits = HALFPI; + par.lam0 = 0.; + setup(par, proj_parm); + } + + }} // namespace detail::stere + #endif // doxygen + + /*! + \brief Stereographic 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_ts: Latitude of true scale (degrees) + \par Example + \image html ex_stere.gif + */ + template <typename CalculationType, typename Parameters> + struct stere_ellipsoid : public detail::stere::base_stere_ellipsoid<CalculationType, Parameters> + { + inline stere_ellipsoid(const Parameters& par) : detail::stere::base_stere_ellipsoid<CalculationType, Parameters>(par) + { + detail::stere::setup_stere(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Stereographic 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_ts: Latitude of true scale (degrees) + \par Example + \image html ex_stere.gif + */ + template <typename CalculationType, typename Parameters> + struct stere_spheroid : public detail::stere::base_stere_spheroid<CalculationType, Parameters> + { + inline stere_spheroid(const Parameters& par) : detail::stere::base_stere_spheroid<CalculationType, Parameters>(par) + { + detail::stere::setup_stere(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Universal Polar Stereographic 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 + - south: Denotes southern hemisphere UTM zone (boolean) + \par Example + \image html ex_ups.gif + */ + template <typename CalculationType, typename Parameters> + struct ups_ellipsoid : public detail::stere::base_stere_ellipsoid<CalculationType, Parameters> + { + inline ups_ellipsoid(const Parameters& par) : detail::stere::base_stere_ellipsoid<CalculationType, Parameters>(par) + { + detail::stere::setup_ups(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Universal Polar Stereographic 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 + - south: Denotes southern hemisphere UTM zone (boolean) + \par Example + \image html ex_ups.gif + */ + template <typename CalculationType, typename Parameters> + struct ups_spheroid : public detail::stere::base_stere_spheroid<CalculationType, Parameters> + { + inline ups_spheroid(const Parameters& par) : detail::stere::base_stere_spheroid<CalculationType, Parameters>(par) + { + detail::stere::setup_ups(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::stere, stere_spheroid, stere_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::ups, ups_spheroid, ups_ellipsoid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class stere_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<stere_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + else + return new base_v_fi<stere_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class ups_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<ups_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + else + return new base_v_fi<ups_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void stere_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("stere", new stere_entry<CalculationType, Parameters>); + factory.add_to_factory("ups", new ups_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_STERE_HPP + diff --git a/boost/geometry/srs/projections/proj/sterea.hpp b/boost/geometry/srs/projections/proj/sterea.hpp new file mode 100644 index 0000000000..f9de2c6896 --- /dev/null +++ b/boost/geometry/srs/projections/proj/sterea.hpp @@ -0,0 +1,210 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_STEREA_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) 2003 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> +#include <boost/geometry/srs/projections/impl/pj_gauss.hpp> + + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct sterea {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace sterea + { + + static const double DEL_TOL = 1.e-14; + static const int MAX_ITER = 10; + + template <typename T> + struct par_sterea + { + T phic0; + T cosc0, sinc0; + T R2; + gauss::GAUSS<T> en; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_sterea_ellipsoid : public base_t_fi<base_sterea_ellipsoid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_sterea<CalculationType> m_proj_parm; + + inline base_sterea_ellipsoid(const Parameters& par) + : base_t_fi<base_sterea_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 cosc, sinc, cosl_, k; + + detail::gauss::gauss(m_proj_parm.en, lp_lon, lp_lat); + sinc = sin(lp_lat); + cosc = cos(lp_lat); + cosl_ = cos(lp_lon); + k = this->m_par.k0 * this->m_proj_parm.R2 / (1. + this->m_proj_parm.sinc0 * sinc + this->m_proj_parm.cosc0 * cosc * cosl_); + xy_x = k * cosc * sin(lp_lon); + xy_y = k * (this->m_proj_parm.cosc0 * sinc - this->m_proj_parm.sinc0 * cosc * cosl_); + } + + // 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 rho, c, sinc, cosc; + + xy_x /= this->m_par.k0; + xy_y /= this->m_par.k0; + if((rho = boost::math::hypot(xy_x, xy_y))) { + c = 2. * atan2(rho, this->m_proj_parm.R2); + sinc = sin(c); + cosc = cos(c); + lp_lat = asin(cosc * this->m_proj_parm.sinc0 + xy_y * sinc * this->m_proj_parm.cosc0 / rho); + lp_lon = atan2(xy_x * sinc, rho * this->m_proj_parm.cosc0 * cosc - + xy_y * this->m_proj_parm.sinc0 * sinc); + } else { + lp_lat = this->m_proj_parm.phic0; + lp_lon = 0.; + } + detail::gauss::inv_gauss(m_proj_parm.en, lp_lon, lp_lat); + } + + static inline std::string get_name() + { + return "sterea_ellipsoid"; + } + + }; + + // Oblique Stereographic Alternative + template <typename Parameters, typename T> + inline void setup_sterea(Parameters& par, par_sterea<T>& proj_parm) + { + T R; + + proj_parm.en = detail::gauss::gauss_ini(par.e, par.phi0, proj_parm.phic0, R); + proj_parm.sinc0 = sin(proj_parm.phic0); + proj_parm.cosc0 = cos(proj_parm.phic0); + proj_parm.R2 = 2. * R; + } + + }} // namespace detail::sterea + #endif // doxygen + + /*! + \brief Oblique Stereographic Alternative 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_sterea.gif + */ + template <typename CalculationType, typename Parameters> + struct sterea_ellipsoid : public detail::sterea::base_sterea_ellipsoid<CalculationType, Parameters> + { + inline sterea_ellipsoid(const Parameters& par) : detail::sterea::base_sterea_ellipsoid<CalculationType, Parameters>(par) + { + detail::sterea::setup_sterea(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::sterea, sterea_ellipsoid, sterea_ellipsoid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class sterea_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<sterea_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void sterea_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("sterea", new sterea_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP + diff --git a/boost/geometry/srs/projections/proj/sts.hpp b/boost/geometry/srs/projections/proj/sts.hpp new file mode 100644 index 0000000000..ca0d3f0cd1 --- /dev/null +++ b/boost/geometry/srs/projections/proj/sts.hpp @@ -0,0 +1,325 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_STS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_STS_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 kav5 {}; + struct qua_aut {}; + struct mbt_s {}; + struct fouc {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace sts + { + template <typename T> + struct par_sts + { + T C_x, C_y, C_p; + int tan_mode; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_sts_spheroid : public base_t_fi<base_sts_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_sts<CalculationType> m_proj_parm; + + inline base_sts_spheroid(const Parameters& par) + : base_t_fi<base_sts_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; + + xy_x = this->m_proj_parm.C_x * lp_lon * cos(lp_lat); + xy_y = this->m_proj_parm.C_y; + lp_lat *= this->m_proj_parm.C_p; + c = cos(lp_lat); + if (this->m_proj_parm.tan_mode) { + xy_x *= c * c; + xy_y *= tan(lp_lat); + } else { + xy_x /= c; + xy_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; + + xy_y /= this->m_proj_parm.C_y; + c = cos(lp_lat = this->m_proj_parm.tan_mode ? atan(xy_y) : aasin(xy_y)); + lp_lat /= this->m_proj_parm.C_p; + lp_lon = xy_x / (this->m_proj_parm.C_x * cos(lp_lat)); + if (this->m_proj_parm.tan_mode) + lp_lon /= c * c; + else + lp_lon *= c; + } + + static inline std::string get_name() + { + return "sts_spheroid"; + } + + }; + + template <typename Parameters, typename T> + inline void setup(Parameters& par, par_sts<T>& proj_parm, T const& p, T const& q, int mode) + { + par.es = 0.; + proj_parm.C_x = q / p; + proj_parm.C_y = p; + proj_parm.C_p = 1/ q; + proj_parm.tan_mode = mode; + } + + + // Kavraisky V + template <typename Parameters, typename T> + inline void setup_kav5(Parameters& par, par_sts<T>& proj_parm) + { + setup(par, proj_parm, 1.50488, 1.35439, 0); + } + + // Quartic Authalic + template <typename Parameters, typename T> + inline void setup_qua_aut(Parameters& par, par_sts<T>& proj_parm) + { + setup(par, proj_parm, 2., 2., 0); + } + + // McBryde-Thomas Flat-Polar Sine (No. 1) + template <typename Parameters, typename T> + inline void setup_mbt_s(Parameters& par, par_sts<T>& proj_parm) + { + setup(par, proj_parm, 1.48875, 1.36509, 0); + } + + // Foucaut + template <typename Parameters, typename T> + inline void setup_fouc(Parameters& par, par_sts<T>& proj_parm) + { + setup(par, proj_parm, 2., 2., 1); + } + + }} // namespace detail::sts + #endif // doxygen + + /*! + \brief Kavraisky 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_kav5.gif + */ + template <typename CalculationType, typename Parameters> + struct kav5_spheroid : public detail::sts::base_sts_spheroid<CalculationType, Parameters> + { + inline kav5_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<CalculationType, Parameters>(par) + { + detail::sts::setup_kav5(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Quartic Authalic 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_qua_aut.gif + */ + template <typename CalculationType, typename Parameters> + struct qua_aut_spheroid : public detail::sts::base_sts_spheroid<CalculationType, Parameters> + { + inline qua_aut_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<CalculationType, Parameters>(par) + { + detail::sts::setup_qua_aut(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief McBryde-Thomas Flat-Polar Sine (No. 1) 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_mbt_s.gif + */ + template <typename CalculationType, typename Parameters> + struct mbt_s_spheroid : public detail::sts::base_sts_spheroid<CalculationType, Parameters> + { + inline mbt_s_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<CalculationType, Parameters>(par) + { + detail::sts::setup_mbt_s(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Foucaut 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_fouc.gif + */ + template <typename CalculationType, typename Parameters> + struct fouc_spheroid : public detail::sts::base_sts_spheroid<CalculationType, Parameters> + { + inline fouc_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<CalculationType, Parameters>(par) + { + detail::sts::setup_fouc(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::kav5, kav5_spheroid, kav5_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::qua_aut, qua_aut_spheroid, qua_aut_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::mbt_s, mbt_s_spheroid, mbt_s_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::fouc, fouc_spheroid, fouc_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class kav5_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<kav5_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class qua_aut_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<qua_aut_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class mbt_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<mbt_s_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class fouc_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_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void sts_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("kav5", new kav5_entry<CalculationType, Parameters>); + factory.add_to_factory("qua_aut", new qua_aut_entry<CalculationType, Parameters>); + factory.add_to_factory("mbt_s", new mbt_s_entry<CalculationType, Parameters>); + factory.add_to_factory("fouc", new fouc_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_STS_HPP + diff --git a/boost/geometry/srs/projections/proj/tcc.hpp b/boost/geometry/srs/projections/proj/tcc.hpp new file mode 100644 index 0000000000..26cb62b3e8 --- /dev/null +++ b/boost/geometry/srs/projections/proj/tcc.hpp @@ -0,0 +1,163 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_TCC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_TCC_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> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct tcc {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace tcc + { + + static const double EPS10 = 1.e-10; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_tcc_spheroid : public base_t_f<base_tcc_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + inline base_tcc_spheroid(const Parameters& par) + : base_t_f<base_tcc_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 b, bt; + + b = cos(lp_lat) * sin(lp_lon); + if ((bt = 1. - b * b) < EPS10) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + xy_x = b / sqrt(bt); + xy_y = atan2(tan(lp_lat) , cos(lp_lon)); + } + + static inline std::string get_name() + { + return "tcc_spheroid"; + } + + }; + + // Transverse Central Cylindrical + template <typename Parameters> + inline void setup_tcc(Parameters& par) + { + par.es = 0.; + } + + }} // namespace detail::tcc + #endif // doxygen + + /*! + \brief Transverse Central Cylindrical projection + \ingroup projections + \tparam Geographic latlong point type + \tparam Cartesian xy point type + \tparam Parameters parameter type + \par Projection characteristics + - Cylindrical + - Spheroid + - no inverse + \par Example + \image html ex_tcc.gif + */ + template <typename CalculationType, typename Parameters> + struct tcc_spheroid : public detail::tcc::base_tcc_spheroid<CalculationType, Parameters> + { + inline tcc_spheroid(const Parameters& par) : detail::tcc::base_tcc_spheroid<CalculationType, Parameters>(par) + { + detail::tcc::setup_tcc(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::tcc, tcc_spheroid, tcc_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class tcc_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_f<tcc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void tcc_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("tcc", new tcc_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_TCC_HPP + diff --git a/boost/geometry/srs/projections/proj/tcea.hpp b/boost/geometry/srs/projections/proj/tcea.hpp new file mode 100644 index 0000000000..b87574e947 --- /dev/null +++ b/boost/geometry/srs/projections/proj/tcea.hpp @@ -0,0 +1,176 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_TCEA_HPP +#define BOOST_GEOMETRY_PROJECTIONS_TCEA_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 tcea {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace tcea + { + template <typename T> + struct par_tcea + { + T rk0; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_tcea_spheroid : public base_t_fi<base_tcea_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_tcea<CalculationType> m_proj_parm; + + inline base_tcea_spheroid(const Parameters& par) + : base_t_fi<base_tcea_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.rk0 * cos(lp_lat) * sin(lp_lon); + xy_y = this->m_par.k0 * (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 t; + + xy_y = xy_y * this->m_proj_parm.rk0 + this->m_par.phi0; + xy_x *= this->m_par.k0; + t = sqrt(1. - xy_x * xy_x); + lp_lat = asin(t * sin(xy_y)); + lp_lon = atan2(xy_x, t * cos(xy_y)); + } + + static inline std::string get_name() + { + return "tcea_spheroid"; + } + + }; + + // Transverse Cylindrical Equal Area + template <typename Parameters, typename T> + inline void setup_tcea(Parameters& par, par_tcea<T>& proj_parm) + { + proj_parm.rk0 = 1 / par.k0; + par.es = 0.; + } + + }} // namespace detail::tcea + #endif // doxygen + + /*! + \brief Transverse Cylindrical Equal Area 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_tcea.gif + */ + template <typename CalculationType, typename Parameters> + struct tcea_spheroid : public detail::tcea::base_tcea_spheroid<CalculationType, Parameters> + { + inline tcea_spheroid(const Parameters& par) : detail::tcea::base_tcea_spheroid<CalculationType, Parameters>(par) + { + detail::tcea::setup_tcea(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::tcea, tcea_spheroid, tcea_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class tcea_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<tcea_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void tcea_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("tcea", new tcea_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_TCEA_HPP + diff --git a/boost/geometry/srs/projections/proj/tmerc.hpp b/boost/geometry/srs/projections/proj/tmerc.hpp new file mode 100644 index 0000000000..6ed2902142 --- /dev/null +++ b/boost/geometry/srs/projections/proj/tmerc.hpp @@ -0,0 +1,495 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_TMERC_HPP +#define BOOST_GEOMETRY_PROJECTIONS_TMERC_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/function_overloads.hpp> +#include <boost/geometry/srs/projections/impl/pj_mlfn.hpp> + + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct tmerc {}; + struct utm {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace tmerc + { + + static const double EPS10 = 1.e-10; + //static const double FC1 = 1.; + //static const double FC2 = .5; + //static const double FC3 = .16666666666666666666; + //static const double FC4 = .08333333333333333333; + //static const double FC5 = .05; + //static const double FC6 = .03333333333333333333; + //static const double FC7 = .02380952380952380952; + //static const double FC8 = .01785714285714285714; + + template <typename T> + inline T FC1() { return 1.; } + template <typename T> + inline T FC2() { return .5; } + template <typename T> + inline T FC3() { return .16666666666666666666666666666666666666; } + template <typename T> + inline T FC4() { return .08333333333333333333333333333333333333; } + template <typename T> + inline T FC5() { return .05; } + template <typename T> + inline T FC6() { return .03333333333333333333333333333333333333; } + template <typename T> + inline T FC7() { return .02380952380952380952380952380952380952; } + template <typename T> + inline T FC8() { return .01785714285714285714285714285714285714; } + + template <typename T> + struct par_tmerc + { + T esp; + T ml0; + T en[EN_SIZE]; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_tmerc_ellipsoid : public base_t_fi<base_tmerc_ellipsoid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_tmerc<CalculationType> m_proj_parm; + + inline base_tmerc_ellipsoid(const Parameters& par) + : base_t_fi<base_tmerc_ellipsoid<CalculationType, Parameters>, + CalculationType, Parameters>(*this, par) {} + + // FORWARD(e_forward) ellipse + // 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 FC1 = tmerc::FC1<CalculationType>(); + static const CalculationType FC2 = tmerc::FC2<CalculationType>(); + static const CalculationType FC3 = tmerc::FC3<CalculationType>(); + static const CalculationType FC4 = tmerc::FC4<CalculationType>(); + static const CalculationType FC5 = tmerc::FC5<CalculationType>(); + static const CalculationType FC6 = tmerc::FC6<CalculationType>(); + static const CalculationType FC7 = tmerc::FC7<CalculationType>(); + static const CalculationType FC8 = tmerc::FC8<CalculationType>(); + + CalculationType al, als, n, cosphi, sinphi, t; + + /* + * Fail if our longitude is more than 90 degrees from the + * central meridian since the results are essentially garbage. + * Is error -20 really an appropriate return value? + * + * http://trac.osgeo.org/proj/ticket/5 + */ + if( lp_lon < -HALFPI || lp_lon > HALFPI ) + { + xy_x = HUGE_VAL; + xy_y = HUGE_VAL; + BOOST_THROW_EXCEPTION( projection_exception(-14) ); + return; + } + + sinphi = sin(lp_lat); + cosphi = cos(lp_lat); + t = fabs(cosphi) > 1e-10 ? sinphi/cosphi : 0.; + t *= t; + al = cosphi * lp_lon; + als = al * al; + al /= sqrt(1. - this->m_par.es * sinphi * sinphi); + n = this->m_proj_parm.esp * cosphi * cosphi; + xy_x = this->m_par.k0 * al * (FC1 + + FC3 * als * (1. - t + n + + FC5 * als * (5. + t * (t - 18.) + n * (14. - 58. * t) + + FC7 * als * (61. + t * ( t * (179. - t) - 479. ) ) + ))); + xy_y = this->m_par.k0 * (pj_mlfn(lp_lat, sinphi, cosphi, this->m_proj_parm.en) - this->m_proj_parm.ml0 + + sinphi * al * lp_lon * FC2 * ( 1. + + FC4 * als * (5. - t + n * (9. + 4. * n) + + FC6 * als * (61. + t * (t - 58.) + n * (270. - 330 * t) + + FC8 * als * (1385. + t * ( t * (543. - t) - 3111.) ) + )))); + } + + // 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>(); + static const CalculationType FC1 = tmerc::FC1<CalculationType>(); + static const CalculationType FC2 = tmerc::FC2<CalculationType>(); + static const CalculationType FC3 = tmerc::FC3<CalculationType>(); + static const CalculationType FC4 = tmerc::FC4<CalculationType>(); + static const CalculationType FC5 = tmerc::FC5<CalculationType>(); + static const CalculationType FC6 = tmerc::FC6<CalculationType>(); + static const CalculationType FC7 = tmerc::FC7<CalculationType>(); + static const CalculationType FC8 = tmerc::FC8<CalculationType>(); + + CalculationType n, con, cosphi, d, ds, sinphi, t; + + lp_lat = pj_inv_mlfn(this->m_proj_parm.ml0 + xy_y / this->m_par.k0, this->m_par.es, this->m_proj_parm.en); + if (fabs(lp_lat) >= HALFPI) { + lp_lat = xy_y < 0. ? -HALFPI : HALFPI; + lp_lon = 0.; + } else { + sinphi = sin(lp_lat); + cosphi = cos(lp_lat); + t = fabs(cosphi) > 1e-10 ? sinphi/cosphi : 0.; + n = this->m_proj_parm.esp * cosphi * cosphi; + d = xy_x * sqrt(con = 1. - this->m_par.es * sinphi * sinphi) / this->m_par.k0; + con *= t; + t *= t; + ds = d * d; + lp_lat -= (con * ds / (1.-this->m_par.es)) * FC2 * (1. - + ds * FC4 * (5. + t * (3. - 9. * n) + n * (1. - 4 * n) - + ds * FC6 * (61. + t * (90. - 252. * n + + 45. * t) + 46. * n + - ds * FC8 * (1385. + t * (3633. + t * (4095. + 1574. * t)) ) + ))); + lp_lon = d*(FC1 - + ds*FC3*( 1. + 2.*t + n - + ds*FC5*(5. + t*(28. + 24.*t + 8.*n) + 6.*n + - ds * FC7 * (61. + t * (662. + t * (1320. + 720. * t)) ) + ))) / cosphi; + } + } + + static inline std::string get_name() + { + return "tmerc_ellipsoid"; + } + + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_tmerc_spheroid : public base_t_fi<base_tmerc_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_tmerc<CalculationType> m_proj_parm; + + inline base_tmerc_spheroid(const Parameters& par) + : base_t_fi<base_tmerc_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 HALFPI = detail::HALFPI<CalculationType>(); + + CalculationType b, cosphi; + + /* + * Fail if our longitude is more than 90 degrees from the + * central meridian since the results are essentially garbage. + * Is error -20 really an appropriate return value? + * + * http://trac.osgeo.org/proj/ticket/5 + */ + if( lp_lon < -HALFPI || lp_lon > HALFPI ) + { + xy_x = HUGE_VAL; + xy_y = HUGE_VAL; + BOOST_THROW_EXCEPTION( projection_exception(-14) ); + return; + } + + cosphi = cos(lp_lat); + b = cosphi * sin(lp_lon); + if (fabs(fabs(b) - 1.) <= EPS10) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + + xy_x = this->m_proj_parm.ml0 * log((1. + b) / (1. - b)); + xy_y = cosphi * cos(lp_lon) / sqrt(1. - b * b); + + b = fabs( xy_y ); + if (b >= 1.) { + if ((b - 1.) > EPS10) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + else xy_y = 0.; + } else + xy_y = acos(xy_y); + + if (lp_lat < 0.) + xy_y = -xy_y; + xy_y = this->m_proj_parm.esp * (xy_y - this->m_par.phi0); + } + + // 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 + { + CalculationType h, g; + + h = exp(xy_x / this->m_proj_parm.esp); + g = .5 * (h - 1. / h); + h = cos(this->m_par.phi0 + xy_y / this->m_proj_parm.esp); + lp_lat = asin(sqrt((1. - h * h) / (1. + g * g))); + if (xy_y < 0.) lp_lat = -lp_lat; + lp_lon = (g || h) ? atan2(g, h) : 0.; + } + + static inline std::string get_name() + { + return "tmerc_spheroid"; + } + + }; + + template <typename Parameters, typename T> + inline void setup(Parameters& par, par_tmerc<T>& proj_parm) /* general initialization */ + { + if (par.es) { + if (!pj_enfn(par.es, proj_parm.en)) + BOOST_THROW_EXCEPTION( projection_exception(0) ); + proj_parm.ml0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en); + proj_parm.esp = par.es / (1. - par.es); + } else { + proj_parm.esp = par.k0; + proj_parm.ml0 = .5 * proj_parm.esp; + } + } + + + // Transverse Mercator + template <typename Parameters, typename T> + inline void setup_tmerc(Parameters& par, par_tmerc<T>& proj_parm) + { + setup(par, proj_parm); + } + + // Universal Transverse Mercator (UTM) + template <typename Parameters, typename T> + inline void setup_utm(Parameters& par, par_tmerc<T>& proj_parm) + { + static const T ONEPI = detail::ONEPI<T>(); + + int zone; + + par.y0 = pj_param(par.params, "bsouth").i ? 10000000. : 0.; + par.x0 = 500000.; + if (pj_param(par.params, "tzone").i) /* zone input ? */ + if ((zone = pj_param(par.params, "izone").i) > 0 && zone <= 60) + --zone; + else + BOOST_THROW_EXCEPTION( projection_exception(-35) ); + else /* nearest central meridian input */ + if ((zone = int_floor((adjlon(par.lam0) + ONEPI) * 30. / ONEPI)) < 0) + zone = 0; + else if (zone >= 60) + zone = 59; + par.lam0 = (zone + .5) * ONEPI / 30. - ONEPI; + par.k0 = 0.9996; + par.phi0 = 0.; + setup(par, proj_parm); + } + + }} // namespace detail::tmerc + #endif // doxygen + + /*! + \brief Transverse Mercator 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_tmerc.gif + */ + template <typename CalculationType, typename Parameters> + struct tmerc_ellipsoid : public detail::tmerc::base_tmerc_ellipsoid<CalculationType, Parameters> + { + inline tmerc_ellipsoid(const Parameters& par) : detail::tmerc::base_tmerc_ellipsoid<CalculationType, Parameters>(par) + { + detail::tmerc::setup_tmerc(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Transverse Mercator 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_tmerc.gif + */ + template <typename CalculationType, typename Parameters> + struct tmerc_spheroid : public detail::tmerc::base_tmerc_spheroid<CalculationType, Parameters> + { + inline tmerc_spheroid(const Parameters& par) : detail::tmerc::base_tmerc_spheroid<CalculationType, Parameters>(par) + { + detail::tmerc::setup_tmerc(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Universal Transverse Mercator (UTM) 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 + - zone: UTM Zone (integer) + - south: Denotes southern hemisphere UTM zone (boolean) + \par Example + \image html ex_utm.gif + */ + template <typename CalculationType, typename Parameters> + struct utm_ellipsoid : public detail::tmerc::base_tmerc_ellipsoid<CalculationType, Parameters> + { + inline utm_ellipsoid(const Parameters& par) : detail::tmerc::base_tmerc_ellipsoid<CalculationType, Parameters>(par) + { + detail::tmerc::setup_utm(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Universal Transverse Mercator (UTM) 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 + - zone: UTM Zone (integer) + - south: Denotes southern hemisphere UTM zone (boolean) + \par Example + \image html ex_utm.gif + */ + template <typename CalculationType, typename Parameters> + struct utm_spheroid : public detail::tmerc::base_tmerc_spheroid<CalculationType, Parameters> + { + inline utm_spheroid(const Parameters& par) : detail::tmerc::base_tmerc_spheroid<CalculationType, Parameters>(par) + { + detail::tmerc::setup_utm(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::tmerc, tmerc_spheroid, tmerc_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::utm, utm_spheroid, utm_ellipsoid) + + // Factory entry(s) - dynamic projection + template <typename CalculationType, typename Parameters> + class tmerc_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<tmerc_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + else + return new base_v_fi<tmerc_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class utm_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<utm_ellipsoid<CalculationType, Parameters>, CalculationType, Parameters>(par); + else + return new base_v_fi<utm_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void tmerc_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("tmerc", new tmerc_entry<CalculationType, Parameters>); + factory.add_to_factory("utm", new utm_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_TMERC_HPP + diff --git a/boost/geometry/srs/projections/proj/tpeqd.hpp b/boost/geometry/srs/projections/proj/tpeqd.hpp new file mode 100644 index 0000000000..2d08d49bde --- /dev/null +++ b/boost/geometry/srs/projections/proj/tpeqd.hpp @@ -0,0 +1,235 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP +#define BOOST_GEOMETRY_PROJECTIONS_TPEQD_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/aasincos.hpp> + +namespace boost { namespace geometry +{ + +namespace srs { namespace par4 +{ + struct tpeqd {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace tpeqd + { + template <typename T> + struct par_tpeqd + { + T cp1, sp1, cp2, sp2, ccs, cs, sc, r2z0, z02, dlam2; + T hz0, thz0, rhshz0, ca, sa, lp, lamc; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_tpeqd_spheroid : public base_t_fi<base_tpeqd_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_tpeqd<CalculationType> m_proj_parm; + + inline base_tpeqd_spheroid(const Parameters& par) + : base_t_fi<base_tpeqd_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 t, z1, z2, dl1, dl2, sp, cp; + + sp = sin(lp_lat); + cp = cos(lp_lat); + z1 = aacos(this->m_proj_parm.sp1 * sp + this->m_proj_parm.cp1 * cp * cos(dl1 = lp_lon + this->m_proj_parm.dlam2)); + z2 = aacos(this->m_proj_parm.sp2 * sp + this->m_proj_parm.cp2 * cp * cos(dl2 = lp_lon - this->m_proj_parm.dlam2)); + z1 *= z1; + z2 *= z2; + xy_x = this->m_proj_parm.r2z0 * (t = z1 - z2); + t = this->m_proj_parm.z02 - t; + xy_y = this->m_proj_parm.r2z0 * asqrt(4. * this->m_proj_parm.z02 * z2 - t * t); + if ((this->m_proj_parm.ccs * sp - cp * (this->m_proj_parm.cs * sin(dl1) - this->m_proj_parm.sc * sin(dl2))) < 0.) + xy_y = -xy_y; + } + + // 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 + { + CalculationType cz1, cz2, s, d, cp, sp; + + cz1 = cos(boost::math::hypot(xy_y, xy_x + this->m_proj_parm.hz0)); + cz2 = cos(boost::math::hypot(xy_y, xy_x - this->m_proj_parm.hz0)); + s = cz1 + cz2; + d = cz1 - cz2; + lp_lon = - atan2(d, (s * this->m_proj_parm.thz0)); + lp_lat = aacos(boost::math::hypot(this->m_proj_parm.thz0 * s, d) * this->m_proj_parm.rhshz0); + if ( xy_y < 0. ) + lp_lat = - lp_lat; + /* lam--phi now in system relative to P1--P2 base equator */ + sp = sin(lp_lat); + cp = cos(lp_lat); + lp_lat = aasin(this->m_proj_parm.sa * sp + this->m_proj_parm.ca * cp * (s = cos(lp_lon -= this->m_proj_parm.lp))); + lp_lon = atan2(cp * sin(lp_lon), this->m_proj_parm.sa * cp * s - this->m_proj_parm.ca * sp) + this->m_proj_parm.lamc; + } + + static inline std::string get_name() + { + return "tpeqd_spheroid"; + } + + }; + + // Two Point Equidistant + template <typename Parameters, typename T> + inline void setup_tpeqd(Parameters& par, par_tpeqd<T>& proj_parm) + { + T lam_1, lam_2, phi_1, phi_2, A12, pp; + + /* get control point locations */ + phi_1 = pj_param(par.params, "rlat_1").f; + lam_1 = pj_param(par.params, "rlon_1").f; + phi_2 = pj_param(par.params, "rlat_2").f; + lam_2 = pj_param(par.params, "rlon_2").f; + if (phi_1 == phi_2 && lam_1 == lam_2) + BOOST_THROW_EXCEPTION( projection_exception(-25) ); + par.lam0 = adjlon(0.5 * (lam_1 + lam_2)); + proj_parm.dlam2 = adjlon(lam_2 - lam_1); + proj_parm.cp1 = cos(phi_1); + proj_parm.cp2 = cos(phi_2); + proj_parm.sp1 = sin(phi_1); + proj_parm.sp2 = sin(phi_2); + proj_parm.cs = proj_parm.cp1 * proj_parm.sp2; + proj_parm.sc = proj_parm.sp1 * proj_parm.cp2; + proj_parm.ccs = proj_parm.cp1 * proj_parm.cp2 * sin(proj_parm.dlam2); + proj_parm.z02 = aacos(proj_parm.sp1 * proj_parm.sp2 + proj_parm.cp1 * proj_parm.cp2 * cos(proj_parm.dlam2)); + proj_parm.hz0 = .5 * proj_parm.z02; + A12 = atan2(proj_parm.cp2 * sin(proj_parm.dlam2), + proj_parm.cp1 * proj_parm.sp2 - proj_parm.sp1 * proj_parm.cp2 * cos(proj_parm.dlam2)); + proj_parm.ca = cos(pp = aasin(proj_parm.cp1 * sin(A12))); + proj_parm.sa = sin(pp); + proj_parm.lp = adjlon(atan2(proj_parm.cp1 * cos(A12), proj_parm.sp1) - proj_parm.hz0); + proj_parm.dlam2 *= .5; + proj_parm.lamc = geometry::math::half_pi<T>() - atan2(sin(A12) * proj_parm.sp1, cos(A12)) - proj_parm.dlam2; + proj_parm.thz0 = tan(proj_parm.hz0); + proj_parm.rhshz0 = .5 / sin(proj_parm.hz0); + proj_parm.r2z0 = 0.5 / proj_parm.z02; + proj_parm.z02 *= proj_parm.z02; + par.es = 0.; + } + + }} // namespace detail::tpeqd + #endif // doxygen + + /*! + \brief Two Point Equidistant 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) + - lon_1 (degrees) + - lat_2: Latitude of second standard parallel (degrees) + - lon_2 (degrees) + \par Example + \image html ex_tpeqd.gif + */ + template <typename CalculationType, typename Parameters> + struct tpeqd_spheroid : public detail::tpeqd::base_tpeqd_spheroid<CalculationType, Parameters> + { + inline tpeqd_spheroid(const Parameters& par) : detail::tpeqd::base_tpeqd_spheroid<CalculationType, Parameters>(par) + { + detail::tpeqd::setup_tpeqd(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::tpeqd, tpeqd_spheroid, tpeqd_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class tpeqd_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<tpeqd_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void tpeqd_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("tpeqd", new tpeqd_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP + diff --git a/boost/geometry/srs/projections/proj/urm5.hpp b/boost/geometry/srs/projections/proj/urm5.hpp new file mode 100644 index 0000000000..96b541f4ea --- /dev/null +++ b/boost/geometry/srs/projections/proj/urm5.hpp @@ -0,0 +1,185 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_URM5_HPP +#define BOOST_GEOMETRY_PROJECTIONS_URM5_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 urm5 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace urm5 + { + template <typename T> + struct par_urm5 + { + T m, rmn, q3, n; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_urm5_spheroid : public base_t_f<base_urm5_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_urm5<CalculationType> m_proj_parm; + + inline base_urm5_spheroid(const Parameters& par) + : base_t_f<base_urm5_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 = lp_lat = aasin(this->m_proj_parm.n * sin(lp_lat)); + xy_x = this->m_proj_parm.m * lp_lon * cos(lp_lat); + t *= t; + xy_y = lp_lat * (1. + t * this->m_proj_parm.q3) * this->m_proj_parm.rmn; + } + + static inline std::string get_name() + { + return "urm5_spheroid"; + } + + }; + + // Urmaev V + template <typename Parameters, typename T> + inline void setup_urm5(Parameters& par, par_urm5<T>& proj_parm) + { + T alpha, t; + + if (pj_param(par.params, "tn").i) { + proj_parm.n = pj_param(par.params, "dn").f; + if (proj_parm.n <= 0. || proj_parm.n > 1.) + BOOST_THROW_EXCEPTION( projection_exception(-40) ); + } else + BOOST_THROW_EXCEPTION( projection_exception(-40) ); + proj_parm.q3 = pj_param(par.params, "dq").f / 3.; + alpha = pj_param(par.params, "ralpha").f; + t = proj_parm.n * sin(alpha); + proj_parm.m = cos(alpha) / sqrt(1. - t * t); + proj_parm.rmn = 1. / (proj_parm.m * proj_parm.n); + par.es = 0.; + } + + }} // namespace detail::urm5 + #endif // doxygen + + /*! + \brief Urmaev V 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 Projection parameters + - n (real) + - q (real) + - alpha: Alpha (degrees) + \par Example + \image html ex_urm5.gif + */ + template <typename CalculationType, typename Parameters> + struct urm5_spheroid : public detail::urm5::base_urm5_spheroid<CalculationType, Parameters> + { + inline urm5_spheroid(const Parameters& par) : detail::urm5::base_urm5_spheroid<CalculationType, Parameters>(par) + { + detail::urm5::setup_urm5(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::urm5, urm5_spheroid, urm5_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class urm5_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_f<urm5_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void urm5_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("urm5", new urm5_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_URM5_HPP + diff --git a/boost/geometry/srs/projections/proj/urmfps.hpp b/boost/geometry/srs/projections/proj/urmfps.hpp new file mode 100644 index 0000000000..14840057dc --- /dev/null +++ b/boost/geometry/srs/projections/proj/urmfps.hpp @@ -0,0 +1,235 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_URMFPS_HPP +#define BOOST_GEOMETRY_PROJECTIONS_URMFPS_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 urmfps {}; + struct wag1 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace urmfps + { + + static const double C_x = 0.8773826753; + static const double Cy = 1.139753528477; + + template <typename T> + struct par_urmfps + { + T n, C_y; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_urmfps_spheroid : public base_t_fi<base_urmfps_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_urmfps<CalculationType> m_proj_parm; + + inline base_urmfps_spheroid(const Parameters& par) + : base_t_fi<base_urmfps_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 + { + lp_lat = aasin(this->m_proj_parm.n * sin(lp_lat)); + xy_x = C_x * lp_lon * 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 = aasin(sin(xy_y) / this->m_proj_parm.n); + lp_lon = xy_x / (C_x * cos(xy_y)); + } + + static inline std::string get_name() + { + return "urmfps_spheroid"; + } + + }; + + template <typename Parameters, typename T> + inline void setup(Parameters& par, par_urmfps<T>& proj_parm) + { + proj_parm.C_y = Cy / proj_parm.n; + par.es = 0.; + } + + + // Urmaev Flat-Polar Sinusoidal + template <typename Parameters, typename T> + inline void setup_urmfps(Parameters& par, par_urmfps<T>& proj_parm) + { + if (pj_param(par.params, "tn").i) { + proj_parm.n = pj_param(par.params, "dn").f; + if (proj_parm.n <= 0. || proj_parm.n > 1.) + BOOST_THROW_EXCEPTION( projection_exception(-40) ); + } else + BOOST_THROW_EXCEPTION( projection_exception(-40) ); + setup(par, proj_parm); + } + + // Wagner I (Kavraisky VI) + template <typename Parameters, typename T> + inline void setup_wag1(Parameters& par, par_urmfps<T>& proj_parm) + { + proj_parm.n = 0.8660254037844386467637231707; + setup(par, proj_parm); + } + + }} // namespace detail::urmfps + #endif // doxygen + + /*! + \brief Urmaev 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 Projection parameters + - n (real) + \par Example + \image html ex_urmfps.gif + */ + template <typename CalculationType, typename Parameters> + struct urmfps_spheroid : public detail::urmfps::base_urmfps_spheroid<CalculationType, Parameters> + { + inline urmfps_spheroid(const Parameters& par) : detail::urmfps::base_urmfps_spheroid<CalculationType, Parameters>(par) + { + detail::urmfps::setup_urmfps(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief Wagner I (Kavraisky 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_wag1.gif + */ + template <typename CalculationType, typename Parameters> + struct wag1_spheroid : public detail::urmfps::base_urmfps_spheroid<CalculationType, Parameters> + { + inline wag1_spheroid(const Parameters& par) : detail::urmfps::base_urmfps_spheroid<CalculationType, Parameters>(par) + { + detail::urmfps::setup_wag1(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::urmfps, urmfps_spheroid, urmfps_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wag1, wag1_spheroid, wag1_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class urmfps_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<urmfps_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class wag1_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<wag1_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void urmfps_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("urmfps", new urmfps_entry<CalculationType, Parameters>); + factory.add_to_factory("wag1", new wag1_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_URMFPS_HPP + diff --git a/boost/geometry/srs/projections/proj/vandg.hpp b/boost/geometry/srs/projections/proj/vandg.hpp new file mode 100644 index 0000000000..1fd95285ea --- /dev/null +++ b/boost/geometry/srs/projections/proj/vandg.hpp @@ -0,0 +1,257 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_VANDG_HPP +#define BOOST_GEOMETRY_PROJECTIONS_VANDG_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 vandg {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace vandg + { + + static const double TOL = 1.e-10; + //static const double THIRD = .33333333333333333333; + //static const double TWO_THRD = .66666666666666666666; + //static const double C2_27 = .07407407407407407407; + //static const double PI4_3 = 4.18879020478639098458; + //static const double PISQ = 9.86960440108935861869; + //static const double TPISQ = 19.73920880217871723738; + //static const double HPISQ = 4.93480220054467930934; + + template <typename T> + inline T C2_27() { return .07407407407407407407407407407407; } + template <typename T> + inline T PI4_3() { return boost::math::constants::four_thirds_pi<T>(); } + template <typename T> + inline T TPISQ() { return 19.739208802178717237668981999752; } + template <typename T> + inline T HPISQ() { return 4.9348022005446793094172454999381; } + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_vandg_spheroid : public base_t_fi<base_vandg_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_vandg_spheroid(const Parameters& par) + : base_t_fi<base_vandg_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 al, al2, g, g2, p2; + + p2 = fabs(lp_lat / HALFPI); + if ((p2 - TOL) > 1.) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (p2 > 1.) + p2 = 1.; + if (fabs(lp_lat) <= TOL) { + xy_x = lp_lon; + xy_y = 0.; + } else if (fabs(lp_lon) <= TOL || fabs(p2 - 1.) < TOL) { + xy_x = 0.; + xy_y = ONEPI * tan(.5 * asin(p2)); + if (lp_lat < 0.) xy_y = -xy_y; + } else { + al = .5 * fabs(ONEPI / lp_lon - lp_lon / ONEPI); + al2 = al * al; + g = sqrt(1. - p2 * p2); + g = g / (p2 + g - 1.); + g2 = g * g; + p2 = g * (2. / p2 - 1.); + p2 = p2 * p2; + xy_x = g - p2; g = p2 + al2; + xy_x = ONEPI * (al * xy_x + sqrt(al2 * xy_x * xy_x - g * (g2 - p2))) / g; + if (lp_lon < 0.) xy_x = -xy_x; + xy_y = fabs(xy_x / ONEPI); + xy_y = 1. - xy_y * (xy_y + 2. * al); + if (xy_y < -TOL) + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + if (xy_y < 0.) + xy_y = 0.; + else + xy_y = sqrt(xy_y) * (lp_lat < 0. ? -ONEPI : ONEPI); + } + } + + // 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 ONEPI = detail::ONEPI<CalculationType>(); + static const CalculationType PISQ = detail::PI_SQR<CalculationType>(); + static const CalculationType THIRD = detail::THIRD<CalculationType>(); + static const CalculationType TWOPI = detail::TWOPI<CalculationType>(); + + static const CalculationType C2_27 = vandg::C2_27<CalculationType>(); + static const CalculationType PI4_3 = vandg::PI4_3<CalculationType>(); + static const CalculationType TPISQ = vandg::TPISQ<CalculationType>(); + static const CalculationType HPISQ = vandg::HPISQ<CalculationType>(); + + CalculationType t, c0, c1, c2, c3, al, r2, r, m, d, ay, x2, y2; + + x2 = xy_x * xy_x; + if ((ay = fabs(xy_y)) < TOL) { + lp_lat = 0.; + t = x2 * x2 + TPISQ * (x2 + HPISQ); + lp_lon = fabs(xy_x) <= TOL ? 0. : + .5 * (x2 - PISQ + sqrt(t)) / xy_x; + return; + } + y2 = xy_y * xy_y; + r = x2 + y2; r2 = r * r; + c1 = - ONEPI * ay * (r + PISQ); + c3 = r2 + TWOPI * (ay * r + ONEPI * (y2 + ONEPI * (ay + HALFPI))); + c2 = c1 + PISQ * (r - 3. * y2); + c0 = ONEPI * ay; + c2 /= c3; + al = c1 / c3 - THIRD * c2 * c2; + m = 2. * sqrt(-THIRD * al); + d = C2_27 * c2 * c2 * c2 + (c0 * c0 - THIRD * c2 * c1) / c3; + if (((t = fabs(d = 3. * d / (al * m))) - TOL) <= 1.) { + d = t > 1. ? (d > 0. ? 0. : ONEPI) : acos(d); + lp_lat = ONEPI * (m * cos(d * THIRD + PI4_3) - THIRD * c2); + if (xy_y < 0.) lp_lat = -lp_lat; + t = r2 + TPISQ * (x2 - y2 + HPISQ); + lp_lon = fabs(xy_x) <= TOL ? 0. : + .5 * (r - PISQ + (t <= 0. ? 0. : sqrt(t))) / xy_x; + } else + BOOST_THROW_EXCEPTION( projection_exception(-20) ); + } + + static inline std::string get_name() + { + return "vandg_spheroid"; + } + + }; + + // van der Grinten (I) + template <typename Parameters> + inline void setup_vandg(Parameters& par) + { + par.es = 0.; + } + + }} // namespace detail::vandg + #endif // doxygen + + /*! + \brief van der Grinten (I) 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_vandg.gif + */ + template <typename CalculationType, typename Parameters> + struct vandg_spheroid : public detail::vandg::base_vandg_spheroid<CalculationType, Parameters> + { + inline vandg_spheroid(const Parameters& par) : detail::vandg::base_vandg_spheroid<CalculationType, Parameters>(par) + { + detail::vandg::setup_vandg(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::vandg, vandg_spheroid, vandg_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class vandg_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<vandg_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void vandg_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("vandg", new vandg_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_VANDG_HPP + diff --git a/boost/geometry/srs/projections/proj/vandg2.hpp b/boost/geometry/srs/projections/proj/vandg2.hpp new file mode 100644 index 0000000000..650a64f432 --- /dev/null +++ b/boost/geometry/srs/projections/proj/vandg2.hpp @@ -0,0 +1,237 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_VANDG2_HPP +#define BOOST_GEOMETRY_PROJECTIONS_VANDG2_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 vandg2 {}; + struct vandg3 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace vandg2 + { + + static const double TOL = 1e-10; + //static const double TWORPI = 0.63661977236758134308; + + struct par_vandg2 + { + int vdg3; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_vandg2_spheroid : public base_t_f<base_vandg2_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_vandg2 m_proj_parm; + + inline base_vandg2_spheroid(const Parameters& par) + : base_t_f<base_vandg2_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 ONEPI = detail::ONEPI<CalculationType>(); + static const CalculationType TWORPI = detail::TWO_D_PI<CalculationType>(); + + CalculationType x1, at, bt, ct; + + bt = fabs(TWORPI * lp_lat); + if ((ct = 1. - bt * bt) < 0.) + ct = 0.; + else + ct = sqrt(ct); + if (fabs(lp_lon) < TOL) { + xy_x = 0.; + xy_y = ONEPI * (lp_lat < 0. ? -bt : bt) / (1. + ct); + } else { + at = 0.5 * fabs(ONEPI / lp_lon - lp_lon / ONEPI); + if (this->m_proj_parm.vdg3) { + x1 = bt / (1. + ct); + xy_x = ONEPI * (sqrt(at * at + 1. - x1 * x1) - at); + xy_y = ONEPI * x1; + } else { + x1 = (ct * sqrt(1. + at * at) - at * ct * ct) / + (1. + at * at * bt * bt); + xy_x = ONEPI * x1; + xy_y = ONEPI * sqrt(1. - x1 * (x1 + 2. * at) + TOL); + } + if ( lp_lon < 0.) xy_x = -xy_x; + if ( lp_lat < 0.) xy_y = -xy_y; + } + } + + static inline std::string get_name() + { + return "vandg2_spheroid"; + } + + }; + + // van der Grinten II + template <typename Parameters> + inline void setup_vandg2(Parameters& /*par*/, par_vandg2& proj_parm) + { + proj_parm.vdg3 = 0; + } + + // van der Grinten III + template <typename Parameters> + inline void setup_vandg3(Parameters& par, par_vandg2& proj_parm) + { + proj_parm.vdg3 = 1; + par.es = 0.; + } + + }} // namespace detail::vandg2 + #endif // doxygen + + /*! + \brief van der Grinten II 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_vandg2.gif + */ + template <typename CalculationType, typename Parameters> + struct vandg2_spheroid : public detail::vandg2::base_vandg2_spheroid<CalculationType, Parameters> + { + inline vandg2_spheroid(const Parameters& par) : detail::vandg2::base_vandg2_spheroid<CalculationType, Parameters>(par) + { + detail::vandg2::setup_vandg2(this->m_par, this->m_proj_parm); + } + }; + + /*! + \brief van der Grinten III 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_vandg3.gif + */ + template <typename CalculationType, typename Parameters> + struct vandg3_spheroid : public detail::vandg2::base_vandg2_spheroid<CalculationType, Parameters> + { + inline vandg3_spheroid(const Parameters& par) : detail::vandg2::base_vandg2_spheroid<CalculationType, Parameters>(par) + { + detail::vandg2::setup_vandg3(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::vandg2, vandg2_spheroid, vandg2_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::vandg3, vandg3_spheroid, vandg3_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class vandg2_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_f<vandg2_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + class vandg3_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_f<vandg3_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void vandg2_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("vandg2", new vandg2_entry<CalculationType, Parameters>); + factory.add_to_factory("vandg3", new vandg3_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_VANDG2_HPP + diff --git a/boost/geometry/srs/projections/proj/vandg4.hpp b/boost/geometry/srs/projections/proj/vandg4.hpp new file mode 100644 index 0000000000..0b85fedef4 --- /dev/null +++ b/boost/geometry/srs/projections/proj/vandg4.hpp @@ -0,0 +1,194 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_VANDG4_HPP +#define BOOST_GEOMETRY_PROJECTIONS_VANDG4_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 vandg4 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace vandg4 + { + + static const double TOL = 1e-10; + //static const double TWORPI = 0.63661977236758134308; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_vandg4_spheroid : public base_t_f<base_vandg4_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_vandg4_spheroid(const Parameters& par) + : base_t_f<base_vandg4_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 TWORPI = detail::TWO_D_PI<CalculationType>(); + + CalculationType x1, t, bt, ct, ft, bt2, ct2, dt, dt2; + + if (fabs(lp_lat) < TOL) { + xy_x = lp_lon; + xy_y = 0.; + } else if (fabs(lp_lon) < TOL || fabs(fabs(lp_lat) - HALFPI) < TOL) { + xy_x = 0.; + xy_y = lp_lat; + } else { + bt = fabs(TWORPI * lp_lat); + bt2 = bt * bt; + ct = 0.5 * (bt * (8. - bt * (2. + bt2)) - 5.) + / (bt2 * (bt - 1.)); + ct2 = ct * ct; + dt = TWORPI * lp_lon; + dt = dt + 1. / dt; + dt = sqrt(dt * dt - 4.); + if ((fabs(lp_lon) - HALFPI) < 0.) dt = -dt; + dt2 = dt * dt; + x1 = bt + ct; x1 *= x1; + t = bt + 3.*ct; + ft = x1 * (bt2 + ct2 * dt2 - 1.) + (1.-bt2) * ( + bt2 * (t * t + 4. * ct2) + + ct2 * (12. * bt * ct + 4. * ct2) ); + x1 = (dt*(x1 + ct2 - 1.) + 2.*sqrt(ft)) / + (4.* x1 + dt2); + xy_x = HALFPI * x1; + xy_y = HALFPI * sqrt(1. + dt * fabs(x1) - x1 * x1); + if (lp_lon < 0.) xy_x = -xy_x; + if (lp_lat < 0.) xy_y = -xy_y; + } + } + + static inline std::string get_name() + { + return "vandg4_spheroid"; + } + + }; + + // van der Grinten IV + template <typename Parameters> + inline void setup_vandg4(Parameters& par) + { + par.es = 0.; + } + + }} // namespace detail::vandg4 + #endif // doxygen + + /*! + \brief van der Grinten IV 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_vandg4.gif + */ + template <typename CalculationType, typename Parameters> + struct vandg4_spheroid : public detail::vandg4::base_vandg4_spheroid<CalculationType, Parameters> + { + inline vandg4_spheroid(const Parameters& par) : detail::vandg4::base_vandg4_spheroid<CalculationType, Parameters>(par) + { + detail::vandg4::setup_vandg4(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::vandg4, vandg4_spheroid, vandg4_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class vandg4_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_f<vandg4_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void vandg4_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("vandg4", new vandg4_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_VANDG4_HPP + diff --git a/boost/geometry/srs/projections/proj/wag2.hpp b/boost/geometry/srs/projections/proj/wag2.hpp new file mode 100644 index 0000000000..2d16892a9d --- /dev/null +++ b/boost/geometry/srs/projections/proj/wag2.hpp @@ -0,0 +1,172 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_WAG2_HPP +#define BOOST_GEOMETRY_PROJECTIONS_WAG2_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 wag2 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace wag2 + { + + static const double C_x = 0.92483; + static const double C_y = 1.38725; + static const double C_p1 = 0.88022; + static const double C_p2 = 0.88550; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_wag2_spheroid : public base_t_fi<base_wag2_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_wag2_spheroid(const Parameters& par) + : base_t_fi<base_wag2_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 + { + lp_lat = aasin(C_p1 * sin(C_p2 * lp_lat)); + xy_x = C_x * lp_lon * cos(lp_lat); + xy_y = C_y * 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 / C_y; + lp_lon = xy_x / (C_x * cos(lp_lat)); + lp_lat = aasin(sin(lp_lat) / C_p1) / C_p2; + } + + static inline std::string get_name() + { + return "wag2_spheroid"; + } + + }; + + // Wagner II + template <typename Parameters> + inline void setup_wag2(Parameters& par) + { + par.es = 0.; + } + + }} // namespace detail::wag2 + #endif // doxygen + + /*! + \brief Wagner 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_wag2.gif + */ + template <typename CalculationType, typename Parameters> + struct wag2_spheroid : public detail::wag2::base_wag2_spheroid<CalculationType, Parameters> + { + inline wag2_spheroid(const Parameters& par) : detail::wag2::base_wag2_spheroid<CalculationType, Parameters>(par) + { + detail::wag2::setup_wag2(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wag2, wag2_spheroid, wag2_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class wag2_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<wag2_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void wag2_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("wag2", new wag2_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_WAG2_HPP + diff --git a/boost/geometry/srs/projections/proj/wag3.hpp b/boost/geometry/srs/projections/proj/wag3.hpp new file mode 100644 index 0000000000..3ddbfe8258 --- /dev/null +++ b/boost/geometry/srs/projections/proj/wag3.hpp @@ -0,0 +1,180 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_WAG3_HPP +#define BOOST_GEOMETRY_PROJECTIONS_WAG3_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 wag3 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace wag3 + { + template <typename T> + struct par_wag3 + { + T C_x; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_wag3_spheroid : public base_t_fi<base_wag3_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_wag3<CalculationType> m_proj_parm; + + inline base_wag3_spheroid(const Parameters& par) + : base_t_fi<base_wag3_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 TWOTHIRD = detail::TWOTHIRD<CalculationType>(); + + xy_x = this->m_proj_parm.C_x * lp_lon * cos(TWOTHIRD * lp_lat); + xy_y = 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 TWOTHIRD = detail::TWOTHIRD<CalculationType>(); + + lp_lat = xy_y; + lp_lon = xy_x / (this->m_proj_parm.C_x * cos(TWOTHIRD * lp_lat)); + } + + static inline std::string get_name() + { + return "wag3_spheroid"; + } + + }; + + // Wagner III + template <typename Parameters, typename T> + inline void setup_wag3(Parameters& par, par_wag3<T>& proj_parm) + { + T ts; + + ts = pj_param(par.params, "rlat_ts").f; + proj_parm.C_x = cos(ts) / cos(2.*ts/3.); + par.es = 0.; + } + + }} // namespace detail::wag3 + #endif // doxygen + + /*! + \brief Wagner III 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_ts: Latitude of true scale (degrees) + \par Example + \image html ex_wag3.gif + */ + template <typename CalculationType, typename Parameters> + struct wag3_spheroid : public detail::wag3::base_wag3_spheroid<CalculationType, Parameters> + { + inline wag3_spheroid(const Parameters& par) : detail::wag3::base_wag3_spheroid<CalculationType, Parameters>(par) + { + detail::wag3::setup_wag3(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wag3, wag3_spheroid, wag3_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class wag3_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<wag3_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void wag3_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("wag3", new wag3_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_WAG3_HPP + diff --git a/boost/geometry/srs/projections/proj/wag7.hpp b/boost/geometry/srs/projections/proj/wag7.hpp new file mode 100644 index 0000000000..c752ff33ee --- /dev/null +++ b/boost/geometry/srs/projections/proj/wag7.hpp @@ -0,0 +1,161 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_WAG7_HPP +#define BOOST_GEOMETRY_PROJECTIONS_WAG7_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 wag7 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace wag7 + { + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_wag7_spheroid : public base_t_f<base_wag7_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + + inline base_wag7_spheroid(const Parameters& par) + : base_t_f<base_wag7_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 theta, ct, D; + + theta = asin(xy_y = 0.90630778703664996 * sin(lp_lat)); + xy_x = 2.66723 * (ct = cos(theta)) * sin(lp_lon /= 3.); + xy_y *= 1.24104 * (D = 1/(sqrt(0.5 * (1 + ct * cos(lp_lon))))); + xy_x *= D; + } + + static inline std::string get_name() + { + return "wag7_spheroid"; + } + + }; + + // Wagner VII + template <typename Parameters> + inline void setup_wag7(Parameters& par) + { + par.es = 0.; + } + + }} // namespace detail::wag7 + #endif // doxygen + + /*! + \brief Wagner VII 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_wag7.gif + */ + template <typename CalculationType, typename Parameters> + struct wag7_spheroid : public detail::wag7::base_wag7_spheroid<CalculationType, Parameters> + { + inline wag7_spheroid(const Parameters& par) : detail::wag7::base_wag7_spheroid<CalculationType, Parameters>(par) + { + detail::wag7::setup_wag7(this->m_par); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wag7, wag7_spheroid, wag7_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class wag7_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_f<wag7_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void wag7_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("wag7", new wag7_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_WAG7_HPP + diff --git a/boost/geometry/srs/projections/proj/wink1.hpp b/boost/geometry/srs/projections/proj/wink1.hpp new file mode 100644 index 0000000000..36ecc95500 --- /dev/null +++ b/boost/geometry/srs/projections/proj/wink1.hpp @@ -0,0 +1,174 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_WINK1_HPP +#define BOOST_GEOMETRY_PROJECTIONS_WINK1_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 wink1 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace wink1 + { + + template <typename T> + struct par_wink1 + { + T cosphi1; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_wink1_spheroid : public base_t_fi<base_wink1_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_wink1<CalculationType> m_proj_parm; + + inline base_wink1_spheroid(const Parameters& par) + : base_t_fi<base_wink1_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 = .5 * lp_lon * (this->m_proj_parm.cosphi1 + cos(lp_lat)); + xy_y = 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; + lp_lon = 2. * xy_x / (this->m_proj_parm.cosphi1 + cos(lp_lat)); + } + + static inline std::string get_name() + { + return "wink1_spheroid"; + } + + }; + + // Winkel I + template <typename Parameters, typename T> + inline void setup_wink1(Parameters& par, par_wink1<T>& proj_parm) + { + proj_parm.cosphi1 = cos(pj_param(par.params, "rlat_ts").f); + par.es = 0.; + } + + }} // namespace detail::wink1 + #endif // doxygen + + /*! + \brief Winkel I 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_ts: Latitude of true scale (degrees) + \par Example + \image html ex_wink1.gif + */ + template <typename CalculationType, typename Parameters> + struct wink1_spheroid : public detail::wink1::base_wink1_spheroid<CalculationType, Parameters> + { + inline wink1_spheroid(const Parameters& par) : detail::wink1::base_wink1_spheroid<CalculationType, Parameters>(par) + { + detail::wink1::setup_wink1(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wink1, wink1_spheroid, wink1_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class wink1_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_fi<wink1_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void wink1_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("wink1", new wink1_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_WINK1_HPP + diff --git a/boost/geometry/srs/projections/proj/wink2.hpp b/boost/geometry/srs/projections/proj/wink2.hpp new file mode 100644 index 0000000000..9c90d42481 --- /dev/null +++ b/boost/geometry/srs/projections/proj/wink2.hpp @@ -0,0 +1,195 @@ +#ifndef BOOST_GEOMETRY_PROJECTIONS_WINK2_HPP +#define BOOST_GEOMETRY_PROJECTIONS_WINK2_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 wink2 {}; + +}} //namespace srs::par4 + +namespace projections +{ + #ifndef DOXYGEN_NO_DETAIL + namespace detail { namespace wink2 + { + + static const int MAX_ITER = 10; + + static const double LOOP_TOL = 1e-7; + //static const double TWO_D_PI = 0.636619772367581343; + + template <typename T> + struct par_wink2 + { + T cosphi1; + }; + + // template class, using CRTP to implement forward/inverse + template <typename CalculationType, typename Parameters> + struct base_wink2_spheroid : public base_t_f<base_wink2_spheroid<CalculationType, Parameters>, + CalculationType, Parameters> + { + + typedef CalculationType geographic_type; + typedef CalculationType cartesian_type; + + par_wink2<CalculationType> m_proj_parm; + + inline base_wink2_spheroid(const Parameters& par) + : base_t_f<base_wink2_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 ONEPI = detail::ONEPI<CalculationType>(); + static const CalculationType HALFPI = detail::HALFPI<CalculationType>(); + static const CalculationType FORTPI = detail::FORTPI<CalculationType>(); + static const CalculationType TWO_D_PI = detail::TWO_D_PI<CalculationType>(); + + CalculationType k, V; + int i; + + xy_y = lp_lat * TWO_D_PI; + k = ONEPI * sin(lp_lat); + lp_lat *= 1.8; + for (i = MAX_ITER; i ; --i) { + lp_lat -= V = (lp_lat + sin(lp_lat) - k) / + (1. + cos(lp_lat)); + if (fabs(V) < LOOP_TOL) + break; + } + if (!i) + lp_lat = (lp_lat < 0.) ? -HALFPI : HALFPI; + else + lp_lat *= 0.5; + xy_x = 0.5 * lp_lon * (cos(lp_lat) + this->m_proj_parm.cosphi1); + xy_y = FORTPI * (sin(lp_lat) + xy_y); + } + + static inline std::string get_name() + { + return "wink2_spheroid"; + } + + }; + + // Winkel II + template <typename Parameters, typename T> + inline void setup_wink2(Parameters& par, par_wink2<T>& proj_parm) + { + proj_parm.cosphi1 = cos(pj_param(par.params, "rlat_1").f); + par.es = 0.; + } + + }} // namespace detail::wink2 + #endif // doxygen + + /*! + \brief Winkel II 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 Projection parameters + - lat_1: Latitude of first standard parallel (degrees) + \par Example + \image html ex_wink2.gif + */ + template <typename CalculationType, typename Parameters> + struct wink2_spheroid : public detail::wink2::base_wink2_spheroid<CalculationType, Parameters> + { + inline wink2_spheroid(const Parameters& par) : detail::wink2::base_wink2_spheroid<CalculationType, Parameters>(par) + { + detail::wink2::setup_wink2(this->m_par, this->m_proj_parm); + } + }; + + #ifndef DOXYGEN_NO_DETAIL + namespace detail + { + + // Static projection + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::wink2, wink2_spheroid, wink2_spheroid) + + // Factory entry(s) + template <typename CalculationType, typename Parameters> + class wink2_entry : public detail::factory_entry<CalculationType, Parameters> + { + public : + virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const + { + return new base_v_f<wink2_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par); + } + }; + + template <typename CalculationType, typename Parameters> + inline void wink2_init(detail::base_factory<CalculationType, Parameters>& factory) + { + factory.add_to_factory("wink2", new wink2_entry<CalculationType, Parameters>); + } + + } // namespace detail + #endif // doxygen + +} // namespace projections + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_PROJECTIONS_WINK2_HPP + |