thomas.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  5. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  6. // This file was modified by Oracle on 2015, 2017.
  7. // Modifications copyright (c) 2015-2017 Oracle and/or its affiliates.
  8. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  9. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  10. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  11. // Use, modification and distribution is subject to the Boost Software License,
  12. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  13. // http://www.boost.org/LICENSE_1_0.txt)
  14. #include <geometry_test_common.hpp>
  15. #include <boost/concept_check.hpp>
  16. #include <boost/geometry/algorithms/assign.hpp>
  17. #include <boost/geometry/algorithms/distance.hpp>
  18. #include <boost/geometry/geometries/point.hpp>
  19. #include <boost/geometry/srs/spheroid.hpp>
  20. #include <boost/geometry/strategies/concepts/distance_concept.hpp>
  21. #include <boost/geometry/strategies/geographic/distance_thomas.hpp>
  22. #include <boost/geometry/strategies/geographic/side_thomas.hpp>
  23. #include <test_common/test_point.hpp>
  24. #ifdef HAVE_TTMATH
  25. # include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
  26. #endif
  27. template <typename P1, typename P2>
  28. void test_distance(double lon1, double lat1, double lon2, double lat2, double expected_km)
  29. {
  30. // Set radius type, but for integer coordinates we want to have floating point radius type
  31. typedef typename bg::promote_floating_point
  32. <
  33. typename bg::coordinate_type<P1>::type
  34. >::type rtype;
  35. typedef bg::srs::spheroid<rtype> stype;
  36. typedef bg::strategy::distance::thomas<stype> thomas_type;
  37. typedef bg::strategy::distance::geographic<bg::strategy::thomas, stype> geographic_type;
  38. BOOST_CONCEPT_ASSERT
  39. (
  40. (bg::concepts::PointDistanceStrategy<thomas_type, P1, P2>)
  41. );
  42. thomas_type thomas;
  43. geographic_type geographic;
  44. typedef typename bg::strategy::distance
  45. ::services::return_type<thomas_type, P1, P2>::type return_type;
  46. P1 p1;
  47. P2 p2;
  48. bg::assign_values(p1, lon1, lat1);
  49. bg::assign_values(p2, lon2, lat2);
  50. BOOST_CHECK_CLOSE(thomas.apply(p1, p2), return_type(1000.0 * expected_km), 0.001);
  51. BOOST_CHECK_CLOSE(geographic.apply(p1, p2), return_type(1000.0 * expected_km), 0.001);
  52. BOOST_CHECK_CLOSE(bg::distance(p1, p2, thomas), return_type(1000.0 * expected_km), 0.001);
  53. }
  54. template <typename PS, typename P>
  55. void test_side(double lon1, double lat1,
  56. double lon2, double lat2,
  57. double lon, double lat,
  58. int expected_side)
  59. {
  60. // Set radius type, but for integer coordinates we want to have floating point radius type
  61. typedef typename bg::promote_floating_point
  62. <
  63. typename bg::coordinate_type<PS>::type
  64. >::type rtype;
  65. typedef bg::srs::spheroid<rtype> stype;
  66. typedef bg::strategy::side::thomas<stype> strategy_type;
  67. typedef bg::strategy::side::geographic<bg::strategy::thomas, stype> strategy2_type;
  68. strategy_type strategy;
  69. strategy2_type strategy2;
  70. PS p1, p2;
  71. P p;
  72. bg::assign_values(p1, lon1, lat1);
  73. bg::assign_values(p2, lon2, lat2);
  74. bg::assign_values(p, lon, lat);
  75. int side = strategy.apply(p1, p2, p);
  76. int side2 = strategy2.apply(p1, p2, p);
  77. BOOST_CHECK_EQUAL(side, expected_side);
  78. BOOST_CHECK_EQUAL(side2, expected_side);
  79. }
  80. template <typename P1, typename P2>
  81. void test_all()
  82. {
  83. test_distance<P1, P2>(0, 90, 1, 80, 1116.825795); // polar
  84. test_distance<P1, P2>(0, -90, 1, -80, 1116.825795); // polar
  85. test_distance<P1, P2>(4, 52, 4, 52, 0.0); // no point difference
  86. test_distance<P1, P2>(4, 52, 3, 40, 1336.025365); // normal case
  87. test_side<P1, P2>(0, 0, 0, 1, 0, 2, 0);
  88. test_side<P1, P2>(0, 0, 0, 1, 0, -2, 0);
  89. test_side<P1, P2>(10, 0, 10, 1, 10, 2, 0);
  90. test_side<P1, P2>(10, 0, 10, -1, 10, 2, 0);
  91. test_side<P1, P2>(10, 0, 10, 1, 0, 2, 1); // left
  92. test_side<P1, P2>(10, 0, 10, -1, 0, 2, -1); // right
  93. test_side<P1, P2>(-10, -10, 10, 10, 10, 0, -1); // right
  94. test_side<P1, P2>(-10, -10, 10, 10, -10, 0, 1); // left
  95. test_side<P1, P2>(170, -10, -170, 10, -170, 0, -1); // right
  96. test_side<P1, P2>(170, -10, -170, 10, 170, 0, 1); // left
  97. }
  98. template <typename P>
  99. void test_all()
  100. {
  101. test_all<P, P>();
  102. }
  103. int test_main(int, char* [])
  104. {
  105. //test_all<float[2]>();
  106. //test_all<double[2]>();
  107. test_all<bg::model::point<int, 2, bg::cs::geographic<bg::degree> > >();
  108. test_all<bg::model::point<float, 2, bg::cs::geographic<bg::degree> > >();
  109. test_all<bg::model::point<double, 2, bg::cs::geographic<bg::degree> > >();
  110. #if defined(HAVE_TTMATH)
  111. test_all<bg::model::point<ttmath::Big<1,4>, 2, bg::cs::geographic<bg::degree> > >();
  112. test_all<bg::model::point<ttmath_big, 2, bg::cs::geographic<bg::degree> > >();
  113. #endif
  114. return 0;
  115. }