diff DEPENDENCIES/generic/include/boost/geometry/algorithms/simplify.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
line wrap: on
line diff
--- a/DEPENDENCIES/generic/include/boost/geometry/algorithms/simplify.hpp	Fri Sep 04 12:01:02 2015 +0100
+++ b/DEPENDENCIES/generic/include/boost/geometry/algorithms/simplify.hpp	Mon Sep 07 11:12:49 2015 +0100
@@ -1,8 +1,8 @@
 // Boost.Geometry (aka GGL, Generic Geometry Library)
 
-// 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) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
 
 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -14,28 +14,33 @@
 #ifndef BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
 #define BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
 
-
 #include <cstddef>
 
+#include <boost/core/ignore_unused.hpp>
 #include <boost/range.hpp>
-#include <boost/typeof/typeof.hpp>
+
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
 
 #include <boost/geometry/core/cs.hpp>
 #include <boost/geometry/core/closure.hpp>
-#include <boost/geometry/core/ring_type.hpp>
 #include <boost/geometry/core/exterior_ring.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/strategies/agnostic/simplify_douglas_peucker.hpp>
 #include <boost/geometry/strategies/concepts/simplify_concept.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
+#include <boost/geometry/strategies/distance.hpp>
 
 #include <boost/geometry/algorithms/clear.hpp>
 #include <boost/geometry/algorithms/convert.hpp>
 #include <boost/geometry/algorithms/not_implemented.hpp>
-#include <boost/geometry/algorithms/num_interior_rings.hpp>
 
+#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
 
 namespace boost { namespace geometry
 {
@@ -50,6 +55,8 @@
     static inline void apply(Range const& range, OutputIterator out,
                              Distance const& max_distance, Strategy const& strategy)
     {
+        boost::ignore_unused(strategy);
+
         if (boost::size(range) <= 2 || max_distance < 0)
         {
             std::copy(boost::begin(range), boost::end(range), out);
@@ -114,13 +121,54 @@
 
 struct simplify_polygon
 {
+private:
+
+    template
+    <
+        std::size_t Minimum,
+        typename IteratorIn,
+        typename IteratorOut,
+        typename Distance,
+        typename Strategy
+    >
+    static inline void iterate(IteratorIn begin, IteratorIn end,
+                    IteratorOut it_out,
+                    Distance const& max_distance, Strategy const& strategy)
+    {
+        for (IteratorIn it_in = begin; it_in != end;  ++it_in, ++it_out)
+        {
+            simplify_range<Minimum>::apply(*it_in, *it_out, max_distance, strategy);
+        }
+    }
+
+    template
+    <
+        std::size_t Minimum,
+        typename InteriorRingsIn,
+        typename InteriorRingsOut,
+        typename Distance,
+        typename Strategy
+    >
+    static inline void apply_interior_rings(
+                    InteriorRingsIn const& interior_rings_in,
+                    InteriorRingsOut& interior_rings_out,
+                    Distance const& max_distance, Strategy const& strategy)
+    {
+        traits::resize<InteriorRingsOut>::apply(interior_rings_out,
+            boost::size(interior_rings_in));
+
+        iterate<Minimum>(
+            boost::begin(interior_rings_in), boost::end(interior_rings_in),
+            boost::begin(interior_rings_out),
+            max_distance, strategy);
+    }
+
+public:
     template <typename Polygon, typename Strategy, typename Distance>
     static inline void apply(Polygon const& poly_in, Polygon& poly_out,
                     Distance const& max_distance, Strategy const& strategy)
     {
-        typedef typename ring_type<Polygon>::type ring_type;
-
-        int const Minimum = core_detail::closure::minimum_ring_size
+        std::size_t const minimum = core_detail::closure::minimum_ring_size
             <
                 geometry::closure<Polygon>::value
             >::value;
@@ -128,28 +176,34 @@
         // Note that if there are inner rings, and distance is too large,
         // they might intersect with the outer ring in the output,
         // while it didn't in the input.
-        simplify_range<Minimum>::apply(exterior_ring(poly_in),
+        simplify_range<minimum>::apply(exterior_ring(poly_in),
                                        exterior_ring(poly_out),
                                        max_distance, strategy);
 
-        traits::resize
-            <
-                typename boost::remove_reference
-                <
-                    typename traits::interior_mutable_type<Polygon>::type
-                >::type
-            >::apply(interior_rings(poly_out), num_interior_rings(poly_in));
+        apply_interior_rings<minimum>(interior_rings(poly_in),
+                                      interior_rings(poly_out),
+                                      max_distance, strategy);
+    }
+};
 
-        typename interior_return_type<Polygon const>::type rings_in
-                    = interior_rings(poly_in);
-        typename interior_return_type<Polygon>::type rings_out
-                    = interior_rings(poly_out);
-        BOOST_AUTO_TPL(it_out, boost::begin(rings_out));
-        for (BOOST_AUTO_TPL(it_in,  boost::begin(rings_in));
-            it_in != boost::end(rings_in);
-            ++it_in, ++it_out)
+
+template<typename Policy>
+struct simplify_multi
+{
+    template <typename MultiGeometry, typename Strategy, typename Distance>
+    static inline void apply(MultiGeometry const& multi, MultiGeometry& out,
+                    Distance const& max_distance, Strategy const& strategy)
+    {
+        traits::resize<MultiGeometry>::apply(out, boost::size(multi));
+
+        typename boost::range_iterator<MultiGeometry>::type it_out
+                = boost::begin(out);
+        for (typename boost::range_iterator<MultiGeometry const>::type
+                it_in = boost::begin(multi);
+             it_in != boost::end(multi);
+             ++it_in, ++it_out)
         {
-            simplify_range<Minimum>::apply(*it_in, *it_out, max_distance, strategy);
+            Policy::apply(*it_in, *it_out, max_distance, strategy);
         }
     }
 };
@@ -224,11 +278,168 @@
     : detail::simplify::simplify_range_insert
 {};
 
+template <typename MultiPoint>
+struct simplify<MultiPoint, multi_point_tag>
+    : detail::simplify::simplify_copy
+{};
+
+
+template <typename MultiLinestring>
+struct simplify<MultiLinestring, multi_linestring_tag>
+    : detail::simplify::simplify_multi<detail::simplify::simplify_range<2> >
+{};
+
+
+template <typename MultiPolygon>
+struct simplify<MultiPolygon, multi_polygon_tag>
+    : detail::simplify::simplify_multi<detail::simplify::simplify_polygon>
+{};
+
 
 } // namespace dispatch
 #endif // DOXYGEN_NO_DISPATCH
 
 
+namespace resolve_strategy
+{
+
+struct simplify
+{
+    template <typename Geometry, typename Distance, typename Strategy>
+    static inline void apply(Geometry const& geometry,
+                             Geometry& out,
+                             Distance const& max_distance,
+                             Strategy const& strategy)
+    {
+        dispatch::simplify<Geometry>::apply(geometry, out, max_distance, strategy);
+    }
+
+    template <typename Geometry, typename Distance>
+    static inline void apply(Geometry const& geometry,
+                             Geometry& out,
+                             Distance const& max_distance,
+                             default_strategy)
+    {
+        typedef typename point_type<Geometry>::type point_type;
+
+        typedef typename strategy::distance::services::default_strategy
+        <
+            point_tag, segment_tag, point_type
+        >::type ds_strategy_type;
+
+        typedef strategy::simplify::douglas_peucker
+        <
+            point_type, ds_strategy_type
+        > strategy_type;
+
+        BOOST_CONCEPT_ASSERT(
+            (concept::SimplifyStrategy<strategy_type, point_type>)
+        );
+
+        apply(geometry, out, max_distance, strategy_type());
+    }
+};
+
+struct simplify_insert
+{
+    template
+    <
+        typename Geometry,
+        typename OutputIterator,
+        typename Distance,
+        typename Strategy
+    >
+    static inline void apply(Geometry const& geometry,
+                             OutputIterator& out,
+                             Distance const& max_distance,
+                             Strategy const& strategy)
+    {
+        dispatch::simplify_insert<Geometry>::apply(geometry, out, max_distance, strategy);
+    }
+
+    template <typename Geometry, typename OutputIterator, typename Distance>
+    static inline void apply(Geometry const& geometry,
+                             OutputIterator& out,
+                             Distance const& max_distance,
+                             default_strategy)
+    {
+        typedef typename point_type<Geometry>::type point_type;
+
+        typedef typename strategy::distance::services::default_strategy
+        <
+            point_tag, segment_tag, point_type
+        >::type ds_strategy_type;
+
+        typedef strategy::simplify::douglas_peucker
+        <
+            point_type, ds_strategy_type
+        > strategy_type;
+
+        BOOST_CONCEPT_ASSERT(
+            (concept::SimplifyStrategy<strategy_type, point_type>)
+        );
+
+        apply(geometry, out, max_distance, strategy_type());
+    }
+};
+
+} // namespace resolve_strategy
+
+
+namespace resolve_variant {
+
+template <typename Geometry>
+struct simplify
+{
+    template <typename Distance, typename Strategy>
+    static inline void apply(Geometry const& geometry,
+                             Geometry& out,
+                             Distance const& max_distance,
+                             Strategy const& strategy)
+    {
+        resolve_strategy::simplify::apply(geometry, out, max_distance, strategy);
+    }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct simplify<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+    template <typename Distance, typename Strategy>
+    struct visitor: boost::static_visitor<void>
+    {
+        Distance const& m_max_distance;
+        Strategy const& m_strategy;
+
+        visitor(Distance const& max_distance, Strategy const& strategy)
+            : m_max_distance(max_distance)
+            , m_strategy(strategy)
+        {}
+
+        template <typename Geometry>
+        void operator()(Geometry const& geometry, Geometry& out) const
+        {
+            simplify<Geometry>::apply(geometry, out, m_max_distance, m_strategy);
+        }
+    };
+
+    template <typename Distance, typename Strategy>
+    static inline void
+    apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
+          boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& out,
+          Distance const& max_distance,
+          Strategy const& strategy)
+    {
+        boost::apply_visitor(
+            visitor<Distance, Strategy>(max_distance, strategy),
+            geometry,
+            out
+        );
+    }
+};
+
+} // namespace resolve_variant
+
+
 /*!
 \brief Simplify a geometry using a specified strategy
 \ingroup simplify
@@ -252,13 +463,9 @@
 {
     concept::check<Geometry>();
 
-    BOOST_CONCEPT_ASSERT(
-        (concept::SimplifyStrategy<Strategy, typename point_type<Geometry>::type>)
-    );
-
     geometry::clear(out);
 
-    dispatch::simplify<Geometry>::apply(geometry, out, max_distance, strategy);
+    resolve_variant::simplify<Geometry>::apply(geometry, out, max_distance, strategy);
 }
 
 
@@ -284,18 +491,7 @@
 {
     concept::check<Geometry>();
 
-    typedef typename point_type<Geometry>::type point_type;
-    typedef typename strategy::distance::services::default_strategy
-            <
-                segment_tag, point_type
-            >::type ds_strategy_type;
-
-    typedef strategy::simplify::douglas_peucker
-        <
-            point_type, ds_strategy_type
-        > strategy_type;
-
-    simplify(geometry, out, max_distance, strategy_type());
+    simplify(geometry, out, max_distance, default_strategy());
 }
 
 
@@ -321,14 +517,11 @@
 */
 template<typename Geometry, typename OutputIterator, typename Distance, typename Strategy>
 inline void simplify_insert(Geometry const& geometry, OutputIterator out,
-                              Distance const& max_distance, Strategy const& strategy)
+                            Distance const& max_distance, Strategy const& strategy)
 {
     concept::check<Geometry const>();
-    BOOST_CONCEPT_ASSERT(
-        (concept::SimplifyStrategy<Strategy, typename point_type<Geometry>::type>)
-    );
 
-    dispatch::simplify_insert<Geometry>::apply(geometry, out, max_distance, strategy);
+    resolve_strategy::simplify_insert::apply(geometry, out, max_distance, strategy);
 }
 
 /*!
@@ -344,25 +537,13 @@
  */
 template<typename Geometry, typename OutputIterator, typename Distance>
 inline void simplify_insert(Geometry const& geometry, OutputIterator out,
-                              Distance const& max_distance)
+                            Distance const& max_distance)
 {
-    typedef typename point_type<Geometry>::type point_type;
-
     // Concept: output point type = point type of input geometry
     concept::check<Geometry const>();
-    concept::check<point_type>();
+    concept::check<typename point_type<Geometry>::type>();
 
-    typedef typename strategy::distance::services::default_strategy
-        <
-            segment_tag, point_type
-        >::type ds_strategy_type;
-
-    typedef strategy::simplify::douglas_peucker
-        <
-            point_type, ds_strategy_type
-        > strategy_type;
-
-    dispatch::simplify_insert<Geometry>::apply(geometry, out, max_distance, strategy_type());
+    simplify_insert(geometry, out, max_distance, default_strategy());
 }
 
 }} // namespace detail::simplify