areal_areal.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
  5. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
  6. // This file was modified by Oracle on 2013-2019.
  7. // Modifications copyright (c) 2013-2019, Oracle and/or its affiliates.
  8. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  9. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  10. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  11. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  12. // Use, modification and distribution is subject to the Boost Software License,
  13. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  14. // http://www.boost.org/LICENSE_1_0.txt)
  15. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_AREAL_AREAL_HPP
  16. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_AREAL_AREAL_HPP
  17. #include <boost/geometry/core/point_type.hpp>
  18. #include <boost/geometry/algorithms/covered_by.hpp>
  19. #include <boost/geometry/algorithms/detail/for_each_range.hpp>
  20. #include <boost/geometry/algorithms/detail/point_on_border.hpp>
  21. #include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
  22. #include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
  23. #include <boost/geometry/iterators/segment_iterator.hpp>
  24. namespace boost { namespace geometry
  25. {
  26. #ifndef DOXYGEN_NO_DETAIL
  27. namespace detail { namespace disjoint
  28. {
  29. template <typename Geometry1, typename Geometry2, typename Strategy>
  30. inline bool point_on_border_covered_by(Geometry1 const& geometry1,
  31. Geometry2 const& geometry2,
  32. Strategy const& strategy)
  33. {
  34. typename geometry::point_type<Geometry1>::type pt;
  35. return geometry::point_on_border(pt, geometry1)
  36. && geometry::covered_by(pt, geometry2, strategy);
  37. }
  38. /*!
  39. \tparam Strategy point_in_geometry strategy
  40. */
  41. template<typename Geometry, typename Strategy>
  42. struct check_each_ring_for_within
  43. {
  44. bool not_disjoint;
  45. Geometry const& m_geometry;
  46. Strategy const& m_strategy;
  47. inline check_each_ring_for_within(Geometry const& g,
  48. Strategy const& strategy)
  49. : not_disjoint(false)
  50. , m_geometry(g)
  51. , m_strategy(strategy)
  52. {}
  53. template <typename Range>
  54. inline void apply(Range const& range)
  55. {
  56. not_disjoint = not_disjoint
  57. || point_on_border_covered_by(range, m_geometry, m_strategy);
  58. }
  59. };
  60. /*!
  61. \tparam Strategy point_in_geometry strategy
  62. */
  63. template <typename FirstGeometry, typename SecondGeometry, typename Strategy>
  64. inline bool rings_containing(FirstGeometry const& geometry1,
  65. SecondGeometry const& geometry2,
  66. Strategy const& strategy)
  67. {
  68. check_each_ring_for_within
  69. <
  70. FirstGeometry, Strategy
  71. > checker(geometry1, strategy);
  72. geometry::detail::for_each_range(geometry2, checker);
  73. return checker.not_disjoint;
  74. }
  75. template <typename Geometry1, typename Geometry2>
  76. struct areal_areal
  77. {
  78. /*!
  79. \tparam Strategy relate (segments intersection) strategy
  80. */
  81. template <typename Strategy>
  82. static inline bool apply(Geometry1 const& geometry1,
  83. Geometry2 const& geometry2,
  84. Strategy const& strategy)
  85. {
  86. if ( ! disjoint_linear<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy) )
  87. {
  88. return false;
  89. }
  90. // If there is no intersection of segments, they might located
  91. // inside each other
  92. // We check that using a point on the border (external boundary),
  93. // and see if that is contained in the other geometry. And vice versa.
  94. if ( rings_containing(geometry1, geometry2,
  95. strategy.template get_point_in_geometry_strategy<Geometry2, Geometry1>())
  96. || rings_containing(geometry2, geometry1,
  97. strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>()) )
  98. {
  99. return false;
  100. }
  101. return true;
  102. }
  103. };
  104. template <typename Areal, typename Box>
  105. struct areal_box
  106. {
  107. /*!
  108. \tparam Strategy relate (segments intersection) strategy
  109. */
  110. template <typename Strategy>
  111. static inline bool apply(Areal const& areal,
  112. Box const& box,
  113. Strategy const& strategy)
  114. {
  115. if ( ! for_each_segment(geometry::segments_begin(areal),
  116. geometry::segments_end(areal),
  117. box,
  118. strategy.get_disjoint_segment_box_strategy()) )
  119. {
  120. return false;
  121. }
  122. // If there is no intersection of any segment and box,
  123. // the box might be located inside areal geometry
  124. if ( point_on_border_covered_by(box, areal,
  125. strategy.template get_point_in_geometry_strategy<Box, Areal>()) )
  126. {
  127. return false;
  128. }
  129. return true;
  130. }
  131. private:
  132. template <typename SegIter, typename Strategy>
  133. static inline bool for_each_segment(SegIter first,
  134. SegIter last,
  135. Box const& box,
  136. Strategy const& strategy)
  137. {
  138. for ( ; first != last ; ++first)
  139. {
  140. if (! disjoint_segment_box::apply(*first, box, strategy))
  141. {
  142. return false;
  143. }
  144. }
  145. return true;
  146. }
  147. };
  148. }} // namespace detail::disjoint
  149. #endif // DOXYGEN_NO_DETAIL
  150. #ifndef DOXYGEN_NO_DISPATCH
  151. namespace dispatch
  152. {
  153. template <typename Areal1, typename Areal2>
  154. struct disjoint<Areal1, Areal2, 2, areal_tag, areal_tag, false>
  155. : detail::disjoint::areal_areal<Areal1, Areal2>
  156. {};
  157. template <typename Areal, typename Box>
  158. struct disjoint<Areal, Box, 2, areal_tag, box_tag, false>
  159. : detail::disjoint::areal_box<Areal, Box>
  160. {};
  161. } // namespace dispatch
  162. #endif // DOXYGEN_NO_DISPATCH
  163. }} // namespace boost::geometry
  164. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_AREAL_AREAL_HPP