• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry
2 // Unit Test
3 
4 // Copyright (c) 2017-2018, Oracle and/or its affiliates.
5 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
6 
7 // Use, modification and distribution is subject to the Boost Software License,
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 
11 
12 #include <geometry_test_common.hpp>
13 
14 #include <iostream>
15 
16 #include <boost/geometry/srs/projection.hpp>
17 
18 #include "projection_selftest_cases.hpp"
19 #include "proj4.hpp"
20 
21 
test_projection(std::string const & id,std::string const & parameters,const LL * fwd_in,const XY * fwd_expected,const XY * inv_in,const LL * inv_expected)22 void test_projection(std::string const& id, std::string const& parameters,
23                      const LL * fwd_in, const XY * fwd_expected,
24                      const XY * inv_in, const LL * inv_expected)
25 {
26     bg::srs::projection<> prj = bg::srs::proj4(parameters);
27 
28 #ifdef TEST_WITH_PROJ4
29     pj_projection pj_par(parameters);
30 #endif
31 
32     for (std::size_t i = 0 ; i < 4 ; ++i)
33     {
34         if (bg::get<0>(fwd_expected[i]) == HUGE_VAL)
35             break;
36 
37         {
38             XY fwd_out;
39             prj.forward(fwd_in[i], fwd_out);
40 
41             bool fwd_eq = bg::math::abs(bg::get<0>(fwd_out) - bg::get<0>(fwd_expected[i])) < 1e-7
42                        && bg::math::abs(bg::get<1>(fwd_out) - bg::get<1>(fwd_expected[i])) < 1e-7;
43 
44             BOOST_CHECK_MESSAGE((fwd_eq),
45                                 std::setprecision(16) << "Result of " << id << " forward projection {"
46                                 << bg::wkt(fwd_out) << "} different than expected {"
47                                 << bg::wkt(fwd_expected[i]) << "}");
48 
49 #ifdef TEST_WITH_PROJ4
50             {
51                 XY pj_xy;
52                 pj_par.forward(fwd_in[i], pj_xy);
53                 double d1 = bg::math::abs(bg::get<0>(fwd_out) - bg::get<0>(pj_xy));
54                 double d2 = bg::math::abs(bg::get<1>(fwd_out) - bg::get<1>(pj_xy));
55                 double d = (std::max)(d1, d2);
56                 bool same_as_pj = d < 1e-15;
57                 BOOST_CHECK_MESSAGE((same_as_pj),
58                                     std::setprecision(16) << "Result of " << id << " forward projection {"
59                                     << bg::wkt(fwd_out) << "} different than Proj4 {"
60                                     << bg::wkt(pj_xy) << "} by " << d);
61             }
62 #endif
63         }
64 
65         if (bg::get<0>(inv_expected[i]) == HUGE_VAL)
66             break;
67 
68         {
69             LL inv_out;
70             prj.inverse(inv_in[i], inv_out);
71 
72             bool inv_eq = bg::math::abs(bg::get<0>(inv_out) - bg::get<0>(inv_expected[i])) < 1e-7
73                        && bg::math::abs(bg::get<1>(inv_out) - bg::get<1>(inv_expected[i])) < 1e-7;
74 
75             BOOST_CHECK_MESSAGE((inv_eq),
76                                 std::setprecision(16) << "Result of " << id << " inverse projection {"
77                                 << bg::wkt(inv_out) << "} different than expected {"
78                                 << bg::wkt(inv_expected[i]) << "}");
79 
80 #ifdef TEST_WITH_PROJ4
81             {
82                 LL pj_ll;
83                 pj_par.inverse(inv_in[i], pj_ll);
84                 double d1 = bg::math::abs(bg::get<0>(inv_out) - bg::get<0>(pj_ll));
85                 double d2 = bg::math::abs(bg::get<1>(inv_out) - bg::get<1>(pj_ll));
86                 double d = (std::max)(d1, d2);
87                 bool same_as_pj = d < 1e-15;
88                 BOOST_CHECK_MESSAGE((same_as_pj),
89                                     std::setprecision(16) << "Result of " << id << " inverse projection {"
90                                     << bg::wkt(inv_out) << "} different than Proj4 {"
91                                     << bg::wkt(pj_ll) << "} by " << d);
92             }
93 #endif
94         }
95     }
96 }
97 
test_projections(const projection_case * cases,std::size_t n)98 void test_projections(const projection_case * cases, std::size_t n)
99 {
100     for (std::size_t i = 0 ; i < n ; ++i)
101     {
102         projection_case const& pcas = cases[i];
103 
104         test_projection(pcas.id, pcas.args,
105                         pcas.fwd_in, pcas.fwd_expect,
106                         pcas.inv_in, pcas.inv_expect);
107     }
108 }
109 
test_main(int,char * [])110 int test_main(int, char*[])
111 {
112     test_projections(projection_cases, sizeof(projection_cases)/sizeof(projection_case));
113 
114     return 0;
115 }
116