1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4 
5 // This file was modified by Oracle on 2017, 2018, 2019.
6 // Modifications copyright (c) 2017-2019, Oracle and/or its affiliates.
7 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
8 
9 // Use, modification and distribution is subject to the Boost Software License,
10 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12 
13 #ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_DYNAMIC_HPP
14 #define BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_DYNAMIC_HPP
15 
16 #include <string>
17 
18 #include <boost/geometry/srs/projections/exception.hpp>
19 #include <boost/geometry/srs/projections/impl/projects.hpp>
20 
21 namespace boost { namespace geometry { namespace projections
22 {
23 
24 #ifndef DOXYGEN_NO_DETAIL
25 namespace detail
26 {
27 
28 /*!
29     \brief projection virtual base class
30     \details class containing virtual methods
31     \ingroup projection
32     \tparam CT calculation type
33     \tparam P parameters type
34 */
35 template <typename CT, typename P>
36 class dynamic_wrapper_b
37 {
38 public :
dynamic_wrapper_b(P const & par)39     dynamic_wrapper_b(P const& par)
40         : m_par(par)
41     {}
42 
~dynamic_wrapper_b()43     virtual ~dynamic_wrapper_b() {}
44 
45     /// Forward projection using lon / lat and x / y separately
46     virtual void fwd(P const& par, CT const& lp_lon, CT const& lp_lat, CT& xy_x, CT& xy_y) const = 0;
47 
48     /// Inverse projection using x / y and lon / lat
49     virtual void inv(P const& par, CT const& xy_x, CT const& xy_y, CT& lp_lon, CT& lp_lat) const = 0;
50 
51     /// Forward projection, from Latitude-Longitude to Cartesian
52     template <typename LL, typename XY>
forward(LL const & lp,XY & xy) const53     inline bool forward(LL const& lp, XY& xy) const
54     {
55         try
56         {
57             pj_fwd(*this, m_par, lp, xy);
58             return true;
59         }
60         catch (...)
61         {
62             return false;
63         }
64     }
65 
66     /// Inverse projection, from Cartesian to Latitude-Longitude
67     template <typename LL, typename XY>
inverse(XY const & xy,LL & lp) const68     inline bool inverse(XY const& xy, LL& lp) const
69     {
70         try
71         {
72             pj_inv(*this, m_par, xy, lp);
73             return true;
74         }
75         catch (projection_not_invertible_exception &)
76         {
77             BOOST_RETHROW
78         }
79         catch (...)
80         {
81             return false;
82         }
83     }
84 
85     /// Returns name of projection
name() const86     std::string name() const { return m_par.id.name; }
87 
88     /// Returns parameters of projection
params() const89     P const& params() const { return m_par; }
90 
91     /// Returns mutable parameters of projection
mutable_params()92     P& mutable_params() { return m_par; }
93 
94 protected:
95     P m_par;
96 };
97 
98 // Forward
99 template <typename Prj, typename CT, typename P>
100 class dynamic_wrapper_f
101     : public dynamic_wrapper_b<CT, P>
102     , protected Prj
103 {
104     typedef dynamic_wrapper_b<CT, P> base_t;
105 
106 public:
107     template <typename Params>
dynamic_wrapper_f(Params const & params,P const & par)108     dynamic_wrapper_f(Params const& params, P const& par)
109         : base_t(par)
110         , Prj(params, this->m_par) // prj can modify parameters
111     {}
112 
113     template <typename Params, typename P3>
dynamic_wrapper_f(Params const & params,P const & par,P3 const & p3)114     dynamic_wrapper_f(Params const& params, P const& par, P3 const& p3)
115         : base_t(par)
116         , Prj(params, this->m_par, p3) // prj can modify parameters
117     {}
118 
fwd(P const & par,CT const & lp_lon,CT const & lp_lat,CT & xy_x,CT & xy_y) const119     virtual void fwd(P const& par, CT const& lp_lon, CT const& lp_lat, CT& xy_x, CT& xy_y) const
120     {
121         prj().fwd(par, lp_lon, lp_lat, xy_x, xy_y);
122     }
123 
inv(P const &,CT const &,CT const &,CT &,CT &) const124     virtual void inv(P const& , CT const& , CT const& , CT& , CT& ) const
125     {
126         BOOST_THROW_EXCEPTION(projection_not_invertible_exception(this->name()));
127     }
128 
129 protected:
prj() const130     Prj const& prj() const { return *this; }
131 };
132 
133 // Forward/inverse
134 template <typename Prj, typename CT, typename P>
135 class dynamic_wrapper_fi : public dynamic_wrapper_f<Prj, CT, P>
136 {
137     typedef dynamic_wrapper_f<Prj, CT, P> base_t;
138 
139 public:
140     template <typename Params>
dynamic_wrapper_fi(Params const & params,P const & par)141     dynamic_wrapper_fi(Params const& params, P const& par)
142         : base_t(params, par)
143     {}
144 
145     template <typename Params, typename P3>
dynamic_wrapper_fi(Params const & params,P const & par,P3 const & p3)146     dynamic_wrapper_fi(Params const& params, P const& par, P3 const& p3)
147         : base_t(params, par, p3)
148     {}
149 
inv(P const & par,CT const & xy_x,CT const & xy_y,CT & lp_lon,CT & lp_lat) const150     virtual void inv(P const& par, CT const& xy_x, CT const& xy_y, CT& lp_lon, CT& lp_lat) const
151     {
152         this->prj().inv(par, xy_x, xy_y, lp_lon, lp_lat);
153     }
154 };
155 
156 } // namespace detail
157 #endif // DOXYGEN_NO_DETAIL
158 
159 }}} // namespace boost::geometry::projections
160 
161 #endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_DYNAMIC_HPP
162