$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r70571 - in trunk/boost/geometry: . algorithms core multi/algorithms multi/core multi/strategies multi/strategies/cartesian strategies strategies/cartesian
From: barend.gehrels_at_[hidden]
Date: 2011-03-26 13:01:31
Author: barendgehrels
Date: 2011-03-26 13:01:28 EDT (Sat, 26 Mar 2011)
New Revision: 70571
URL: http://svn.boost.org/trac/boost/changeset/70571
Log:
Splitted strategy "centroid_weighted_length.hpp from centroid.hpp
Added tags pointlike_tag, linear_tag, areal_tag to share strategies
Implemented multi_linestring making use of weighted_length
Added:
   trunk/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/geometry/algorithms/centroid.hpp                          |    82 +++++++++++---------------------------- 
   trunk/boost/geometry/core/tags.hpp                                    |    27 +++++++++---                            
   trunk/boost/geometry/geometry.hpp                                     |     4 +                                       
   trunk/boost/geometry/multi/algorithms/centroid.hpp                    |    21 ++++++++++                              
   trunk/boost/geometry/multi/core/tags.hpp                              |     6 +-                                      
   trunk/boost/geometry/multi/strategies/cartesian/centroid_average.hpp  |    11 ++++                                    
   trunk/boost/geometry/multi/strategies/centroid.hpp                    |    35 ----------------                        
   trunk/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp |    20 --------                                
   trunk/boost/geometry/strategies/centroid.hpp                          |    23 -----------                             
   trunk/boost/geometry/strategies/strategies.hpp                        |     1                                         
   10 files changed, 85 insertions(+), 145 deletions(-)
Modified: trunk/boost/geometry/algorithms/centroid.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/centroid.hpp	(original)
+++ trunk/boost/geometry/algorithms/centroid.hpp	2011-03-26 13:01:28 EDT (Sat, 26 Mar 2011)
@@ -26,7 +26,6 @@
 #include <boost/geometry/algorithms/convert.hpp>
 #include <boost/geometry/algorithms/distance.hpp>
 #include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/iterators/segment_returning_iterator.hpp>
 #include <boost/geometry/strategies/centroid.hpp>
 #include <boost/geometry/strategies/concepts/centroid_concept.hpp>
 #include <boost/geometry/views/closeable_view.hpp>
@@ -169,7 +168,7 @@
     \brief Calculate the centroid of a ring.
 */
 template<typename Ring, closure_selector Closure, typename Strategy>
-struct centroid_ring_state
+struct centroid_range_state
 {
     static inline void apply(Ring const& ring,
             Strategy const& strategy, typename Strategy::state_type& state)
@@ -191,71 +190,26 @@
     }
 };
 
-template<typename Ring, typename Point, closure_selector Closure, typename Strategy>
-struct centroid_ring
+template<typename Range, typename Point, closure_selector Closure, typename Strategy>
+struct centroid_range
 {
-    static inline void apply(Ring const& ring, Point& centroid,
+    static inline void apply(Range const& range, Point& centroid,
             Strategy const& strategy)
     {
-        if (range_ok(ring, centroid))
+        if (range_ok(range, centroid))
         {
             typename Strategy::state_type state;
-            centroid_ring_state
+            centroid_range_state
                 <
-                    Ring,
+                    Range,
                     Closure,
                     Strategy
-                >::apply(ring, strategy, state);
+                >::apply(range, strategy, state);
             Strategy::result(state, centroid);
         }
     }
 };
 
-/*!
-    \brief Centroid of a linestring.
-*/
-template<typename Linestring, typename Point, typename Strategy>
-struct centroid_linestring
-{
-    static inline void apply(Linestring const& line, Point& centroid,
-            Strategy const& strategy)
-    {
-        if (range_ok(line, centroid))
-        {
-            // First version, should
-            // - be moved to a strategy
-            // - be made dim-agnostic
-
-            typedef typename point_type<Linestring>::type point_type;
-            typedef typename boost::range_iterator<Linestring const>::type point_iterator_type;
-            typedef segment_returning_iterator<point_iterator_type, point_type> segment_iterator;
-
-            typedef typename geometry::distance_result<Linestring>::type distance_type;
-            distance_type length = distance_type();
-            std::pair<distance_type, distance_type> average_sum;
-
-            segment_iterator it(boost::begin(line), boost::end(line));
-            segment_iterator end(boost::end(line));
-            while (it != end)
-            {
-
-                distance_type const d = geometry::distance(it->first, it->second);
-                length += d;
-
-                distance_type two(2);
-
-                distance_type const mx = (get<0>(it->first) + get<0>(it->second)) / two;
-                distance_type const my = (get<1>(it->first) + get<1>(it->second)) / two;
-                average_sum.first += d * mx;
-                average_sum.second += d * my;
-                ++it;
-            }
-
-            set<0>(centroid, average_sum.first / length );
-            set<1>(centroid, average_sum.second / length );
-        }
-    }
-};
 
 /*!
     \brief Centroid of a polygon.
@@ -270,7 +224,7 @@
     static inline void apply(Polygon const& poly,
             Strategy const& strategy, typename Strategy::state_type& state)
     {
-        typedef centroid_ring_state
+        typedef centroid_range_state
             <
                 ring_type,
                 geometry::closure<ring_type>::value,
@@ -347,7 +301,7 @@
 
 template <typename Ring, typename Point, typename Strategy>
 struct centroid<ring_tag, Ring, Point, Strategy>
-    : detail::centroid::centroid_ring
+    : detail::centroid::centroid_range
         <
             Ring,
             Point,
@@ -358,7 +312,13 @@
 
 template <typename Linestring, typename Point, typename Strategy>
 struct centroid<linestring_tag, Linestring, Point, Strategy>
-    : detail::centroid::centroid_linestring<Linestring, Point, Strategy>
+    : detail::centroid::centroid_range
+        <
+            Linestring,
+            Point,
+            closed,
+            Strategy
+        >
  {};
 
 template <typename Polygon, typename Point, typename Strategy>
@@ -431,7 +391,13 @@
     typedef typename strategy::centroid::services::default_strategy
         <
             typename cs_tag<Geometry>::type,
-            typename tag<Geometry>::type,
+            typename tag_cast
+                <
+                    typename tag<Geometry>::type,
+                    pointlike_tag,
+                    linear_tag,
+                    areal_tag
+                >::type,
             dimension<Geometry>::type::value,
             Point,
             Geometry
Modified: trunk/boost/geometry/core/tags.hpp
==============================================================================
--- trunk/boost/geometry/core/tags.hpp	(original)
+++ trunk/boost/geometry/core/tags.hpp	2011-03-26 13:01:28 EDT (Sat, 26 Mar 2011)
@@ -35,6 +35,19 @@
 /// For multiple-geometries (multi_point, multi_linestring, multi_polygon)
 struct multi_tag {};
 
+/// For point-like types (point, multi_point)
+struct pointlike_tag {};
+
+/// For linear types (linestring, multi-linestring, segment)
+struct linear_tag {};
+
+/// For areal types (polygon, multi_polygon, box, ring)
+struct areal_tag {};
+
+/// For volume types (also box (?), polyhedron)
+struct volumetric_tag {};
+
+
 // Tags defining geometry types
 
 
@@ -42,22 +55,22 @@
 struct geometry_not_recognized_tag {};
 
 /// OGC Point identifying tag
-struct point_tag : single_tag {};
+struct point_tag : single_tag, pointlike_tag {};
 
 /// OGC Linestring identifying tag
-struct linestring_tag : single_tag  {};
+struct linestring_tag : single_tag, linear_tag {};
 
 /// OGC Polygon identifying tag
-struct polygon_tag : single_tag  {};
+struct polygon_tag : single_tag, areal_tag {};
 
 /// Convenience (linear) ring identifying tag
-struct ring_tag : single_tag  {};
+struct ring_tag : single_tag, areal_tag {};
 
-/// Convenience 2D or 3D box (mbr) identifying tag
-struct box_tag : single_tag  {};
+/// Convenience 2D or 3D box (mbr / aabb) identifying tag
+struct box_tag : single_tag, areal_tag {};
 
 /// Convenience segment (2-points) identifying tag
-struct segment_tag : single_tag  {};
+struct segment_tag : single_tag, linear_tag {};
 
 
 
Modified: trunk/boost/geometry/geometry.hpp
==============================================================================
--- trunk/boost/geometry/geometry.hpp	(original)
+++ trunk/boost/geometry/geometry.hpp	2011-03-26 13:01:28 EDT (Sat, 26 Mar 2011)
@@ -65,6 +65,7 @@
 #include <boost/geometry/multi/multi.hpp>
 
 
+
 // check includes all concepts
 #include <boost/geometry/geometries/concepts/check.hpp>
 
@@ -74,4 +75,7 @@
 #include <boost/geometry/util/select_coordinate_type.hpp>
 #include <boost/geometry/util/write_dsv.hpp>
 
+#include <boost/geometry/domains/gis/io/wkt/wkt.hpp>
+
+
 #endif // BOOST_GEOMETRY_GEOMETRY_HPP
Modified: trunk/boost/geometry/multi/algorithms/centroid.hpp
==============================================================================
--- trunk/boost/geometry/multi/algorithms/centroid.hpp	(original)
+++ trunk/boost/geometry/multi/algorithms/centroid.hpp	2011-03-26 13:01:28 EDT (Sat, 26 Mar 2011)
@@ -101,6 +101,27 @@
 
 template
 <
+    typename MultiLinestring,
+    typename Point,
+    typename Strategy
+>
+struct centroid<multi_linestring_tag, MultiLinestring, Point,  Strategy>
+    : detail::centroid::centroid_multi
+        <
+            MultiLinestring,
+            Point,
+            Strategy,
+            detail::centroid::centroid_range_state
+                <
+                    typename boost::range_value<MultiLinestring>::type,
+                    closed,
+                    Strategy
+                >
+        >
+{};
+
+template
+<
     typename MultiPolygon,
     typename Point,
     typename Strategy
Modified: trunk/boost/geometry/multi/core/tags.hpp
==============================================================================
--- trunk/boost/geometry/multi/core/tags.hpp	(original)
+++ trunk/boost/geometry/multi/core/tags.hpp	2011-03-26 13:01:28 EDT (Sat, 26 Mar 2011)
@@ -16,13 +16,13 @@
 {
 
 /// OGC Multi point identifying tag
-struct multi_point_tag : multi_tag  {};
+struct multi_point_tag : multi_tag, pointlike_tag  {};
 
 /// OGC Multi linestring identifying tag
-struct multi_linestring_tag : multi_tag {};
+struct multi_linestring_tag : multi_tag, linear_tag {};
 
 /// OGC Multi polygon identifying tag
-struct multi_polygon_tag : multi_tag{};
+struct multi_polygon_tag : multi_tag, areal_tag {};
 
 /// OGC Geometry Collection identifying tag
 struct geometry_collection_tag : multi_tag {};
Modified: trunk/boost/geometry/multi/strategies/cartesian/centroid_average.hpp
==============================================================================
--- trunk/boost/geometry/multi/strategies/cartesian/centroid_average.hpp	(original)
+++ trunk/boost/geometry/multi/strategies/cartesian/centroid_average.hpp	2011-03-26 13:01:28 EDT (Sat, 26 Mar 2011)
@@ -80,8 +80,15 @@
 namespace services
 {
 
-template <typename Point, typename Geometry>
-struct default_strategy<cartesian_tag, multi_point_tag, 2, Point, Geometry>
+template <typename Point, std::size_t DimensionCount, typename Geometry>
+struct default_strategy
+<
+    cartesian_tag,
+    pointlike_tag,
+    DimensionCount,
+    Point,
+    Geometry
+>
 {
     typedef average
         <
Modified: trunk/boost/geometry/multi/strategies/centroid.hpp
==============================================================================
--- trunk/boost/geometry/multi/strategies/centroid.hpp	(original)
+++ trunk/boost/geometry/multi/strategies/centroid.hpp	2011-03-26 13:01:28 EDT (Sat, 26 Mar 2011)
@@ -6,37 +6,4 @@
 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
-#ifndef BOOST_GEOMETRY_MULTI_STRATEGY_CENTROID_HPP
-#define BOOST_GEOMETRY_MULTI_STRATEGY_CENTROID_HPP
-
-#include <boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp>
-
-
-namespace boost { namespace geometry
-{
-
-
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-
-namespace strategy { namespace centroid { namespace services
-{
-
-template <typename Point, typename Geometry>
-struct default_strategy<cartesian_tag, multi_polygon_tag, 2, Point, Geometry>
-{
-    typedef bashein_detmer
-        <
-            Point,
-            typename point_type<Geometry>::type
-        > type;
-};
-
-}}} // namespace strategy::centroid::services
-
-
-#endif //  DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-
-}} // namespace boost::geometry
-
-
-#endif // BOOST_GEOMETRY_MULTI_STRATEGY_CENTROID_HPP
+// obsolete
Modified: trunk/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
==============================================================================
--- trunk/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp	(original)
+++ trunk/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp	2011-03-26 13:01:28 EDT (Sat, 26 Mar 2011)
@@ -147,17 +147,11 @@
             , sum_y(calculation_type())
         {
             typedef calculation_type ct;
-            //std::cout << "-> calctype: " << typeid(ct).name()
-            //    << " size: " << sizeof(ct)
-            //    << " init: " << sum_a2
-            //    << std::endl;
         }
     };
 
 public :
     typedef sums state_type;
-    typedef Point point_type;
-    typedef PointOfSegment segment_point_type;
 
     static inline void apply(PointOfSegment const& p1,
             PointOfSegment const& p2, sums& state)
@@ -215,19 +209,9 @@
 namespace services
 {
 
-// Register this strategy for rings and polygons, in two dimensions
+// Register this strategy for rings and (multi)polygons, in two dimensions
 template <typename Point, typename Geometry>
-struct default_strategy<cartesian_tag, ring_tag, 2, Point, Geometry>
-{
-    typedef bashein_detmer
-        <
-            Point,
-            typename point_type<Geometry>::type
-        > type;
-};
-
-template <typename Point, typename Geometry>
-struct default_strategy<cartesian_tag, polygon_tag, 2, Point, Geometry>
+struct default_strategy<cartesian_tag, areal_tag, 2, Point, Geometry>
 {
     typedef bashein_detmer
         <
Added: trunk/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp	2011-03-26 13:01:28 EDT (Sat, 26 Mar 2011)
@@ -0,0 +1,139 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
+
+#include <cstddef>
+
+#include <boost/array.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+#include <boost/geometry/strategies/centroid.hpp>
+#include <boost/geometry/strategies/distance_result.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+// Note: when calling the namespace "centroid", it sometimes,
+// somehow, in gcc, gives compilation problems (confusion with function centroid).
+
+namespace strategy { namespace centroid
+{
+
+namespace detail
+{
+
+template <typename Type, std::size_t DimensionCount>
+struct weighted_length_sums
+{
+    Type length;
+    boost::array<Type, DimensionCount> average_sum;
+
+    inline weighted_length_sums()
+        : length(Type())
+    {
+        for (std::size_t i = 0; i < DimensionCount; i++)
+        {
+            average_sum[i] = Type();
+        }
+    }
+};
+}
+
+template
+<
+    typename Point,
+    typename PointOfSegment = Point
+>
+class weighted_length
+{
+private :
+    typedef typename select_most_precise
+        <
+            typename distance_result<Point>::type,
+            typename distance_result<PointOfSegment>::type
+        >::type distance_type;
+
+public :
+    typedef detail::weighted_length_sums<distance_type, 2> state_type;
+
+    static inline void apply(PointOfSegment const& p1,
+            PointOfSegment const& p2, state_type& state)
+    {
+        distance_type const d = geometry::distance(p1, p2);
+        state.length += d;
+
+        distance_type two(2);
+
+        // Might be made generic for N dimensions using specializations
+        distance_type const mx = (get<0>(p1) + get<0>(p2)) / two;
+        distance_type const my = (get<1>(p1) + get<1>(p2)) / two;
+        state.average_sum[0] += d * mx;
+        state.average_sum[1] += d * my;
+    }
+
+    static inline bool result(state_type const& state, Point& centroid)
+    {
+        distance_type const zero = distance_type();
+        if (! geometry::math::equals(state.length, zero))
+        {
+            set<0>(centroid, state.average_sum[0] / state.length);
+            set<1>(centroid, state.average_sum[1] / state.length);
+            return true;
+        }
+
+        return false;
+    }
+
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+// Register this strategy for linestrings and polygons, in two or three dimensions
+template <typename Point, typename Geometry>
+struct default_strategy
+<
+    cartesian_tag,
+    linear_tag,
+    2,
+    Point,
+    Geometry
+>
+{
+    typedef weighted_length
+        <
+            Point,
+            typename point_type<Geometry>::type
+        > type;
+};
+
+
+
+} // namespace services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::centroid
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
Modified: trunk/boost/geometry/strategies/centroid.hpp
==============================================================================
--- trunk/boost/geometry/strategies/centroid.hpp	(original)
+++ trunk/boost/geometry/strategies/centroid.hpp	2011-03-26 13:01:28 EDT (Sat, 26 Mar 2011)
@@ -52,29 +52,6 @@
 >
 struct default_strategy
 {
-    BOOST_MPL_ASSERT_MSG
-        (
-            false, NOT_IMPLEMENTED_FOR_THIS_TYPES
-            , (types<Point, Geometry>)
-        );
-};
-
-// Register NA-strategy for all where not applicable
-template <typename Point, typename Geometry, std::size_t Dimension>
-struct default_strategy<cartesian_tag, point_tag, Dimension, Point, Geometry>
-{
-    typedef not_applicable_strategy type;
-};
-
-template <typename Point, typename Geometry, std::size_t Dimension>
-struct default_strategy<cartesian_tag, box_tag, Dimension, Point, Geometry>
-{
-    typedef not_applicable_strategy type;
-};
-
-template <typename Point, typename Geometry, std::size_t Dimension>
-struct default_strategy<cartesian_tag, linestring_tag, Dimension, Point, Geometry>
-{
     typedef not_applicable_strategy type;
 };
 
Modified: trunk/boost/geometry/strategies/strategies.hpp
==============================================================================
--- trunk/boost/geometry/strategies/strategies.hpp	(original)
+++ trunk/boost/geometry/strategies/strategies.hpp	2011-03-26 13:01:28 EDT (Sat, 26 Mar 2011)
@@ -25,6 +25,7 @@
 
 #include <boost/geometry/strategies/cartesian/area_surveyor.hpp>
 #include <boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp>
+#include <boost/geometry/strategies/cartesian/centroid_weighted_length.hpp>
 #include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
 #include <boost/geometry/strategies/cartesian/distance_projected_point.hpp>
 #include <boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp>