point_order.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Boost.Geometry
  2. // Copyright (c) 2019, Oracle and/or its affiliates.
  3. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  4. // Licensed under the Boost Software License version 1.0.
  5. // http://www.boost.org/users/license.html
  6. #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_POINT_ORDER_HPP
  7. #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_POINT_ORDER_HPP
  8. #include <boost/geometry/core/tags.hpp>
  9. #include <boost/geometry/srs/spheroid.hpp>
  10. #include <boost/geometry/strategies/geographic/parameters.hpp>
  11. #include <boost/geometry/strategies/point_order.hpp>
  12. #include <boost/geometry/strategies/spherical/point_in_point.hpp>
  13. #include <boost/geometry/util/math.hpp>
  14. #include <boost/geometry/util/select_calculation_type.hpp>
  15. namespace boost { namespace geometry
  16. {
  17. namespace strategy { namespace point_order
  18. {
  19. template
  20. <
  21. typename FormulaPolicy = strategy::andoyer,
  22. typename Spheroid = srs::spheroid<double>,
  23. typename CalculationType = void
  24. >
  25. struct geographic
  26. {
  27. typedef azimuth_tag version_tag;
  28. template <typename Geometry>
  29. struct result_type
  30. {
  31. typedef typename geometry::select_calculation_type_alt
  32. <
  33. CalculationType, Geometry
  34. >::type type;
  35. };
  36. geographic()
  37. {}
  38. explicit geographic(Spheroid const& spheroid)
  39. : m_spheroid(spheroid)
  40. {}
  41. template <typename Point>
  42. inline bool apply(Point const& p1, Point const& p2,
  43. typename result_type<Point>::type & azi,
  44. typename result_type<Point>::type & razi) const
  45. {
  46. typedef typename result_type<Point>::type calc_t;
  47. if (equals_point_point(p1, p2))
  48. {
  49. return false;
  50. }
  51. formula::result_inverse<calc_t> res = FormulaPolicy::template inverse
  52. <
  53. calc_t, false, true, true, false, false
  54. >::apply(geometry::get_as_radian<0>(p1),
  55. geometry::get_as_radian<1>(p1),
  56. geometry::get_as_radian<0>(p2),
  57. geometry::get_as_radian<1>(p2),
  58. m_spheroid);
  59. azi = res.azimuth;
  60. razi = res.reverse_azimuth;
  61. return true;
  62. }
  63. template <typename Point>
  64. inline typename result_type<Point>::type
  65. apply(Point const& /*p0*/, Point const& /*p1*/, Point const& /*p2*/,
  66. typename result_type<Point>::type const& azi1,
  67. typename result_type<Point>::type const& azi2) const
  68. {
  69. // TODO: support poles
  70. return math::longitude_distance_signed<radian>(azi1, azi2);
  71. }
  72. private:
  73. template <typename Point>
  74. static bool equals_point_point(Point const& p0, Point const& p1)
  75. {
  76. return strategy::within::spherical_point_point::apply(p0, p1);
  77. }
  78. Spheroid m_spheroid;
  79. };
  80. namespace services
  81. {
  82. template <>
  83. struct default_strategy<geographic_tag>
  84. {
  85. typedef geographic<> type;
  86. };
  87. } // namespace services
  88. }} // namespace strategy::point_order
  89. }} // namespace boost::geometry
  90. #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_POINT_ORDER_HPP