buffered_ring.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
  3. // This file was modified by Oracle on 2020.
  4. // Modifications copyright (c) 2020 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_BUFFER_BUFFERED_RING
  10. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING
  11. #include <cstddef>
  12. #include <boost/range/size.hpp>
  13. #include <boost/range/value_type.hpp>
  14. #include <boost/geometry/core/assert.hpp>
  15. #include <boost/geometry/core/coordinate_type.hpp>
  16. #include <boost/geometry/core/closure.hpp>
  17. #include <boost/geometry/core/point_order.hpp>
  18. #include <boost/geometry/core/point_type.hpp>
  19. #include <boost/geometry/strategies/buffer.hpp>
  20. #include <boost/geometry/algorithms/within.hpp>
  21. #include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
  22. #include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
  23. #include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
  24. #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
  25. #include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
  26. #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
  27. namespace boost { namespace geometry
  28. {
  29. #ifndef DOXYGEN_NO_DETAIL
  30. namespace detail { namespace buffer
  31. {
  32. struct buffered_ring_collection_tag : polygonal_tag, multi_tag
  33. {};
  34. template <typename Ring>
  35. struct buffered_ring : public Ring
  36. {
  37. bool has_concave;
  38. bool has_accepted_intersections;
  39. bool has_discarded_intersections;
  40. bool is_untouched_outside_original;
  41. inline buffered_ring()
  42. : has_concave(false)
  43. , has_accepted_intersections(false)
  44. , has_discarded_intersections(false)
  45. , is_untouched_outside_original(false)
  46. {}
  47. inline bool discarded() const
  48. {
  49. return has_discarded_intersections && ! has_accepted_intersections;
  50. }
  51. inline bool has_intersections() const
  52. {
  53. return has_discarded_intersections || has_accepted_intersections;
  54. }
  55. };
  56. // This is a collection now special for overlay (needs vector of rings)
  57. template <typename Ring>
  58. struct buffered_ring_collection : public std::vector<Ring>
  59. {
  60. };
  61. }} // namespace detail::buffer
  62. // Turn off concept checking (for now)
  63. namespace concepts
  64. {
  65. template <typename Geometry>
  66. struct concept_type<Geometry, geometry::detail::buffer::buffered_ring_collection_tag>
  67. {
  68. struct dummy {};
  69. using type = dummy;
  70. };
  71. }
  72. #endif // DOXYGEN_NO_DETAIL
  73. // Register the types
  74. namespace traits
  75. {
  76. template <typename Ring>
  77. struct tag<geometry::detail::buffer::buffered_ring<Ring> >
  78. {
  79. typedef ring_tag type;
  80. };
  81. template <typename Ring>
  82. struct point_order<geometry::detail::buffer::buffered_ring<Ring> >
  83. {
  84. static const order_selector value = geometry::point_order<Ring>::value;
  85. };
  86. template <typename Ring>
  87. struct closure<geometry::detail::buffer::buffered_ring<Ring> >
  88. {
  89. static const closure_selector value = geometry::closure<Ring>::value;
  90. };
  91. template <typename Ring>
  92. struct point_type<geometry::detail::buffer::buffered_ring_collection<Ring> >
  93. {
  94. typedef typename geometry::point_type<Ring>::type type;
  95. };
  96. template <typename Ring>
  97. struct tag<geometry::detail::buffer::buffered_ring_collection<Ring> >
  98. {
  99. typedef geometry::detail::buffer::buffered_ring_collection_tag type;
  100. };
  101. } // namespace traits
  102. namespace core_dispatch
  103. {
  104. template <typename Ring>
  105. struct ring_type
  106. <
  107. detail::buffer::buffered_ring_collection_tag,
  108. detail::buffer::buffered_ring_collection<Ring>
  109. >
  110. {
  111. typedef Ring type;
  112. };
  113. // There is a specific tag, so this specialization cannot be placed in traits
  114. template <typename Ring>
  115. struct point_order<detail::buffer::buffered_ring_collection_tag,
  116. geometry::detail::buffer::buffered_ring_collection
  117. <
  118. geometry::detail::buffer::buffered_ring<Ring>
  119. > >
  120. {
  121. static const order_selector value
  122. = core_dispatch::point_order<ring_tag, Ring>::value;
  123. };
  124. }
  125. template <>
  126. struct single_tag_of<detail::buffer::buffered_ring_collection_tag>
  127. {
  128. typedef ring_tag type;
  129. };
  130. namespace dispatch
  131. {
  132. template
  133. <
  134. typename MultiRing,
  135. bool Reverse,
  136. typename SegmentIdentifier,
  137. typename PointOut
  138. >
  139. struct copy_segment_point
  140. <
  141. detail::buffer::buffered_ring_collection_tag,
  142. MultiRing,
  143. Reverse,
  144. SegmentIdentifier,
  145. PointOut
  146. >
  147. : detail::copy_segments::copy_segment_point_multi
  148. <
  149. MultiRing,
  150. SegmentIdentifier,
  151. PointOut,
  152. detail::copy_segments::copy_segment_point_range
  153. <
  154. typename boost::range_value<MultiRing>::type,
  155. Reverse,
  156. SegmentIdentifier,
  157. PointOut
  158. >
  159. >
  160. {};
  161. template<bool Reverse>
  162. struct copy_segments
  163. <
  164. detail::buffer::buffered_ring_collection_tag,
  165. Reverse
  166. >
  167. : detail::copy_segments::copy_segments_multi
  168. <
  169. detail::copy_segments::copy_segments_ring<Reverse>
  170. >
  171. {};
  172. template <typename Point, typename MultiGeometry>
  173. struct within
  174. <
  175. Point,
  176. MultiGeometry,
  177. point_tag,
  178. detail::buffer::buffered_ring_collection_tag
  179. >
  180. {
  181. template <typename Strategy>
  182. static inline bool apply(Point const& point,
  183. MultiGeometry const& multi, Strategy const& strategy)
  184. {
  185. return detail::within::point_in_geometry(point, multi, strategy) == 1;
  186. }
  187. };
  188. template <typename Geometry>
  189. struct is_empty<Geometry, detail::buffer::buffered_ring_collection_tag>
  190. : detail::is_empty::multi_is_empty<detail::is_empty::range_is_empty>
  191. {};
  192. template <typename Geometry>
  193. struct envelope<Geometry, detail::buffer::buffered_ring_collection_tag>
  194. : detail::envelope::envelope_multi_range
  195. <
  196. detail::envelope::envelope_range
  197. >
  198. {};
  199. } // namespace dispatch
  200. namespace detail { namespace overlay
  201. {
  202. template<>
  203. struct get_ring<detail::buffer::buffered_ring_collection_tag>
  204. {
  205. template<typename MultiGeometry>
  206. static inline typename ring_type<MultiGeometry>::type const& apply(
  207. ring_identifier const& id,
  208. MultiGeometry const& multi_ring)
  209. {
  210. BOOST_GEOMETRY_ASSERT
  211. (
  212. id.multi_index >= 0
  213. && id.multi_index < int(boost::size(multi_ring))
  214. );
  215. return get_ring<ring_tag>::apply(id, multi_ring[id.multi_index]);
  216. }
  217. };
  218. }}
  219. }} // namespace boost::geometry
  220. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_BUFFERED_RING