buffered_ring.hpp 6.4 KB

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