summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/unique.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/unique.hpp')
-rw-r--r--boost/geometry/algorithms/unique.hpp85
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