proj4.hpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. // Boost.Geometry
  2. // Copyright (c) 2017-2019, Oracle and/or its affiliates.
  3. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  4. // Use, modification and distribution is subject to the Boost Software License,
  5. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_GEOMETRY_TEST_SRS_PROJ4_HPP
  8. #define BOOST_GEOMETRY_TEST_SRS_PROJ4_HPP
  9. #include <string>
  10. #include <boost/geometry/core/access.hpp>
  11. #include <boost/geometry/core/radian_access.hpp>
  12. #if defined(TEST_WITH_PROJ6)
  13. #define TEST_WITH_PROJ5
  14. #endif
  15. #if defined(TEST_WITH_PROJ5)
  16. #define TEST_WITH_PROJ4
  17. #include <proj.h>
  18. #endif
  19. #if defined(TEST_WITH_PROJ4)
  20. #define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
  21. #include <proj_api.h>
  22. struct pj_ptr
  23. {
  24. explicit pj_ptr(projPJ ptr = NULL)
  25. : m_ptr(ptr)
  26. {}
  27. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  28. pj_ptr(pj_ptr && other)
  29. : m_ptr(other.m_ptr)
  30. {
  31. other.m_ptr = NULL;
  32. }
  33. pj_ptr & operator=(pj_ptr && other)
  34. {
  35. if (m_ptr)
  36. pj_free(m_ptr);
  37. m_ptr = other.m_ptr;
  38. other.m_ptr = NULL;
  39. return *this;
  40. }
  41. #endif
  42. projPJ get() const
  43. {
  44. return m_ptr;
  45. }
  46. ~pj_ptr()
  47. {
  48. if (m_ptr)
  49. pj_free(m_ptr);
  50. }
  51. private:
  52. pj_ptr(pj_ptr const&);
  53. pj_ptr & operator=(pj_ptr const&);
  54. projPJ m_ptr;
  55. };
  56. /*
  57. struct pj_projection
  58. {
  59. pj_projection(std::string const& prj)
  60. : m_ptr(pj_init_plus(prj.c_str()))
  61. {}
  62. template <typename In, typename Out>
  63. void forward(In const& in, Out & out) const
  64. {
  65. double x = boost::geometry::get_as_radian<0>(in);
  66. double y = boost::geometry::get_as_radian<1>(in);
  67. projUV p1;
  68. projUV p2;
  69. p1.u = x;
  70. p1.v = y;
  71. p2 = pj_fwd(p1, m_ptr.get());
  72. boost::geometry::set_from_radian<0>(out, p2.u);
  73. boost::geometry::set_from_radian<1>(out, p2.v);
  74. }
  75. template <typename In, typename Out>
  76. void inverse(In const& in, Out & out) const
  77. {
  78. double lon = boost::geometry::get_as_radian<0>(in);
  79. double lat = boost::geometry::get_as_radian<1>(in);
  80. projUV p1;
  81. projUV p2;
  82. p1.u = lon;
  83. p1.v = lat;
  84. p2 = pj_inv(p1, m_ptr.get());
  85. boost::geometry::set_from_radian<0>(out, p2.u);
  86. boost::geometry::set_from_radian<1>(out, p2.v);
  87. }
  88. private:
  89. pj_ptr m_ptr;
  90. };*/
  91. struct pj_transformation
  92. {
  93. pj_transformation(std::string const& from, std::string const& to)
  94. : m_from(pj_init_plus(from.c_str()))
  95. , m_to(pj_init_plus(to.c_str()))
  96. {}
  97. void forward(std::vector<double> in_x,
  98. std::vector<double> in_y,
  99. std::vector<double> & out_x,
  100. std::vector<double> & out_y) const
  101. {
  102. assert(in_x.size() == in_y.size());
  103. pj_transform(m_from.get(), m_to.get(), (long)in_x.size(), 1, &in_x[0], &in_y[0], NULL);
  104. out_x = std::move(in_x);
  105. out_y = std::move(in_y);
  106. }
  107. void forward(std::vector<double> in_xy,
  108. std::vector<double> & out_xy) const
  109. {
  110. assert(in_xy.size() % 2 == 0);
  111. pj_transform(m_from.get(), m_to.get(), (long)in_xy.size() / 2, 2, &in_xy[0], &in_xy[1], NULL);
  112. out_xy = std::move(in_xy);
  113. }
  114. void forward(std::vector<std::vector<double> > const& in_xy,
  115. std::vector<std::vector<double> > & out_xy) const
  116. {
  117. out_xy.resize(in_xy.size());
  118. for (size_t i = 0 ; i < in_xy.size(); ++i)
  119. forward(in_xy[i], out_xy[i]);
  120. }
  121. template <typename In, typename Out>
  122. void forward(In const& in, Out & out,
  123. typename boost::enable_if_c
  124. <
  125. boost::is_same
  126. <
  127. typename boost::geometry::tag<In>::type,
  128. boost::geometry::point_tag
  129. >::value
  130. >::type* dummy = 0) const
  131. {
  132. transform_point(in, out, m_from, m_to);
  133. }
  134. template <typename In, typename Out>
  135. void inverse(In const& in, Out & out,
  136. typename boost::enable_if_c
  137. <
  138. boost::is_same
  139. <
  140. typename boost::geometry::tag<In>::type,
  141. boost::geometry::point_tag
  142. >::value
  143. >::type* dummy = 0) const
  144. {
  145. transform_point(in, out, m_to, m_from);
  146. }
  147. private:
  148. template <typename In, typename Out>
  149. static void transform_point(In const& in, Out & out,
  150. pj_ptr const& from, pj_ptr const& to)
  151. {
  152. double x = boost::geometry::get_as_radian<0>(in);
  153. double y = boost::geometry::get_as_radian<1>(in);
  154. pj_transform(from.get(), to.get(), 1, 0, &x, &y, NULL);
  155. boost::geometry::set_from_radian<0>(out, x);
  156. boost::geometry::set_from_radian<1>(out, y);
  157. }
  158. pj_ptr m_from;
  159. pj_ptr m_to;
  160. };
  161. #endif // TEST_WITH_PROJ4
  162. #if defined(TEST_WITH_PROJ5)
  163. struct proj5_ptr
  164. {
  165. explicit proj5_ptr(PJ *ptr = NULL)
  166. : m_ptr(ptr)
  167. {}
  168. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  169. proj5_ptr(proj5_ptr && other)
  170. : m_ptr(other.m_ptr)
  171. {
  172. other.m_ptr = NULL;
  173. }
  174. proj5_ptr & operator=(proj5_ptr && other)
  175. {
  176. if (m_ptr)
  177. proj_destroy(m_ptr);
  178. m_ptr = other.m_ptr;
  179. other.m_ptr = NULL;
  180. return *this;
  181. }
  182. #endif
  183. PJ *get() const
  184. {
  185. return m_ptr;
  186. }
  187. ~proj5_ptr()
  188. {
  189. if (m_ptr)
  190. proj_destroy(m_ptr);
  191. }
  192. private:
  193. proj5_ptr(proj5_ptr const&);
  194. proj5_ptr & operator=(proj5_ptr const&);
  195. PJ *m_ptr;
  196. };
  197. struct proj5_transformation
  198. {
  199. proj5_transformation(std::string const& to)
  200. : m_proj(proj_create(PJ_DEFAULT_CTX, to.c_str()))
  201. {}
  202. void forward(std::vector<PJ_COORD> in,
  203. std::vector<PJ_COORD> & out) const
  204. {
  205. proj_trans_array(m_proj.get(), PJ_FWD, in.size(), &in[0]);
  206. out = std::move(in);
  207. }
  208. template <typename In, typename Out>
  209. void forward(In const& in, Out & out,
  210. typename boost::enable_if_c
  211. <
  212. boost::is_same
  213. <
  214. typename boost::geometry::tag<In>::type,
  215. boost::geometry::point_tag
  216. >::value
  217. >::type* dummy = 0) const
  218. {
  219. PJ_COORD c;
  220. c.lp.lam = boost::geometry::get_as_radian<0>(in);
  221. c.lp.phi = boost::geometry::get_as_radian<1>(in);
  222. c = proj_trans(m_proj.get(), PJ_FWD, c);
  223. boost::geometry::set_from_radian<0>(out, c.xy.x);
  224. boost::geometry::set_from_radian<1>(out, c.xy.y);
  225. }
  226. private:
  227. proj5_ptr m_proj;
  228. };
  229. #endif // TEST_WITH_PROJ5
  230. #if defined(TEST_WITH_PROJ6)
  231. struct proj6_transformation
  232. {
  233. proj6_transformation(std::string const& from, std::string const& to)
  234. : m_proj(proj_create_crs_to_crs(PJ_DEFAULT_CTX, from.c_str(), to.c_str(), NULL))
  235. {
  236. //proj_normalize_for_visualization(0, m_proj.get());
  237. }
  238. void forward(std::vector<PJ_COORD> in,
  239. std::vector<PJ_COORD> & out) const
  240. {
  241. proj_trans_array(m_proj.get(), PJ_FWD, in.size(), &in[0]);
  242. out = std::move(in);
  243. }
  244. template <typename In, typename Out>
  245. void forward(In const& in, Out & out,
  246. typename boost::enable_if_c
  247. <
  248. boost::is_same
  249. <
  250. typename boost::geometry::tag<In>::type,
  251. boost::geometry::point_tag
  252. >::value
  253. >::type* dummy = 0) const
  254. {
  255. PJ_COORD c;
  256. c.lp.lam = boost::geometry::get_as_radian<0>(in);
  257. c.lp.phi = boost::geometry::get_as_radian<1>(in);
  258. c = proj_trans(m_proj.get(), PJ_FWD, c);
  259. boost::geometry::set_from_radian<0>(out, c.xy.x);
  260. boost::geometry::set_from_radian<1>(out, c.xy.y);
  261. }
  262. private:
  263. proj5_ptr m_proj;
  264. };
  265. #endif // TEST_WITH_PROJ6
  266. #endif // BOOST_GEOMETRY_TEST_SRS_PROJ4_HPP