diff options
Diffstat (limited to 'boost/geometry/algorithms/unique.hpp')
-rw-r--r-- | boost/geometry/algorithms/unique.hpp | 85 |
1 files changed, 58 insertions, 27 deletions
diff --git a/boost/geometry/algorithms/unique.hpp b/boost/geometry/algorithms/unique.hpp index 3bbf479f9b..fed9f8af4b 100644 --- a/boost/geometry/algorithms/unique.hpp +++ b/boost/geometry/algorithms/unique.hpp @@ -3,6 +3,7 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -17,10 +18,12 @@ #include <algorithm> #include <boost/range.hpp> -#include <boost/typeof/typeof.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/geometry/algorithms/detail/interior_iterator.hpp> #include <boost/geometry/core/interior_rings.hpp> #include <boost/geometry/core/mutable_range.hpp> +#include <boost/geometry/core/tags.hpp> #include <boost/geometry/geometries/concepts/check.hpp> #include <boost/geometry/policies/compare.hpp> @@ -34,9 +37,9 @@ namespace detail { namespace unique { -template <typename Range, typename ComparePolicy> struct range_unique { + template <typename Range, typename ComparePolicy> static inline void apply(Range& range, ComparePolicy const& policy) { typename boost::range_iterator<Range>::type it @@ -52,26 +55,41 @@ struct range_unique }; -template <typename Polygon, typename ComparePolicy> struct polygon_unique { + template <typename Polygon, typename ComparePolicy> static inline void apply(Polygon& polygon, ComparePolicy const& policy) { - typedef typename geometry::ring_type<Polygon>::type ring_type; + range_unique::apply(exterior_ring(polygon), policy); - typedef range_unique<ring_type, ComparePolicy> per_range; - per_range::apply(exterior_ring(polygon), policy); + typename interior_return_type<Polygon>::type + rings = interior_rings(polygon); - typename interior_return_type<Polygon>::type rings - = interior_rings(polygon); - for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it) + for (typename detail::interior_iterator<Polygon>::type + it = boost::begin(rings); it != boost::end(rings); ++it) { - per_range::apply(*it, policy); + range_unique::apply(*it, policy); } } }; +template <typename Policy> +struct multi_unique +{ + template <typename MultiGeometry, typename ComparePolicy> + static inline void apply(MultiGeometry& multi, ComparePolicy const& compare) + { + for (typename boost::range_iterator<MultiGeometry>::type + it = boost::begin(multi); + it != boost::end(multi); + ++it) + { + Policy::apply(*it, compare); + } + } +}; + }} // namespace detail::unique #endif // DOXYGEN_NO_DETAIL @@ -85,32 +103,50 @@ namespace dispatch template < - typename Tag, typename Geometry, - typename ComparePolicy + typename Tag = typename tag<Geometry>::type > struct unique { + template <typename ComparePolicy> static inline void apply(Geometry&, ComparePolicy const& ) {} }; -template <typename Ring, typename ComparePolicy> -struct unique<ring_tag, Ring, ComparePolicy> - : detail::unique::range_unique<Ring, ComparePolicy> +template <typename Ring> +struct unique<Ring, ring_tag> + : detail::unique::range_unique +{}; + + +template <typename LineString> +struct unique<LineString, linestring_tag> + : detail::unique::range_unique +{}; + + +template <typename Polygon> +struct unique<Polygon, polygon_tag> + : detail::unique::polygon_unique {}; -template <typename LineString, typename ComparePolicy> -struct unique<linestring_tag, LineString, ComparePolicy> - : detail::unique::range_unique<LineString, ComparePolicy> +// For points, unique is not applicable and does nothing +// (Note that it is not "spatially unique" but that it removes duplicate coordinates, +// like std::unique does). Spatially unique is "dissolve" which can (or will be) +// possible for multi-points as well, removing points at the same location. + + +template <typename MultiLineString> +struct unique<MultiLineString, multi_linestring_tag> + : detail::unique::multi_unique<detail::unique::range_unique> {}; -template <typename Polygon, typename ComparePolicy> -struct unique<polygon_tag, Polygon, ComparePolicy> - : detail::unique::polygon_unique<Polygon, ComparePolicy> +template <typename MultiPolygon> +struct unique<MultiPolygon, multi_polygon_tag> + : detail::unique::multi_unique<detail::unique::polygon_unique> {}; @@ -139,12 +175,7 @@ inline void unique(Geometry& geometry) > policy; - dispatch::unique - < - typename tag<Geometry>::type, - Geometry, - policy - >::apply(geometry, policy()); + dispatch::unique<Geometry>::apply(geometry, policy()); } }} // namespace boost::geometry |