diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/is_simple/areal.hpp')
-rw-r--r-- | boost/geometry/algorithms/detail/is_simple/areal.hpp | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/boost/geometry/algorithms/detail/is_simple/areal.hpp b/boost/geometry/algorithms/detail/is_simple/areal.hpp new file mode 100644 index 0000000000..9a1a16507a --- /dev/null +++ b/boost/geometry/algorithms/detail/is_simple/areal.hpp @@ -0,0 +1,141 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_AREAL_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_AREAL_HPP + +#include <boost/range.hpp> + +#include <boost/geometry/core/closure.hpp> +#include <boost/geometry/core/exterior_ring.hpp> +#include <boost/geometry/core/interior_rings.hpp> +#include <boost/geometry/core/ring_type.hpp> +#include <boost/geometry/core/tags.hpp> + +#include <boost/geometry/algorithms/detail/check_iterator_range.hpp> +#include <boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp> + +#include <boost/geometry/algorithms/dispatch/is_simple.hpp> + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace is_simple +{ + + +template <typename Ring> +struct is_simple_ring +{ + static inline bool apply(Ring const& ring) + { + return + !detail::is_valid::has_duplicates + < + Ring, geometry::closure<Ring>::value + >::apply(ring); + } +}; + + +template <typename Polygon> +class is_simple_polygon +{ +private: + template <typename InteriorRings> + static inline + bool are_simple_interior_rings(InteriorRings const& interior_rings) + { + return + detail::check_iterator_range + < + is_simple_ring + < + typename boost::range_value<InteriorRings>::type + > + >::apply(boost::begin(interior_rings), + boost::end(interior_rings)); + } + +public: + static inline bool apply(Polygon const& polygon) + { + return + is_simple_ring + < + typename ring_type<Polygon>::type + >::apply(exterior_ring(polygon)) + && + are_simple_interior_rings(geometry::interior_rings(polygon)); + } +}; + + +}} // namespace detail::is_simple +#endif // DOXYGEN_NO_DETAIL + + + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + + +// A Ring is a Polygon. +// A Polygon is always a simple geometric object provided that it is valid. +// +// Reference (for polygon validity): OGC 06-103r4 (6.1.11.1) +template <typename Ring> +struct is_simple<Ring, ring_tag> + : detail::is_simple::is_simple_ring<Ring> +{}; + + +// A Polygon is always a simple geometric object provided that it is valid. +// +// Reference (for validity of Polygons): OGC 06-103r4 (6.1.11.1) +template <typename Polygon> +struct is_simple<Polygon, polygon_tag> + : detail::is_simple::is_simple_polygon<Polygon> +{}; + + +// Not clear what the definition is. +// Right now we consider a MultiPolygon as simple if it is valid. +// +// Reference (for validity of MultiPolygons): OGC 06-103r4 (6.1.14) +template <typename MultiPolygon> +struct is_simple<MultiPolygon, multi_polygon_tag> +{ + static inline bool apply(MultiPolygon const& multipolygon) + { + return + detail::check_iterator_range + < + detail::is_simple::is_simple_polygon + < + typename boost::range_value<MultiPolygon>::type + >, + false // do not allow empty multi-polygon + >::apply(boost::begin(multipolygon), boost::end(multipolygon)); + } +}; + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_SIMPLE_AREAL_HPP |