normalize_spheroidal_box_coordinates.hpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2015-2017, Oracle and/or its affiliates.
  3. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  4. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  5. // Licensed under the Boost Software License version 1.0.
  6. // http://www.boost.org/users/license.html
  7. #ifndef BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
  8. #define BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP
  9. #include <boost/geometry/core/assert.hpp>
  10. #include <boost/geometry/util/math.hpp>
  11. #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
  12. namespace boost { namespace geometry
  13. {
  14. namespace math
  15. {
  16. #ifndef DOXYGEN_NO_DETAIL
  17. namespace detail
  18. {
  19. template <typename Units, typename CoordinateType, bool IsEquatorial = true>
  20. class normalize_spheroidal_box_coordinates
  21. {
  22. private:
  23. typedef normalize_spheroidal_coordinates<Units, CoordinateType> normalize;
  24. typedef constants_on_spheroid<CoordinateType, Units> constants;
  25. static inline bool is_band(CoordinateType const& longitude1,
  26. CoordinateType const& longitude2)
  27. {
  28. return ! math::smaller(math::abs(longitude1 - longitude2),
  29. constants::period());
  30. }
  31. public:
  32. static inline void apply(CoordinateType& longitude1,
  33. CoordinateType& latitude1,
  34. CoordinateType& longitude2,
  35. CoordinateType& latitude2,
  36. bool band)
  37. {
  38. normalize::apply(longitude1, latitude1, false);
  39. normalize::apply(longitude2, latitude2, false);
  40. latitude_convert_if_polar<Units, IsEquatorial>::apply(latitude1);
  41. latitude_convert_if_polar<Units, IsEquatorial>::apply(latitude2);
  42. if (math::equals(latitude1, constants::min_latitude())
  43. && math::equals(latitude2, constants::min_latitude()))
  44. {
  45. // box degenerates to the south pole
  46. longitude1 = longitude2 = CoordinateType(0);
  47. }
  48. else if (math::equals(latitude1, constants::max_latitude())
  49. && math::equals(latitude2, constants::max_latitude()))
  50. {
  51. // box degenerates to the north pole
  52. longitude1 = longitude2 = CoordinateType(0);
  53. }
  54. else if (band)
  55. {
  56. // the box is a band between two small circles (parallel
  57. // to the equator) on the spheroid
  58. longitude1 = constants::min_longitude();
  59. longitude2 = constants::max_longitude();
  60. }
  61. else if (longitude1 > longitude2)
  62. {
  63. // the box crosses the antimeridian, so we need to adjust
  64. // the longitudes
  65. longitude2 += constants::period();
  66. }
  67. latitude_convert_if_polar<Units, IsEquatorial>::apply(latitude1);
  68. latitude_convert_if_polar<Units, IsEquatorial>::apply(latitude2);
  69. #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
  70. BOOST_GEOMETRY_ASSERT(! math::larger(latitude1, latitude2));
  71. BOOST_GEOMETRY_ASSERT(! math::smaller(latitude1, constants::min_latitude()));
  72. BOOST_GEOMETRY_ASSERT(! math::larger(latitude2, constants::max_latitude()));
  73. #endif
  74. BOOST_GEOMETRY_ASSERT(! math::larger(longitude1, longitude2));
  75. BOOST_GEOMETRY_ASSERT(! math::smaller(longitude1, constants::min_longitude()));
  76. BOOST_GEOMETRY_ASSERT
  77. (! math::larger(longitude2 - longitude1, constants::period()));
  78. }
  79. static inline void apply(CoordinateType& longitude1,
  80. CoordinateType& latitude1,
  81. CoordinateType& longitude2,
  82. CoordinateType& latitude2)
  83. {
  84. bool const band = is_band(longitude1, longitude2);
  85. apply(longitude1, latitude1, longitude2, latitude2, band);
  86. }
  87. };
  88. } // namespace detail
  89. #endif // DOXYGEN_NO_DETAIL
  90. /*!
  91. \brief Short utility to normalize the coordinates of a box on a spheroid
  92. \tparam Units The units of the coordindate system in the spheroid
  93. \tparam CoordinateType The type of the coordinates
  94. \param longitude1 Minimum longitude of the box
  95. \param latitude1 Minimum latitude of the box
  96. \param longitude2 Maximum longitude of the box
  97. \param latitude2 Maximum latitude of the box
  98. \ingroup utility
  99. */
  100. template <typename Units, typename CoordinateType>
  101. inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
  102. CoordinateType& latitude1,
  103. CoordinateType& longitude2,
  104. CoordinateType& latitude2)
  105. {
  106. detail::normalize_spheroidal_box_coordinates
  107. <
  108. Units, CoordinateType
  109. >::apply(longitude1, latitude1, longitude2, latitude2);
  110. }
  111. template <typename Units, bool IsEquatorial, typename CoordinateType>
  112. inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
  113. CoordinateType& latitude1,
  114. CoordinateType& longitude2,
  115. CoordinateType& latitude2)
  116. {
  117. detail::normalize_spheroidal_box_coordinates
  118. <
  119. Units, CoordinateType, IsEquatorial
  120. >::apply(longitude1, latitude1, longitude2, latitude2);
  121. }
  122. /*!
  123. \brief Short utility to normalize the coordinates of a box on a spheroid
  124. \tparam Units The units of the coordindate system in the spheroid
  125. \tparam CoordinateType The type of the coordinates
  126. \param longitude1 Minimum longitude of the box
  127. \param latitude1 Minimum latitude of the box
  128. \param longitude2 Maximum longitude of the box
  129. \param latitude2 Maximum latitude of the box
  130. \param band Indicates whether the box should be treated as a band or
  131. not and avoid the computation done in the other version of the function
  132. \ingroup utility
  133. */
  134. template <typename Units, typename CoordinateType>
  135. inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
  136. CoordinateType& latitude1,
  137. CoordinateType& longitude2,
  138. CoordinateType& latitude2,
  139. bool band)
  140. {
  141. detail::normalize_spheroidal_box_coordinates
  142. <
  143. Units, CoordinateType
  144. >::apply(longitude1, latitude1, longitude2, latitude2, band);
  145. }
  146. template <typename Units, bool IsEquatorial, typename CoordinateType>
  147. inline void normalize_spheroidal_box_coordinates(CoordinateType& longitude1,
  148. CoordinateType& latitude1,
  149. CoordinateType& longitude2,
  150. CoordinateType& latitude2,
  151. bool band)
  152. {
  153. detail::normalize_spheroidal_box_coordinates
  154. <
  155. Units, CoordinateType, IsEquatorial
  156. >::apply(longitude1, latitude1, longitude2, latitude2, band);
  157. }
  158. } // namespace math
  159. }} // namespace boost::geometry
  160. #endif // BOOST_GEOMETRY_UTIL_NORMALIZE_SPHEROIDAL_BOX_COORDINATES_HPP