1 #ifndef BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP
2 #define BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP
4 // Boost.Geometry - extensions-gis-projections (based on PROJ4)
5 // This file is automatically generated. DO NOT EDIT.
7 // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
9 // This file was modified by Oracle on 2017.
10 // Modifications copyright (c) 2017, Oracle and/or its affiliates.
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
13 // Use, modification and distribution is subject to the Boost Software License,
14 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15 // http://www.boost.org/LICENSE_1_0.txt)
17 // This file is converted from PROJ4, http://trac.osgeo.org/proj
18 // PROJ4 is originally written by Gerald Evenden (then of the USGS)
19 // PROJ4 is maintained by Frank Warmerdam
20 // PROJ4 is converted to Boost.Geometry by Barend Gehrels
22 // Last updated version of proj: 4.9.1
24 // Original copyright notice:
26 // Permission is hereby granted, free of charge, to any person obtaining a
27 // copy of this software and associated documentation files (the "Software"),
28 // to deal in the Software without restriction, including without limitation
29 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
30 // and/or sell copies of the Software, and to permit persons to whom the
31 // Software is furnished to do so, subject to the following conditions:
33 // The above copyright notice and this permission notice shall be included
34 // in all copies or substantial portions of the Software.
36 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
37 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
39 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
41 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
42 // DEALINGS IN THE SOFTWARE.
44 #include <boost/geometry/util/math.hpp>
45 #include <boost/math/special_functions/hypot.hpp>
47 #include <boost/geometry/srs/projections/impl/base_static.hpp>
48 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
49 #include <boost/geometry/srs/projections/impl/projects.hpp>
50 #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
51 #include <boost/geometry/srs/projections/impl/aasincos.hpp>
53 namespace boost { namespace geometry
56 namespace srs { namespace par4
60 }} //namespace srs::par4
64 #ifndef DOXYGEN_NO_DETAIL
65 namespace detail { namespace tpeqd
70 T cp1, sp1, cp2, sp2, ccs, cs, sc, r2z0, z02, dlam2;
71 T hz0, thz0, rhshz0, ca, sa, lp, lamc;
74 // template class, using CRTP to implement forward/inverse
75 template <typename CalculationType, typename Parameters>
76 struct base_tpeqd_spheroid : public base_t_fi<base_tpeqd_spheroid<CalculationType, Parameters>,
77 CalculationType, Parameters>
80 typedef CalculationType geographic_type;
81 typedef CalculationType cartesian_type;
83 par_tpeqd<CalculationType> m_proj_parm;
85 inline base_tpeqd_spheroid(const Parameters& par)
86 : base_t_fi<base_tpeqd_spheroid<CalculationType, Parameters>,
87 CalculationType, Parameters>(*this, par) {}
89 // FORWARD(s_forward) sphere
90 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
91 inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
93 CalculationType t, z1, z2, dl1, dl2, sp, cp;
97 z1 = aacos(this->m_proj_parm.sp1 * sp + this->m_proj_parm.cp1 * cp * cos(dl1 = lp_lon + this->m_proj_parm.dlam2));
98 z2 = aacos(this->m_proj_parm.sp2 * sp + this->m_proj_parm.cp2 * cp * cos(dl2 = lp_lon - this->m_proj_parm.dlam2));
101 xy_x = this->m_proj_parm.r2z0 * (t = z1 - z2);
102 t = this->m_proj_parm.z02 - t;
103 xy_y = this->m_proj_parm.r2z0 * asqrt(4. * this->m_proj_parm.z02 * z2 - t * t);
104 if ((this->m_proj_parm.ccs * sp - cp * (this->m_proj_parm.cs * sin(dl1) - this->m_proj_parm.sc * sin(dl2))) < 0.)
108 // INVERSE(s_inverse) sphere
109 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
110 inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
112 CalculationType cz1, cz2, s, d, cp, sp;
114 cz1 = cos(boost::math::hypot(xy_y, xy_x + this->m_proj_parm.hz0));
115 cz2 = cos(boost::math::hypot(xy_y, xy_x - this->m_proj_parm.hz0));
118 lp_lon = - atan2(d, (s * this->m_proj_parm.thz0));
119 lp_lat = aacos(boost::math::hypot(this->m_proj_parm.thz0 * s, d) * this->m_proj_parm.rhshz0);
122 /* lam--phi now in system relative to P1--P2 base equator */
125 lp_lat = aasin(this->m_proj_parm.sa * sp + this->m_proj_parm.ca * cp * (s = cos(lp_lon -= this->m_proj_parm.lp)));
126 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;
129 static inline std::string get_name()
131 return "tpeqd_spheroid";
136 // Two Point Equidistant
137 template <typename Parameters, typename T>
138 inline void setup_tpeqd(Parameters& par, par_tpeqd<T>& proj_parm)
140 T lam_1, lam_2, phi_1, phi_2, A12, pp;
142 /* get control point locations */
143 phi_1 = pj_param(par.params, "rlat_1").f;
144 lam_1 = pj_param(par.params, "rlon_1").f;
145 phi_2 = pj_param(par.params, "rlat_2").f;
146 lam_2 = pj_param(par.params, "rlon_2").f;
147 if (phi_1 == phi_2 && lam_1 == lam_2)
148 BOOST_THROW_EXCEPTION( projection_exception(-25) );
149 par.lam0 = adjlon(0.5 * (lam_1 + lam_2));
150 proj_parm.dlam2 = adjlon(lam_2 - lam_1);
151 proj_parm.cp1 = cos(phi_1);
152 proj_parm.cp2 = cos(phi_2);
153 proj_parm.sp1 = sin(phi_1);
154 proj_parm.sp2 = sin(phi_2);
155 proj_parm.cs = proj_parm.cp1 * proj_parm.sp2;
156 proj_parm.sc = proj_parm.sp1 * proj_parm.cp2;
157 proj_parm.ccs = proj_parm.cp1 * proj_parm.cp2 * sin(proj_parm.dlam2);
158 proj_parm.z02 = aacos(proj_parm.sp1 * proj_parm.sp2 + proj_parm.cp1 * proj_parm.cp2 * cos(proj_parm.dlam2));
159 proj_parm.hz0 = .5 * proj_parm.z02;
160 A12 = atan2(proj_parm.cp2 * sin(proj_parm.dlam2),
161 proj_parm.cp1 * proj_parm.sp2 - proj_parm.sp1 * proj_parm.cp2 * cos(proj_parm.dlam2));
162 proj_parm.ca = cos(pp = aasin(proj_parm.cp1 * sin(A12)));
163 proj_parm.sa = sin(pp);
164 proj_parm.lp = adjlon(atan2(proj_parm.cp1 * cos(A12), proj_parm.sp1) - proj_parm.hz0);
165 proj_parm.dlam2 *= .5;
166 proj_parm.lamc = geometry::math::half_pi<T>() - atan2(sin(A12) * proj_parm.sp1, cos(A12)) - proj_parm.dlam2;
167 proj_parm.thz0 = tan(proj_parm.hz0);
168 proj_parm.rhshz0 = .5 / sin(proj_parm.hz0);
169 proj_parm.r2z0 = 0.5 / proj_parm.z02;
170 proj_parm.z02 *= proj_parm.z02;
174 }} // namespace detail::tpeqd
178 \brief Two Point Equidistant projection
180 \tparam Geographic latlong point type
181 \tparam Cartesian xy point type
182 \tparam Parameters parameter type
183 \par Projection characteristics
186 \par Projection parameters
187 - lat_1: Latitude of first standard parallel (degrees)
189 - lat_2: Latitude of second standard parallel (degrees)
192 \image html ex_tpeqd.gif
194 template <typename CalculationType, typename Parameters>
195 struct tpeqd_spheroid : public detail::tpeqd::base_tpeqd_spheroid<CalculationType, Parameters>
197 inline tpeqd_spheroid(const Parameters& par) : detail::tpeqd::base_tpeqd_spheroid<CalculationType, Parameters>(par)
199 detail::tpeqd::setup_tpeqd(this->m_par, this->m_proj_parm);
203 #ifndef DOXYGEN_NO_DETAIL
208 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::par4::tpeqd, tpeqd_spheroid, tpeqd_spheroid)
211 template <typename CalculationType, typename Parameters>
212 class tpeqd_entry : public detail::factory_entry<CalculationType, Parameters>
215 virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
217 return new base_v_fi<tpeqd_spheroid<CalculationType, Parameters>, CalculationType, Parameters>(par);
221 template <typename CalculationType, typename Parameters>
222 inline void tpeqd_init(detail::base_factory<CalculationType, Parameters>& factory)
224 factory.add_to_factory("tpeqd", new tpeqd_entry<CalculationType, Parameters>);
227 } // namespace detail
230 } // namespace projections
232 }} // namespace boost::geometry
234 #endif // BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP