point_geometry.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // This file was modified by Oracle on 2013-2022.
  4. // Modifications copyright (c) 2013-2022 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_ALGORITHMS_DETAIL_RELATE_POINT_GEOMETRY_HPP
  10. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_GEOMETRY_HPP
  11. #include <boost/geometry/algorithms/detail/relate/result.hpp>
  12. #include <boost/geometry/algorithms/detail/relate/topology_check.hpp>
  13. #include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
  14. #include <boost/geometry/util/condition.hpp>
  15. namespace boost { namespace geometry
  16. {
  17. #ifndef DOXYGEN_NO_DETAIL
  18. namespace detail { namespace relate {
  19. // non-point geometry
  20. template <typename Point, typename Geometry, bool Transpose = false>
  21. struct point_geometry
  22. {
  23. // TODO: interrupt only if the topology check is complex
  24. static const bool interruption_enabled = true;
  25. template <typename Result, typename Strategy>
  26. static inline void apply(Point const& point, Geometry const& geometry, Result & result, Strategy const& strategy)
  27. {
  28. int pig = detail::within::point_in_geometry(point, geometry, strategy);
  29. if ( pig > 0 ) // within
  30. {
  31. update<interior, interior, '0', Transpose>(result);
  32. }
  33. else if ( pig == 0 )
  34. {
  35. update<interior, boundary, '0', Transpose>(result);
  36. }
  37. else // pig < 0 - not within
  38. {
  39. update<interior, exterior, '0', Transpose>(result);
  40. }
  41. update<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
  42. if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
  43. return;
  44. typedef detail::relate::topology_check<Geometry, Strategy> tc_t;
  45. if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
  46. || relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result) )
  47. {
  48. // the point is on the boundary
  49. if ( pig == 0 )
  50. {
  51. // NOTE: even for MLs, if there is at least one boundary point,
  52. // somewhere there must be another one
  53. update<exterior, interior, tc_t::interior, Transpose>(result);
  54. update<exterior, boundary, tc_t::boundary, Transpose>(result);
  55. }
  56. else
  57. {
  58. // check if there is a boundary in Geometry
  59. tc_t tc(geometry, strategy);
  60. if ( tc.has_interior() )
  61. {
  62. update<exterior, interior, tc_t::interior, Transpose>(result);
  63. }
  64. if ( tc.has_boundary() )
  65. {
  66. update<exterior, boundary, tc_t::boundary, Transpose>(result);
  67. }
  68. }
  69. }
  70. }
  71. };
  72. // transposed result of point_geometry
  73. template <typename Geometry, typename Point>
  74. struct geometry_point
  75. {
  76. // TODO: interrupt only if the topology check is complex
  77. static const bool interruption_enabled = true;
  78. template <typename Result, typename Strategy>
  79. static inline void apply(Geometry const& geometry, Point const& point, Result & result, Strategy const& strategy)
  80. {
  81. point_geometry<Point, Geometry, true>::apply(point, geometry, result, strategy);
  82. }
  83. };
  84. // TODO: rewrite the folowing:
  85. //// NOTE: Those tests should be consistent with within(Point, Box) and covered_by(Point, Box)
  86. //// There is no EPS used in those functions, values are compared using < or <=
  87. //// so comparing MIN and MAX in the same way should be fine
  88. //
  89. //template <typename Box, std::size_t I = 0, std::size_t D = geometry::dimension<Box>::value>
  90. //struct box_has_interior
  91. //{
  92. // static inline bool apply(Box const& box)
  93. // {
  94. // return geometry::get<min_corner, I>(box) < geometry::get<max_corner, I>(box)
  95. // && box_has_interior<Box, I + 1, D>::apply(box);
  96. // }
  97. //};
  98. //
  99. //template <typename Box, std::size_t D>
  100. //struct box_has_interior<Box, D, D>
  101. //{
  102. // static inline bool apply(Box const&) { return true; }
  103. //};
  104. //
  105. //// NOTE: especially important here (see the NOTE above).
  106. //
  107. //template <typename Box, std::size_t I = 0, std::size_t D = geometry::dimension<Box>::value>
  108. //struct box_has_equal_min_max
  109. //{
  110. // static inline bool apply(Box const& box)
  111. // {
  112. // return geometry::get<min_corner, I>(box) == geometry::get<max_corner, I>(box)
  113. // && box_has_equal_min_max<Box, I + 1, D>::apply(box);
  114. // }
  115. //};
  116. //
  117. //template <typename Box, std::size_t D>
  118. //struct box_has_equal_min_max<Box, D, D>
  119. //{
  120. // static inline bool apply(Box const&) { return true; }
  121. //};
  122. //
  123. //template <typename Point, typename Box>
  124. //struct point_box
  125. //{
  126. // static inline result apply(Point const& point, Box const& box)
  127. // {
  128. // result res;
  129. //
  130. // if ( geometry::within(point, box) ) // this also means that the box has interior
  131. // {
  132. // return result("0FFFFFTTT");
  133. // }
  134. // else if ( geometry::covered_by(point, box) ) // point is on the boundary
  135. // {
  136. // //if ( box_has_interior<Box>::apply(box) )
  137. // //{
  138. // // return result("F0FFFFTTT");
  139. // //}
  140. // //else if ( box_has_equal_min_max<Box>::apply(box) ) // no boundary outside point
  141. // //{
  142. // // return result("F0FFFFFFT");
  143. // //}
  144. // //else // no interior outside point
  145. // //{
  146. // // return result("F0FFFFFTT");
  147. // //}
  148. // return result("F0FFFF**T");
  149. // }
  150. // else
  151. // {
  152. // /*if ( box_has_interior<Box>::apply(box) )
  153. // {
  154. // return result("FF0FFFTTT");
  155. // }
  156. // else
  157. // {
  158. // return result("FF0FFFFTT");
  159. // }*/
  160. // return result("FF0FFF*TT");
  161. // }
  162. //
  163. // return res;
  164. // }
  165. //};
  166. //
  167. //template <typename Box, typename Point>
  168. //struct box_point
  169. //{
  170. // static inline result apply(Box const& box, Point const& point)
  171. // {
  172. // if ( geometry::within(point, box) )
  173. // return result("0FTFFTFFT");
  174. // else if ( geometry::covered_by(point, box) )
  175. // return result("FF*0F*FFT");
  176. // else
  177. // return result("FF*FFT0FT");
  178. // }
  179. //};
  180. }} // namespace detail::relate
  181. #endif // DOXYGEN_NO_DETAIL
  182. }} // namespace boost::geometry
  183. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_GEOMETRY_HPP