$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r62172 - in sandbox/geometry: boost/geometry/algorithms boost/geometry/geometries boost/geometry/iterators boost/geometry/multi/algorithms libs/geometry/example libs/geometry/test/algorithms libs/geometry/test/iterators
From: barend.gehrels_at_[hidden]
Date: 2010-05-24 09:54:34
Author: barendgehrels
Date: 2010-05-24 09:54:32 EDT (Mon, 24 May 2010)
New Revision: 62172
URL: http://svn.boost.org/trac/boost/changeset/62172
Log:
Corrected closure for area
Added closure for centroid
Modified/fixed closing iterator (didn't compile for MSVC 2010)
Text files modified: 
   sandbox/geometry/boost/geometry/algorithms/area.hpp                |     3 -                                       
   sandbox/geometry/boost/geometry/algorithms/centroid.hpp            |    75 ++++++++++++++++++++------------------- 
   sandbox/geometry/boost/geometry/algorithms/correct.hpp             |    12 +++++                                   
   sandbox/geometry/boost/geometry/algorithms/transform.hpp           |     3 +                                       
   sandbox/geometry/boost/geometry/geometries/linear_ring.hpp         |    22 +++++++++++                             
   sandbox/geometry/boost/geometry/iterators/closing_iterator.hpp     |    24 +++++------                             
   sandbox/geometry/boost/geometry/multi/algorithms/centroid.hpp      |     7 ++-                                     
   sandbox/geometry/libs/geometry/example/custom_examples.sln         |     6 +++                                     
   sandbox/geometry/libs/geometry/test/algorithms/centroid.cpp        |     5 ++                                      
   sandbox/geometry/libs/geometry/test/algorithms/correct.cpp         |    26 ++++++++++---                           
   sandbox/geometry/libs/geometry/test/iterators/closing_iterator.cpp |    25 +++++++++++++                           
   11 files changed, 147 insertions(+), 61 deletions(-)
Modified: sandbox/geometry/boost/geometry/algorithms/area.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/area.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/area.hpp	2010-05-24 09:54:32 EDT (Mon, 24 May 2010)
@@ -31,7 +31,6 @@
 
 #include <boost/geometry/strategies/concepts/area_concept.hpp>
 
-#include <boost/geometry/util/closure_as_bool.hpp>
 #include <boost/geometry/util/math.hpp>
 #include <boost/geometry/util/order_as_direction.hpp>
 #include <boost/geometry/util/closeable_view.hpp>
@@ -122,7 +121,7 @@
         typedef closeable_view
             <
                 rview_type const,
-                Closure == closed
+                Closure == open // close it if it is open
             > view_type;
         typedef typename boost::range_iterator<view_type const>::type iterator_type;
 
Modified: sandbox/geometry/boost/geometry/algorithms/centroid.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/centroid.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/centroid.hpp	2010-05-24 09:54:32 EDT (Mon, 24 May 2010)
@@ -15,16 +15,19 @@
 
 #include <boost/range.hpp>
 
-#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/core/closure.hpp>
 #include <boost/geometry/core/cs.hpp>
 #include <boost/geometry/core/coordinate_dimension.hpp>
 #include <boost/geometry/core/exception.hpp>
 #include <boost/geometry/core/exterior_ring.hpp>
 #include <boost/geometry/core/interior_rings.hpp>
+
+#include <boost/geometry/algorithms/distance.hpp>
 #include <boost/geometry/geometries/concepts/check.hpp>
 #include <boost/geometry/iterators/segment_iterator.hpp>
 #include <boost/geometry/strategies/centroid.hpp>
 #include <boost/geometry/strategies/concepts/centroid_concept.hpp>
+#include <boost/geometry/util/closeable_view.hpp>
 #include <boost/geometry/util/copy.hpp>
 #include <boost/geometry/util/for_each_coordinate.hpp>
 
@@ -182,41 +185,34 @@
 /*!
     \brief Calculate the centroid of a ring.
 */
-template<typename Ring, typename Strategy>
+template<typename Ring, closure_selector Closure, typename Strategy>
 struct centroid_ring_state
 {
     static inline void apply(Ring const& ring,
             Strategy const& strategy, typename Strategy::state_type& state)
     {
-        typedef typename boost::range_iterator<Ring const>::type iterator_type;
-        iterator_type it = boost::begin(ring);
+        typedef closeable_view
+            <
+                Ring const,
+                Closure == open // close it if it is open
+            > view_type;
+
+        typedef typename boost::range_iterator<view_type const>::type iterator_type;
+
+        view_type view(ring);
+        iterator_type it = boost::begin(view);
+        iterator_type end = boost::end(view);
+
         for (iterator_type previous = it++;
-            it != boost::end(ring);
-            previous = it++)
+            it != end;
+            ++previous, ++it)
         {
             Strategy::apply(*previous, *it, state);
         }
-
-        /* using segment_iterator: nice, well looking, but much slower...
-            normal iterator: 0.156 s
-            segment iterator: 1.985 s...
-        typedef segment_iterator
-            <
-                typename boost::range_iterator<Ring const>::type,
-                typename point_type<Ring>::type
-            > iterator_type;
-
-        iterator_type it(boost::begin(ring), boost::end(ring));
-        iterator_type end(boost::end(ring));
-        for(; it != end; ++it)
-        {
-            Strategy::apply(it->first, it->second, state);
-        }
-        */
     }
 };
 
-template<typename Ring, typename Point, typename Strategy>
+template<typename Ring, typename Point, closure_selector Closure, typename Strategy>
 struct centroid_ring
 {
     static inline void apply(Ring const& ring, Point& centroid,
@@ -228,6 +224,7 @@
             centroid_ring_state
                 <
                     Ring,
+                    Closure,
                     Strategy
                 >::apply(ring, strategy, state);
             Strategy::result(state, centroid);
@@ -279,7 +276,7 @@
     \note Because outer ring is clockwise, inners are counter clockwise,
     triangle approach is OK and works for polygons with rings.
 */
-template<typename Polygon, typename Strategy>
+template<typename Polygon, closure_selector Closure, typename Strategy>
 struct centroid_polygon_state
 {
     static inline void apply(Polygon const& poly,
@@ -288,6 +285,7 @@
         typedef centroid_ring_state
             <
                 typename ring_type<Polygon>::type,
+                Closure,
                 Strategy
             > per_ring;
 
@@ -305,7 +303,7 @@
     }
 };
 
-template<typename Polygon, typename Point, typename Strategy>
+template<typename Polygon, typename Point, closure_selector Closure, typename Strategy>
 struct centroid_polygon
 {
     static inline void apply(Polygon const& poly, Point& centroid,
@@ -317,6 +315,7 @@
             centroid_polygon_state
                 <
                     Polygon,
+                    Closure,
                     Strategy
                 >::apply(poly, strategy, state);
             Strategy::result(state, centroid);
@@ -338,6 +337,7 @@
     typename Tag,
     typename Geometry,
     typename Point,
+    closure_selector Closure,
     typename Strategy
 >
 struct centroid {};
@@ -346,9 +346,10 @@
 <
     typename Geometry,
     typename Point,
+    closure_selector Closure,
     typename Strategy
 >
-struct centroid<point_tag, Geometry, Point, Strategy>
+struct centroid<point_tag, Geometry, Point, Closure, Strategy>
     : detail::centroid::centroid_point<Geometry, Point, Strategy>
 {};
 
@@ -356,25 +357,26 @@
 <
     typename Box,
     typename Point,
+    closure_selector Closure,
     typename Strategy
 >
-struct centroid<box_tag, Box, Point, Strategy>
+struct centroid<box_tag, Box, Point, Closure, Strategy>
     : detail::centroid::centroid_box<Box, Point, Strategy>
 {};
 
-template <typename Ring, typename Point, typename Strategy>
-struct centroid<ring_tag, Ring, Point, Strategy>
-    : detail::centroid::centroid_ring<Ring, Point, Strategy>
+template <typename Ring, typename Point, closure_selector Closure, typename Strategy>
+struct centroid<ring_tag, Ring, Point, Closure, Strategy>
+    : detail::centroid::centroid_ring<Ring, Point, Closure, Strategy>
 {};
 
-template <typename Linestring, typename Point, typename Strategy>
-struct centroid<linestring_tag, Linestring, Point, Strategy>
+template <typename Linestring, typename Point, closure_selector Closure, typename Strategy>
+struct centroid<linestring_tag, Linestring, Point, Closure, Strategy>
     : detail::centroid::centroid_linestring<Linestring, Point, Strategy>
  {};
 
-template <typename Polygon, typename Point, typename Strategy>
-struct centroid<polygon_tag, Polygon, Point, Strategy>
-    : detail::centroid::centroid_polygon<Polygon, Point, Strategy>
+template <typename Polygon, typename Point, closure_selector Closure, typename Strategy>
+struct centroid<polygon_tag, Polygon, Point, Closure, Strategy>
+    : detail::centroid::centroid_polygon<Polygon, Point, Closure, Strategy>
  {};
 
 } // namespace dispatch
@@ -405,6 +407,7 @@
             typename tag<Geometry>::type,
             Geometry,
             Point,
+            geometry::closure<Geometry>::value,
             Strategy
         >::apply(geometry, c, strategy);
 }
Modified: sandbox/geometry/boost/geometry/algorithms/correct.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/correct.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/correct.hpp	2010-05-24 09:54:32 EDT (Mon, 24 May 2010)
@@ -16,6 +16,7 @@
 
 #include <boost/range.hpp>
 
+#include <boost/geometry/core/closure.hpp>
 #include <boost/geometry/core/cs.hpp>
 #include <boost/geometry/core/ring_type.hpp>
 #include <boost/geometry/core/exterior_ring.hpp>
@@ -114,12 +115,21 @@
         if (boost::size(r) > 2)
         {
             // check if closed, if not, close it
-            if (geometry::disjoint(*boost::begin(r), *(boost::end(r) - 1)))
+            bool const disjoint = geometry::disjoint(*boost::begin(r), *(boost::end(r) - 1));
+            closure_selector s = geometry::closure<Ring>::value;
+
+            if (disjoint && (s == closed))
             {
+                // Close it
                 point_type first;
                 geometry::copy_coordinates(*boost::begin(r), first);
                 *(std::back_inserter(r)++) = first;
             }
+            if (! disjoint && geometry::closure<Ring>::value != closed)
+            {
+                // Open it, TODO!
+                std::cout << "TODO";
+            }
         }
         // Check area
         Predicate predicate;
Modified: sandbox/geometry/boost/geometry/algorithms/transform.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/transform.hpp	(original)
+++ sandbox/geometry/boost/geometry/algorithms/transform.hpp	2010-05-24 09:54:32 EDT (Mon, 24 May 2010)
@@ -220,7 +220,8 @@
     {
         typedef typename point_type<Range2>::type point_type;
 
-        geometry::clear(range2);
+        // Should NOT be done here!
+        // geometry::clear(range2);
         return transform_range_out<point_type>(range1,
                 std::back_inserter(range2), strategy);
     }
Modified: sandbox/geometry/boost/geometry/geometries/linear_ring.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/geometries/linear_ring.hpp	(original)
+++ sandbox/geometry/boost/geometry/geometries/linear_ring.hpp	2010-05-24 09:54:32 EDT (Mon, 24 May 2010)
@@ -86,7 +86,29 @@
     static const order_selector value = clockwise;
 };
 
+template
+<
+    typename P,
+    template<typename, typename> class V,
+    bool PointOrder,
+    template<typename> class A
+>
+struct closure< linear_ring<P, V, PointOrder, true, A> >
+{
+    static const closure_selector value = closed;
+};
 
+template
+<
+    typename P,
+    template<typename, typename> class V,
+    bool PointOrder,
+    template<typename> class A
+>
+struct closure< linear_ring<P, V, PointOrder, false, A> >
+{
+    static const closure_selector value = open;
+};
 
 
 } // namespace traits
Modified: sandbox/geometry/boost/geometry/iterators/closing_iterator.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/iterators/closing_iterator.hpp	(original)
+++ sandbox/geometry/boost/geometry/iterators/closing_iterator.hpp	2010-05-24 09:54:32 EDT (Mon, 24 May 2010)
@@ -13,7 +13,6 @@
 #include <boost/iterator/iterator_adaptor.hpp>
 #include <boost/iterator/iterator_categories.hpp>
 
-#include <boost/geometry/iterators/base.hpp>
 
 
 namespace boost { namespace geometry
@@ -29,15 +28,14 @@
 */
 template <typename Range>
 struct closing_iterator 
-    : public detail::iterators::iterator_base
-        <
-            closing_iterator<Range>,
-            typename boost::range_iterator<Range>::type,
-            boost::forward_traversal_tag
-        >
+    : public boost::iterator_adaptor
+    <
+        closing_iterator<Range>,
+        typename boost::range_iterator<Range>::type,
+        boost::use_default,
+        boost::forward_traversal_tag
+    >
 {
-    friend class boost::iterator_core_access;
-
     explicit inline closing_iterator(Range& range)
         : m_range(range)
         , m_beyond(false)
@@ -55,15 +53,15 @@
         this->base_reference() = m_end;
     }
 
-    inline bool equal(closing_iterator const& other) const
+private:
+    friend class boost::iterator_core_access;
+
+    inline bool equal(closing_iterator<Range> const& other) const
     {
         return this->base() == other.base() 
             && this->m_beyond == other.m_beyond;
     }
 
-
-private:
-
     inline void increment()
     {
         if (m_beyond)
Modified: sandbox/geometry/boost/geometry/multi/algorithms/centroid.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/multi/algorithms/centroid.hpp	(original)
+++ sandbox/geometry/boost/geometry/multi/algorithms/centroid.hpp	2010-05-24 09:54:32 EDT (Mon, 24 May 2010)
@@ -103,9 +103,10 @@
 <
     typename MultiPolygon,
     typename Point,
+    closure_selector Closure,
     typename Strategy
 >
-struct centroid<multi_polygon_tag, MultiPolygon, Point, Strategy>
+struct centroid<multi_polygon_tag, MultiPolygon, Point, Closure, Strategy>
     : detail::centroid::centroid_multi
         <
             MultiPolygon,
@@ -114,6 +115,7 @@
             detail::centroid::centroid_polygon_state
                 <
                     typename boost::range_value<MultiPolygon>::type,
+                    Closure,
                     Strategy
                 >
         >
@@ -124,9 +126,10 @@
 <
     typename MultiPoint,
     typename Point,
+    closure_selector Closure,
     typename Strategy
 >
-struct centroid<multi_point_tag, MultiPoint, Point, Strategy>
+struct centroid<multi_point_tag, MultiPoint, Point, Closure, Strategy>
     : detail::centroid::centroid_multi
         <
             MultiPoint,
Modified: sandbox/geometry/libs/geometry/example/custom_examples.sln
==============================================================================
--- sandbox/geometry/libs/geometry/example/custom_examples.sln	(original)
+++ sandbox/geometry/libs/geometry/example/custom_examples.sln	2010-05-24 09:54:32 EDT (Mon, 24 May 2010)
@@ -18,6 +18,8 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "c08_custom_non_std_example", "c08_custom_non_std_example.vcproj", "{C215F131-F021-4155-A96E-BB2D91918A17}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "c09_custom_fusion_example", "c09_custom_fusion_example.vcproj", "{DA36AD55-E448-43DE-A974-EA765AE3967A}"
+EndProject
 Global
         GlobalSection(SolutionConfigurationPlatforms) = preSolution
                 Debug|Win32 = Debug|Win32
@@ -60,6 +62,10 @@
                 {C215F131-F021-4155-A96E-BB2D91918A17}.Debug|Win32.Build.0 = Debug|Win32
                 {C215F131-F021-4155-A96E-BB2D91918A17}.Release|Win32.ActiveCfg = Release|Win32
                 {C215F131-F021-4155-A96E-BB2D91918A17}.Release|Win32.Build.0 = Release|Win32
+		{DA36AD55-E448-43DE-A974-EA765AE3967A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DA36AD55-E448-43DE-A974-EA765AE3967A}.Debug|Win32.Build.0 = Debug|Win32
+		{DA36AD55-E448-43DE-A974-EA765AE3967A}.Release|Win32.ActiveCfg = Release|Win32
+		{DA36AD55-E448-43DE-A974-EA765AE3967A}.Release|Win32.Build.0 = Release|Win32
         EndGlobalSection
         GlobalSection(SolutionProperties) = preSolution
                 HideSolutionNode = FALSE
Modified: sandbox/geometry/libs/geometry/test/algorithms/centroid.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/algorithms/centroid.cpp	(original)
+++ sandbox/geometry/libs/geometry/test/algorithms/centroid.cpp	2010-05-24 09:54:32 EDT (Mon, 24 May 2010)
@@ -43,6 +43,11 @@
             ",3.7 1.6,3.4 1.2,2.8 1.8,2.4 1.7,2 1.3))",
         4.06923363095238, 1.65055803571429);
 
+    // open / closed
+    test_centroid<boost::geometry::linear_ring<P, std::vector, true, true> >(
+            "POLYGON((1 1,2 2,3 1,2 0,1 1))", 2.0, 1.0);
+    test_centroid<boost::geometry::linear_ring<P, std::vector, true, false> >(
+            "POLYGON((1 1,2 2,3 1,2 0))", 2.0, 1.0);
 
     test_centroid<boost::geometry::box<P> >("POLYGON((1 2,3 4))", 2, 3);
     test_centroid<P>("POINT(3 3)", 3, 3);
Modified: sandbox/geometry/libs/geometry/test/algorithms/correct.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/algorithms/correct.cpp	(original)
+++ sandbox/geometry/libs/geometry/test/algorithms/correct.cpp	2010-05-24 09:54:32 EDT (Mon, 24 May 2010)
@@ -67,10 +67,10 @@
 void test_all()
 {
     // Define clockwise and counter clockwise polygon
-    std::string cw_ring =
-            "POLYGON((0 0,0 1,1 1,1 0,0 0))";
-    std::string ccw_ring =
-            "POLYGON((0 0,1 0,1 1,0 1,0 0))";
+    std::string cw_ring       = "POLYGON((0 0,0 1,1 1,1 0,0 0))";
+    std::string ccw_ring      = "POLYGON((0 0,1 0,1 1,0 1,0 0))";
+    std::string cw_open_ring  = "POLYGON((0 0,0 1,1 1,1 0))";
+    std::string ccw_open_ring = "POLYGON((0 0,1 0,1 1,0 1))";
 
     // already cw_ring
     test_geometry<boost::geometry::linear_ring<P> >(cw_ring, cw_ring);
@@ -78,9 +78,23 @@
     // wrong order
     test_geometry<boost::geometry::linear_ring<P> >(ccw_ring, cw_ring);
 
+    // ccw-ring, input ccw-ring, already correct
+    test_geometry<boost::geometry::linear_ring<P, std::vector, false> >(ccw_ring, ccw_ring);
+
+    // ccw-ring, input cw-ring, corrected
+    test_geometry<boost::geometry::linear_ring<P, std::vector, false> >(cw_ring, ccw_ring);
+
+    // open-ring, input ccw-ring, already correct
+    test_geometry<boost::geometry::linear_ring<P, std::vector, true, false> >(cw_open_ring, cw_open_ring);
+
+    // ccw-ring, input cw-ring, corrected
+    test_geometry<boost::geometry::linear_ring<P, std::vector, true, false> >(ccw_open_ring, "POLYGON((0 1,1 1,1 0,0 0))");
+
+
+
     // not closed
     test_geometry<boost::geometry::linear_ring<P> >(
-            "POLYGON((0 0,1 0,1 1,0 1))",
+            ccw_open_ring,
             cw_ring);
 
     // counter clockwise, cw_ring
@@ -99,7 +113,7 @@
             cw_ring);
     // wrong order & not closed
     test_geometry<boost::geometry::polygon<P> >(
-            "POLYGON((0 0,1 0,1 1,0 1))",
+            ccw_open_ring,
             cw_ring);
 
 
Modified: sandbox/geometry/libs/geometry/test/iterators/closing_iterator.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/iterators/closing_iterator.cpp	(original)
+++ sandbox/geometry/libs/geometry/test/iterators/closing_iterator.cpp	2010-05-24 09:54:32 EDT (Mon, 24 May 2010)
@@ -21,6 +21,30 @@
 
 
 
+void test_minimal()
+{
+    std::vector<int> v;
+    v.push_back(1);
+    v.push_back(2);
+    v.push_back(3);
+
+    typedef boost::geometry::closing_iterator
+        <
+            std::vector<int> const
+        > closing_iterator;
+
+
+    closing_iterator it(v);
+    closing_iterator end(v, true);
+
+    std::ostringstream out;
+    for (; it != end; ++it)
+    {
+        out << *it;
+    }
+    BOOST_CHECK_EQUAL(out.str(), "1231");
+}
+
 
 
 
@@ -78,6 +102,7 @@
 template <typename P>
 void test_all()
 {
+    test_minimal();
     test_geometry<boost::geometry::linear_ring<P> >("POLYGON((1 1,1 4,4 4,4 1))");
 }