mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-10 11:32:15 +00:00
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 [SVN r70571]
This commit is contained in:
@@ -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 @@ inline bool range_ok(Range const& range, Point& centroid)
|
||||
\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 @@ struct centroid_ring_state
|
||||
}
|
||||
};
|
||||
|
||||
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 @@ struct centroid_polygon_state
|
||||
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 @@ struct centroid<box_tag, Box, Point, Strategy>
|
||||
|
||||
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 @@ struct centroid<ring_tag, Ring, Point, Strategy>
|
||||
|
||||
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 @@ inline void centroid(Geometry const& geometry, Point& c)
|
||||
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
|
||||
|
||||
@@ -35,6 +35,19 @@ struct single_tag {};
|
||||
/// 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 multi_tag {};
|
||||
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 {};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -99,6 +99,27 @@ struct centroid_multi
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
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,
|
||||
|
||||
@@ -16,13 +16,13 @@ namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
/// 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 {};
|
||||
|
||||
@@ -80,8 +80,15 @@ public :
|
||||
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
|
||||
<
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -147,17 +147,11 @@ private :
|
||||
, 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 @@ public :
|
||||
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
|
||||
<
|
||||
|
||||
@@ -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
|
||||
@@ -51,29 +51,6 @@ template
|
||||
typename Geometry
|
||||
>
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user