3 // Copyright (c) 2017-2019, Oracle and/or its affiliates.
4 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
6 // Use, modification and distribution is subject to the Boost Software License,
7 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
10 #ifndef BOOST_GEOMETRY_TEST_SRS_PROJ4_HPP
11 #define BOOST_GEOMETRY_TEST_SRS_PROJ4_HPP
15 #include <boost/geometry/core/access.hpp>
16 #include <boost/geometry/core/radian_access.hpp>
18 #if defined(TEST_WITH_PROJ6)
19 #define TEST_WITH_PROJ5
22 #if defined(TEST_WITH_PROJ5)
23 #define TEST_WITH_PROJ4
29 #if defined(TEST_WITH_PROJ4)
30 #define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
36 explicit pj_ptr(projPJ ptr = NULL)
40 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
41 pj_ptr(pj_ptr && other)
47 pj_ptr & operator=(pj_ptr && other)
69 pj_ptr(pj_ptr const&);
70 pj_ptr & operator=(pj_ptr const&);
77 pj_projection(std::string const& prj)
78 : m_ptr(pj_init_plus(prj.c_str()))
81 template <typename In, typename Out>
82 void forward(In const& in, Out & out) const
84 double x = boost::geometry::get_as_radian<0>(in);
85 double y = boost::geometry::get_as_radian<1>(in);
93 p2 = pj_fwd(p1, m_ptr.get());
95 boost::geometry::set_from_radian<0>(out, p2.u);
96 boost::geometry::set_from_radian<1>(out, p2.v);
99 template <typename In, typename Out>
100 void inverse(In const& in, Out & out) const
102 double lon = boost::geometry::get_as_radian<0>(in);
103 double lat = boost::geometry::get_as_radian<1>(in);
111 p2 = pj_inv(p1, m_ptr.get());
113 boost::geometry::set_from_radian<0>(out, p2.u);
114 boost::geometry::set_from_radian<1>(out, p2.v);
121 struct pj_transformation
123 pj_transformation(std::string const& from, std::string const& to)
124 : m_from(pj_init_plus(from.c_str()))
125 , m_to(pj_init_plus(to.c_str()))
128 void forward(std::vector<double> in_x,
129 std::vector<double> in_y,
130 std::vector<double> & out_x,
131 std::vector<double> & out_y) const
133 assert(in_x.size() == in_y.size());
134 pj_transform(m_from.get(), m_to.get(), (long)in_x.size(), 1, &in_x[0], &in_y[0], NULL);
135 out_x = std::move(in_x);
136 out_y = std::move(in_y);
139 void forward(std::vector<double> in_xy,
140 std::vector<double> & out_xy) const
142 assert(in_xy.size() % 2 == 0);
143 pj_transform(m_from.get(), m_to.get(), (long)in_xy.size() / 2, 2, &in_xy[0], &in_xy[1], NULL);
144 out_xy = std::move(in_xy);
147 void forward(std::vector<std::vector<double> > const& in_xy,
148 std::vector<std::vector<double> > & out_xy) const
150 out_xy.resize(in_xy.size());
151 for (size_t i = 0 ; i < in_xy.size(); ++i)
152 forward(in_xy[i], out_xy[i]);
155 template <typename In, typename Out>
156 void forward(In const& in, Out & out,
157 typename boost::enable_if_c
161 typename boost::geometry::tag<In>::type,
162 boost::geometry::point_tag
164 >::type* dummy = 0) const
166 transform_point(in, out, m_from, m_to);
169 template <typename In, typename Out>
170 void inverse(In const& in, Out & out,
171 typename boost::enable_if_c
175 typename boost::geometry::tag<In>::type,
176 boost::geometry::point_tag
178 >::type* dummy = 0) const
180 transform_point(in, out, m_to, m_from);
184 template <typename In, typename Out>
185 static void transform_point(In const& in, Out & out,
186 pj_ptr const& from, pj_ptr const& to)
188 double x = boost::geometry::get_as_radian<0>(in);
189 double y = boost::geometry::get_as_radian<1>(in);
191 pj_transform(from.get(), to.get(), 1, 0, &x, &y, NULL);
193 boost::geometry::set_from_radian<0>(out, x);
194 boost::geometry::set_from_radian<1>(out, y);
201 #endif // TEST_WITH_PROJ4
203 #if defined(TEST_WITH_PROJ5)
207 explicit proj5_ptr(PJ *ptr = NULL)
211 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
212 proj5_ptr(proj5_ptr && other)
218 proj5_ptr & operator=(proj5_ptr && other)
240 proj5_ptr(proj5_ptr const&);
241 proj5_ptr & operator=(proj5_ptr const&);
246 struct proj5_transformation
248 proj5_transformation(std::string const& to)
249 : m_proj(proj_create(PJ_DEFAULT_CTX, to.c_str()))
252 void forward(std::vector<PJ_COORD> in,
253 std::vector<PJ_COORD> & out) const
255 proj_trans_array(m_proj.get(), PJ_FWD, in.size(), &in[0]);
259 template <typename In, typename Out>
260 void forward(In const& in, Out & out,
261 typename boost::enable_if_c
265 typename boost::geometry::tag<In>::type,
266 boost::geometry::point_tag
268 >::type* dummy = 0) const
271 c.lp.lam = boost::geometry::get_as_radian<0>(in);
272 c.lp.phi = boost::geometry::get_as_radian<1>(in);
274 c = proj_trans(m_proj.get(), PJ_FWD, c);
276 boost::geometry::set_from_radian<0>(out, c.xy.x);
277 boost::geometry::set_from_radian<1>(out, c.xy.y);
284 #endif // TEST_WITH_PROJ5
286 #if defined(TEST_WITH_PROJ6)
288 struct proj6_transformation
290 proj6_transformation(std::string const& from, std::string const& to)
291 : m_proj(proj_create_crs_to_crs(PJ_DEFAULT_CTX, from.c_str(), to.c_str(), NULL))
293 //proj_normalize_for_visualization(0, m_proj.get());
296 void forward(std::vector<PJ_COORD> in,
297 std::vector<PJ_COORD> & out) const
299 proj_trans_array(m_proj.get(), PJ_FWD, in.size(), &in[0]);
303 template <typename In, typename Out>
304 void forward(In const& in, Out & out,
305 typename boost::enable_if_c
309 typename boost::geometry::tag<In>::type,
310 boost::geometry::point_tag
312 >::type* dummy = 0) const
315 c.lp.lam = boost::geometry::get_as_radian<0>(in);
316 c.lp.phi = boost::geometry::get_as_radian<1>(in);
318 c = proj_trans(m_proj.get(), PJ_FWD, c);
320 boost::geometry::set_from_radian<0>(out, c.xy.x);
321 boost::geometry::set_from_radian<1>(out, c.xy.y);
328 #endif // TEST_WITH_PROJ6
330 #endif // BOOST_GEOMETRY_TEST_SRS_PROJ4_HPP