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