linear_areal.hpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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-2018.
  7. // Modifications copyright (c) 2013-2018, 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_LINEAR_AREAL_HPP
  16. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_AREAL_HPP
  17. #include <iterator>
  18. #include <boost/range.hpp>
  19. #include <boost/geometry/core/closure.hpp>
  20. #include <boost/geometry/core/point_type.hpp>
  21. #include <boost/geometry/core/ring_type.hpp>
  22. #include <boost/geometry/core/exterior_ring.hpp>
  23. #include <boost/geometry/core/interior_rings.hpp>
  24. #include <boost/geometry/core/tag.hpp>
  25. #include <boost/geometry/core/tag_cast.hpp>
  26. #include <boost/geometry/core/tags.hpp>
  27. #include <boost/geometry/algorithms/covered_by.hpp>
  28. #include <boost/geometry/algorithms/not_implemented.hpp>
  29. #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
  30. #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
  31. #include <boost/geometry/algorithms/detail/point_on_border.hpp>
  32. #include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
  33. #include <boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp>
  34. #include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
  35. #include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
  36. #include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
  37. #include <boost/geometry/algorithms/dispatch/disjoint.hpp>
  38. namespace boost { namespace geometry
  39. {
  40. #ifndef DOXYGEN_NO_DETAIL
  41. namespace detail { namespace disjoint
  42. {
  43. template <typename Geometry1, typename Geometry2,
  44. typename Tag1 = typename tag<Geometry1>::type,
  45. typename Tag1OrMulti = typename tag_cast<Tag1, multi_tag>::type>
  46. struct disjoint_no_intersections_policy
  47. {
  48. /*!
  49. \tparam Strategy point_in_geometry strategy
  50. */
  51. template <typename Strategy>
  52. static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
  53. {
  54. typedef typename point_type<Geometry1>::type point1_type;
  55. point1_type p;
  56. geometry::point_on_border(p, g1);
  57. return !geometry::covered_by(p, g2, strategy);
  58. }
  59. };
  60. template <typename Geometry1, typename Geometry2, typename Tag1>
  61. struct disjoint_no_intersections_policy<Geometry1, Geometry2, Tag1, multi_tag>
  62. {
  63. /*!
  64. \tparam Strategy point_in_geometry strategy
  65. */
  66. template <typename Strategy>
  67. static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
  68. {
  69. // TODO: use partition or rtree on g2
  70. typedef typename boost::range_iterator<Geometry1 const>::type iterator;
  71. for ( iterator it = boost::begin(g1) ; it != boost::end(g1) ; ++it )
  72. {
  73. typedef typename boost::range_value<Geometry1 const>::type value_type;
  74. if ( ! disjoint_no_intersections_policy<value_type const, Geometry2>
  75. ::apply(*it, g2, strategy) )
  76. {
  77. return false;
  78. }
  79. }
  80. return true;
  81. }
  82. };
  83. template<typename Geometry1, typename Geometry2,
  84. typename NoIntersectionsPolicy
  85. = disjoint_no_intersections_policy<Geometry1, Geometry2> >
  86. struct disjoint_linear_areal
  87. {
  88. /*!
  89. \tparam Strategy relate (segments intersection) strategy
  90. */
  91. template <typename Strategy>
  92. static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
  93. {
  94. // if there are intersections - return false
  95. if ( !disjoint_linear<Geometry1, Geometry2>::apply(g1, g2, strategy) )
  96. {
  97. return false;
  98. }
  99. return NoIntersectionsPolicy
  100. ::apply(g1, g2,
  101. strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>());
  102. }
  103. };
  104. template
  105. <
  106. typename Segment,
  107. typename Areal,
  108. typename Tag = typename tag<Areal>::type
  109. >
  110. struct disjoint_segment_areal
  111. : not_implemented<Segment, Areal>
  112. {};
  113. template <typename Segment, typename Polygon>
  114. class disjoint_segment_areal<Segment, Polygon, polygon_tag>
  115. {
  116. private:
  117. template <typename InteriorRings, typename Strategy>
  118. static inline
  119. bool check_interior_rings(InteriorRings const& interior_rings,
  120. Segment const& segment,
  121. Strategy const& strategy)
  122. {
  123. typedef typename boost::range_value<InteriorRings>::type ring_type;
  124. typedef unary_disjoint_geometry_to_query_geometry
  125. <
  126. Segment,
  127. Strategy,
  128. disjoint_range_segment_or_box
  129. <
  130. ring_type, closure<ring_type>::value, Segment
  131. >
  132. > unary_predicate_type;
  133. return check_iterator_range
  134. <
  135. unary_predicate_type
  136. >::apply(boost::begin(interior_rings),
  137. boost::end(interior_rings),
  138. unary_predicate_type(segment, strategy));
  139. }
  140. public:
  141. template <typename IntersectionStrategy>
  142. static inline bool apply(Segment const& segment,
  143. Polygon const& polygon,
  144. IntersectionStrategy const& strategy)
  145. {
  146. typedef typename geometry::ring_type<Polygon>::type ring;
  147. if ( !disjoint_range_segment_or_box
  148. <
  149. ring, closure<Polygon>::value, Segment
  150. >::apply(geometry::exterior_ring(polygon), segment, strategy) )
  151. {
  152. return false;
  153. }
  154. if ( !check_interior_rings(geometry::interior_rings(polygon), segment, strategy) )
  155. {
  156. return false;
  157. }
  158. typename point_type<Segment>::type p;
  159. detail::assign_point_from_index<0>(segment, p);
  160. return !geometry::covered_by(p, polygon,
  161. strategy.template get_point_in_geometry_strategy<Segment, Polygon>());
  162. }
  163. };
  164. template <typename Segment, typename MultiPolygon>
  165. struct disjoint_segment_areal<Segment, MultiPolygon, multi_polygon_tag>
  166. {
  167. template <typename IntersectionStrategy>
  168. static inline bool apply(Segment const& segment, MultiPolygon const& multipolygon,
  169. IntersectionStrategy const& strategy)
  170. {
  171. return multirange_constant_size_geometry
  172. <
  173. MultiPolygon, Segment
  174. >::apply(multipolygon, segment, strategy);
  175. }
  176. };
  177. template <typename Segment, typename Ring>
  178. struct disjoint_segment_areal<Segment, Ring, ring_tag>
  179. {
  180. template <typename IntersectionStrategy>
  181. static inline bool apply(Segment const& segment,
  182. Ring const& ring,
  183. IntersectionStrategy const& strategy)
  184. {
  185. if ( !disjoint_range_segment_or_box
  186. <
  187. Ring, closure<Ring>::value, Segment
  188. >::apply(ring, segment, strategy) )
  189. {
  190. return false;
  191. }
  192. typename point_type<Segment>::type p;
  193. detail::assign_point_from_index<0>(segment, p);
  194. return !geometry::covered_by(p, ring,
  195. strategy.template get_point_in_geometry_strategy<Segment, Ring>());
  196. }
  197. };
  198. }} // namespace detail::disjoint
  199. #endif // DOXYGEN_NO_DETAIL
  200. #ifndef DOXYGEN_NO_DISPATCH
  201. namespace dispatch
  202. {
  203. template <typename Linear, typename Areal>
  204. struct disjoint<Linear, Areal, 2, linear_tag, areal_tag, false>
  205. : public detail::disjoint::disjoint_linear_areal<Linear, Areal>
  206. {};
  207. template <typename Areal, typename Linear>
  208. struct disjoint<Areal, Linear, 2, areal_tag, linear_tag, false>
  209. {
  210. template <typename Strategy>
  211. static inline bool apply(Areal const& areal, Linear const& linear,
  212. Strategy const& strategy)
  213. {
  214. return detail::disjoint::disjoint_linear_areal
  215. <
  216. Linear, Areal
  217. >::apply(linear, areal, strategy);
  218. }
  219. };
  220. template <typename Areal, typename Segment>
  221. struct disjoint<Areal, Segment, 2, areal_tag, segment_tag, false>
  222. {
  223. template <typename Strategy>
  224. static inline bool apply(Areal const& g1, Segment const& g2,
  225. Strategy const& strategy)
  226. {
  227. return detail::disjoint::disjoint_segment_areal
  228. <
  229. Segment, Areal
  230. >::apply(g2, g1, strategy);
  231. }
  232. };
  233. template <typename Segment, typename Areal>
  234. struct disjoint<Segment, Areal, 2, segment_tag, areal_tag, false>
  235. : detail::disjoint::disjoint_segment_areal<Segment, Areal>
  236. {};
  237. } // namespace dispatch
  238. #endif // DOXYGEN_NO_DISPATCH
  239. }} // namespace boost::geometry
  240. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_AREAL_HPP