closure.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // This file was modified by Oracle on 2014-2021.
  6. // Modifications copyright (c) 2014-2021 Oracle and/or its affiliates.
  7. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  8. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  9. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  10. // Use, modification and distribution is subject to the Boost Software License,
  11. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. #ifndef BOOST_GEOMETRY_CORE_CLOSURE_HPP
  14. #define BOOST_GEOMETRY_CORE_CLOSURE_HPP
  15. #include <boost/range/value_type.hpp>
  16. #include <boost/geometry/core/ring_type.hpp>
  17. #include <boost/geometry/core/static_assert.hpp>
  18. #include <boost/geometry/core/tag.hpp>
  19. #include <boost/geometry/core/tags.hpp>
  20. #include <boost/geometry/util/type_traits_std.hpp>
  21. namespace boost { namespace geometry
  22. {
  23. /*!
  24. \brief Enumerates options for defining if polygons are open or closed
  25. \ingroup enum
  26. \details The enumeration closure_selector describes options for if a polygon is
  27. open or closed. In a closed polygon the very first point (per ring) should
  28. be equal to the very last point.
  29. The specific closing property of a polygon type is defined by the closure
  30. metafunction. The closure metafunction defines a value, which is one of the
  31. values enumerated in the closure_selector
  32. \qbk{
  33. [heading See also]
  34. [link geometry.reference.core.closure The closure metafunction]
  35. }
  36. */
  37. enum closure_selector
  38. {
  39. /// Rings are open: first point and last point are different, algorithms
  40. /// close them explicitly on the fly
  41. open = 0,
  42. /// Rings are closed: first point and last point must be the same
  43. closed = 1,
  44. /// (Not yet implemented): algorithms first figure out if ring must be
  45. /// closed on the fly
  46. closure_undertermined = -1
  47. };
  48. namespace traits
  49. {
  50. /*!
  51. \brief Traits class indicating if points within a
  52. ring or (multi)polygon are closed (last point == first point),
  53. open or not known.
  54. \ingroup traits
  55. \par Geometries:
  56. - ring
  57. \tparam G geometry
  58. */
  59. template <typename G>
  60. struct closure
  61. {
  62. static const closure_selector value = closed;
  63. };
  64. } // namespace traits
  65. #ifndef DOXYGEN_NO_DETAIL
  66. namespace core_detail { namespace closure
  67. {
  68. struct closed
  69. {
  70. static const closure_selector value = geometry::closed;
  71. };
  72. /// Metafunction to define the minimum size of a ring:
  73. /// 3 for open rings, 4 for closed rings
  74. template <closure_selector Closure>
  75. struct minimum_ring_size {};
  76. template <>
  77. struct minimum_ring_size<geometry::closed>
  78. : std::integral_constant<std::size_t, 4>
  79. {};
  80. template <>
  81. struct minimum_ring_size<geometry::open>
  82. : std::integral_constant<std::size_t, 3>
  83. {};
  84. }} // namespace core_detail::closure
  85. #endif // DOXYGEN_NO_DETAIL
  86. #ifndef DOXYGEN_NO_DISPATCH
  87. namespace core_dispatch
  88. {
  89. template <typename Tag, typename Geometry>
  90. struct closure
  91. {
  92. BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
  93. "Not implemented for this Geometry type.",
  94. Geometry);
  95. };
  96. template <typename Box>
  97. struct closure<point_tag, Box> : public core_detail::closure::closed {};
  98. template <typename Box>
  99. struct closure<box_tag, Box> : public core_detail::closure::closed {};
  100. template <typename Box>
  101. struct closure<segment_tag, Box> : public core_detail::closure::closed {};
  102. template <typename LineString>
  103. struct closure<linestring_tag, LineString>
  104. : public core_detail::closure::closed {};
  105. template <typename Ring>
  106. struct closure<ring_tag, Ring>
  107. {
  108. static const closure_selector value
  109. = geometry::traits::closure<Ring>::value;
  110. };
  111. // Specialization for Polygon: the closure is the closure of its rings
  112. template <typename Polygon>
  113. struct closure<polygon_tag, Polygon>
  114. {
  115. static const closure_selector value = core_dispatch::closure
  116. <
  117. ring_tag,
  118. typename ring_type<polygon_tag, Polygon>::type
  119. >::value ;
  120. };
  121. template <typename MultiPoint>
  122. struct closure<multi_point_tag, MultiPoint>
  123. : public core_detail::closure::closed {};
  124. template <typename MultiLinestring>
  125. struct closure<multi_linestring_tag, MultiLinestring>
  126. : public core_detail::closure::closed {};
  127. // Specialization for MultiPolygon: the closure is the closure of Polygon's rings
  128. template <typename MultiPolygon>
  129. struct closure<multi_polygon_tag, MultiPolygon>
  130. {
  131. static const closure_selector value = core_dispatch::closure
  132. <
  133. polygon_tag,
  134. typename boost::range_value<MultiPolygon>::type
  135. >::value ;
  136. };
  137. } // namespace core_dispatch
  138. #endif // DOXYGEN_NO_DISPATCH
  139. /*!
  140. \brief \brief_meta{value, closure (clockwise\, counterclockwise),
  141. \meta_geometry_type}
  142. \tparam Geometry \tparam_geometry
  143. \ingroup core
  144. \qbk{[include reference/core/closure.qbk]}
  145. */
  146. template <typename Geometry>
  147. struct closure
  148. {
  149. static const closure_selector value = core_dispatch::closure
  150. <
  151. typename tag<Geometry>::type,
  152. typename util::remove_cptrref<Geometry>::type
  153. >::value;
  154. };
  155. #ifndef DOXYGEN_NO_DETAIL
  156. namespace detail
  157. {
  158. template
  159. <
  160. typename Geometry,
  161. closure_selector Closure = geometry::closure<Geometry>::value
  162. >
  163. using minimum_ring_size = core_detail::closure::minimum_ring_size<Closure>;
  164. } // namespace detail
  165. #endif // DOXYGEN_NO_DETAIL
  166. }} // namespace boost::geometry
  167. #endif // BOOST_GEOMETRY_CORE_CLOSURE_HPP