Boost logo

Boost-Commit :

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>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk