Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:45

0001 // Boost.Geometry - gis-projections (based on PROJ4)
0002 
0003 // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
0004 
0005 // This file was modified by Oracle on 2017, 2018, 2019.
0006 // Modifications copyright (c) 2017-2019, Oracle and/or its affiliates.
0007 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
0008 
0009 // Use, modification and distribution is subject to the Boost Software License,
0010 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0011 // http://www.boost.org/LICENSE_1_0.txt)
0012 
0013 // This file is converted from PROJ4, http://trac.osgeo.org/proj
0014 // PROJ4 is originally written by Gerald Evenden (then of the USGS)
0015 // PROJ4 is maintained by Frank Warmerdam
0016 // PROJ4 is converted to Boost.Geometry by Barend Gehrels
0017 
0018 // Last updated version of proj: 5.0.0
0019 
0020 // Original copyright notice:
0021 
0022 // Permission is hereby granted, free of charge, to any person obtaining a
0023 // copy of this software and associated documentation files (the "Software"),
0024 // to deal in the Software without restriction, including without limitation
0025 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
0026 // and/or sell copies of the Software, and to permit persons to whom the
0027 // Software is furnished to do so, subject to the following conditions:
0028 
0029 // The above copyright notice and this permission notice shall be included
0030 // in all copies or substantial portions of the Software.
0031 
0032 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0033 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0034 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
0035 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0036 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0037 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
0038 // DEALINGS IN THE SOFTWARE.
0039 
0040 #ifndef BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP
0041 #define BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP
0042 
0043 #include <boost/geometry/util/math.hpp>
0044 
0045 #include <boost/geometry/srs/projections/impl/base_static.hpp>
0046 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
0047 #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
0048 #include <boost/geometry/srs/projections/impl/pj_param.hpp>
0049 #include <boost/geometry/srs/projections/impl/projects.hpp>
0050 
0051 namespace boost { namespace geometry
0052 {
0053 
0054 namespace projections
0055 {
0056     #ifndef DOXYGEN_NO_DETAIL
0057     namespace detail { namespace ocea
0058     {
0059             template <typename T>
0060             struct par_ocea
0061             {
0062                 T    rok;
0063                 T    rtk;
0064                 T    sinphi;
0065                 T    cosphi;
0066                 T    singam;
0067                 T    cosgam;
0068             };
0069 
0070             template <typename T, typename Parameters>
0071             struct base_ocea_spheroid
0072             {
0073                 par_ocea<T> m_proj_parm;
0074 
0075                 // FORWARD(s_forward)  spheroid
0076                 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
0077                 inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
0078                 {
0079                     static const T pi = detail::pi<T>();
0080 
0081                     T t;
0082 
0083                     xy_y = sin(lp_lon);
0084                     t = cos(lp_lon);
0085                     xy_x = atan((tan(lp_lat) * this->m_proj_parm.cosphi + this->m_proj_parm.sinphi * xy_y) / t);
0086                     if (t < 0.)
0087                         xy_x += pi;
0088                     xy_x *= this->m_proj_parm.rtk;
0089                     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);
0090                 }
0091 
0092                 // INVERSE(s_inverse)  spheroid
0093                 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
0094                 inline void inv(Parameters const& , T xy_x, T xy_y, T& lp_lon, T& lp_lat) const
0095                 {
0096                     T t, s;
0097 
0098                     xy_y /= this->m_proj_parm.rok;
0099                     xy_x /= this->m_proj_parm.rtk;
0100                     t = sqrt(1. - xy_y * xy_y);
0101                     lp_lat = asin(xy_y * this->m_proj_parm.sinphi + t * this->m_proj_parm.cosphi * (s = sin(xy_x)));
0102                     lp_lon = atan2(t * this->m_proj_parm.sinphi * s - xy_y * this->m_proj_parm.cosphi,
0103                         t * cos(xy_x));
0104                 }
0105 
0106                 static inline std::string get_name()
0107                 {
0108                     return "ocea_spheroid";
0109                 }
0110 
0111             };
0112 
0113             // Oblique Cylindrical Equal Area
0114             template <typename Params, typename Parameters, typename T>
0115             inline void setup_ocea(Params const& params, Parameters& par, par_ocea<T>& proj_parm)
0116             {
0117                 static const T half_pi = detail::half_pi<T>();
0118 
0119                 T phi_0=0.0, phi_1, phi_2, lam_1, lam_2, lonz, alpha;
0120 
0121                 proj_parm.rok = 1. / par.k0;
0122                 proj_parm.rtk = par.k0;
0123                 /*If the keyword "alpha" is found in the sentence then use 1point+1azimuth*/
0124                 if ( pj_param_r<srs::spar::alpha>(params, "alpha", srs::dpar::alpha, alpha)) {
0125                     /*Define Pole of oblique transformation from 1 point & 1 azimuth*/
0126                     //alpha = pj_get_param_r(par.params, "alpha"); // set above
0127                     lonz = pj_get_param_r<T, srs::spar::lonc>(params, "lonc", srs::dpar::lonc);
0128                     /*Equation 9-8 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/
0129                     proj_parm.singam = atan(-cos(alpha)/(-sin(phi_0) * sin(alpha))) + lonz;
0130                     /*Equation 9-7 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/
0131                     proj_parm.sinphi = asin(cos(phi_0) * sin(alpha));
0132                 /*If the keyword "alpha" is NOT found in the sentence then use 2points*/
0133                 } else {
0134                     /*Define Pole of oblique transformation from 2 points*/
0135                     phi_1 = pj_get_param_r<T, srs::spar::lat_1>(params, "lat_1", srs::dpar::lat_1);
0136                     phi_2 = pj_get_param_r<T, srs::spar::lat_2>(params, "lat_2", srs::dpar::lat_2);
0137                     lam_1 = pj_get_param_r<T, srs::spar::lon_1>(params, "lon_1", srs::dpar::lon_1);
0138                     lam_2 = pj_get_param_r<T, srs::spar::lon_2>(params, "lon_2", srs::dpar::lon_2);
0139                     /*Equation 9-1 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/
0140                     proj_parm.singam = atan2(cos(phi_1) * sin(phi_2) * cos(lam_1) -
0141                         sin(phi_1) * cos(phi_2) * cos(lam_2),
0142                         sin(phi_1) * cos(phi_2) * sin(lam_2) -
0143                         cos(phi_1) * sin(phi_2) * sin(lam_1) );
0144 
0145                     /* take care of P->lam0 wrap-around when +lam_1=-90*/
0146                     if (lam_1 == -half_pi)
0147                         proj_parm.singam = -proj_parm.singam;
0148 
0149                     /*Equation 9-2 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/
0150                     proj_parm.sinphi = atan(-cos(proj_parm.singam - lam_1) / tan(phi_1));
0151                 }
0152                 par.lam0 = proj_parm.singam + half_pi;
0153                 proj_parm.cosphi = cos(proj_parm.sinphi);
0154                 proj_parm.sinphi = sin(proj_parm.sinphi);
0155                 proj_parm.cosgam = cos(proj_parm.singam);
0156                 proj_parm.singam = sin(proj_parm.singam);
0157                 par.es = 0.;
0158             }
0159 
0160     }} // namespace detail::ocea
0161     #endif // doxygen
0162 
0163     /*!
0164         \brief Oblique Cylindrical Equal Area projection
0165         \ingroup projections
0166         \tparam Geographic latlong point type
0167         \tparam Cartesian xy point type
0168         \tparam Parameters parameter type
0169         \par Projection characteristics
0170          - Cylindrical
0171          - Spheroid
0172         \par Projection parameters
0173          - lonc: Longitude (only used if alpha (or gamma) is specified) (degrees)
0174          - alpha: Alpha (degrees)
0175          - lat_1: Latitude of first standard parallel (degrees)
0176          - lat_2: Latitude of second standard parallel (degrees)
0177          - lon_1 (degrees)
0178          - lon_2 (degrees)
0179         \par Example
0180         \image html ex_ocea.gif
0181     */
0182     template <typename T, typename Parameters>
0183     struct ocea_spheroid : public detail::ocea::base_ocea_spheroid<T, Parameters>
0184     {
0185         template <typename Params>
0186         inline ocea_spheroid(Params const& params, Parameters & par)
0187         {
0188             detail::ocea::setup_ocea(params, par, this->m_proj_parm);
0189         }
0190     };
0191 
0192     #ifndef DOXYGEN_NO_DETAIL
0193     namespace detail
0194     {
0195 
0196         // Static projection
0197         BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_ocea, ocea_spheroid)
0198 
0199         // Factory entry(s)
0200         BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(ocea_entry, ocea_spheroid)
0201 
0202         BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(ocea_init)
0203         {
0204             BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(ocea, ocea_entry)
0205         }
0206 
0207     } // namespace detail
0208     #endif // doxygen
0209 
0210 } // namespace projections
0211 
0212 }} // namespace boost::geometry
0213 
0214 #endif // BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP
0215