mapping_ssf.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // This file was modified by Oracle on 2014, 2017.
  4. // Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
  5. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  6. // Use, modification and distribution is subject to the Boost Software License,
  7. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_MAPPING_SSF_HPP
  10. #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_MAPPING_SSF_HPP
  11. #include <boost/core/ignore_unused.hpp>
  12. #include <boost/geometry/core/radius.hpp>
  13. #include <boost/geometry/util/math.hpp>
  14. #include <boost/geometry/util/promote_floating_point.hpp>
  15. #include <boost/geometry/util/select_calculation_type.hpp>
  16. #include <boost/geometry/strategies/side.hpp>
  17. #include <boost/geometry/strategies/spherical/ssf.hpp>
  18. namespace boost { namespace geometry
  19. {
  20. namespace strategy { namespace side
  21. {
  22. // An enumeration type defining types of mapping of geographical
  23. // latitude to spherical latitude.
  24. // See: http://en.wikipedia.org/wiki/Great_ellipse
  25. // http://en.wikipedia.org/wiki/Latitude#Auxiliary_latitudes
  26. enum mapping_type { mapping_geodetic, mapping_reduced, mapping_geocentric };
  27. #ifndef DOXYGEN_NO_DETAIL
  28. namespace detail
  29. {
  30. template <typename Spheroid, mapping_type Mapping>
  31. struct mapper
  32. {
  33. explicit inline mapper(Spheroid const& /*spheroid*/) {}
  34. template <typename CalculationType>
  35. static inline CalculationType const& apply(CalculationType const& lat)
  36. {
  37. return lat;
  38. }
  39. };
  40. template <typename Spheroid>
  41. struct mapper<Spheroid, mapping_reduced>
  42. {
  43. typedef typename promote_floating_point
  44. <
  45. typename radius_type<Spheroid>::type
  46. >::type fraction_type;
  47. explicit inline mapper(Spheroid const& spheroid)
  48. {
  49. fraction_type const a = geometry::get_radius<0>(spheroid);
  50. fraction_type const b = geometry::get_radius<2>(spheroid);
  51. b_div_a = b / a;
  52. }
  53. template <typename CalculationType>
  54. inline CalculationType apply(CalculationType const& lat) const
  55. {
  56. return atan(static_cast<CalculationType>(b_div_a) * tan(lat));
  57. }
  58. fraction_type b_div_a;
  59. };
  60. template <typename Spheroid>
  61. struct mapper<Spheroid, mapping_geocentric>
  62. {
  63. typedef typename promote_floating_point
  64. <
  65. typename radius_type<Spheroid>::type
  66. >::type fraction_type;
  67. explicit inline mapper(Spheroid const& spheroid)
  68. {
  69. fraction_type const a = geometry::get_radius<0>(spheroid);
  70. fraction_type const b = geometry::get_radius<2>(spheroid);
  71. sqr_b_div_a = b / a;
  72. sqr_b_div_a *= sqr_b_div_a;
  73. }
  74. template <typename CalculationType>
  75. inline CalculationType apply(CalculationType const& lat) const
  76. {
  77. return atan(static_cast<CalculationType>(sqr_b_div_a) * tan(lat));
  78. }
  79. fraction_type sqr_b_div_a;
  80. };
  81. }
  82. #endif // DOXYGEN_NO_DETAIL
  83. /*!
  84. \brief Check at which side of a geographical segment a point lies
  85. left of segment (> 0), right of segment (< 0), on segment (0).
  86. The check is performed by mapping the geographical coordinates
  87. to spherical coordinates and using spherical_side_formula.
  88. \ingroup strategies
  89. \tparam Spheroid The reference spheroid model
  90. \tparam Mapping The type of mapping of geographical to spherical latitude
  91. \tparam CalculationType \tparam_calculation
  92. */
  93. template <typename Spheroid,
  94. mapping_type Mapping = mapping_geodetic,
  95. typename CalculationType = void>
  96. class mapping_spherical_side_formula
  97. {
  98. public :
  99. inline mapping_spherical_side_formula()
  100. : m_mapper(Spheroid())
  101. {}
  102. explicit inline mapping_spherical_side_formula(Spheroid const& spheroid)
  103. : m_mapper(spheroid)
  104. {}
  105. template <typename P1, typename P2, typename P>
  106. inline int apply(P1 const& p1, P2 const& p2, P const& p) const
  107. {
  108. typedef typename promote_floating_point
  109. <
  110. typename select_calculation_type_alt
  111. <
  112. CalculationType,
  113. P1, P2, P
  114. >::type
  115. >::type calculation_type;
  116. calculation_type lon1 = get_as_radian<0>(p1);
  117. calculation_type lat1 = m_mapper.template apply<calculation_type>(get_as_radian<1>(p1));
  118. calculation_type lon2 = get_as_radian<0>(p2);
  119. calculation_type lat2 = m_mapper.template apply<calculation_type>(get_as_radian<1>(p2));
  120. calculation_type lon = get_as_radian<0>(p);
  121. calculation_type lat = m_mapper.template apply<calculation_type>(get_as_radian<1>(p));
  122. return detail::spherical_side_formula(lon1, lat1, lon2, lat2, lon, lat);
  123. }
  124. private:
  125. side::detail::mapper<Spheroid, Mapping> const m_mapper;
  126. };
  127. // The specialization for geodetic latitude which can be used directly
  128. template <typename Spheroid,
  129. typename CalculationType>
  130. class mapping_spherical_side_formula<Spheroid, mapping_geodetic, CalculationType>
  131. {
  132. public :
  133. inline mapping_spherical_side_formula() {}
  134. explicit inline mapping_spherical_side_formula(Spheroid const& /*spheroid*/) {}
  135. template <typename P1, typename P2, typename P>
  136. static inline int apply(P1 const& p1, P2 const& p2, P const& p)
  137. {
  138. return spherical_side_formula<CalculationType>::apply(p1, p2, p);
  139. }
  140. };
  141. }} // namespace strategy::side
  142. }} // namespace boost::geometry
  143. #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_MAPPING_SSF_HPP