Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / geometry / test / srs / proj4.hpp
index 436db11..10a7f4d 100644 (file)
 #ifndef BOOST_GEOMETRY_TEST_SRS_PROJ4_HPP
 #define BOOST_GEOMETRY_TEST_SRS_PROJ4_HPP
 
-#ifdef TEST_WITH_PROJ4
-
 #include <string>
 
 #include <boost/geometry/core/access.hpp>
 #include <boost/geometry/core/radian_access.hpp>
 
+#if defined(TEST_WITH_PROJ6)
+#define TEST_WITH_PROJ5
+#endif
+
+#if defined(TEST_WITH_PROJ5)
+#define TEST_WITH_PROJ4
+
+#include <proj.h>
+
+#endif
+
+#if defined(TEST_WITH_PROJ4)
+#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
+
 #include <proj_api.h>
 
 struct pj_ptr
 {
-    explicit pj_ptr(projPJ ptr)
+    explicit pj_ptr(projPJ ptr = NULL)
         : m_ptr(ptr)
+    {}
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    pj_ptr(pj_ptr && other)
+        : m_ptr(other.m_ptr)
+    {
+        other.m_ptr = NULL;
+    }
+
+    pj_ptr & operator=(pj_ptr && other)
     {
-        if (ptr == NULL)
-            throw std::runtime_error("bleh");
+        if (m_ptr)
+            pj_free(m_ptr);
+        m_ptr = other.m_ptr;
+        other.m_ptr = NULL;
+        return *this;
     }
+#endif
 
     projPJ get() const
     {
@@ -40,9 +66,12 @@ struct pj_ptr
     }
 
 private:
+    pj_ptr(pj_ptr const&);
+    pj_ptr & operator=(pj_ptr const&);
+
     projPJ m_ptr;
 };
-
+/*
 struct pj_projection
 {
     pj_projection(std::string const& prj)
@@ -87,7 +116,7 @@ struct pj_projection
 
 private:
     pj_ptr m_ptr;
-};
+};*/
 
 struct pj_transformation
 {
@@ -96,25 +125,13 @@ struct pj_transformation
         , m_to(pj_init_plus(to.c_str()))
     {}
 
-    template <typename In, typename Out>
-    void forward(In const& in, Out & out) const
-    {
-        double x = boost::geometry::get_as_radian<0>(in);
-        double y = boost::geometry::get_as_radian<1>(in);
-    
-        pj_transform(m_from.get(), m_to.get(), 1, 0, &x, &y, NULL);
-
-        boost::geometry::set_from_radian<0>(out, x);
-        boost::geometry::set_from_radian<1>(out, y);
-    }
-
     void forward(std::vector<double> in_x,
                  std::vector<double> in_y,
                  std::vector<double> & out_x,
                  std::vector<double> & out_y) const
     {
         assert(in_x.size() == in_y.size());
-        pj_transform(m_from.get(), m_to.get(), in_x.size(), 1, &in_x[0], &in_y[0], NULL);
+        pj_transform(m_from.get(), m_to.get(), (long)in_x.size(), 1, &in_x[0], &in_y[0], NULL);
         out_x = std::move(in_x);
         out_y = std::move(in_y);
     }
@@ -123,7 +140,7 @@ struct pj_transformation
                  std::vector<double> & out_xy) const
     {
         assert(in_xy.size() % 2 == 0);
-        pj_transform(m_from.get(), m_to.get(), in_xy.size() / 2, 2, &in_xy[0], &in_xy[1], NULL);
+        pj_transform(m_from.get(), m_to.get(), (long)in_xy.size() / 2, 2, &in_xy[0], &in_xy[1], NULL);
         out_xy = std::move(in_xy);
     }
 
@@ -135,11 +152,179 @@ struct pj_transformation
             forward(in_xy[i], out_xy[i]);
     }
 
+    template <typename In, typename Out>
+    void forward(In const& in, Out & out,
+                 typename boost::enable_if_c
+                    <
+                        boost::is_same
+                            <
+                                typename boost::geometry::tag<In>::type,
+                                boost::geometry::point_tag
+                            >::value
+                    >::type* dummy = 0) const
+    {
+        transform_point(in, out, m_from, m_to);
+    }
+
+    template <typename In, typename Out>
+    void inverse(In const& in, Out & out,
+                 typename boost::enable_if_c
+                    <
+                        boost::is_same
+                            <
+                                typename boost::geometry::tag<In>::type,
+                                boost::geometry::point_tag
+                            >::value
+                    >::type* dummy = 0) const
+    {
+        transform_point(in, out, m_to, m_from);
+    }
+
 private:
+    template <typename In, typename Out>
+    static void transform_point(In const& in, Out & out,
+                                pj_ptr const& from, pj_ptr const& to)
+    {
+        double x = boost::geometry::get_as_radian<0>(in);
+        double y = boost::geometry::get_as_radian<1>(in);
+
+        pj_transform(from.get(), to.get(), 1, 0, &x, &y, NULL);
+
+        boost::geometry::set_from_radian<0>(out, x);
+        boost::geometry::set_from_radian<1>(out, y);
+    }
+
     pj_ptr m_from;
     pj_ptr m_to;
 };
 
 #endif // TEST_WITH_PROJ4
 
+#if defined(TEST_WITH_PROJ5)
+
+struct proj5_ptr
+{
+    explicit proj5_ptr(PJ *ptr = NULL)
+        : m_ptr(ptr)
+    {}
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    proj5_ptr(proj5_ptr && other)
+        : m_ptr(other.m_ptr)
+    {
+        other.m_ptr = NULL;
+    }
+
+    proj5_ptr & operator=(proj5_ptr && other)
+    {
+        if (m_ptr)
+            proj_destroy(m_ptr);
+        m_ptr = other.m_ptr;
+        other.m_ptr = NULL;
+        return *this;
+    }
+#endif
+
+    PJ *get() const
+    {
+        return m_ptr;
+    }
+
+    ~proj5_ptr()
+    {
+        if (m_ptr)
+            proj_destroy(m_ptr);
+    }
+
+private:
+    proj5_ptr(proj5_ptr const&);
+    proj5_ptr & operator=(proj5_ptr const&);
+
+    PJ *m_ptr;
+};
+
+struct proj5_transformation
+{
+    proj5_transformation(std::string const& to)
+        : m_proj(proj_create(PJ_DEFAULT_CTX, to.c_str()))
+    {}
+
+    void forward(std::vector<PJ_COORD> in,
+                 std::vector<PJ_COORD> & out) const
+    {
+        proj_trans_array(m_proj.get(), PJ_FWD, in.size(), &in[0]);
+        out = std::move(in);
+    }
+
+    template <typename In, typename Out>
+    void forward(In const& in, Out & out,
+                 typename boost::enable_if_c
+                    <
+                        boost::is_same
+                            <
+                                typename boost::geometry::tag<In>::type,
+                                boost::geometry::point_tag
+                            >::value
+                    >::type* dummy = 0) const
+    {
+        PJ_COORD c;
+        c.lp.lam = boost::geometry::get_as_radian<0>(in);
+        c.lp.phi = boost::geometry::get_as_radian<1>(in);
+
+        c = proj_trans(m_proj.get(), PJ_FWD, c);
+
+        boost::geometry::set_from_radian<0>(out, c.xy.x);
+        boost::geometry::set_from_radian<1>(out, c.xy.y);
+    }
+
+private:
+    proj5_ptr m_proj;
+};
+
+#endif // TEST_WITH_PROJ5
+
+#if defined(TEST_WITH_PROJ6)
+
+struct proj6_transformation
+{
+    proj6_transformation(std::string const& from, std::string const& to)
+        : m_proj(proj_create_crs_to_crs(PJ_DEFAULT_CTX, from.c_str(), to.c_str(), NULL))
+    {
+        //proj_normalize_for_visualization(0, m_proj.get());
+    }
+
+    void forward(std::vector<PJ_COORD> in,
+                 std::vector<PJ_COORD> & out) const
+    {
+        proj_trans_array(m_proj.get(), PJ_FWD, in.size(), &in[0]);
+        out = std::move(in);
+    }
+
+    template <typename In, typename Out>
+    void forward(In const& in, Out & out,
+                 typename boost::enable_if_c
+                    <
+                        boost::is_same
+                            <
+                                typename boost::geometry::tag<In>::type,
+                                boost::geometry::point_tag
+                            >::value
+                    >::type* dummy = 0) const
+    {
+        PJ_COORD c;
+        c.lp.lam = boost::geometry::get_as_radian<0>(in);
+        c.lp.phi = boost::geometry::get_as_radian<1>(in);
+
+        c = proj_trans(m_proj.get(), PJ_FWD, c);
+
+        boost::geometry::set_from_radian<0>(out, c.xy.x);
+        boost::geometry::set_from_radian<1>(out, c.xy.y);
+    }
+
+private:
+    proj5_ptr m_proj;
+};
+
+#endif // TEST_WITH_PROJ6
+
 #endif // BOOST_GEOMETRY_TEST_SRS_PROJ4_HPP