Back to home page

EIC code displayed by LXR

 
 

    


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

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 // The Natural Earth projection was designed by Tom Patterson, US National Park
0041 // Service, in 2007, using Flex Projector. The shape of the original projection
0042 // was defined at every 5 degrees and piece-wise cubic spline interpolation was
0043 // used to compute the complete graticule.
0044 // The code here uses polynomial functions instead of cubic splines and
0045 // is therefore much simpler to program. The polynomial approximation was
0046 // developed by Bojan Savric, in collaboration with Tom Patterson and Bernhard
0047 // Jenny, Institute of Cartography, ETH Zurich. It slightly deviates from
0048 // Patterson's original projection by adding additional curvature to meridians
0049 // where they meet the horizontal pole line. This improvement is by intention
0050 // and designed in collaboration with Tom Patterson.
0051 // Port to PROJ.4 by Bernhard Jenny, 6 June 2011
0052 
0053 #ifndef BOOST_GEOMETRY_PROJECTIONS_NATEARTH_HPP
0054 #define BOOST_GEOMETRY_PROJECTIONS_NATEARTH_HPP
0055 
0056 #include <boost/geometry/srs/projections/impl/base_static.hpp>
0057 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
0058 #include <boost/geometry/srs/projections/impl/projects.hpp>
0059 #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
0060 
0061 namespace boost { namespace geometry
0062 {
0063 
0064 namespace projections
0065 {
0066     #ifndef DOXYGEN_NO_DETAIL
0067     namespace detail { namespace natearth
0068     {
0069 
0070             static const double A0 = 0.8707;
0071             static const double A1 = -0.131979;
0072             static const double A2 = -0.013791;
0073             static const double A3 = 0.003971;
0074             static const double A4 = -0.001529;
0075             static const double B0 = 1.007226;
0076             static const double B1 = 0.015085;
0077             static const double B2 = -0.044475;
0078             static const double B3 = 0.028874;
0079             static const double B4 = -0.005916;
0080             static const double C0 = B0;
0081             static const double C1 = (3 * B1);
0082             static const double C2 = (7 * B2);
0083             static const double C3 = (9 * B3);
0084             static const double C4 = (11 * B4);
0085             static const double epsilon = 1e-11;
0086 
0087             template <typename T>
0088             inline T max_y() { return (0.8707 * 0.52 * detail::pi<T>()); }
0089 
0090             /* Not sure at all of the appropriate number for max_iter... */
0091             static const int max_iter = 100;
0092 
0093             template <typename T, typename Parameters>
0094             struct base_natearth_spheroid
0095             {
0096                 // FORWARD(s_forward)  spheroid
0097                 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
0098                 inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
0099                 {
0100                     T phi2, phi4;
0101 
0102                     phi2 = lp_lat * lp_lat;
0103                     phi4 = phi2 * phi2;
0104                     xy_x = lp_lon * (A0 + phi2 * (A1 + phi2 * (A2 + phi4 * phi2 * (A3 + phi2 * A4))));
0105                     xy_y = lp_lat * (B0 + phi2 * (B1 + phi4 * (B2 + B3 * phi2 + B4 * phi4)));
0106                 }
0107 
0108                 // INVERSE(s_inverse)  spheroid
0109                 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
0110                 inline void inv(Parameters const& , T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const
0111                 {
0112                     static const T max_y = natearth::max_y<T>();
0113 
0114                     T yc, tol, y2, y4, f, fder;
0115                     int i;
0116 
0117                     /* make sure y is inside valid range */
0118                     if (xy_y > max_y) {
0119                         xy_y = max_y;
0120                     } else if (xy_y < -max_y) {
0121                         xy_y = -max_y;
0122                     }
0123 
0124                     /* latitude */
0125                     yc = xy_y;
0126                     for (i = max_iter; i ; --i) { /* Newton-Raphson */
0127                         y2 = yc * yc;
0128                         y4 = y2 * y2;
0129                         f = (yc * (B0 + y2 * (B1 + y4 * (B2 + B3 * y2 + B4 * y4)))) - xy_y;
0130                         fder = C0 + y2 * (C1 + y4 * (C2 + C3 * y2 + C4 * y4));
0131                         yc -= tol = f / fder;
0132                         if (fabs(tol) < epsilon) {
0133                             break;
0134                         }
0135                     }
0136                     if( i == 0 )
0137                         BOOST_THROW_EXCEPTION( projection_exception(error_non_convergent) );
0138                     lp_lat = yc;
0139 
0140                     /* longitude */
0141                     y2 = yc * yc;
0142                     lp_lon = xy_x / (A0 + y2 * (A1 + y2 * (A2 + y2 * y2 * y2 * (A3 + y2 * A4))));
0143                 }
0144 
0145                 static inline std::string get_name()
0146                 {
0147                     return "natearth_spheroid";
0148                 }
0149 
0150             };
0151 
0152             // Natural Earth
0153             template <typename Parameters>
0154             inline void setup_natearth(Parameters& par)
0155             {
0156                 par.es = 0;
0157             }
0158 
0159     }} // namespace detail::natearth
0160     #endif // doxygen
0161 
0162     /*!
0163         \brief Natural Earth projection
0164         \ingroup projections
0165         \tparam Geographic latlong point type
0166         \tparam Cartesian xy point type
0167         \tparam Parameters parameter type
0168         \par Projection characteristics
0169          - Pseudocylindrical
0170          - Spheroid
0171         \par Example
0172         \image html ex_natearth.gif
0173     */
0174     template <typename T, typename Parameters>
0175     struct natearth_spheroid : public detail::natearth::base_natearth_spheroid<T, Parameters>
0176     {
0177         template <typename Params>
0178         inline natearth_spheroid(Params const& , Parameters & par)
0179         {
0180             detail::natearth::setup_natearth(par);
0181         }
0182     };
0183 
0184     #ifndef DOXYGEN_NO_DETAIL
0185     namespace detail
0186     {
0187 
0188         // Static projection
0189         BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_natearth, natearth_spheroid)
0190 
0191         // Factory entry(s)
0192         BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(natearth_entry, natearth_spheroid)
0193 
0194         BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(natearth_init)
0195         {
0196             BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(natearth, natearth_entry)
0197         }
0198 
0199     } // namespace detail
0200     #endif // doxygen
0201 
0202 } // namespace projections
0203 
0204 }} // namespace boost::geometry
0205 
0206 #endif // BOOST_GEOMETRY_PROJECTIONS_NATEARTH_HPP
0207