unique.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  6. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  7. // Use, modification and distribution is subject to the Boost Software License,
  8. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_GEOMETRY_ALGORITHMS_UNIQUE_HPP
  11. #define BOOST_GEOMETRY_ALGORITHMS_UNIQUE_HPP
  12. #include <algorithm>
  13. #include <boost/range.hpp>
  14. #include <boost/typeof/typeof.hpp>
  15. #include <boost/geometry/core/interior_rings.hpp>
  16. #include <boost/geometry/core/mutable_range.hpp>
  17. #include <boost/geometry/geometries/concepts/check.hpp>
  18. #include <boost/geometry/policies/compare.hpp>
  19. namespace boost { namespace geometry
  20. {
  21. #ifndef DOXYGEN_NO_DETAIL
  22. namespace detail { namespace unique
  23. {
  24. struct range_unique
  25. {
  26. template <typename Range, typename ComparePolicy>
  27. static inline void apply(Range& range, ComparePolicy const& policy)
  28. {
  29. typename boost::range_iterator<Range>::type it
  30. = std::unique
  31. (
  32. boost::begin(range),
  33. boost::end(range),
  34. policy
  35. );
  36. traits::resize<Range>::apply(range, it - boost::begin(range));
  37. }
  38. };
  39. struct polygon_unique
  40. {
  41. template <typename Polygon, typename ComparePolicy>
  42. static inline void apply(Polygon& polygon, ComparePolicy const& policy)
  43. {
  44. range_unique::apply(exterior_ring(polygon), policy);
  45. typename interior_return_type<Polygon>::type rings
  46. = interior_rings(polygon);
  47. for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
  48. {
  49. range_unique::apply(*it, policy);
  50. }
  51. }
  52. };
  53. }} // namespace detail::unique
  54. #endif // DOXYGEN_NO_DETAIL
  55. #ifndef DOXYGEN_NO_DISPATCH
  56. namespace dispatch
  57. {
  58. template
  59. <
  60. typename Geometry,
  61. typename Tag = typename tag<Geometry>::type
  62. >
  63. struct unique
  64. {
  65. template <typename ComparePolicy>
  66. static inline void apply(Geometry&, ComparePolicy const& )
  67. {}
  68. };
  69. template <typename Ring>
  70. struct unique<Ring, ring_tag>
  71. : detail::unique::range_unique
  72. {};
  73. template <typename LineString>
  74. struct unique<LineString, linestring_tag>
  75. : detail::unique::range_unique
  76. {};
  77. template <typename Polygon>
  78. struct unique<Polygon, polygon_tag>
  79. : detail::unique::polygon_unique
  80. {};
  81. } // namespace dispatch
  82. #endif
  83. /*!
  84. \brief \brief_calc{minimal set}
  85. \ingroup unique
  86. \details \details_calc{unique,minimal set (where duplicate consecutive points are removed)}.
  87. \tparam Geometry \tparam_geometry
  88. \param geometry \param_geometry which will be made unique
  89. \qbk{[include reference/algorithms/unique.qbk]}
  90. */
  91. template <typename Geometry>
  92. inline void unique(Geometry& geometry)
  93. {
  94. concept::check<Geometry>();
  95. // Default strategy is the default point-comparison policy
  96. typedef geometry::equal_to
  97. <
  98. typename geometry::point_type<Geometry>::type
  99. > policy;
  100. dispatch::unique<Geometry>::apply(geometry, policy());
  101. }
  102. }} // namespace boost::geometry
  103. #endif // BOOST_GEOMETRY_ALGORITHMS_UNIQUE_HPP