1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2014-2020, Oracle and/or its affiliates.
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
11 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_AREAL_HPP
12 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_AREAL_HPP
14 #include <boost/range/begin.hpp>
15 #include <boost/range/empty.hpp>
16 #include <boost/range/end.hpp>
17 #include <boost/range/value_type.hpp>
19 #include <boost/geometry/core/closure.hpp>
20 #include <boost/geometry/core/exterior_ring.hpp>
21 #include <boost/geometry/core/interior_rings.hpp>
22 #include <boost/geometry/core/ring_type.hpp>
23 #include <boost/geometry/core/tags.hpp>
25 #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
26 #include <boost/geometry/algorithms/detail/is_simple/failure_policy.hpp>
27 #include <boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp>
29 #include <boost/geometry/algorithms/dispatch/is_simple.hpp>
32 namespace boost { namespace geometry
36 #ifndef DOXYGEN_NO_DETAIL
37 namespace detail { namespace is_simple
41 template <typename Ring, typename CSTag>
44 static inline bool apply(Ring const& ring)
46 simplicity_failure_policy policy;
47 return ! boost::empty(ring)
48 && ! detail::is_valid::has_duplicates
50 Ring, geometry::closure<Ring>::value, CSTag
51 >::apply(ring, policy);
56 template <typename Polygon, typename CSTag>
57 class is_simple_polygon
60 template <typename InteriorRings>
62 bool are_simple_interior_rings(InteriorRings const& interior_rings)
65 detail::check_iterator_range
69 typename boost::range_value<InteriorRings>::type,
72 >::apply(boost::begin(interior_rings),
73 boost::end(interior_rings));
77 static inline bool apply(Polygon const& polygon)
82 typename ring_type<Polygon>::type,
84 >::apply(exterior_ring(polygon))
86 are_simple_interior_rings(geometry::interior_rings(polygon));
91 }} // namespace detail::is_simple
92 #endif // DOXYGEN_NO_DETAIL
97 #ifndef DOXYGEN_NO_DISPATCH
102 // A Ring is a Polygon.
103 // A Polygon is always a simple geometric object provided that it is valid.
105 // Reference (for polygon validity): OGC 06-103r4 (6.1.11.1)
106 template <typename Ring>
107 struct is_simple<Ring, ring_tag>
109 template <typename Strategy>
110 static inline bool apply(Ring const& ring, Strategy const&)
112 return detail::is_simple::is_simple_ring
115 typename Strategy::cs_tag
121 // A Polygon is always a simple geometric object provided that it is valid.
123 // Reference (for validity of Polygons): OGC 06-103r4 (6.1.11.1)
124 template <typename Polygon>
125 struct is_simple<Polygon, polygon_tag>
127 template <typename Strategy>
128 static inline bool apply(Polygon const& polygon, Strategy const&)
130 return detail::is_simple::is_simple_polygon
133 typename Strategy::cs_tag
139 // Not clear what the definition is.
140 // Right now we consider a MultiPolygon as simple if it is valid.
142 // Reference (for validity of MultiPolygons): OGC 06-103r4 (6.1.14)
143 template <typename MultiPolygon>
144 struct is_simple<MultiPolygon, multi_polygon_tag>
146 template <typename Strategy>
147 static inline bool apply(MultiPolygon const& multipolygon, Strategy const&)
150 detail::check_iterator_range
152 detail::is_simple::is_simple_polygon
154 typename boost::range_value<MultiPolygon>::type,
155 typename Strategy::cs_tag
157 true // allow empty multi-polygon
158 >::apply(boost::begin(multipolygon), boost::end(multipolygon));
163 } // namespace dispatch
164 #endif // DOXYGEN_NO_DISPATCH
167 }} // namespace boost::geometry
169 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_AREAL_HPP