areal.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2014-2019, Oracle and/or its affiliates.
  3. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  4. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  5. // Licensed under the Boost Software License version 1.0.
  6. // http://www.boost.org/users/license.html
  7. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_AREAL_HPP
  8. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_AREAL_HPP
  9. #include <boost/range.hpp>
  10. #include <boost/geometry/core/closure.hpp>
  11. #include <boost/geometry/core/exterior_ring.hpp>
  12. #include <boost/geometry/core/interior_rings.hpp>
  13. #include <boost/geometry/core/ring_type.hpp>
  14. #include <boost/geometry/core/tags.hpp>
  15. #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
  16. #include <boost/geometry/algorithms/detail/is_simple/failure_policy.hpp>
  17. #include <boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp>
  18. #include <boost/geometry/algorithms/dispatch/is_simple.hpp>
  19. namespace boost { namespace geometry
  20. {
  21. #ifndef DOXYGEN_NO_DETAIL
  22. namespace detail { namespace is_simple
  23. {
  24. template <typename Ring, typename CSTag>
  25. struct is_simple_ring
  26. {
  27. static inline bool apply(Ring const& ring)
  28. {
  29. simplicity_failure_policy policy;
  30. return ! boost::empty(ring)
  31. && ! detail::is_valid::has_duplicates
  32. <
  33. Ring, geometry::closure<Ring>::value, CSTag
  34. >::apply(ring, policy);
  35. }
  36. };
  37. template <typename Polygon, typename CSTag>
  38. class is_simple_polygon
  39. {
  40. private:
  41. template <typename InteriorRings>
  42. static inline
  43. bool are_simple_interior_rings(InteriorRings const& interior_rings)
  44. {
  45. return
  46. detail::check_iterator_range
  47. <
  48. is_simple_ring
  49. <
  50. typename boost::range_value<InteriorRings>::type,
  51. CSTag
  52. >
  53. >::apply(boost::begin(interior_rings),
  54. boost::end(interior_rings));
  55. }
  56. public:
  57. static inline bool apply(Polygon const& polygon)
  58. {
  59. return
  60. is_simple_ring
  61. <
  62. typename ring_type<Polygon>::type,
  63. CSTag
  64. >::apply(exterior_ring(polygon))
  65. &&
  66. are_simple_interior_rings(geometry::interior_rings(polygon));
  67. }
  68. };
  69. }} // namespace detail::is_simple
  70. #endif // DOXYGEN_NO_DETAIL
  71. #ifndef DOXYGEN_NO_DISPATCH
  72. namespace dispatch
  73. {
  74. // A Ring is a Polygon.
  75. // A Polygon is always a simple geometric object provided that it is valid.
  76. //
  77. // Reference (for polygon validity): OGC 06-103r4 (6.1.11.1)
  78. template <typename Ring>
  79. struct is_simple<Ring, ring_tag>
  80. {
  81. template <typename Strategy>
  82. static inline bool apply(Ring const& ring, Strategy const&)
  83. {
  84. return detail::is_simple::is_simple_ring
  85. <
  86. Ring,
  87. typename Strategy::cs_tag
  88. >::apply(ring);
  89. }
  90. };
  91. // A Polygon is always a simple geometric object provided that it is valid.
  92. //
  93. // Reference (for validity of Polygons): OGC 06-103r4 (6.1.11.1)
  94. template <typename Polygon>
  95. struct is_simple<Polygon, polygon_tag>
  96. {
  97. template <typename Strategy>
  98. static inline bool apply(Polygon const& polygon, Strategy const&)
  99. {
  100. return detail::is_simple::is_simple_polygon
  101. <
  102. Polygon,
  103. typename Strategy::cs_tag
  104. >::apply(polygon);
  105. }
  106. };
  107. // Not clear what the definition is.
  108. // Right now we consider a MultiPolygon as simple if it is valid.
  109. //
  110. // Reference (for validity of MultiPolygons): OGC 06-103r4 (6.1.14)
  111. template <typename MultiPolygon>
  112. struct is_simple<MultiPolygon, multi_polygon_tag>
  113. {
  114. template <typename Strategy>
  115. static inline bool apply(MultiPolygon const& multipolygon, Strategy const&)
  116. {
  117. return
  118. detail::check_iterator_range
  119. <
  120. detail::is_simple::is_simple_polygon
  121. <
  122. typename boost::range_value<MultiPolygon>::type,
  123. typename Strategy::cs_tag
  124. >,
  125. true // allow empty multi-polygon
  126. >::apply(boost::begin(multipolygon), boost::end(multipolygon));
  127. }
  128. };
  129. } // namespace dispatch
  130. #endif // DOXYGEN_NO_DISPATCH
  131. }} // namespace boost::geometry
  132. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_AREAL_HPP