projection_selftest.cpp 4.0 KB

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