|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r57286 - in sandbox/ggl/formal_review_request/boost/ggl: . algorithms algorithms/detail algorithms/overlay core extensions/gis/geographic/strategies geometries/adapted geometries/concepts geometries/concepts/detail iterators multi multi/algorithms multi/algorithms/overlay multi/iterators multi/strategies multi/strategies/cartesian multi/util policies strategies strategies/agnostic strategies/cartesian strategies/concepts strategies/spherical strategies/transform util
From: barend.gehrels_at_[hidden]
Date: 2009-11-02 10:51:09
Author: barendgehrels
Date: 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
New Revision: 57286
URL: http://svn.boost.org/trac/boost/changeset/57286
Log:
Many tweaks for upcoming review
in overlay (intersection/union),
strategies (hull, etc), strategy-concepts.
Added:
sandbox/ggl/formal_review_request/boost/ggl/algorithms/detail/point_on_border.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/assemble.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/clip_linestring.hpp
- copied, changed from r56825, /sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection_linestring.hpp
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/sort_interior_rings.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/algorithms/union.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/iterators/range_type.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/multi/iterators/range_type.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/multi/multi.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/multi/strategies/
sandbox/ggl/formal_review_request/boost/ggl/multi/strategies/cartesian/
sandbox/ggl/formal_review_request/boost/ggl/multi/strategies/cartesian/centroid_average.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/multi/strategies/centroid.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/multi/util/for_each_range.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/policies/compare.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/hull_graham_andrew.hpp
- copied, changed from r57036, /sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_convex_hull.hpp
sandbox/ggl/formal_review_request/boost/ggl/strategies/area.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/distance_projected_point.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/distance_pythagoras.hpp
- copied, changed from r57036, /sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_distance.hpp
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/side_by_triangle.hpp
- copied, changed from r57147, /sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_side.hpp
sandbox/ggl/formal_review_request/boost/ggl/strategies/centroid.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/compare.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/convex_hull_concept.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/convex_hull.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/distance.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/parse.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/point_in_poly.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/side.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/compare_circular.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/tags.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/strategies/transform.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/util/add_const_if_c.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/util/for_each_range.hpp (contents, props changed)
sandbox/ggl/formal_review_request/boost/ggl/util/range_iterator_const_if_c.hpp (contents, props changed)
Removed:
sandbox/ggl/formal_review_request/boost/ggl/algorithms/buffer.hpp
sandbox/ggl/formal_review_request/boost/ggl/algorithms/intermediate.hpp
sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection_linestring.hpp
sandbox/ggl/formal_review_request/boost/ggl/algorithms/selected.hpp
sandbox/ggl/formal_review_request/boost/ggl/iterators/vertex_iterator.hpp
sandbox/ggl/formal_review_request/boost/ggl/multi/iterators/vertex_iterator.hpp
sandbox/ggl/formal_review_request/boost/ggl/multi/util/as_range.hpp
sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_convex_hull.hpp
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_compare.hpp
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_distance.hpp
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_envelope.hpp
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_side.hpp
sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/sph_envelope.hpp
sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_traits.hpp
sandbox/ggl/formal_review_request/boost/ggl/util/get_cs_as_radian.hpp
sandbox/ggl/formal_review_request/boost/ggl/util/less.hpp
sandbox/ggl/formal_review_request/boost/ggl/util/loop.hpp
Text files modified:
sandbox/ggl/formal_review_request/boost/ggl/algorithms/append.hpp | 4
sandbox/ggl/formal_review_request/boost/ggl/algorithms/area.hpp | 11
sandbox/ggl/formal_review_request/boost/ggl/algorithms/centroid.hpp | 317 ++++++++++++++++++++------------
sandbox/ggl/formal_review_request/boost/ggl/algorithms/combine.hpp | 175 ++++++++++++++---
sandbox/ggl/formal_review_request/boost/ggl/algorithms/convert.hpp | 161 +++++++++++-----
sandbox/ggl/formal_review_request/boost/ggl/algorithms/convex_hull.hpp | 228 ++++++++++++-----------
sandbox/ggl/formal_review_request/boost/ggl/algorithms/disjoint.hpp | 113 +++++++----
sandbox/ggl/formal_review_request/boost/ggl/algorithms/distance.hpp | 23 +-
sandbox/ggl/formal_review_request/boost/ggl/algorithms/envelope.hpp | 172 +++++++----------
sandbox/ggl/formal_review_request/boost/ggl/algorithms/equals.hpp | 12 -
sandbox/ggl/formal_review_request/boost/ggl/algorithms/for_each.hpp | 95 ++++-----
sandbox/ggl/formal_review_request/boost/ggl/algorithms/get_section.hpp | 24 +
sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection.hpp | 318 +++++++++++---------------------
sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersects.hpp | 9
sandbox/ggl/formal_review_request/boost/ggl/algorithms/length.hpp | 6
sandbox/ggl/formal_review_request/boost/ggl/algorithms/make.hpp | 1
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlaps.hpp | 175 ++++++++++++++++-
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/adapt_turns.hpp | 49 ++--
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/clip_linestring.hpp | 36 +-
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/copy_segments.hpp | 5
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/enrich_intersection_points.hpp | 6
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/get_intersection_points.hpp | 68 +++++-
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/intersection_point.hpp | 2
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/merge_intersection_points.hpp | 8
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/segment_identifier.hpp | 1
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/self_intersection_points.hpp | 6
sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/traverse.hpp | 24 -
sandbox/ggl/formal_review_request/boost/ggl/algorithms/simplify.hpp | 116 ++++++-----
sandbox/ggl/formal_review_request/boost/ggl/algorithms/transform.hpp | 4
sandbox/ggl/formal_review_request/boost/ggl/algorithms/within.hpp | 130 +++++++------
sandbox/ggl/formal_review_request/boost/ggl/core/exterior_ring.hpp | 68 +++++--
sandbox/ggl/formal_review_request/boost/ggl/core/interior_rings.hpp | 212 ++++++++++++++-------
sandbox/ggl/formal_review_request/boost/ggl/core/reverse_dispatch.hpp | 2
sandbox/ggl/formal_review_request/boost/ggl/core/ring_type.hpp | 32 +-
sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/geographic/strategies/andoyer.hpp | 6
sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/geographic/strategies/vincenty.hpp | 10
sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/std_as_linestring.hpp | 5
sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/check.hpp | 15 +
sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/detail/check_append.hpp | 5
sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/detail/check_clear.hpp | 8
sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/point_concept.hpp | 2
sandbox/ggl/formal_review_request/boost/ggl/ggl.hpp | 1
sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/centroid.hpp | 79 +++++---
sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/convex_hull.hpp | 143 --------------
sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/distance.hpp | 29 ++
sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/envelope.hpp | 48 +++-
sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/for_each.hpp | 8
sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/get_section.hpp | 5
sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/intersection.hpp | 4
sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/overlay/get_intersection_points.hpp | 2
sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/simplify.hpp | 2
sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/hull_graham_andrew.hpp | 384 ++++++++++++++++++++++++---------------
sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/point_in_poly_winding.hpp | 8
sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/simplify_douglas_peucker.hpp | 31 +-
sandbox/ggl/formal_review_request/boost/ggl/strategies/area_result.hpp | 9
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/area_by_triangles.hpp | 6
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_intersect.hpp | 6
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/centroid_bashein_detmer.hpp | 38 +++
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/distance_pythagoras.hpp | 186 +++---------------
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/point_in_poly_crossings_multiply.hpp | 99 ----------
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/point_in_poly_franklin.hpp | 6
sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/side_by_triangle.hpp | 67 +++---
sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/area_concept.hpp | 12
sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/centroid_concept.hpp | 11
sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/distance_concept.hpp | 48 +++-
sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/simplify_concept.hpp | 16 +
sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/within_concept.hpp | 32 ++-
sandbox/ggl/formal_review_request/boost/ggl/strategies/distance_result.hpp | 31 +++
sandbox/ggl/formal_review_request/boost/ggl/strategies/intersection_result.hpp | 6
sandbox/ggl/formal_review_request/boost/ggl/strategies/length_result.hpp | 6
sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/area_huiller.hpp | 2
sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/distance_cross_track.hpp | 170 ++++++++--------
sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/distance_haversine.hpp | 114 +++++------
sandbox/ggl/formal_review_request/boost/ggl/strategies/strategies.hpp | 28 +-
sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_transform.hpp | 6
sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/matrix_transformers.hpp | 8
sandbox/ggl/formal_review_request/boost/ggl/util/as_range.hpp | 91 +++------
sandbox/ggl/formal_review_request/boost/ggl/util/math.hpp | 13
sandbox/ggl/formal_review_request/boost/ggl/util/select_calculation_type.hpp | 11
sandbox/ggl/formal_review_request/boost/ggl/util/select_coordinate_type.hpp | 8
sandbox/ggl/formal_review_request/boost/ggl/util/select_most_precise.hpp | 8
sandbox/ggl/formal_review_request/boost/ggl/util/write_dsv.hpp | 39 +--
82 files changed, 2411 insertions(+), 2074 deletions(-)
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/append.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/append.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/append.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -78,7 +78,7 @@
{
append_point<range_type, Point, Std>::apply(exterior_ring(polygon), point, -1, -1);
}
- else if (ring_index < boost::size(interior_rings(polygon)))
+ else if (ring_index < int(num_interior_rings(polygon)))
{
append_point<range_type, Point, Std>::apply(interior_rings(polygon)[ring_index], point, -1, -1);
}
@@ -96,7 +96,7 @@
{
append_range<ring_type, Range, Std>::apply(exterior_ring(polygon), range, -1, -1);
}
- else if (ring_index < boost::size(interior_rings(polygon)))
+ else if (ring_index < int(num_interior_rings(polygon)))
{
append_range<ring_type, Range, Std>::apply(interior_rings(polygon)[ring_index], range, -1, -1);
}
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/area.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/area.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/area.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -24,7 +24,7 @@
#include <ggl/algorithms/detail/calculate_null.hpp>
#include <ggl/algorithms/detail/calculate_sum.hpp>
-#include <ggl/strategies/strategies.hpp>
+#include <ggl/strategies/area.hpp>
#include <ggl/strategies/area_result.hpp>
#include <ggl/strategies/concepts/area_concept.hpp>
@@ -36,7 +36,7 @@
\par Performance
2776 * 1000 area calculations are done in 0.11 seconds
-(other libraries: 0.125 seconds, 0.125 seconds, 0.5 seconds)
+(http://trac.osgeo.org/ggl/wiki/Performance#Area1)
\par Coordinate systems and strategies
Area calculation can be done in Cartesian and in spherical/geographic
@@ -70,12 +70,11 @@
static inline return_type apply(Box const& box, Strategy const&)
{
// Currently only works for 2D Cartesian boxes
- // Todo: use extreme-strategy
assert_dimension<Box, 2>();
- return_type const dx = get<max_corner, 0>(box)
+ return_type const dx = get<max_corner, 0>(box)
- get<min_corner, 0>(box);
- return_type const dy = get<max_corner, 1>(box)
+ return_type const dy = get<max_corner, 1>(box)
- get<min_corner, 1>(box);
return dx * dy;
@@ -235,7 +234,7 @@
}
/*!
- \brief Calculate area of a geometry using a strategy
+ \brief Calculate area of a geometry using a specified strategy
\ingroup area
\details This version of area calculation takes a strategy
\param geometry a geometry
Deleted: sandbox/ggl/formal_review_request/boost/ggl/algorithms/buffer.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/buffer.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,158 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_ALGORITHMS_BUFFER_HPP
-#define GGL_ALGORITHMS_BUFFER_HPP
-
-#include <cstddef>
-
-#include <boost/numeric/conversion/cast.hpp>
-
-#include <ggl/geometries/concepts/check.hpp>
-
-#include <ggl/arithmetic/arithmetic.hpp>
-
-// Buffer functions
-// Was before: "grow" but then only for box
-// Now "buffer", but still only implemented for a box...
-
-/*!
-\defgroup buffer buffer calculation
-\par Source description:
-- OGC: Returns a geometric object that represents all Points whose distance
-from this geometric object is less than or equal to distance. Calculations are in the spatial reference system of
-this geometric object. Because of the limitations of linear interpolation, there will often be some relatively
-small error in this distance, but it should be near the resolution of the coordinates used
-\see http://en.wikipedia.org/wiki/Buffer_(GIS)
-*/
-namespace ggl
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace buffer {
-
-template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t D, std::size_t N>
-struct box_loop
-{
- typedef typename coordinate_type<BoxOut>::type coordinate_type;
-
- static inline void apply(BoxIn const& box_in, T const& distance, BoxOut& box_out)
- {
- set<C, D>(box_out, boost::numeric_cast<coordinate_type>(get<C, D>(box_in) + distance));
- box_loop<BoxIn, BoxOut, T, C, D + 1, N>::apply(box_in, distance, box_out);
- }
-};
-
-template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t N>
-struct box_loop<BoxIn, BoxOut, T, C, N, N>
-{
- static inline void apply(BoxIn const&, T const&, BoxOut&) {}
-};
-
-// Extends a box with the same amount in all directions
-template<typename BoxIn, typename BoxOut, typename T>
-inline void buffer_box(BoxIn const& box_in, T const& distance, BoxOut& box_out)
-{
- assert_dimension_equal<BoxIn, BoxOut>();
-
- static const std::size_t N = dimension<BoxIn>::value;
-
- box_loop<BoxIn, BoxOut, T, min_corner, 0, N>::apply(box_in, -distance, box_out);
- box_loop<BoxIn, BoxOut, T, max_corner, 0, N>::apply(box_in, +distance, box_out);
-}
-
-}} // namespace detail::buffer
-#endif // DOXYGEN_NO_DETAIL
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-template <typename TagIn, typename TagOut, typename Input, typename T, typename Output>
-struct buffer {};
-
-
-template <typename BoxIn, typename T, typename BoxOut>
-struct buffer<box_tag, box_tag, BoxIn, T, BoxOut>
-{
- static inline void apply(BoxIn const& box_in, T const& distance,
- T const& chord_length, BoxIn& box_out)
- {
- detail::buffer::buffer_box(box_in, distance, box_out);
- }
-};
-
-// Many things to do. Point is easy, other geometries require self intersections
-// For point, note that it should output as a polygon (like the rest). Buffers
-// of a set of geometries are often lateron combined using a "dissolve" operation.
-// Two points close to each other get a combined kidney shaped buffer then.
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-/*!
- \brief Calculate buffer (= new geometry) around specified distance of geometry
- \ingroup buffer
- \param geometry_in input geometry
- \param distance the distance used in buffer
- \param chord_length length of the chord's in the generated arcs around points or bends
- \param geometry_out buffered geometry
- \note Currently only implemented for box, the trivial case, but still useful
- \par Use case:
- BOX + distance -> BOX: it is allowed that "geometry_out" the same object as "geometry_in"
- */
-template <typename Input, typename Output, typename T>
-inline void buffer(Input const& geometry_in, Output& geometry_out,
- T const& distance, T const& chord_length = -1)
-{
- concept::check<const Input>();
- concept::check<Output>();
-
- dispatch::buffer
- <
- typename tag<Input>::type,
- typename tag<Output>::type,
- Input,
- T,
- Output
- >::apply(geometry_in, distance, chord_length, geometry_out);
-}
-
-/*!
- \brief Calculate and return buffer (= new geometry) around specified distance of geometry
- \ingroup buffer
- \param geometry input geometry
- \param distance the distance used in buffer
- \param chord_length length of the chord's in the generated arcs around points or bends
- \return the buffered geometry
- \note See also: buffer
- */
-template <typename Output, typename Input, typename T>
-Output make_buffer(Input const& geometry, T const& distance, T const& chord_length = -1)
-{
- concept::check<const Input>();
- concept::check<Output>();
-
- Output geometry_out;
-
- dispatch::buffer
- <
- typename tag<Input>::type,
- typename tag<Output>::type,
- Input,
- T,
- Output
- >::apply(geometry, distance, chord_length, geometry_out);
-
- return geometry_out;
-}
-
-} // namespace ggl
-
-#endif // GGL_ALGORITHMS_BUFFER_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/centroid.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/centroid.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/centroid.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -2,6 +2,7 @@
//
// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
// Copyright Bruno Lalande 2008, 2009
+// Copyright (c) 2009 Mateusz Loskot <mateusz_at_[hidden]>
// 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)
@@ -14,35 +15,54 @@
#include <boost/range/functions.hpp>
#include <boost/range/metafunctions.hpp>
+#include <ggl/algorithms/distance.hpp>
#include <ggl/core/cs.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
#include <ggl/core/exception.hpp>
#include <ggl/core/exterior_ring.hpp>
#include <ggl/core/interior_rings.hpp>
-
#include <ggl/geometries/concepts/check.hpp>
-
-#include <ggl/strategies/strategies.hpp>
+#include <ggl/iterators/segment_iterator.hpp>
+#include <ggl/strategies/centroid.hpp>
#include <ggl/strategies/concepts/centroid_concept.hpp>
#include <ggl/util/copy.hpp>
+#include <ggl/util/for_each_coordinate.hpp>
+
/*!
\defgroup centroid centroid calculation
\par Source descriptions:
-- OGC description: The mathematical centroid for this Surface as a Point. The
+- OGC description: The mathematical centroid for this Surface as a Point. The
result is not guaranteed to be on this Surface.
- From Wikipedia: Informally, it is the "average" of all points
\see http://en.wikipedia.org/wiki/Centroid
+\note Polygon should be closed, and can be orientated either way
\note The "centroid" functions are taking a non const reference to the centroid.
- The "make_centroid" functions return the centroid, the type has to be
+ The "make_centroid" functions return the centroid, the type has to be
specified.
+\note Both of them have an overloaded version where
+ a centroid calculation strategy can be specified
+\exception centroid_exception if calculation is not successful,
+ e.g. because polygon didn't contain points
+
+\par Example:
+Example showing centroid calculation
+\dontinclude doxygen_examples.cpp
+\skip example_centroid_polygon
+\line {
+\until }
+
+\par Performance
+2776 * 1000 centroid calculations are done in 0.16 seconds
+(http://trac.osgeo.org/ggl/wiki/Performance#Centroid1)
-\note There are versions where a centroid calculation strategy can be specified
\par Geometries:
- RING: \image html centroid_ring.png
- BOX: the centroid of a 2D or 3D box is the center of the box
- POLYGON \image html centroid_polygon.png
-- POINT, LINESTRING, SEGMENT: trying to calculate the centroid will result in a
- compilation error
+- POINT: the point is the centroid
+- LINESTRING: the average of the centers of its segments
+- MULTIPOINT: the average of the points
*/
namespace ggl
@@ -52,8 +72,7 @@
{
public:
- inline centroid_exception()
- {}
+ inline centroid_exception() {}
virtual char const* what() const throw()
{
@@ -61,28 +80,23 @@
}
};
-
-
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace centroid {
-
template<typename Point, typename PointCentroid, typename Strategy>
struct centroid_point
{
- static inline bool apply(Point const& point, PointCentroid& centroid,
- Strategy const&, typename Strategy::state_type&)
+ static inline void apply(Point const& point, PointCentroid& centroid,
+ Strategy const&)
{
copy_coordinates(point, centroid);
- return false;
}
};
-
template
<
- typename Box,
- typename Point,
+ typename Box,
+ typename Point,
std::size_t Dimension,
std::size_t DimensionCount
>
@@ -109,7 +123,6 @@
}
};
-
template<typename Box, typename Point, std::size_t DimensionCount>
struct centroid_box_calculator<Box, Point, DimensionCount, DimensionCount>
{
@@ -118,50 +131,58 @@
}
};
-
template<typename Box, typename Point, typename Strategy>
struct centroid_box
{
- static inline bool apply(Box const& box, Point& centroid,
- Strategy const&, typename Strategy::state_type&)
+ static inline void apply(Box const& box, Point& centroid,
+ Strategy const&)
{
centroid_box_calculator
<
Box, Point,
0, dimension<Box>::type::value
>::apply(box, centroid);
- return false;
}
};
+// There is one thing where centroid is different from e.g. within.
+// If the ring has only one point, it might make sense that
+// that point is the centroid.
+template<typename Point, typename Range>
+inline bool range_ok(Range const& range, Point& centroid)
+{
+ std::size_t const n = boost::size(range);
+ if (n > 1)
+ {
+ return true;
+ }
+ else if (n <= 0)
+ {
+#if defined(CENTROID_WITH_CATCH)
+ throw centroid_exception();
+#endif
+ return false;
+ }
+ else // if (n == 1)
+ {
+ // Take over the first point in a "coordinate neutral way"
+ copy_coordinates(range.front(), centroid);
+ return false;
+ }
+ return true;
+}
+
/*!
\brief Calculate the centroid of a ring.
*/
-template<typename Ring, typename Point, typename Strategy>
-struct centroid_ring
+template<typename Ring, typename Strategy>
+struct centroid_ring_state
{
- static inline bool apply(Ring const& ring, Point& centroid,
+ static inline void apply(Ring const& ring,
Strategy const& strategy, typename Strategy::state_type& state)
{
typedef typename boost::range_const_iterator<Ring>::type iterator_type;
-
- // There is one thing where centroid is different from e.g. within.
- // If the ring has only one point, it might make sense that
- // that point is the centroid. So then, pass it twice, as a trick
- // to avoid adding another method.
-
- switch(boost::size(ring))
- {
- case 0 : // will cause exception in the end
- return true;
- case 1 :
- Strategy::apply(ring.front(), ring.front(), state);
- return false;
- }
-
- // Normal behaviour:
-
iterator_type it = boost::begin(ring);
for (iterator_type previous = it++;
it != boost::end(ring);
@@ -169,41 +190,129 @@
{
Strategy::apply(*previous, *it, state);
}
- return true;
+
+ /* 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_const_iterator<Ring>::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>
+struct centroid_ring
+{
+ static inline void apply(Ring const& ring, Point& centroid,
+ Strategy const& strategy)
+ {
+ if (range_ok(ring, centroid))
+ {
+ typename Strategy::state_type state;
+ centroid_ring_state
+ <
+ Ring,
+ Strategy
+ >::apply(ring, 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)
+ {
+ // TODO: This is test that operates on 2D point only. Make dim-agnostic.
+
+ typedef typename point_type<Linestring>::type point_type;
+ typedef typename boost::range_const_iterator<Linestring>::type point_iterator_type;
+ typedef segment_iterator<point_iterator_type, point_type> segment_iterator;
+
+ double length = double();
+ std::pair<double, double> average_sum;
+
+ segment_iterator it(boost::begin(line), boost::end(line));
+ segment_iterator end(boost::end(line));
+ while (it != end)
+ {
+ double const d = ggl::distance(it->first, it->second);
+ length += d;
+
+ double const mx = (get<0>(it->first) + get<0>(it->second)) / 2;
+ double const my = (get<1>(it->first) + get<1>(it->second)) / 2;
+ 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.
\note Because outer ring is clockwise, inners are counter clockwise,
triangle approach is OK and works for polygons with rings.
*/
-template<typename Polygon, typename Point, typename Strategy>
-struct centroid_polygon
+template<typename Polygon, typename Strategy>
+struct centroid_polygon_state
{
- static inline bool apply(Polygon const& poly, Point& centroid,
+ static inline void apply(Polygon const& poly,
Strategy const& strategy, typename Strategy::state_type& state)
{
- typedef centroid_ring
+ typedef centroid_ring_state
<
- typename ring_type<Polygon>::type,
- Point,
+ typename ring_type<Polygon>::type,
Strategy
> per_ring;
- per_ring::apply(exterior_ring(poly), centroid, strategy, state);
+ per_ring::apply(exterior_ring(poly), strategy, state);
for (typename boost::range_const_iterator
<
typename interior_type<Polygon>::type
>::type it = boost::begin(interior_rings(poly));
- it != boost::end(interior_rings(poly));
+ it != boost::end(interior_rings(poly));
++it)
{
- per_ring::apply(*it, centroid, strategy, state);
+ per_ring::apply(*it, strategy, state);
+ }
+ }
+};
+
+template<typename Polygon, typename Point, typename Strategy>
+struct centroid_polygon
+{
+ static inline void apply(Polygon const& poly, Point& centroid,
+ Strategy const& strategy)
+ {
+ if (range_ok(exterior_ring(poly), centroid))
+ {
+ typename Strategy::state_type state;
+ centroid_polygon_state
+ <
+ Polygon,
+ Strategy
+ >::apply(poly, strategy, state);
+ Strategy::result(state, centroid);
}
- return true; // always check exception
}
};
@@ -216,146 +325,117 @@
namespace dispatch
{
-template
+template
<
- typename Tag,
- std::size_t Dimension,
- typename Geometry,
+ typename Tag,
+ typename Geometry,
typename Point,
typename Strategy
>
struct centroid {};
-template
+template
<
- std::size_t Dimension,
- typename Geometry,
- typename Point,
+ typename Geometry,
+ typename Point,
typename Strategy
>
-struct centroid<point_tag, Dimension, Geometry, Point, Strategy>
+struct centroid<point_tag, Geometry, Point, Strategy>
: detail::centroid::centroid_point<Geometry, Point, Strategy>
{};
-template
+template
<
- std::size_t Dimension,
- typename Box,
- typename Point,
+ typename Box,
+ typename Point,
typename Strategy
>
-struct centroid<box_tag, Dimension, Box, Point, Strategy>
+struct centroid<box_tag, Box, Point, Strategy>
: detail::centroid::centroid_box<Box, Point, Strategy>
{};
template <typename Ring, typename Point, typename Strategy>
-struct centroid<ring_tag, 2, Ring, Point, Strategy>
+struct centroid<ring_tag, Ring, Point, Strategy>
: detail::centroid::centroid_ring<Ring, Point, Strategy>
{};
+template <typename Linestring, typename Point, typename Strategy>
+struct centroid<linestring_tag, Linestring, Point, Strategy>
+ : detail::centroid::centroid_linestring<Linestring, Point, Strategy>
+ {};
+
template <typename Polygon, typename Point, typename Strategy>
-struct centroid<polygon_tag, 2, Polygon, Point, Strategy>
+struct centroid<polygon_tag, Polygon, Point, Strategy>
: detail::centroid::centroid_polygon<Polygon, Point, Strategy>
-
-{};
+ {};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
-
/*!
\brief Calculate centroid using a specified strategy
\ingroup centroid
\param geometry the geometry to calculate centroid from
\param c reference to point which will contain the centroid
\param strategy Calculation strategy for centroid
- \exception centroid_exception if calculation is not successful,
- e.g. because polygon didn't contain points
*/
template<typename Geometry, typename Point, typename Strategy>
-inline void centroid(Geometry const& geometry, Point& c,
+inline void centroid(Geometry const& geometry, Point& c,
Strategy const& strategy)
{
- BOOST_CONCEPT_ASSERT( (ggl::concept::CentroidStrategy<Strategy>) );
+ //BOOST_CONCEPT_ASSERT( (ggl::concept::CentroidStrategy<Strategy>) );
- concept::check<const Geometry>();
- concept::check<Point>();
+ concept::check_concepts_and_equal_dimensions<Point, const Geometry>();
- assert_dimension_equal<Geometry, Point>();
typedef typename point_type<Geometry>::type point_type;
- typename Strategy::state_type state;
-
// Call dispatch apply method. That one returns true if centroid
// should be taken from state.
- if (dispatch::centroid
+ dispatch::centroid
<
typename tag<Geometry>::type,
- dimension<point_type>::type::value,
Geometry,
Point,
Strategy
- >::apply(geometry, c, strategy, state))
- {
- if (! Strategy::result(state, c))
- {
- throw centroid_exception();
- }
- }
+ >::apply(geometry, c, strategy);
}
-
/*!
\brief Calculate centroid
\ingroup centroid
- \details The function centroid calculates the centroid of a geometry
- using the default strategy.
- Polygon should be closed, and can be orientated either way
\param geometry a geometry (e.g. closed ring or polygon)
\param c reference to point which will contain the centroid
- \exception centroid_exception if calculation is not successful,
- e.g. because polygon didn't contain points
- \par Example:
- Example showing centroid calculation
- \dontinclude doxygen_examples.cpp
- \skip example_centroid_polygon
- \line {
- \until }
*/
template<typename Geometry, typename Point>
inline void centroid(Geometry const& geometry, Point& c)
{
- concept::check<const Geometry>();
- concept::check<Point>();
+ concept::check_concepts_and_equal_dimensions<Point, const Geometry>();
- typedef typename point_type<Geometry>::type point_type;
typedef typename strategy_centroid
<
- typename cs_tag<point_type>::type,
+ typename cs_tag<Geometry>::type,
+ typename tag<Geometry>::type,
+ dimension<Geometry>::type::value,
Point,
- point_type
+ Geometry
>::type strategy_type;
centroid(geometry, c, strategy_type());
}
-// Versions returning a centroid
/*!
\brief Calculate and return centroid
\ingroup centroid
\param geometry the geometry to calculate centroid from
\return the centroid
- \exception centroid_exception if calculation is not successful,
- e.g. because polygon didn't contain points
*/
template<typename Point, typename Geometry>
inline Point make_centroid(Geometry const& geometry)
{
- concept::check<const Geometry>();
- concept::check<Point>();
+ concept::check_concepts_and_equal_dimensions<Point, const Geometry>();
Point c;
centroid(geometry, c);
@@ -363,21 +443,18 @@
}
/*!
- \brief Calculate and return centroid
+ \brief Calculate and return centroid, using a specified strategy
\ingroup centroid
\param geometry the geometry to calculate centroid from
\param strategy Calculation strategy for centroid
\return the centroid
- \exception centroid_exception if calculation is not successful,
- e.g. because polygon didn't contain points
*/
template<typename Point, typename Geometry, typename Strategy>
inline Point make_centroid(Geometry const& geometry, Strategy const& strategy)
{
- BOOST_CONCEPT_ASSERT( (ggl::concept::CentroidStrategy<Strategy>) );
+ //BOOST_CONCEPT_ASSERT( (ggl::concept::CentroidStrategy<Strategy>) );
- concept::check<const Geometry>();
- concept::check<Point>();
+ concept::check_concepts_and_equal_dimensions<Point, const Geometry>();
Point c;
centroid(geometry, c, strategy);
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/combine.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/combine.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/combine.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -16,16 +16,19 @@
#include <ggl/core/coordinate_dimension.hpp>
#include <ggl/geometries/concepts/check.hpp>
-#include <ggl/arithmetic/arithmetic.hpp>
-
#include <ggl/util/select_coordinate_type.hpp>
+#include <ggl/strategies/compare.hpp>
+#include <ggl/policies/compare.hpp>
+
+
/*!
\defgroup combine combine: add a geometry to a bounding box
\par Geometries:
-- BOX + BOX -> BOX: the box will be combined with the other box \image html combine_box_box.png
-- BOX + POINT -> BOX: the box will combined with the point \image html combine_box_point.png
-\note Previously called "grow"
+- BOX + BOX -> BOX: the box will be combined with the other box
+ \image html combine_box_box.png
+- BOX + POINT -> BOX: the box will combined with the point
+ \image html combine_box_point.png
*/
namespace ggl
{
@@ -36,27 +39,44 @@
template
<
typename Box, typename Point,
+ typename StrategyLess, typename StrategyGreater,
std::size_t Dimension, std::size_t DimensionCount
>
struct point_loop
{
- typedef typename coordinate_type<Point>::type coordinate_type;
+ typedef typename select_coordinate_type<Point, Box>::type coordinate_type;
static inline void apply(Box& box, Point const& source)
{
coordinate_type const coord = get<Dimension>(source);
- if (coord < get<min_corner, Dimension>(box))
+ // Declare two strategies
+ typename strategy::compare::detail::select_strategy
+ <
+ StrategyLess, 1, Point, Dimension
+ >::type less;
+
+ typename strategy::compare::detail::select_strategy
+ <
+ StrategyGreater, -1, Point, Dimension
+ >::type greater;
+
+ if (less(coord, get<min_corner, Dimension>(box)))
{
- set<min_corner, Dimension>(box, coord );
+ set<min_corner, Dimension>(box, coord);
}
- if (coord > get<max_corner, Dimension>(box))
+ if (greater(coord, get<max_corner, Dimension>(box)))
{
set<max_corner, Dimension>(box, coord);
}
- point_loop<Box, Point, Dimension + 1, DimensionCount>::apply(box, source);
+ point_loop
+ <
+ Box, Point,
+ StrategyLess, StrategyGreater,
+ Dimension + 1, DimensionCount
+ >::apply(box, source);
}
};
@@ -64,9 +84,10 @@
template
<
typename Box, typename Point,
+ typename StrategyLess, typename StrategyGreater,
std::size_t DimensionCount
>
-struct point_loop<Box, Point, DimensionCount, DimensionCount>
+struct point_loop<Box, Point, StrategyLess, StrategyGreater, DimensionCount, DimensionCount>
{
static inline void apply(Box&, Point const&) {}
};
@@ -75,30 +96,48 @@
template
<
typename BoxIn, typename BoxOut,
+ typename StrategyLess, typename StrategyGreater,
std::size_t Corner,
std::size_t Dimension, std::size_t DimensionCount
>
struct box_loop
{
- typedef typename select_coordinate_type<BoxIn, BoxOut>::type coordinate_type;
+ typedef typename select_coordinate_type
+ <
+ BoxIn,
+ BoxOut
+ >::type coordinate_type;
+ typedef typename point_type<BoxIn>::type point_type;
static inline void apply(BoxIn& box, BoxOut const& source)
{
coordinate_type const coord = get<Corner, Dimension>(source);
- if (coord < get<min_corner, Dimension>(box))
+ typename strategy::compare::detail::select_strategy
+ <
+ StrategyLess, 1, point_type, Dimension
+ >::type less;
+
+ typename strategy::compare::detail::select_strategy
+ <
+ StrategyGreater, -1, point_type, Dimension
+ >::type greater;
+
+ if (less(coord, get<min_corner, Dimension>(box)))
{
set<min_corner, Dimension>(box, coord);
}
- if (coord > get<max_corner, Dimension>(box))
+ if (greater(coord, get<max_corner, Dimension>(box)))
{
set<max_corner, Dimension>(box, coord);
}
box_loop
<
- BoxIn, BoxOut, Corner, Dimension + 1, DimensionCount
+ BoxIn, BoxOut,
+ StrategyLess, StrategyGreater,
+ Corner, Dimension + 1, DimensionCount
>::apply(box, source);
}
};
@@ -107,31 +146,58 @@
template
<
typename BoxIn, typename BoxOut,
+ typename StrategyLess, typename StrategyGreater,
std::size_t Corner, std::size_t DimensionCount
>
-struct box_loop<BoxIn, BoxOut, Corner, DimensionCount, DimensionCount>
+struct box_loop
+ <
+ BoxIn, BoxOut,
+ StrategyLess, StrategyGreater,
+ Corner, DimensionCount, DimensionCount
+ >
{
static inline void apply(BoxIn&, BoxOut const&) {}
};
// Changes a box b such that it also contains point p
-template<typename Box, typename Point>
+template
+<
+ typename Box, typename Point,
+ typename StrategyLess, typename StrategyGreater
+>
struct combine_box_with_point
- : point_loop<Box, Point, 0, dimension<Point>::type::value>
+ : point_loop
+ <
+ Box, Point,
+ StrategyLess, StrategyGreater,
+ 0, dimension<Point>::type::value
+ >
{};
// Changes a box such that the other box is also contained by the box
-template<typename BoxOut, typename BoxIn>
+template
+<
+ typename BoxOut, typename BoxIn,
+ typename StrategyLess, typename StrategyGreater
+>
struct combine_box_with_box
{
static inline void apply(BoxOut& b, BoxIn const& other)
{
- box_loop<BoxOut, BoxIn, min_corner, 0,
- dimension<BoxIn>::type::value>::apply(b, other);
- box_loop<BoxOut, BoxIn, max_corner, 0,
- dimension<BoxIn>::type::value>::apply(b, other);
+ box_loop
+ <
+ BoxOut, BoxIn,
+ StrategyLess, StrategyGreater,
+ min_corner, 0, dimension<BoxIn>::type::value
+ >::apply(b, other);
+ box_loop
+ <
+ BoxOut, BoxIn,
+ StrategyLess, StrategyGreater,
+ max_corner, 0, dimension<BoxIn>::type::value
+ >::apply(b, other);
}
};
@@ -142,22 +208,37 @@
namespace dispatch
{
-template <typename Tag, typename BoxOut, typename Geometry>
+template
+<
+ typename Tag,
+ typename BoxOut, typename Geometry,
+ typename StrategyLess, typename StrategyGreater
+>
struct combine
{};
// Box + point -> new box containing also point
-template <typename BoxOut, typename Point>
-struct combine<point_tag, BoxOut, Point>
- : detail::combine::combine_box_with_point<BoxOut, Point>
+template
+<
+ typename BoxOut, typename Point,
+ typename StrategyLess, typename StrategyGreater
+>
+struct combine<point_tag, BoxOut, Point, StrategyLess, StrategyGreater>
+ : detail::combine::combine_box_with_point
+ <BoxOut, Point, StrategyLess, StrategyGreater>
{};
// Box + box -> new box containing two input boxes
-template <typename BoxOut, typename BoxIn>
-struct combine<box_tag, BoxOut, BoxIn>
- : detail::combine::combine_box_with_box<BoxOut, BoxIn>
+template
+<
+ typename BoxOut, typename BoxIn,
+ typename StrategyLess, typename StrategyGreater
+>
+struct combine<box_tag, BoxOut, BoxIn, StrategyLess, StrategyGreater>
+ : detail::combine::combine_box_with_box
+ <BoxOut, BoxIn, StrategyLess, StrategyGreater>
{};
@@ -172,18 +253,44 @@
\tparam Geometry of second geometry, to be combined with the box
\param box box to combine another geometry with, might be changed
\param geometry other geometry
+ \param strategy_less
+ \param strategy_greater
+ */
+template <typename Box, typename Geometry, typename StrategyLess, typename StrategyGreater>
+inline void combine(Box& box, Geometry const& geometry,
+ StrategyLess const& strategy_less,
+ StrategyGreater const& strategy_greater)
+{
+ concept::check_concepts_and_equal_dimensions<Box, const Geometry>();
+
+ dispatch::combine
+ <
+ typename tag<Geometry>::type,
+ Box,
+ Geometry,
+ StrategyLess, StrategyGreater
+ >::apply(box, geometry);
+}
+
+/*!
+ \brief Combines a box with another geometry (box, point)
+ \ingroup combine
+ \tparam Box type of the box
+ \tparam Geometry of second geometry, to be combined with the box
+ \param box box to combine another geometry with, might be changed
+ \param geometry other geometry
*/
template <typename Box, typename Geometry>
inline void combine(Box& box, Geometry const& geometry)
{
- concept::check<const Geometry>();
- concept::check<Box>();
+ concept::check_concepts_and_equal_dimensions<Box, const Geometry>();
- assert_dimension_equal<Box, Geometry>();
dispatch::combine
<
typename tag<Geometry>::type,
- Box, Geometry
+ Box, Geometry,
+ strategy::compare::default_strategy,
+ strategy::compare::default_strategy
>::apply(box, geometry);
}
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/convert.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/convert.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/convert.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -22,12 +22,11 @@
#include <ggl/core/cs.hpp>
#include <ggl/geometries/concepts/check.hpp>
-#include <ggl/geometries/segment.hpp>
-#include <ggl/strategies/strategies.hpp>
/*!
\defgroup convert convert geometries from one type to another
-\details Convert from one geometry type to another type, for example from BOX to POLYGON
+\details Convert from one geometry type to another type,
+ for example from BOX to POLYGON
*/
namespace ggl
@@ -36,25 +35,45 @@
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace convert {
-template <typename P, typename B, std::size_t C, std::size_t D, std::size_t N>
+template
+<
+ typename Point,
+ typename Box,
+ std::size_t Index,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
struct point_to_box
{
- static inline void apply(P const& point, B& box)
+ static inline void apply(Point const& point, Box& box)
{
- typedef typename coordinate_type<B>::type coordinate_type;
+ typedef typename coordinate_type<Box>::type coordinate_type;
- set<C, D>(box, boost::numeric_cast<coordinate_type>(get<D>(point)));
- point_to_box<P, B, C, D + 1, N>::apply(point, box);
+ set<Index, Dimension>(box,
+ boost::numeric_cast<coordinate_type>(get<Dimension>(point)));
+ point_to_box
+ <
+ Point, Box,
+ Index, Dimension + 1, DimensionCount
+ >::apply(point, box);
}
};
-template <typename P, typename B, std::size_t C, std::size_t N>
-struct point_to_box<P, B, C, N, N>
+
+template
+<
+ typename Point,
+ typename Box,
+ std::size_t Index,
+ std::size_t DimensionCount
+>
+struct point_to_box<Point, Box, Index, DimensionCount, DimensionCount>
{
- static inline void apply(P const& point, B& box)
+ static inline void apply(Point const& point, Box& box)
{}
};
+
}} // namespace detail::convert
#endif // DOXYGEN_NO_DETAIL
@@ -65,41 +84,52 @@
template
<
- typename T1, typename T2,
+ typename Tag1, typename Tag2,
std::size_t Dimensions,
- typename G1, typename G2
+ typename Geometry1, typename Geometry2
>
struct convert
{
};
+
template
<
- typename T,
+ typename Tag,
std::size_t Dimensions,
- typename G1, typename G2
+ typename Geometry1, typename Geometry2
>
-struct convert<T, T, Dimensions, G1, G2>
+struct convert<Tag, Tag, Dimensions, Geometry1, Geometry2>
{
// Same geometry type -> copy coordinates from G1 to G2
+ // Actually: we try now to just copy it
+ static inline void apply(Geometry1 const& source, Geometry2& destination)
+ {
+ destination = source;
+ }
};
-template <typename T, std::size_t Dimensions, typename G>
-struct convert<T, T, Dimensions, G, G>
+
+template <typename Tag, std::size_t Dimensions, typename Geometry>
+struct convert<Tag, Tag, Dimensions, Geometry, Geometry>
{
- // Same geometry -> can be copied
+ // Same geometry -> can be copied (if copyable)
+ static inline void apply(Geometry const& source, Geometry& destination)
+ {
+ destination = source;
+ }
};
// Partial specializations
-template <typename B, typename R>
-struct convert<box_tag, ring_tag, 2, B, R>
+template <typename Box, typename Ring>
+struct convert<box_tag, ring_tag, 2, Box, Ring>
{
- static inline void apply(B const& box, R& ring)
+ static inline void apply(Box const& box, Ring& ring)
{
// go from box to ring -> add coordinates in correct order
ring.clear();
- typename point_type<B>::type point;
+ typename point_type<Box>::type point;
ggl::assign(point, get<min_corner, 0>(box), get<min_corner, 1>(box));
ggl::append(ring, point);
@@ -118,33 +148,71 @@
}
};
-template <typename B, typename P>
-struct convert<box_tag, polygon_tag, 2, B, P>
+
+template <typename Box, typename Polygon>
+struct convert<box_tag, polygon_tag, 2, Box, Polygon>
{
- static inline void apply(B const& box, P& polygon)
+ static inline void apply(Box const& box, Polygon& polygon)
{
- typedef typename ring_type<P>::type ring_type;
+ typedef typename ring_type<Polygon>::type ring_type;
- convert<box_tag, ring_tag, 2, B, ring_type>::apply(box, exterior_ring(polygon));
+ convert
+ <
+ box_tag, ring_tag,
+ 2, Box, ring_type
+ >::apply(box, exterior_ring(polygon));
}
};
-template <typename P, std::size_t Dimensions, typename B>
-struct convert<point_tag, box_tag, Dimensions, P, B>
+
+template <typename Point, std::size_t Dimensions, typename Box>
+struct convert<point_tag, box_tag, Dimensions, Point, Box>
{
- static inline void apply(P const& point, B& box)
+ static inline void apply(Point const& point, Box& box)
{
detail::convert::point_to_box
<
- P, B, min_corner, 0, Dimensions
+ Point, Box, min_corner, 0, Dimensions
>::apply(point, box);
detail::convert::point_to_box
<
- P, B, max_corner, 0, Dimensions
+ Point, Box, max_corner, 0, Dimensions
>::apply(point, box);
}
};
+
+template <typename Ring, typename Polygon>
+struct convert<ring_tag, polygon_tag, 2, Ring, Polygon>
+{
+ static inline void apply(Ring const& ring, Polygon& polygon)
+ {
+ typedef typename ring_type<Polygon>::type ring_type;
+ convert
+ <
+ ring_tag, ring_tag, 2,
+ Ring, ring_type
+ >::apply(ring, exterior_ring(polygon));
+ }
+};
+
+
+template <typename Polygon, typename Ring>
+struct convert<polygon_tag, ring_tag, 2, Polygon, Ring>
+{
+ static inline void apply(Polygon const& polygon, Ring& ring)
+ {
+ typedef typename ring_type<Polygon>::type ring_type;
+
+ convert
+ <
+ ring_tag, ring_tag, 2,
+ ring_type, Ring
+ >::apply(exterior_ring(polygon), ring);
+ }
+};
+
+
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
@@ -153,26 +221,23 @@
\details The convert algorithm converts one geometry, e.g. a BOX, to another geometry, e.g. a RING. This only
if it is possible and applicable.
\ingroup convert
- \tparam G1 first geometry type
- \tparam G2 second geometry type
- \param geometry1 first geometry
- \param geometry2 second geometry
+ \tparam Geometry1 first geometry type
+ \tparam Geometry2 second geometry type
+ \param geometry1 first geometry (source)
+ \param geometry2 second geometry (target)
*/
-template <typename G1, typename G2>
-inline void convert(G1 const& geometry1, G2& geometry2)
+template <typename Geometry1, typename Geometry2>
+inline void convert(Geometry1 const& geometry1, Geometry2& geometry2)
{
- concept::check<const G1>();
- concept::check<G2>();
-
- assert_dimension_equal<G1, G2>();
+ concept::check_concepts_and_equal_dimensions<const Geometry1, Geometry2>();
dispatch::convert
<
- typename tag<G1>::type,
- typename tag<G2>::type,
- dimension<G1>::type::value,
- G1,
- G2
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ dimension<Geometry1>::type::value,
+ Geometry1,
+ Geometry2
>::apply(geometry1, geometry2);
}
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/convex_hull.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/convex_hull.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/convex_hull.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -19,8 +19,11 @@
#include <ggl/geometries/concepts/check.hpp>
+#include <ggl/iterators/range_type.hpp>
+
+#include <ggl/strategies/convex_hull.hpp>
+#include <ggl/strategies/concepts/convex_hull_concept.hpp>
-#include <ggl/strategies/strategies.hpp>
#include <ggl/util/as_range.hpp>
@@ -34,15 +37,38 @@
\see http://en.wikipedia.org/wiki/Convex_hull
\par Performance
-2776 counties of US are "hulled" in 0.9 seconds (other libraries: 0.9, 4.1, 3.3, 1.4 seconds)
+2776 counties of US are "hulled" in 0.9 seconds
+(http://trac.osgeo.org/ggl/wiki/Performance#Convexhull1)
\note The convex hull is always a ring, holes are not possible. Therefore it is
can also be used in combination with an output iterator.
-\par Geometries:
+
+\par Geometries supported:
In the images below the convex hull is painted in red.
-- POINT: will not compile
-- POLYGON: will deliver a polygon without holes
- \image html convexhull_polygon_polygon.png
+
+- \b point: will not compile
+
+- \b linestring:
+
+- \b polygon: will deliver a polygon without holes
+ \image html svg_convex_hull_country.png
+
+- \b multi_point:
+ \image html svg_convex_hull_cities.png
+
+- \b multi_linestring:
+
+- \b multi_polygon:
+
+\par Output geometries supported:
+
+- \b polygon
+
+- \b ring
+
+- inserter version (with output iterator) can output to any array supporting
+ points of same type as the input geometry type
+
*/
namespace ggl {
@@ -52,29 +78,22 @@
template
<
typename Geometry,
- order_selector Order
+ order_selector Order,
+ typename Strategy
>
struct hull_inserter
{
+
// Member template function, to avoid inconvenient declaration
- // of output-iterator-type
+ // of output-iterator-type, from hull_to_geometry
template <typename OutputIterator>
static inline OutputIterator apply(Geometry const& geometry,
- OutputIterator out)
+ OutputIterator out, Strategy const& strategy)
{
- typedef typename point_type<Geometry>::type point_type;
+ typename Strategy::state_type state;
- typedef typename strategy_convex_hull
- <
- typename cs_tag<point_type>::type,
- point_type
- >::type strategy_type;
-
- strategy_type s(as_range
- <
- typename as_range_type<Geometry>::type
- >(geometry));
- s.get(out, Order == clockwise);
+ strategy.apply(geometry, state);
+ strategy.result(state, out, Order == clockwise);
return out;
}
};
@@ -82,120 +101,90 @@
template
<
typename Geometry,
- typename OutputGeometry
+ typename OutputGeometry,
+ typename Strategy
>
struct hull_to_geometry
{
- static inline void apply(Geometry const& geometry, OutputGeometry& out)
+ static inline void apply(Geometry const& geometry, OutputGeometry& out,
+ Strategy const& strategy)
{
hull_inserter
<
Geometry,
- ggl::point_order<OutputGeometry>::value
+ ggl::point_order<OutputGeometry>::value,
+ Strategy
>::apply(geometry,
std::back_inserter(
+ // Handle both ring and polygon the same:
ggl::as_range
<
- typename ggl::as_range_type<OutputGeometry>::type
- >(out)));
+ typename ggl::range_type<OutputGeometry>::type
+ >(out)), strategy);
}
};
-
-
}} // namespace detail::convex_hull
#endif // DOXYGEN_NO_DETAIL
+
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
+
template
<
typename Tag1,
bool IsMulti,
- typename Polygon, typename Output
->
-struct convex_hull
-{};
-
-
-template <typename Polygon, typename Output>
-struct convex_hull
-<
- polygon_tag, false,
- Polygon, Output
->
- : detail::convex_hull::hull_to_geometry<Polygon, Output>
-{};
-
-template <typename Polygon, typename Output>
-struct convex_hull
-<
- ring_tag, false,
- Polygon, Output
+ typename Geometry,
+ typename Output,
+ typename Strategy
>
- : detail::convex_hull::hull_to_geometry<Polygon, Output>
-{};
-
-template <typename Polygon, typename Output>
struct convex_hull
-<
- linestring_tag, false,
- Polygon, Output
->
- : detail::convex_hull::hull_to_geometry<Polygon, Output>
+ : detail::convex_hull::hull_to_geometry<Geometry, Output, Strategy>
{};
-
template
<
typename GeometryTag,
order_selector Order,
bool IsMulti,
- typename GeometryIn
+ typename GeometryIn, typename Strategy
>
-struct convex_hull_inserter {};
-
-template <typename Linestring, order_selector Order>
struct convex_hull_inserter
-<
- linestring_tag,
- Order, false,
- Linestring
->
- : detail::convex_hull::hull_inserter<Linestring, Order>
+ : detail::convex_hull::hull_inserter<GeometryIn, Order, Strategy>
{};
-template <typename Ring, order_selector Order>
-struct convex_hull_inserter
-<
- ring_tag,
- Order, false,
- Ring
->
- : detail::convex_hull::hull_inserter<Ring, Order>
-{};
-
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
-template <typename Polygon, order_selector Order>
-struct convex_hull_inserter
-<
- polygon_tag,
- Order, false,
- Polygon
->
- : detail::convex_hull::hull_inserter<Polygon, Order>
-{};
+template<typename Geometry1, typename Geometry2, typename Strategy>
+inline void convex_hull(Geometry1 const& geometry,
+ Geometry2& out, Strategy const& strategy)
+{
+ concept::check_concepts_and_equal_dimensions
+ <
+ const Geometry1,
+ Geometry2
+ >();
+ BOOST_CONCEPT_ASSERT( (ggl::concept::ConvexHullStrategy<Strategy>) );
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
+ dispatch::convex_hull
+ <
+ typename tag<Geometry1>::type,
+ is_multi<Geometry1>::type::value,
+ Geometry1,
+ Geometry2,
+ Strategy
+ >::apply(geometry, out, strategy);
+}
/*!
@@ -205,25 +194,48 @@
\tparam Geometry2: the output geometry type
\param geometry the geometry to calculate convex hull from
\param out a geometry receiving points of the convex hull
- \note the output may be:
- - a polygon
- - a ring
-
*/
template<typename Geometry1, typename Geometry2>
inline void convex_hull(Geometry1 const& geometry,
Geometry2& out)
{
- concept::check<const Geometry1>();
- concept::check<Geometry2>();
+ concept::check_concepts_and_equal_dimensions
+ <
+ const Geometry1,
+ Geometry2
+ >();
- dispatch::convex_hull
+ //typedef typename range_type<Geometry1>::type range_type;
+ typedef typename point_type<Geometry2>::type point_type;
+
+ typedef typename strategy_convex_hull
<
- typename tag<Geometry1>::type,
- is_multi<Geometry1>::type::value,
+ typename cs_tag<point_type>::type,
Geometry1,
- Geometry2
- >::apply(geometry, out);
+ point_type
+ >::type strategy_type;
+
+ convex_hull(geometry, out, strategy_type());
+}
+
+
+template<typename Geometry, typename OutputIterator, typename Strategy>
+inline OutputIterator convex_hull_inserter(Geometry const& geometry,
+ OutputIterator out, Strategy const& strategy)
+{
+ // Concept: output point type = point type of input geometry
+ concept::check<const Geometry>();
+ concept::check<typename point_type<Geometry>::type>();
+
+ BOOST_CONCEPT_ASSERT( (ggl::concept::ConvexHullStrategy<Strategy>) );
+
+ return dispatch::convex_hull_inserter
+ <
+ typename tag<Geometry>::type,
+ ggl::point_order<Geometry>::value,
+ is_multi<Geometry>::type::value,
+ Geometry, Strategy
+ >::apply(geometry, out, strategy);
}
@@ -248,13 +260,17 @@
concept::check<const Geometry>();
concept::check<typename point_type<Geometry>::type>();
- return dispatch::convex_hull_inserter
+ typedef typename range_type<Geometry>::type range_type;
+ typedef typename point_type<Geometry>::type point_type;
+
+ typedef typename strategy_convex_hull
<
- typename tag<Geometry>::type,
- ggl::point_order<Geometry>::value,
- is_multi<Geometry>::type::value,
- Geometry
- >::apply(geometry, out);
+ typename cs_tag<point_type>::type,
+ Geometry,
+ point_type
+ >::type strategy_type;
+
+ return convex_hull_inserter(geometry, out, strategy_type());
}
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/detail/point_on_border.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/detail/point_on_border.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,173 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. 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 GGL_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
+#define GGL_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
+
+
+#include <boost/range/functions.hpp>
+
+#include <ggl/core/point_type.hpp>
+#include <ggl/core/ring_type.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/algorithms/assign.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace point_on_border {
+
+template
+<
+ typename Range,
+ typename Point
+>
+struct point_on_range
+{
+ static inline bool apply(Range const& range, Point& point)
+ {
+ if (boost::size(range) > 0)
+ {
+ point = *boost::begin(range);
+ return true;
+ }
+ return false;
+ }
+};
+
+
+template
+<
+ typename Polygon,
+ typename Point
+>
+struct point_on_polygon
+{
+ static inline bool apply(Polygon const& polygon, Point& point)
+ {
+ return point_on_range
+ <
+ typename ring_type<Polygon>::type,
+ Point
+ >::apply(exterior_ring(polygon), point);
+ }
+};
+
+
+template
+<
+ typename Box,
+ typename Point
+>
+struct point_on_box
+{
+ static inline bool apply(Box const& box, Point& point)
+ {
+ detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, point);
+ return true;
+ }
+};
+
+
+}} // namespace detail::point_on_border
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryTag,
+ typename Geometry,
+ typename Point
+
+>
+struct point_on_border
+{
+};
+
+
+template<typename Point>
+struct point_on_border
+ <
+ point_tag, Point, Point
+ >
+{
+ static inline bool apply(Point const& source, Point& destination)
+ {
+ destination = source;
+ return true;
+ }
+};
+
+
+template<typename Linestring, typename Point>
+struct point_on_border<linestring_tag, Linestring, Point>
+ : detail::point_on_border::point_on_range<Linestring, Point>
+{};
+
+
+template<typename Ring, typename Point>
+struct point_on_border<ring_tag, Ring, Point>
+ : detail::point_on_border::point_on_range<Ring, Point>
+{};
+
+
+template<typename Polygon, typename Point>
+struct point_on_border<polygon_tag, Polygon, Point>
+ : detail::point_on_border::point_on_polygon<Polygon, Point>
+{};
+
+
+template<typename Box, typename Point>
+struct point_on_border<box_tag, Box, Point>
+ : detail::point_on_border::point_on_box<Box, Point>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+ \brief Take point on a border
+ \ingroup utility
+ \tparam Geometry geometry type
+ \param geometry geometry to take point from
+ \param point
+ \return TRUE if successful, else false.
+ It is only false if polygon/line have no points
+ \note for a polygon, it is always a point on the exterior ring
+ */
+template <typename Geometry>
+inline bool point_on_border(Geometry const& geometry,
+ typename point_type<Geometry>::type& point)
+{
+ typedef typename point_type<Geometry>::type point_type;
+
+ concept::check<const Geometry>();
+ concept::check<point_type>();
+
+ return dispatch::point_on_border
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ point_type
+ >::apply(geometry, point);
+}
+
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/disjoint.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/disjoint.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/disjoint.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -9,6 +9,14 @@
#ifndef GGL_ALGORITHMS_DISJOINT_HPP
#define GGL_ALGORITHMS_DISJOINT_HPP
+
+/*!
+\defgroup disjoint disjoint, not any spatial relation
+\details disjoint means spatially disjoint, there is no overlap of interiors
+ and boundaries, the intersection of interiors or boundaries is empty.
+*/
+
+
#include <boost/mpl/if.hpp>
#include <boost/range/functions.hpp>
#include <boost/range/metafunctions.hpp>
@@ -29,86 +37,112 @@
namespace ggl
{
+
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace disjoint {
-template <typename P1, typename P2, std::size_t D, std::size_t N>
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
struct point_point
{
- typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
-
- static inline bool apply(P1 const& p1, P2 const& p2)
+ static inline bool apply(Point1 const& p1, Point2 const& p2)
{
- if (! ggl::math::equals(get<D>(p1), get<D>(p2)))
+ if (! ggl::math::equals(get<Dimension>(p1), get<Dimension>(p2)))
{
return true;
}
- return point_point<P1, P2, D + 1, N>::apply(p1, p2);
+ return point_point
+ <
+ Point1, Point2,
+ Dimension + 1, DimensionCount
+ >::apply(p1, p2);
}
};
-template <typename P1, typename P2, std::size_t N>
-struct point_point<P1, P2, N, N>
+
+template <typename Point1, typename Point2, std::size_t DimensionCount>
+struct point_point<Point1, Point2, DimensionCount, DimensionCount>
{
- static inline bool apply(P1 const& , P2 const& )
+ static inline bool apply(Point1 const& , Point2 const& )
{
return false;
}
};
-template <typename P, typename B, std::size_t D, std::size_t N>
+template
+<
+ typename Point, typename Box,
+ std::size_t Dimension, std::size_t DimensionCount
+>
struct point_box
{
- static inline bool apply(P const& point, B const& box)
+ static inline bool apply(Point const& point, Box const& box)
{
- if (get<D>(point) < get<min_corner, D>(box)
- || get<D>(point) > get<max_corner, D>(box))
+ if (get<Dimension>(point) < get<min_corner, Dimension>(box)
+ || get<Dimension>(point) > get<max_corner, Dimension>(box))
{
return true;
}
- return point_box<P, B, D + 1, N>::apply(point, box);
+ return point_box
+ <
+ Point, Box,
+ Dimension + 1, DimensionCount
+ >::apply(point, box);
}
};
-template <typename P, typename B, std::size_t N>
-struct point_box<P, B, N, N>
+
+template <typename Point, typename Box, std::size_t DimensionCount>
+struct point_box<Point, Box, DimensionCount, DimensionCount>
{
- static inline bool apply(P const& , B const& )
+ static inline bool apply(Point const& , Box const& )
{
return false;
}
};
-template <typename B1, typename B2, std::size_t D, std::size_t N>
+template
+<
+ typename Box1, typename Box2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
struct box_box
{
- static inline bool apply(B1 const& box1, B2 const& box2)
+ static inline bool apply(Box1 const& box1, Box2 const& box2)
{
- if (get<max_corner, D>(box1) < get<min_corner, D>(box2))
+ if (get<max_corner, Dimension>(box1) < get<min_corner, Dimension>(box2))
{
return true;
}
- if (get<min_corner, D>(box1) > get<max_corner, D>(box2))
+ if (get<min_corner, Dimension>(box1) > get<max_corner, Dimension>(box2))
{
return true;
}
- return box_box<B1, B2, D + 1, N>::apply(box1, box2);
+ return box_box
+ <
+ Box1, Box2,
+ Dimension + 1, DimensionCount
+ >::apply(box1, box2);
}
};
-template <typename B1, typename B2, std::size_t N>
-struct box_box<B1, B2, N, N>
+
+template <typename Box1, typename Box2, std::size_t DimensionCount>
+struct box_box<Box1, Box2, DimensionCount, DimensionCount>
{
- static inline bool apply(B1 const& , B2 const& )
+ static inline bool apply(Box1 const& , Box2 const& )
{
return false;
}
};
-
}} // namespace detail::disjoint
#endif // DOXYGEN_NO_DETAIL
@@ -117,6 +151,7 @@
namespace dispatch
{
+
template
<
typename GeometryTag1, typename GeometryTag2,
@@ -125,26 +160,25 @@
std::size_t DimensionCount
>
struct disjoint
-{
-};
+{};
+
template <typename P1, typename P2, std::size_t DimensionCount>
struct disjoint<point_tag, point_tag, P1, P2, false, false, DimensionCount>
: detail::disjoint::point_point<P1, P2, 0, DimensionCount>
-{
-};
+{};
+
template <typename B1, typename B2, std::size_t DimensionCount>
struct disjoint<box_tag, box_tag, B1, B2, false, false, DimensionCount>
: detail::disjoint::box_box<B1, B2, 0, DimensionCount>
-{
-};
+{};
+
template <typename P, typename B, std::size_t DimensionCount>
struct disjoint<point_tag, box_tag, P, B, false, false, DimensionCount>
: detail::disjoint::point_box<P, B, 0, DimensionCount>
-{
-};
+{};
template
@@ -176,7 +210,7 @@
/*!
\brief Calculate if two geometries are disjoint
- \ingroup boolean_relations
+ \ingroup disjoint
\tparam Geometry1 first geometry type
\tparam Geometry2 second geometry type
\param geometry1 first geometry
@@ -187,10 +221,11 @@
inline bool disjoint(const Geometry1& geometry1,
const Geometry2& geometry2)
{
- concept::check<const Geometry1>();
- concept::check<const Geometry2>();
-
- assert_dimension_equal<Geometry1, Geometry2>();
+ concept::check_concepts_and_equal_dimensions
+ <
+ const Geometry1,
+ const Geometry2
+ >();
typedef typename boost::remove_const<Geometry1>::type ncg1_type;
typedef typename boost::remove_const<Geometry2>::type ncg2_type;
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/distance.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/distance.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/distance.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -17,9 +17,12 @@
#include <ggl/core/cs.hpp>
#include <ggl/core/is_multi.hpp>
#include <ggl/core/reverse_dispatch.hpp>
+
#include <ggl/geometries/segment.hpp>
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/strategies/distance.hpp>
#include <ggl/strategies/distance_result.hpp>
-#include <ggl/strategies/strategies.hpp>
/*!
\defgroup distance distance calculation
@@ -64,7 +67,7 @@
static inline typename Strategy::return_type apply(P1 const& p1,
P2 const& p2, Strategy const& strategy)
{
- return strategy(p1, p2);
+ return strategy.apply(p1, p2);
}
};
@@ -80,10 +83,10 @@
typename cs_tag<Point>::type,
typename cs_tag<Segment>::type,
Point,
- Segment
+ typename point_type<Segment>::type
>::type segment_strategy;
- return segment_strategy(point, segment);
+ return segment_strategy.apply(point, segment.first, segment.second);
}
};
@@ -109,18 +112,18 @@
iterator_type prev = it++;
if (it == boost::end(linestring))
{
- return pp_strategy(point, *boost::begin(linestring));
+ return pp_strategy.apply(point, *boost::begin(linestring));
}
// start with first segment distance
- return_type d = ps_strategy(point, segment_type(*prev, *it));
+ return_type d = ps_strategy.apply(point, *prev, *it);
// check if other segments are closer
prev = it++;
while(it != boost::end(linestring))
{
- return_type ds = ps_strategy(point, segment_type(*prev, *it));
+ return_type ds = ps_strategy.apply(point, *prev, *it);
if (ggl::close_to_zero(ds))
{
return return_type(0);
@@ -182,13 +185,13 @@
Linestring const& linestring,
Strategy const& strategy)
{
- typedef segment<const typename point_type<Linestring>::type> segment_type;
+ //typedef segment<const > segment_type;
typedef typename ggl::strategy_distance_segment
<
typename cs_tag<Point>::type,
- typename cs_tag<segment_type>::type,
+ typename cs_tag<Linestring>::type,
Point,
- segment_type
+ typename point_type<Linestring>::type
>::type ps_strategy_type;
return detail::distance::point_to_linestring
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/envelope.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/envelope.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/envelope.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -17,12 +17,8 @@
#include <ggl/algorithms/convert.hpp>
#include <ggl/core/cs.hpp>
#include <ggl/core/exterior_ring.hpp>
-
#include <ggl/geometries/concepts/check.hpp>
-
-#include <ggl/strategies/strategies.hpp>
-
/*!
\defgroup envelope envelope calculation
\par Source descriptions:
@@ -39,7 +35,6 @@
There are two versions:
- envelope, taking a reference to a box as second parameter
- make_envelope, returning a newly constructed box (type as a template parameter in the function call)
-- either of them has an optional strategy
\par Geometries:
- POINT: a box with zero area, the maximum and the minimum point of the box are
@@ -69,10 +64,10 @@
/// Calculate envelope of an 2D or 3D point
-template<typename Point, typename Box, typename Strategy>
+template<typename Point, typename Box>
struct envelope_point
{
- static inline void apply(Point const& p, Box& mbr, Strategy const&)
+ static inline void apply(Point const& p, Box& mbr)
{
// Envelope of a point is an empty box, a box with zero volume, located
// at the point.
@@ -83,12 +78,12 @@
/// Calculate envelope of an 2D or 3D segment
-template<typename Segment, typename Box, typename Strategy>
+template<typename Segment, typename Box>
struct envelope_segment
{
- static inline void apply(Segment const& s, Box& mbr, Strategy const&)
+ static inline void apply(Segment const& s, Box& mbr)
{
- // TODO: remove s.first/s.second, use strategies
+ // TODO: remove s.first/s.second
ggl::assign_inverse(mbr);
ggl::combine(mbr, s.first);
ggl::combine(mbr, s.second);
@@ -96,10 +91,9 @@
};
-/// Version with state iterating through range (also used in multi*)
-template<typename Range, typename Strategy>
-inline void envelope_range_state(Range const& range,
- Strategy const& strategy, typename Strategy::state_type& state)
+/// Iterate through range (also used in multi*)
+template<typename Range, typename Box>
+inline void envelope_range_additional(Range const& range, Box& mbr)
{
typedef typename boost::range_const_iterator<Range>::type iterator_type;
@@ -107,22 +101,21 @@
it != boost::end(range);
++it)
{
- strategy(*it, state);
+ ggl::combine(mbr, *it);
}
}
/// Generic range dispatching struct
-template <typename Range, typename Box, typename Strategy>
+template <typename Range, typename Box>
struct envelope_range
{
/// Calculate envelope of range using a strategy
- static inline void apply(Range const& range, Box& mbr,
- Strategy const& strategy)
+ static inline void apply(Range const& range, Box& mbr)
{
- typename Strategy::state_type state(mbr);
- envelope_range_state(range, strategy, state);
+ assign_inverse(mbr);
+ envelope_range_additional(range, mbr);
}
};
@@ -137,65 +130,87 @@
<
typename Tag1, typename Tag2,
typename Geometry, typename Box,
- typename Strategy
+ typename StrategyLess, typename StrategyGreater
>
struct envelope {};
-template <typename Point, typename Box, typename Strategy>
-struct envelope<point_tag, box_tag, Point, Box, Strategy>
- : detail::envelope::envelope_point<Point, Box, Strategy>
+template
+<
+ typename Point, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope<point_tag, box_tag, Point, Box, StrategyLess, StrategyGreater>
+ : detail::envelope::envelope_point<Point, Box>
{};
-template <typename Box, typename Strategy>
-struct envelope<box_tag, box_tag, Box, Box, Strategy>
+template
+<
+ typename BoxIn, typename BoxOut,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope<box_tag, box_tag, BoxIn, BoxOut, StrategyLess, StrategyGreater>
{
/*!
\brief Calculate envelope of a box
\details The envelope of a box is itself, provided
for consistency, on itself it is not useful.
*/
- static inline void apply(Box const& box, Box& mbr, Strategy const&)
+ static inline void apply(BoxIn const& box, BoxOut& mbr)
{
mbr = box;
}
};
-template <typename Segment, typename Box, typename Strategy>
-struct envelope<segment_tag, box_tag, Segment, Box, Strategy>
- : detail::envelope::envelope_segment<Segment, Box, Strategy>
+template
+<
+ typename Segment, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope<segment_tag, box_tag, Segment, Box, StrategyLess, StrategyGreater>
+ : detail::envelope::envelope_segment<Segment, Box>
{};
-template <typename Linestring, typename Box, typename Strategy>
-struct envelope<linestring_tag, box_tag, Linestring, Box, Strategy>
- : detail::envelope::envelope_range<Linestring, Box, Strategy>
+template
+<
+ typename Linestring, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope<linestring_tag, box_tag, Linestring, Box, StrategyLess, StrategyGreater>
+ : detail::envelope::envelope_range<Linestring, Box>
{};
-template <typename Ring, typename Box, typename Strategy>
-struct envelope<ring_tag, box_tag, Ring, Box, Strategy>
- : detail::envelope::envelope_range<Ring, Box, Strategy>
+template
+<
+ typename Ring, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope<ring_tag, box_tag, Ring, Box, StrategyLess, StrategyGreater>
+ : detail::envelope::envelope_range<Ring, Box>
{};
-template <typename Polygon, typename Box, typename Strategy>
-struct envelope<polygon_tag, box_tag, Polygon, Box, Strategy>
+template
+<
+ typename Polygon, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope<polygon_tag, box_tag, Polygon, Box, StrategyLess, StrategyGreater>
{
- static inline void apply(Polygon const& poly, Box& mbr,
- Strategy const& strategy)
+ static inline void apply(Polygon const& poly, Box& mbr)
{
// For polygon, inspecting outer ring is sufficient
detail::envelope::envelope_range
<
typename ring_type<Polygon>::type,
- Box,
- Strategy
- >::apply(exterior_ring(poly), mbr, strategy);
+ Box
+ >::apply(exterior_ring(poly), mbr);
}
};
@@ -206,30 +221,6 @@
/*!
-\brief Calculate envelope of a geometry, using a specified strategy
-\ingroup envelope
-\param geometry the geometry
-\param mbr the box receiving the envelope
-\param strategy strategy to be used
-*/
-template<typename Geometry, typename Box, typename Strategy>
-inline void envelope(Geometry const& geometry,
- Box& mbr, Strategy const& strategy)
-{
- concept::check<const Geometry>();
- concept::check<Box>();
-
- dispatch::envelope
- <
- typename tag<Geometry>::type, typename tag<Box>::type,
- Geometry, Box, Strategy
- >::apply(geometry, mbr, strategy);
-}
-
-
-
-
-/*!
\brief Calculate envelope of a geometry
\ingroup envelope
\param geometry the geometry
@@ -247,38 +238,12 @@
concept::check<const Geometry>();
concept::check<Box>();
- typename strategy_envelope
- <
- typename cs_tag<typename point_type<Geometry>::type>::type,
- typename cs_tag<typename point_type<Box>::type>::type,
- typename point_type<Geometry>::type,
- Box
- >::type strategy;
-
- envelope(geometry, mbr, strategy);
-}
-
-
-/*!
-\brief Calculate and return envelope of a geometry
-\ingroup envelope
-\param geometry the geometry
-\param strategy the strategy to be used
-*/
-template<typename Box, typename Geometry, typename Strategy>
-inline Box make_envelope(Geometry const& geometry, Strategy const& strategy)
-{
- concept::check<const Geometry>();
- concept::check<Box>();
-
- Box box;
dispatch::envelope
<
typename tag<Geometry>::type, typename tag<Box>::type,
- Geometry, Box, Strategy
- >::apply(geometry, box, strategy);
-
- return box;
+ Geometry, Box,
+ void, void
+ >::apply(geometry, mbr);
}
@@ -293,17 +258,16 @@
concept::check<const Geometry>();
concept::check<Box>();
- typename strategy_envelope
+ Box mbr;
+ dispatch::envelope
<
- typename cs_tag<typename point_type<Geometry>::type>::type,
- typename cs_tag<typename point_type<Box>::type>::type,
- typename point_type<Geometry>::type,
- Box
- >::type strategy;
- return make_envelope<Box>(geometry, strategy);
+ typename tag<Geometry>::type, typename tag<Box>::type,
+ Geometry, Box,
+ void, void
+ >::apply(geometry, mbr);
+ return mbr;
}
-
} // namespace ggl
#endif // GGL_ALGORITHMS_ENVELOPE_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/equals.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/equals.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/equals.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -23,9 +23,7 @@
#include <ggl/util/math.hpp>
/*!
-
-\defgroup boolean_relations boolean relationships (equals, disjoint, overlaps, etc)
-
+\defgroup equals equals, test if two geometries are spatially equal
*/
namespace ggl
@@ -110,13 +108,7 @@
template <typename Geometry1, typename Geometry2>
inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
- concept::check<const Geometry1>();
- concept::check<const Geometry2>();
- assert_dimension_equal<Geometry1, Geometry2>();
-
-// TODO: assert types equal:
-// typename tag<ncg1_type>::type, typename tag<ncg2_type>::type,
-// (LATER): NO! a linestring can be spatially equal to a multi_linestring
+ concept::check_concepts_and_equal_dimensions<const Geometry1, const Geometry2>();
typedef typename boost::remove_const<Geometry1>::type ncg1_type;
typedef typename boost::remove_const<Geometry2>::type ncg2_type;
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/for_each.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/for_each.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/for_each.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -10,19 +10,15 @@
#define GGL_ALGORITHMS_FOR_EACH_HPP
/*!
-\defgroup loop loops and for-each functionality
-There are several algorithms provided which walk through the points or segments
+\defgroup for_each for_each: applying a functor for each point or segment
+There are two algorithms provided which walk through the points or segments
of linestrings and polygons. They are called for_each_point, for_each_segment,
-after the standard library, and \b loop which is more adapted
-and of which the functor could break out if necessary.
-Of the for_each algorithms there is a \b const and a non-const version provided.
+after the standard library
+\note For both for_each algorithms there is a \b const and a non-const version provided.
*/
#include <algorithm>
-#include <boost/mpl/if.hpp>
-#include <boost/range/functions.hpp>
-#include <boost/range/metafunctions.hpp>
#include <ggl/core/exterior_ring.hpp>
#include <ggl/core/interior_rings.hpp>
@@ -31,7 +27,10 @@
#include <ggl/geometries/concepts/check.hpp>
#include <ggl/geometries/segment.hpp>
-#include <ggl/iterators/vertex_iterator.hpp>
+
+#include <ggl/util/add_const_if_c.hpp>
+#include <ggl/util/range_iterator_const_if_c.hpp>
+
namespace ggl
{
@@ -40,79 +39,58 @@
namespace detail { namespace for_each {
-// There is probably something in boost type_traits
-// or MPL with this functionality
-template <typename Type, bool IsConst>
-struct c_nc
-{
- typedef typename boost::mpl::if_c
- <
- IsConst,
- const Type,
- Type
- >::type type;
-};
-
-// Utility to adapt a boost-range for const/non const
-template <typename Range, bool IsConst>
-struct c_nc_range
-{
- typedef typename boost::mpl::if_c
- <
- IsConst,
- typename boost::range_const_iterator<Range>::type,
- typename boost::range_iterator<Range>::type
- >::type type;
-};
-
-
template <typename Point, typename Functor, bool IsConst>
struct fe_point_per_point
{
static inline Functor apply(
- typename c_nc<Point, IsConst>::type& point, Functor f)
+ typename add_const_if_c<IsConst, Point>::type& point, Functor f)
{
f(point);
return f;
}
};
+
template <typename Point, typename Functor, bool IsConst>
struct fe_point_per_segment
{
static inline Functor apply(
- typename c_nc<Point, IsConst>::type& point, Functor f)
+ typename add_const_if_c<IsConst, Point>::type& point, Functor f)
{
return f;
}
};
+
template <typename Range, typename Functor, bool IsConst>
struct fe_range_per_point
{
static inline Functor apply(
- typename c_nc<Range, IsConst>::type& range,
+ typename add_const_if_c<IsConst, Range>::type& range,
Functor f)
{
return (std::for_each(boost::begin(range), boost::end(range), f));
}
};
+
template <typename Range, typename Functor, bool IsConst>
struct fe_range_per_segment
{
static inline Functor apply(
- typename c_nc<Range, IsConst>::type& range,
+ typename add_const_if_c<IsConst, Range>::type& range,
Functor f)
{
- typedef typename ggl::vertex_iterator
+ typedef typename range_iterator_const_if_c
<
- Range, IsConst
+ IsConst,
+ Range
>::type iterator_type;
- typedef typename c_nc
+ typedef typename add_const_if_c
<
- typename point_type<Range>::type, IsConst
+ IsConst,
+ typename point_type<Range>::type
>::type point_type;
iterator_type it = boost::begin(range);
@@ -133,13 +111,13 @@
struct fe_polygon_per_point
{
static inline Functor apply(
- typename c_nc<Polygon, IsConst>::type& poly,
+ typename add_const_if_c<IsConst, Polygon>::type& poly,
Functor f)
{
- typedef typename c_nc_range
+ typedef typename range_iterator_const_if_c
<
- typename interior_type<Polygon>::type,
- IsConst
+ IsConst,
+ typename interior_type<Polygon>::type
>::type iterator_type;
typedef fe_range_per_point
@@ -168,13 +146,13 @@
struct fe_polygon_per_segment
{
static inline Functor apply(
- typename c_nc<Polygon, IsConst>::type& poly,
+ typename add_const_if_c<IsConst, Polygon>::type& poly,
Functor f)
{
- typedef typename c_nc_range
+ typedef typename range_iterator_const_if_c
<
- typename interior_type<Polygon>::type,
- IsConst
+ IsConst,
+ typename interior_type<Polygon>::type
>::type iterator_type;
typedef fe_range_per_segment
@@ -198,6 +176,7 @@
};
+
}} // namespace detail::for_each
#endif // DOXYGEN_NO_DETAIL
@@ -216,29 +195,31 @@
>
struct for_each_point {};
+
template <typename Point, typename Functor, bool IsConst>
struct for_each_point<point_tag, false, Point, Functor, IsConst>
: detail::for_each::fe_point_per_point<Point, Functor, IsConst>
{};
+
template <typename Linestring, typename Functor, bool IsConst>
struct for_each_point<linestring_tag, false, Linestring, Functor, IsConst>
: detail::for_each::fe_range_per_point<Linestring, Functor, IsConst>
{};
+
template <typename Ring, typename Functor, bool IsConst>
struct for_each_point<ring_tag, false, Ring, Functor, IsConst>
: detail::for_each::fe_range_per_point<Ring, Functor, IsConst>
{};
+
template <typename Polygon, typename Functor, bool IsConst>
struct for_each_point<polygon_tag, false, Polygon, Functor, IsConst>
: detail::for_each::fe_polygon_per_point<Polygon, Functor, IsConst>
{};
-
-
template
<
typename Tag,
@@ -254,16 +235,19 @@
: detail::for_each::fe_point_per_segment<Point, Functor, IsConst>
{};
+
template <typename Linestring, typename Functor, bool IsConst>
struct for_each_segment<linestring_tag, false, Linestring, Functor, IsConst>
: detail::for_each::fe_range_per_segment<Linestring, Functor, IsConst>
{};
+
template <typename Ring, typename Functor, bool IsConst>
struct for_each_segment<ring_tag, false, Ring, Functor, IsConst>
: detail::for_each::fe_range_per_segment<Ring, Functor, IsConst>
{};
+
template <typename Polygon, typename Functor, bool IsConst>
struct for_each_segment<polygon_tag, false, Polygon, Functor, IsConst>
: detail::for_each::fe_polygon_per_segment<Polygon, Functor, IsConst>
@@ -273,6 +257,7 @@
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
+
/*!
\brief Calls functor for geometry
\ingroup loop
@@ -295,6 +280,7 @@
>::apply(geometry, f);
}
+
/*!
\brief Calls functor for geometry
\ingroup loop
@@ -317,6 +303,7 @@
>::apply(geometry, f);
}
+
/*!
\brief Calls functor for segments on linestrings, rings, polygons, ...
\ingroup loop
@@ -363,6 +350,8 @@
>::apply(geometry, f);
}
+
} // namespace ggl
+
#endif // GGL_ALGORITHMS_FOR_EACH_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/get_section.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/get_section.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/get_section.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -18,7 +18,7 @@
#include <ggl/core/exterior_ring.hpp>
#include <ggl/core/interior_rings.hpp>
-#include <ggl/iterators/vertex_iterator.hpp>
+#include <ggl/iterators/range_type.hpp>
#include <ggl/geometries/segment.hpp>
@@ -35,7 +35,11 @@
template <typename Tag, typename Geometry, typename Section>
struct get_section
{
- typedef typename ggl::vertex_iterator<Geometry, true>::type iterator_type;
+ typedef typename boost::range_const_iterator
+ <
+ typename ggl::range_type<Geometry>::type
+ >::type iterator_type;
+
static inline void apply(Geometry const& geometry, Section const& section,
iterator_type& begin, iterator_type& end)
{
@@ -47,7 +51,11 @@
template <typename Polygon, typename Section>
struct get_section<polygon_tag, Polygon, Section>
{
- typedef typename ggl::vertex_iterator<Polygon, true>::type iterator_type;
+ typedef typename boost::range_const_iterator
+ <
+ typename ggl::range_type<Polygon>::type
+ >::type iterator_type;
+
static inline void apply(Polygon const& polygon, Section const& section,
iterator_type& begin, iterator_type& end)
{
@@ -81,8 +89,14 @@
*/
template <typename Geometry, typename Section>
inline void get_section(Geometry const& geometry, Section const& section,
- typename vertex_iterator<Geometry, true>::type& begin,
- typename vertex_iterator<Geometry, true>::type& end)
+ typename boost::range_const_iterator
+ <
+ typename ggl::range_type<Geometry>::type
+ >::type& begin,
+ typename boost::range_const_iterator
+ <
+ typename ggl::range_type<Geometry>::type
+ >::type& end)
{
concept::check<const Geometry>();
Deleted: sandbox/ggl/formal_review_request/boost/ggl/algorithms/intermediate.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/intermediate.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,135 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_ALGORITHMS_INTERMEDIATE_HPP
-#define GGL_ALGORITHMS_INTERMEDIATE_HPP
-
-#include <cstddef>
-#include <iterator>
-
-#include <boost/range/functions.hpp>
-#include <boost/range/metafunctions.hpp>
-
-#include <ggl/core/cs.hpp>
-#include <ggl/geometries/concepts/check.hpp>
-#include <ggl/strategies/strategies.hpp>
-
-/*!
-\defgroup intermediate intermediate calculation
-The intermediate algorithm calculate points IN BETWEEN of other points
-\par Purpose:
-- Remove corners in rectangular lines / polygons. Calling them several times will result in smooth lines
-- Creating 3D models
-*/
-
-namespace ggl
-{
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace intermediate {
-
-template <typename Src, typename Dst, std::size_t Dimension, std::size_t DimensionCount>
-struct calculate_coordinate
-{
- static inline void apply(Src const& p1, Src const& p2, Dst& p)
- {
- ggl::set<Dimension>(p,
- (ggl::get<Dimension>(p1) + ggl::get<Dimension>(p2)) / 2.0);
- calculate_coordinate<Src, Dst, Dimension + 1, DimensionCount>::apply(p1, p2, p);
- }
-};
-
-template <typename Src, typename Dst, std::size_t DimensionCount>
-struct calculate_coordinate<Src, Dst, DimensionCount, DimensionCount>
-{
- static inline void apply(Src const&, Src const&, Dst&)
- {
- }
-};
-
-template<typename Range, typename Iterator>
-struct range_intermediate
-{
- static inline void apply(Range const& range,
- bool start_and_end, Iterator out)
- {
- typedef typename point_type<Range>::type point_type;
- typedef typename boost::range_const_iterator<Range>::type iterator_type;
-
- iterator_type it = boost::begin(range);
-
- if (start_and_end)
- {
- *out++ = *it;
- }
-
- iterator_type prev = it++;
- for (; it != boost::end(range); prev = it++)
- {
- point_type p;
- calculate_coordinate
- <
- point_type,
- point_type,
- 0,
- dimension<point_type>::type::value
- >::apply(*prev, *it, p);
- *out++ = p;
- }
-
- if (start_and_end)
- {
- *out++ = *prev;
- }
- }
-};
-
-}} // namespace detail::intermediate
-#endif // DOXYGEN_NO_DETAIL
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-template <typename GeometryTag, typename G, typename Iterator>
-struct intermediate {};
-
-template <typename G, typename Iterator>
-struct intermediate<ring_tag, G, Iterator>
- : detail::intermediate::range_intermediate<G, Iterator> {};
-
-template <typename G, typename Iterator>
-struct intermediate<linestring_tag, G, Iterator>
- : detail::intermediate::range_intermediate<G, Iterator> {};
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-/*!
- \brief Calculate intermediate of a geometry
- \ingroup intermediate
- */
-template<typename Geometry, typename Iterator>
-inline void intermediate(Geometry const& geometry,
- bool start_and_end, Iterator out)
-{
- concept::check<const Geometry>();
-
- dispatch::intermediate
- <
- typename tag<Geometry>::type,
- Geometry,
- Iterator
- >::apply(geometry, start_and_end, out);
-}
-
-} // namespace ggl
-
-#endif // GGL_ALGORITHMS_INTERMEDIATE_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -9,61 +9,60 @@
#ifndef GGL_ALGORITHMS_INTERSECTION_HPP
#define GGL_ALGORITHMS_INTERSECTION_HPP
-#include <deque>
#include <boost/mpl/if.hpp>
+#include <ggl/core/reverse_dispatch.hpp>
#include <ggl/geometries/concepts/check.hpp>
-
-#include <ggl/algorithms/intersection_linestring.hpp>
-
-#include <ggl/algorithms/overlay/get_intersection_points.hpp>
-#include <ggl/algorithms/overlay/merge_intersection_points.hpp>
-#include <ggl/algorithms/overlay/adapt_turns.hpp>
-#include <ggl/algorithms/overlay/enrich_intersection_points.hpp>
-#include <ggl/algorithms/overlay/traverse.hpp>
-
-#include <ggl/algorithms/assign.hpp>
-#include <ggl/algorithms/convert.hpp>
-#include <ggl/algorithms/within.hpp>
+#include <ggl/algorithms/overlay/clip_linestring.hpp>
+#include <ggl/algorithms/overlay/assemble.hpp>
/*!
-\defgroup overlay overlay operations (intersection, union, clipping)
-\details The intersection of two geometries A and B is the geometry containing all points of A also belonging to B,
-but no other elements. The so-called clip is an intersection of a geometry with a box.
+\defgroup intersection intersection operations
+ (clipping, polygon-polygon intersection)
+\details The intersection of two geometries A and B is the geometry containing
+ all points of A also belonging to B, but no other elements. The so-called
+ clip is an intersection of a geometry with a box.
\par Source description:
-- OGC: Returns a geometric object that represents the Point set intersection of this geometric object with another Geometry.
+- OGC: Returns a geometric object that represents the Point set intersection of
+ this geometric object with another Geometry.
\see http://en.wikipedia.org/wiki/Intersection_(set_theory)
\note Any intersection can result in no geometry at all
-\note Used strategies still have to be modelled. Working only for cartesian
+\par Performance
+- 2776 counties of US are intersected with a 100-points ellipse in 1.1 seconds
+(http://trac.osgeo.org/ggl/wiki/Performance#Interesection)
+- 2776 counties of US are clipped in 0.2 seconds
+(http://trac.osgeo.org/ggl/wiki/Performance#Clip)
+
+
\par Geometries:
-The intersection result is painted with a red outline.
-- clip: POLYGON + BOX -> output iterator of polygons
-\image html clip_polygon.png
-- clip: LINESTRING + BOX -> output iterator of linestrings
-\image html clip_linestring.png
-\note There are some difficulties to model an intersection in the template world. The intersection of two segments can
-result into nothing, into a point, into another segment. At compiletime the result type is not known. An output iterator
-iterating points is appropriate here.
-\image html clip_segment_segment.png
-An intersection of two linestrings can result into nothing, one or more points, one or more segments or one or more
-linestrings. So an output iterator will NOT do here.
-So the output might be changed into a unified algorithm where the output is a multi-geometry.
-For the current clip-only operations the output iterator will do.
+- \b polygon + \b box (clip) -> \b polygon(s)
+\image html svg_intersection_polygon_box.png
+\image html svg_intersection_countries.png
+- \b ring + \b box (clip) -> \b polygon(s)
+\image html svg_intersection_ring_box.png
+- \b ring + \b ring -> \b polygon(s)
+\image html svg_intersection_ring_ring.png
+- \b polygon + \b ring -> \b polygon(s)
+\image html svg_intersection_polygon_ring.png
+- combinations above -> \b ring(s).
+ <i>If the output is an ouput iterator of rings, holes are omitted</i>
+- \b linestring + \b box (clip)
+\image html svg_intersection_roads.png
\par Example:
Example showing clipping of linestring with box
\dontinclude doxygen_examples.cpp
-\skip example_intersection_linestring1
+\skip example_clip_linestring1
\line {
\until }
\par Example:
Example showing clipping of vector, outputting vectors, with box
\dontinclude doxygen_examples.cpp
-\skip example_intersection_linestring2
+\skip example_clip_linestring2
\line {
\until }
\par Example:
@@ -79,194 +78,93 @@
#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace intersection {
+namespace detail { namespace overlay {
+
+// Specializations for "take_one" for intersection
+// "one" should be the inner one
+
+// for ring and box
template
<
- typename Polygon1, typename Polygon2,
- typename OutputIterator, typename GeometryOut
+ typename Tag1, typename Geometry1,
+ typename Tag2, typename Geometry2,
+ typename GeometryOut
>
-struct intersection_polygon_polygon
+struct take_if_1_is_in_2<Tag1, Geometry1, Tag2, Geometry2, GeometryOut, -1>
{
- static inline OutputIterator apply(Polygon1 const& polygon1,
- Polygon2 const& polygon2, OutputIterator out)
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ GeometryOut& out
+ )
{
- typedef detail::intersection::intersection_point
- <
- typename ggl::point_type<GeometryOut>::type
- > ip_type;
- typedef std::deque<ip_type> ips_container;
-
- typedef typename ggl::ring_type<GeometryOut>::type ring_type;
-
- ips_container ips;
-
- bool trivial = ggl::get_intersection_points(polygon1, polygon2, ips);
-
- if (ips.size() <= 0)
- {
- // If there are no IP-s, check if one point is in other polygon
- // assume both polygons having points
- if (ggl::within(ggl::exterior_ring(polygon1).front(), polygon2))
- {
- // Assume same type (output = input)
- // TODO: solve this (we go to specialize again...)
- *out = polygon1;
- out++;
- }
- else if (ggl::within(ggl::exterior_ring(polygon2).front(), polygon1))
- {
- *out = polygon2;
- out++;
- }
- }
- else
- {
- if (! trivial)
- {
- ggl::merge_intersection_points(ips);
- ggl::adapt_turns(ips);
-
- }
-
- ggl::enrich_intersection_points(ips, trivial);
-
-
- std::vector<ring_type> v;
- ggl::traverse<ring_type>
- (
- polygon1,
- polygon2,
- -1,
- ips,
- trivial,
- std::back_inserter(v)
- );
-
-
- // TODO:
- // assemble rings / inner rings / to polygons
- for (typename std::vector<ring_type>::const_iterator it = v.begin();
- it != v.end(); ++it)
- {
- // How can we avoid the double copy here! It is really bad!
- // We have to create a polygon, then copy it to the output iterator.
- // Having an output-vector would have been better: append it to the vector!
- // So output iterators are not that good.
- GeometryOut poly;
- poly.outer() = *it;
- *out = poly;
- out++;
- }
- }
-
-
- return out;
+ ggl::convert(geometry1, out);
}
};
-
-
template
<
- typename Polygon, typename Box,
- typename OutputIterator, typename GeometryOut
+ typename Geometry1,
+ typename Tag2, typename Geometry2,
+ typename GeometryOut
>
-struct intersection_polygon_box
+struct take_if_1_is_in_2<polygon_tag, Geometry1, Tag2, Geometry2, GeometryOut, -1>
{
- static inline OutputIterator apply(Polygon const& polygon,
- Box const& box, OutputIterator out)
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ GeometryOut& out
+ )
{
- typedef typename ggl::point_type<GeometryOut>::type point_type;
- typedef detail::intersection::intersection_point<point_type> ip_type;
- typedef std::deque<ip_type> ips_container;
+ ggl::convert(exterior_ring(geometry1), out);
+ }
+};
- typedef typename ggl::ring_type<GeometryOut>::type ring_type;
- ips_container ips;
+template
+<
+ typename Geometry, typename GeometryOut, typename Container
+>
+struct add_holes<polygon_tag, Geometry, GeometryOut, Container, -1>
+{
- bool trivial = ggl::get_intersection_points(polygon, box, ips);
+ static inline void apply(Geometry const& geometry,
+ GeometryOut& out,
+ Container const& holes
+ )
+ {
+ std::vector<sortable> v;
+ sort_interior_rings(holes, v, -1);
- // TODO: share this all with polygon_polygon using an "assemble" function!
- // It is only different in the 'within' calls, can be sorted out with specialization
+ // For an intersection, if a ring is containing an inner ring,
+ // take the outer
+ std::size_t const n = boost::size(v);
- if (ips.size() <= 0)
+ for (std::size_t i = 0; i < n; i++)
{
- // If there are no IP-s, check if one point is in other polygon
- // assume both polygons having points
- if (ggl::within(ggl::exterior_ring(polygon).front(), box))
- {
- // Assume same type (output = input)
- // TODO: solve this (we go to specialize again...)
- *out = polygon;
- out++;
- }
- else
+ // So, only if no inners:
+ if (v[i].index_of_parent == -1)
{
- typename ggl::point_type<Box>::type p;
- ggl::set<0>(p, ggl::get<min_corner, 0>(box));
- ggl::set<1>(p, ggl::get<min_corner, 1>(box));
- if (ggl::within(p, polygon))
+ typename ggl::point_type<GeometryOut>::type point;
+ ggl::point_on_border(holes[v[i].index], point);
+ if (ggl::within(point, geometry))
{
- GeometryOut boxpoly;
- ggl::convert(box, boxpoly);
- *out = boxpoly;
- out++;
+ typename ring_type<GeometryOut>::type hole;
+ ggl::convert(holes[v[i].index], hole);
+ ggl::interior_rings(out).push_back(hole);
}
}
}
- else
- {
- if (trivial)
- {
- ggl::merge_intersection_points(ips);
- }
-
- ggl::enrich_intersection_points(ips, trivial);
-
- std::vector<ring_type> v;
- ggl::traverse<ring_type>
- (
- polygon,
- box,
- -1,
- ips,
- trivial,
- std::back_inserter(v)
- );
-
- // TODO:
- // assemble rings / inner rings / to polygons
- for (typename std::vector<ring_type>::const_iterator it = v.begin();
- it != v.end(); ++it)
- {
- // How can we avoid the double copy here! It is really bad!
- // We have to create a polygon, then copy it to the output iterator.
- // Having an output-vector would have been better: append it to the vector!
- // So output iterators are not that good.
- GeometryOut poly;
- poly.outer() = *it;
- *out = poly;
- out++;
- }
- }
-
-
- return out;
}
};
-}} // namespace detail::intersection
+}} // namespace detail::overlay
#endif // DOXYGEN_NO_DETAIL
-
-
-
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
@@ -278,7 +176,7 @@
typename OutputIterator,
typename GeometryOut
>
-struct intersection {};
+struct intersection_inserter {};
template
@@ -286,7 +184,7 @@
typename Segment1, typename Segment2,
typename OutputIterator, typename GeometryOut
>
-struct intersection
+struct intersection_inserter
<
segment_tag, segment_tag, point_tag,
Segment1, Segment2,
@@ -326,7 +224,7 @@
typename Linestring, typename Box,
typename OutputIterator, typename GeometryOut
>
-struct intersection
+struct intersection_inserter
<
linestring_tag, box_tag, linestring_tag,
Linestring, Box,
@@ -348,14 +246,14 @@
typename Polygon1, typename Polygon2,
typename OutputIterator, typename GeometryOut
>
-struct intersection
+struct intersection_inserter
<
polygon_tag, polygon_tag, polygon_tag,
Polygon1, Polygon2,
OutputIterator, GeometryOut
>
- : detail::intersection::intersection_polygon_polygon
- <Polygon1, Polygon2, OutputIterator, GeometryOut>
+ : detail::overlay::overlay_and_assemble
+ <Polygon1, Polygon2, OutputIterator, GeometryOut, -1>
{};
@@ -365,14 +263,14 @@
typename Polygon, typename Box,
typename OutputIterator, typename GeometryOut
>
-struct intersection
+struct intersection_inserter
<
polygon_tag, box_tag, polygon_tag,
Polygon, Box,
OutputIterator, GeometryOut
>
- : detail::intersection::intersection_polygon_box
- <Polygon, Box, OutputIterator, GeometryOut>
+ : detail::overlay::overlay_and_assemble
+ <Polygon, Box, OutputIterator, GeometryOut, -1>
{};
@@ -380,17 +278,18 @@
template
<
typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
- typename G1, typename G2,
+ typename Geometry1, typename Geometry2,
typename OutputIterator, typename GeometryOut
>
-struct intersection_reversed
+struct intersection_inserter_reversed
{
- static inline OutputIterator apply(G1 const& g1, G2 const& g2, OutputIterator out)
+ static inline OutputIterator apply(Geometry1 const& g1,
+ Geometry2 const& g2, OutputIterator out)
{
- return intersection
+ return intersection_inserter
<
GeometryTag2, GeometryTag1, GeometryTag3,
- G2, G1,
+ Geometry2, Geometry1,
OutputIterator, GeometryOut
>::apply(g2, g1, out);
}
@@ -403,20 +302,17 @@
/*!
\brief Intersects two geometries which each other
- \ingroup overlay
- \details A sequence of points is intersected (clipped) by the specified box
- and the resulting linestring, or pieces of linestrings, are sent to the specified output operator.
+ \ingroup intersection
+ \details The two input geometries are intersected and the resulting linestring(s),
+ ring(s) or polygon(s) are sent to the specified output operator.
\tparam GeometryOut output geometry type, must be specified
\tparam Geometry1 first geometry type
\tparam Geometry2 second geometry type
\tparam OutputIterator output iterator
- \param geometry1 first geometry (currently only a BOX)
- \param geometry2 second geometry (range, linestring, polygon)
+ \param geometry1 first geometry
+ \param geometry2 second geometry
\param out the output iterator, outputting linestrings or polygons
\return the output iterator
- \note For linestrings: the default clipping strategy, Liang-Barsky, is used. The algorithm is currently only
- implemented for 2D xy points. It could be generic for most ll cases, but not across the 180
- meridian so that issue is still on the todo-list.
*/
template
<
@@ -435,7 +331,7 @@
return boost::mpl::if_c
<
reverse_dispatch<Geometry1, Geometry2>::type::value,
- dispatch::intersection_reversed
+ dispatch::intersection_inserter_reversed
<
typename tag<Geometry1>::type,
typename tag<Geometry2>::type,
@@ -444,7 +340,7 @@
Geometry2,
OutputIterator, GeometryOut
>,
- dispatch::intersection
+ dispatch::intersection_inserter
<
typename tag<Geometry1>::type,
typename tag<Geometry2>::type,
@@ -456,6 +352,8 @@
>::type::apply(geometry1, geometry2, out);
}
+
} // ggl
+
#endif //GGL_ALGORITHMS_INTERSECTION_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection_linestring.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection_linestring.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,236 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_ALGORITHMS_INTERSECTION_LINESTRING_HPP
-#define GGL_ALGORITHMS_INTERSECTION_LINESTRING_HPP
-
-#include <boost/range/functions.hpp>
-#include <boost/range/metafunctions.hpp>
-
-#include <ggl/algorithms/append.hpp>
-#include <ggl/algorithms/clear.hpp>
-#include <ggl/util/copy.hpp>
-#include <ggl/util/select_coordinate_type.hpp>
-#include <ggl/geometries/segment.hpp>
-
-namespace ggl
-{
-
-namespace strategy { namespace intersection {
-
-/*!
- \brief Strategy: line clipping algorithm after Liang Barsky
- \ingroup overlay
- \details The Liang-Barsky line clipping algorithm clips a line with a clipping box.
- It is slightly adapted in the sense that it returns which points are clipped
- \tparam B input box type of clipping box
- \tparam P input/output point-type of segments to be clipped
- \note The algorithm is currently only implemented for 2D Cartesian points
- \author Barend Gehrels, and the following recourses
- - A tutorial: http://www.skytopia.com/project/articles/compsci/clipping.html
- - a German applet (link broken): http://ls7-www.cs.uni-dortmund.de/students/projectgroups/acit/lineclip.shtml
-*/
-template<typename B, typename P>
-class liang_barsky
-{
-private:
- typedef ggl::segment<P> segment_type;
-
- inline bool check_edge(double const& p, double const& q, double& t1, double& t2) const
- {
- bool visible = true;
-
- if(p < 0)
- {
- // TODO: Move r definition one scope level up to reuse --mloskot
- double const r = q / p;
- if (r > t2)
- visible = false;
- else if (r > t1)
- t1 = r;
- }
- else if(p > 0)
- {
- double const r = q / p;
- if (r < t1)
- visible = false;
- else if (r < t2)
- t2 = r;
- }
- else
- {
- if (q < 0)
- visible = false;
- }
-
- return visible;
- }
-
-public:
-
- bool clip_segment(B const& b, segment_type& s, bool& sp1_clipped, bool& sp2_clipped) const
- {
- typedef typename select_coordinate_type<B, P>::type coordinate_type;
-
- double t1 = 0;
- double t2 = 1;
-
- coordinate_type const dx = get<1, 0>(s) - get<0, 0>(s);
- coordinate_type const dy = get<1, 1>(s) - get<0, 1>(s);
-
- coordinate_type const p1 = -dx;
- coordinate_type const p2 = dx;
- coordinate_type const p3 = -dy;
- coordinate_type const p4 = dy;
-
- coordinate_type const q1 = get<0, 0>(s) - get<min_corner, 0>(b);
- coordinate_type const q2 = get<max_corner, 0>(b) - get<0, 0>(s);
- coordinate_type const q3 = get<0, 1>(s) - get<min_corner, 1>(b);
- coordinate_type const q4 = get<max_corner, 1>(b) - get<0, 1>(s);
-
- if (check_edge(p1, q1, t1, t2) // left
- && check_edge(p2, q2, t1, t2) // right
- && check_edge(p3, q3, t1, t2) // bottom
- && check_edge(p4, q4, t1, t2)) // top
- {
- sp1_clipped = t1 > 0;
- sp2_clipped = t2 < 1;
-
- // TODO: maybe round coordinates in case of integer? define some round_traits<> or so?
- // Take boost-round of Fernando
- if (sp2_clipped)
- {
- set<1, 0>(s, get<0, 0>(s) + t2 * dx);
- set<1, 1>(s, get<0, 1>(s) + t2 * dy);
- }
-
- if(sp1_clipped)
- {
- set<0, 0>(s, get<0, 0>(s) + t1 * dx);
- set<0, 1>(s, get<0, 1>(s) + t1 * dy);
- }
-
- return true;
- }
-
- return false;
- }
-
- template<typename L, typename OutputIterator>
- inline void add(L& line_out, OutputIterator out) const
- {
- if (!boost::empty(line_out))
- {
- *out = line_out;
- ++out;
- ggl::clear(line_out);
- }
- }
-};
-}} // namespace strategy::intersection
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace intersection {
-
-/*!
- \brief Clips a linestring with a box
- \details A linestring is intersected (clipped) by the specified box
- and the resulting linestring, or pieces of linestrings, are sent to the specified output operator.
- \tparam OutputLinestring type of the output linestrings
- \tparam OutputIterator an output iterator which outputs linestrings
- \tparam Linestring linestring-type, for example a vector of points, matching the output-iterator type,
- the points should also match the input-iterator type
- \tparam Box box type
- \tparam Strategy strategy, a clipping strategy which should implement the methods "clip_segment" and "add"
-*/
-template
-<
- typename OutputLinestring,
- typename OutputIterator,
- typename Linestring,
- typename Box,
- typename Strategy
->
-OutputIterator clip_linestring_with_box(Box const& b, Linestring const& linestring,
- OutputIterator out, Strategy const& strategy)
-{
- if (boost::begin(linestring) == boost::end(linestring))
- {
- return out;
- }
-
- typedef typename point_type<OutputLinestring>::type point_type;
-
- OutputLinestring line_out;
-
- typedef typename boost::range_const_iterator<Linestring>::type iterator_type;
- iterator_type vertex = boost::begin(linestring);
- for(iterator_type previous = vertex++;
- vertex != boost::end(linestring);
- previous = vertex++)
- {
- point_type p1, p2;
- copy_coordinates(*previous, p1);
- copy_coordinates(*vertex, p2);
-
- // Clip the segment. Five situations:
- // 1. Segment is invisible, finish line if any (shouldn't occur)
- // 2. Segment is completely visible. Add (p1)-p2 to line
- // 3. Point 1 is invisible (clipped), point 2 is visible. Start new line from p1-p2...
- // 4. Point 1 is visible, point 2 is invisible (clipped). End the line with ...p2
- // 5. Point 1 and point 2 are both invisible (clipped). Start/finish an independant line p1-p2
- //
- // This results in:
- // a. if p1 is clipped, start new line
- // b. if segment is partly or completely visible, add the segment
- // c. if p2 is clipped, end the line
-
- bool c1 = false;
- bool c2 = false;
- segment<point_type> s(p1, p2);
-
- if (!strategy.clip_segment(b, s, c1, c2))
- {
- strategy.add(line_out, out);
- }
- else
- {
- // a. If necessary, finish the line and add a start a new one
- if (c1)
- {
- strategy.add(line_out, out);
- }
-
- // b. Add p1 only if it is the first point, then add p2
- if (boost::empty(line_out))
- {
- ggl::append(line_out, p1);
- }
- ggl::append(line_out, p2);
-
- // c. If c2 is clipped, finish the line
- if (c2)
- {
- strategy.add(line_out, out);
- }
- }
-
- }
-
- // Add last part
- strategy.add(line_out, out);
- return out;
-}
-
-}} // namespace detail::intersection
-#endif // DOXYGEN_NO_DETAIL
-
-} // namespace ggl
-
-#endif // GGL_ALGORITHMS_INTERSECTION_LINESTRING_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersects.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersects.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersects.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -9,9 +9,14 @@
#ifndef GGL_ALGORITHMS_INTERSECTS_HPP
#define GGL_ALGORITHMS_INTERSECTS_HPP
+
+/*!
+\defgroup intersects intersects, test a geometry self-intersects or two geometries intersect
+*/
+
+
#include <ggl/geometries/concepts/check.hpp>
-#include <ggl/algorithms/intersection_linestring.hpp>
#include <ggl/algorithms/overlay/get_intersection_points.hpp>
#include <ggl/algorithms/overlay/self_intersection_points.hpp>
@@ -33,7 +38,7 @@
(crossing or self-tangency)
\note This function can be called for one geometry (self-intersection) and
also for two geometries (intersection)
- \ingroup overlay
+ \ingroup intersects
\tparam Geometry geometry type
\param geometry geometry
\return TRUE if there are intersections, else FALSE
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/length.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/length.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/length.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -24,7 +24,7 @@
#include <ggl/algorithms/detail/calculate_null.hpp>
-#include <ggl/strategies/strategies.hpp>
+#include <ggl/strategies/distance.hpp>
#include <ggl/strategies/length_result.hpp>
/*!
@@ -60,7 +60,7 @@
// TODO: the segment concept has to be such that it is easy
// to return a point from it.
// Now it only accesses per coordinate
- return strategy(segment.first, segment.second);
+ return strategy.apply(segment.first, segment.second);
}
};
@@ -89,7 +89,7 @@
{
// Add point-point distance using the return type belonging
// to strategy
- sum += strategy(*previous, *it);
+ sum += strategy.apply(*previous, *it);
previous = it++;
}
}
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/make.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/make.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/make.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -22,6 +22,7 @@
\details the Generic Geometry Library uses concepts for all its geometries. Therefore it does not rely
on constructors. The "make" functions are object generators creating geometries. There are overloads
with two, three, four or six values, which are implemented depending on the geometry specified.
+ \note It does not work with array-point types, like int[2]
\tparam G the geometry type
\tparam T the coordinate type
\return the geometry
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlaps.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlaps.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlaps.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -9,6 +9,15 @@
#ifndef GGL_ALGORITHMS_OVERLAPS_HPP
#define GGL_ALGORITHMS_OVERLAPS_HPP
+/*!
+\defgroup overlaps overlaps, determine any overlap between two geometries
+\par Source descriptions:
+- Egenhofer: Two objects overlap if they have common interior faces and the bounding faces have common parts
+with the opposite interior faces.
+
+*/
+
+
#include <ggl/core/access.hpp>
#include <ggl/geometries/concepts/check.hpp>
@@ -16,35 +25,173 @@
namespace ggl
{
-/*!
- \brief Determines overlap between two geometries
- \details parameters are now boxes but in the future will be geometries
- \ingroup boolean_relations
- \return true if there is overlap
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlaps {
+
+template
+<
+ typename Box1,
+ typename Box2,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct box_box_loop
+{
+ static inline void apply(Box1 const& b1, Box2 const& b2,
+ bool& overlaps, bool& one_in_two, bool& two_in_one)
+ {
+ assert_dimension_equal<Box1, Box2>();
+
+ typedef typename coordinate_type<Box1>::type coordinate_type1;
+ typedef typename coordinate_type<Box2>::type coordinate_type2;
+
+ coordinate_type1 const& min1 = get<min_corner, Dimension>(b1);
+ coordinate_type1 const& max1 = get<max_corner, Dimension>(b1);
+ coordinate_type2 const& min2 = get<min_corner, Dimension>(b2);
+ coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
+
+ // We might use the (not yet accepted) Boost.Interval
+ // submission in the future
+
+ // If:
+ // B1: |-------|
+ // B2: |------|
+ // in any dimension -> no overlap
+ if (max1 <= min2 || min1 >= max2)
+ {
+ overlaps = false;
+ return;
+ }
+
+ // If:
+ // B1: |--------------------|
+ // B2: |-------------|
+ // in all dimensions -> within, then no overlap
+ // B1: |--------------------|
+ // B2: |-------------|
+ // this is "within-touch" -> then no overlap. So use < and >
+ if (min1 < min2 || max1 > max2)
+ {
+ one_in_two = false;
+ }
+ // Same other way round
+ if (min2 < min1 || max2 > max1)
+ {
+ two_in_one = false;
+ }
+
+ box_box_loop
+ <
+ Box1,
+ Box2,
+ Dimension + 1,
+ DimensionCount
+ >::apply(b1, b2, overlaps, one_in_two, two_in_one);
+ }
+};
+
+template
+<
+ typename Box1,
+ typename Box2,
+ std::size_t DimensionCount
+>
+struct box_box_loop<Box1, Box2, DimensionCount, DimensionCount>
+{
+ static inline void apply(Box1 const& , Box2 const&, bool&, bool&, bool&)
+ {
+ }
+};
+
+template
+<
+ typename Box1,
+ typename Box2
+>
+struct box_box
+{
+ static inline bool apply(Box1 const& b1, Box2 const& b2)
+ {
+ bool overlaps = true;
+ bool within1 = true;
+ bool within2 = true;
+ box_box_loop
+ <
+ Box1,
+ Box2,
+ 0,
+ dimension<Box1>::type::value
+ >::apply(b1, b2, overlaps, within1, within2);
+
+ /*
+ \see http://docs.codehaus.org/display/GEOTDOC/02+Geometry+Relationships#02GeometryRelationships-Overlaps
+ where is stated that "inside" is not an "overlap",
+ this is true and is implemented as such.
+ */
+ return overlaps && ! within1 && ! within2;
+ }
+};
- \par Source descriptions:
- - Egenhofer: Two objects overlap if they have common interior faces and the bounding faces have common parts
- with the opposite interior faces.
-
- \note Implemented in scratch the Generic Geometry library. Will be reworked internally to support more geometries
- but function call will stay as it is now.
- \see http://docs.codehaus.org/display/GEOTDOC/02+Geometry+Relationships#02GeometryRelationships-Overlaps
- where is stated that "inside" is not an "overlap", this is probably true and should then be implemented as such.
+}} // namespace detail::overlaps
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Tag1,
+ typename Tag2,
+ typename Geometry1,
+ typename Geometry2
+>
+struct overlaps
+{};
+
+
+template <typename Box1, typename Box2>
+struct overlaps<box_tag, box_tag, Box1, Box2>
+ : detail::overlaps::box_box<Box1, Box2>
+{};
+
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+ \brief Determines overlap between two geometries
+ \ingroup overlaps
+ \return true if there is overlap
*/
template <typename Geometry1, typename Geometry2>
-inline bool overlaps(Geometry1 const& b1, Geometry2 const& b2)
+inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
concept::check<const Geometry1>();
concept::check<const Geometry2>();
+ return dispatch::overlaps
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2);
+
+ /*
return !(
get<max_corner, 0>(b1) <= get<min_corner, 0>(b2) ||
get<min_corner, 0>(b1) >= get<max_corner, 0>(b2) ||
get<max_corner, 1>(b1) <= get<min_corner, 1>(b2) ||
get<min_corner, 1>(b1) >= get<max_corner, 1>(b2)
);
+ */
}
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/adapt_turns.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/adapt_turns.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/adapt_turns.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -18,6 +18,8 @@
#include <ggl/core/coordinate_type.hpp>
+#include <ggl/strategies/side.hpp>
+
#include <ggl/algorithms/equals.hpp>
@@ -29,22 +31,6 @@
namespace detail { namespace intersection {
-
-// TEMP: another COPY of side
-// TODO: solve this inside SIDE!!!
-template <typename P1, typename P2, typename P>
-inline int the_side(P1 const& p1, P2 const& p2, P const& p)
-{
- typedef typename select_coordinate_type<P, P1>::type T;
-
- T dx = get<0>(p2) - get<0>(p1);
- T dy = get<1>(p2) - get<1>(p1);
- T dpx = get<0>(p) - get<0>(p1);
- T dpy = get<1>(p) - get<1>(p1);
- T product = dx * dpy - dy * dpx;
- return product > 0 ? 1 : product < 0 ? -1 : 0;
-}
-
template <typename T>
inline void join_adapt(T& info, int direction)
{
@@ -53,7 +39,6 @@
}
-
template <typename T>
inline void both_same(T const& pi, T & pk, T const& qu, T& qw, int dir_p, int dir_q, int direction)
{
@@ -85,6 +70,7 @@
}
}
+
template <typename T>
inline void crossing(T const& pi, T & pk, T const& qu, T& qw, int dir_p, int dir_q, int direction)
{
@@ -106,7 +92,6 @@
}
-
template <typename T>
inline void collinear(T const& pi, T & pk, T const& qu, T& qw, int dir_p, int dir_q, int direction)
{
@@ -128,6 +113,7 @@
}
+
template <typename T, typename P>
inline void assign_pq(T const& info, P& p, P& q)
{
@@ -155,6 +141,7 @@
}
}
+
template <typename Info, typename Point>
inline void touch_in_the_middle(Info& info, Point const& point)
{
@@ -192,7 +179,13 @@
&& qu->direction == qw->direction
&& qu->seg_id.source_index == qw->seg_id.source_index)
{
- int dir_q = the_side(qu->other_point, point, qw->other_point);
+ typedef typename strategy_side
+ <
+ typename cs_tag<Point>::type
+ >::type side;
+
+
+ int dir_q = side::apply(qu->other_point, point, qw->other_point);
#ifdef GGL_DEBUG_INTERSECTION
std::cout << "Both "
@@ -222,8 +215,6 @@
}
-
-
template <typename Info>
inline void arrive_in_the_middle(Info& info)
{
@@ -261,6 +252,7 @@
}
}
+
template <typename Info>
inline void start_in_the_middle(Info& info, bool opposite)
{
@@ -348,7 +340,6 @@
}
}
-
if (count_m == 2 && count_s == 2)
{
#ifdef GGL_DEBUG_INTERSECTION
@@ -454,8 +445,14 @@
}
}
- int dir_p = the_side(p.first, it->point, p.second);
- int dir_q = the_side(q.first, it->point, q.second);
+ typedef typename strategy_side
+ <
+ typename cs_tag<ip_type>::type
+ >::type side;
+
+
+ int dir_p = side::apply(p.first, it->point, p.second);
+ int dir_q = side::apply(q.first, it->point, q.second);
#ifdef GGL_DEBUG_INTERSECTION
std::cout << "Pi//Qu : " << *pi.first << std::endl;
@@ -518,8 +515,6 @@
tvit->direction = 0;
}
}
-
-
}
}
}
@@ -531,12 +526,10 @@
}
-
}} // namespace detail::intersection
#endif //DOXYGEN_NO_DETAIL
-
template <typename V>
inline void adapt_turns(V& intersection_points)
{
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/assemble.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/assemble.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,471 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_ALGORITHMS_OVERLAY_ASSEMBLE_HPP
+#define GGL_ALGORITHMS_OVERLAY_ASSEMBLE_HPP
+
+
+#include <deque>
+
+#include <ggl/algorithms/overlay/get_intersection_points.hpp>
+#include <ggl/algorithms/overlay/merge_intersection_points.hpp>
+#include <ggl/algorithms/overlay/adapt_turns.hpp>
+#include <ggl/algorithms/overlay/enrich_intersection_points.hpp>
+#include <ggl/algorithms/overlay/traverse.hpp>
+#include <ggl/algorithms/overlay/sort_interior_rings.hpp>
+
+
+#include <ggl/algorithms/convert.hpp>
+#include <ggl/algorithms/num_points.hpp>
+#include <ggl/algorithms/within.hpp>
+
+#include <ggl/algorithms/detail/point_on_border.hpp>
+
+#include <ggl/iterators/range_type.hpp>
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay {
+
+
+// Utility function
+template <typename GeometryOut, typename Geometry, typename OutputIterator>
+void convert_and_output(Geometry const& geometry, OutputIterator& out)
+{
+ // How can we avoid the double copy here! It is really bad!
+ // We have to create a polygon, then copy it to the output iterator.
+ // Having an output-vector would have been better: append it to the vector!
+ // So output iterators are not that good.
+
+ GeometryOut result;
+ ggl::convert(geometry, result);
+ *out = result;
+ out++;
+}
+
+
+
+
+template
+<
+ typename Tag1, typename Geometry1,
+ typename Tag2, typename Geometry2, typename GeometryOut,
+ int Direction
+>
+struct take_if_1_is_in_2
+{};
+
+
+template
+<
+ int Direction,
+ typename Geometry1, typename Geometry2, typename GeometryOut
+>
+inline bool take_one(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ GeometryOut& out
+ )
+{
+ typename ggl::point_type<Geometry1>::type point;
+ ggl::point_on_border(geometry1, point);
+ if (ggl::within(point, geometry2))
+ {
+ take_if_1_is_in_2
+ <
+ typename tag<Geometry1>::type, Geometry1,
+ typename tag<Geometry2>::type, Geometry2,
+ GeometryOut, Direction
+ >::apply(geometry1, geometry2, out);
+ return true;
+ }
+ return false;
+}
+
+
+template
+<
+ typename TagOut,
+ typename Geometry, typename GeometryOut,
+ typename Container,
+ int Direction
+>
+struct add_holes
+{
+ static inline void apply(Geometry const&, GeometryOut&, Container const& holes)
+ {}
+};
+
+
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename OutputIterator, typename GeometryOut,
+ int Direction
+>
+struct take_none_or_both
+{
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ OutputIterator out
+ )
+ {
+ }
+
+};
+
+
+template
+<
+ typename Tag, typename GeometryOut,
+ typename Container, int Direction
+>
+struct assemble_rings
+{
+ template <typename OutputIterator>
+ static inline void apply(Container const& rings,
+ Container const& ni_holes,
+ OutputIterator out)
+ {}
+};
+
+
+template
+<
+ typename GeometryOut, typename Container, int Direction
+>
+struct assemble_rings<polygon_tag, GeometryOut, Container, Direction>
+{
+ typedef typename boost::range_value<Container>::type ring_type;
+ typedef typename ggl::point_type<ring_type>::type point_type;
+
+ template <typename OutputIterator>
+ static inline void apply(Container const& rings,
+ Container const& ni_holes,
+ OutputIterator out)
+ {
+ std::vector<sortable> sorted_rings;
+ sort_interior_rings(rings, sorted_rings, 1);
+
+ // Add polygons, and holes
+ for (std::vector<sortable>::const_iterator
+ rit = boost::begin(sorted_rings);
+ rit != boost::end(sorted_rings);
+ ++rit)
+ {
+ if (rit->index_of_parent == -1)
+ {
+ GeometryOut result;
+ ggl::convert(rings[rit->index], result);
+
+ // Add holes (direction is OK, so no reverse)
+ std::vector<int> const& holes = rit->index_of_holes;
+ for (std::vector<int>::const_iterator hit = holes.begin();
+ hit != holes.end();
+ ++hit)
+ {
+ interior_rings(result).push_back(rings[*hit]);
+ }
+
+ // Add also all non-intersecting-inner-holes
+ add_holes
+ <
+ polygon_tag,
+ ring_type, GeometryOut, Container,
+ Direction
+ >::apply(rings[rit->index], result, ni_holes);
+
+ *out = result;
+ out++;
+ }
+ }
+ }
+};
+
+
+template
+<
+ typename GeometryOut, typename Container, int Direction
+>
+struct assemble_rings<ring_tag, GeometryOut, Container, Direction>
+{
+ typedef typename boost::range_value<Container>::type ring_type;
+ typedef typename ggl::point_type<ring_type>::type point_type;
+
+ template <typename OutputIterator>
+ static inline void apply(Container const& rings,
+ Container const& ni_holes,
+ OutputIterator out)
+ {
+ // Add positive rings, ignore all holes
+ for (typename boost::range_const_iterator<Container>::type
+ it = boost::begin(rings);
+ it != boost::end(rings);
+ ++it)
+ {
+ if (ggl::area(*it) > 0)
+ {
+ convert_and_output<GeometryOut>(*it, out);
+ }
+ }
+ }
+};
+
+
+
+template<typename Tag>
+struct get_not_intersecting_holes
+{
+ template
+ <
+ typename Polygon,
+ typename IpContainer, typename HoleContainer
+ >
+ static inline void apply(Polygon const&, int,
+ IpContainer const&, HoleContainer& )
+ {
+ }
+};
+
+
+template<>
+struct get_not_intersecting_holes<polygon_tag>
+{
+ template
+ <
+ typename Polygon,
+ typename IpContainer, typename HoleContainer
+ >
+ static inline void apply(Polygon const& polygon, int source_index,
+ IpContainer const& ips,
+ HoleContainer& holes)
+ {
+ typedef typename boost::range_value<IpContainer>::type ip_type;
+ typedef typename boost::range_const_iterator<IpContainer>::type iterator_type;
+ typedef typename ip_type::traversal_vector vector_type;
+ typedef typename boost::range_const_iterator<vector_type>::type tvit_type;
+
+ // Declare vector, fill with false
+ int const n = num_interior_rings(polygon);
+ std::vector<bool> intersecting(n, false);
+
+
+ // Check all IP's and set corresponding inner rings to "intersecting"
+ for (iterator_type it = boost::begin(ips);
+ it != boost::end(ips);
+ ++it)
+ {
+ for (tvit_type tvit = boost::begin(it->info);
+ tvit != boost::end(it->info);
+ ++tvit)
+ {
+ if (tvit->seg_id.source_index == source_index)
+ {
+ int const r = tvit->seg_id.ring_index;
+ if (r >= 0 && r < n)
+ {
+ intersecting[r] = true;
+ }
+ }
+ }
+ }
+
+ typename boost::range_const_iterator
+ <
+ typename interior_type<Polygon>::type
+ >::type rit = boost::begin(interior_rings(polygon));
+ std::vector<bool>::const_iterator iit = boost::begin(intersecting);
+
+ for (;
+ rit != boost::end(interior_rings(polygon))
+ && iit != boost::end(intersecting);
+ ++rit, ++iit)
+ {
+ if (! (*iit))
+ {
+ // Don't pushback, it might be of different type.
+ holes.resize(holes.size() + 1);
+ ggl::convert(*rit, holes.back());
+ }
+ }
+ }
+};
+
+
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename OutputIterator, typename GeometryOut,
+ int Direction
+>
+struct overlay_and_assemble
+{
+ typedef typename ggl::tag<Geometry1>::type tag1;
+ typedef typename ggl::tag<Geometry2>::type tag2;
+ typedef typename ggl::tag<GeometryOut>::type tag_out;
+
+ static inline OutputIterator apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2, OutputIterator out)
+ {
+ if (ggl::num_points(geometry1) == 0
+ || ggl::num_points(geometry2) == 0)
+ {
+ return out;
+ }
+
+
+ typedef typename ggl::point_type<GeometryOut>::type point_type;
+ typedef detail::intersection::intersection_point<point_type> ip_type;
+ typedef std::deque<ip_type> container_type;
+
+ // "Abuse" rangetype for ringtype: for polygon, it is the type of the
+ // exterior ring. For ring, it is the ring itself. That is what is
+ // wished here as well.
+ typedef typename ggl::range_type<GeometryOut>::type ring_type;
+
+ container_type ips; // intersection points
+
+ bool trivial = ggl::get_intersection_points(geometry1, geometry2, ips);
+
+ // If there are no IP-s, check if one point is in other geometry
+ // (both geometries have points, see check above)
+ // If yes, take the correct one
+
+ // (which depends on intersection/union)
+ // If both are unrelated, take none (intersection) or both (union)
+
+ // If there are disjoint or containing holes:
+ // - Hole of A can be within hole of B
+ // - for union: take hole of A
+ // - for intersection: take hole of B
+ // - Hole of A can be disjoint from B
+ // - for union: remove those holes
+ // - for intersection: take all those holes
+ // -> generic procedure
+ // - Collect all holes in one vector
+ // - Sort them on decreasing area
+ // - Check if one is within a larger one,
+ // - if yes, take one of them
+ // - if no, take all, or none of them
+
+ // Gather non-intersecting holes
+ typedef std::vector<ring_type> hole_vector_type;
+ hole_vector_type ni_holes;
+ get_not_intersecting_holes<tag1>::apply(geometry1, 0, ips, ni_holes);
+ get_not_intersecting_holes<tag2>::apply(geometry2, 1, ips, ni_holes);
+
+ if (ips.size() <= 0)
+ {
+ GeometryOut result;
+ if (take_one<Direction>(geometry1, geometry2, result))
+ {
+ add_holes
+ <
+ tag_out, Geometry1, GeometryOut, hole_vector_type,
+ Direction
+ >::apply(geometry1, result, ni_holes);
+ *out = result;
+ out++;
+ }
+ else if (take_one<Direction>(geometry2, geometry1, result))
+ {
+ add_holes
+ <
+ tag_out,
+ Geometry2, GeometryOut, hole_vector_type,
+ Direction
+ >::apply(geometry2, result, ni_holes);
+ *out = result;
+ out++;
+ }
+ else
+ {
+ take_none_or_both
+ <
+ Geometry1, Geometry2,
+ OutputIterator, GeometryOut,
+ Direction
+ >::apply(geometry1, geometry2, out);
+ }
+ }
+ else
+ {
+ if (! trivial)
+ {
+ ggl::merge_intersection_points(ips);
+
+ // If all IP's are removed, they are all collinear or forming
+ // an angle which each other.
+ // In that case, the inputs are EQUAL.
+ // For both intersection and union, just output one.
+ if (ips.size() == 0)
+ {
+ convert_and_output<GeometryOut>(geometry1, out);
+ return out;
+ }
+
+ ggl::adapt_turns(ips);
+ }
+
+ ggl::enrich_intersection_points(ips, trivial);
+
+
+ std::vector<ring_type> v;
+ ggl::traverse<ring_type>
+ (
+ geometry1,
+ geometry2,
+ Direction,
+ ips,
+ trivial,
+ std::back_inserter(v)
+ );
+
+ switch (boost::size(v))
+ {
+ case 0 : break;
+ case 1 :
+ //convert_and_output<GeometryOut>(v.front(), out);
+ {
+ GeometryOut result;
+ ggl::convert(v.front(), result);
+ add_holes
+ <
+ tag_out,
+ ring_type, GeometryOut, hole_vector_type,
+ Direction
+ >::apply(v.front(), result, ni_holes);
+ *out = result;
+ out++;
+ }
+ break;
+ default :
+ assemble_rings
+ <
+ tag_out, GeometryOut,
+ hole_vector_type, Direction
+ >::apply(v, ni_holes, out);
+ }
+ }
+
+ return out;
+ }
+};
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+} // ggl
+
+#endif //GGL_ALGORITHMS_OVERLAY_ASSEMBLE_HPP
Copied: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/clip_linestring.hpp (from r56825, /sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection_linestring.hpp)
==============================================================================
--- /sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection_linestring.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/clip_linestring.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_ALGORITHMS_INTERSECTION_LINESTRING_HPP
-#define GGL_ALGORITHMS_INTERSECTION_LINESTRING_HPP
+#ifndef GGL_ALGORITHMS_OVERLAY_CLIP_LINESTRING_HPP
+#define GGL_ALGORITHMS_OVERLAY_CLIP_LINESTRING_HPP
#include <boost/range/functions.hpp>
#include <boost/range/metafunctions.hpp>
@@ -31,15 +31,18 @@
\tparam B input box type of clipping box
\tparam P input/output point-type of segments to be clipped
\note The algorithm is currently only implemented for 2D Cartesian points
+ \note Though it is implemented in namespace strategy, and theoretically another
+ strategy could be used, it is not (yet) updated to the general strategy concepts,
+ and not (yet) splitted into a file in folder strategies
\author Barend Gehrels, and the following recourses
- A tutorial: http://www.skytopia.com/project/articles/compsci/clipping.html
- a German applet (link broken): http://ls7-www.cs.uni-dortmund.de/students/projectgroups/acit/lineclip.shtml
*/
-template<typename B, typename P>
+template<typename Box, typename Point>
class liang_barsky
{
private:
- typedef ggl::segment<P> segment_type;
+ typedef ggl::segment<Point> segment_type;
inline bool check_edge(double const& p, double const& q, double& t1, double& t2) const
{
@@ -47,7 +50,6 @@
if(p < 0)
{
- // TODO: Move r definition one scope level up to reuse --mloskot
double const r = q / p;
if (r > t2)
visible = false;
@@ -73,9 +75,9 @@
public:
- bool clip_segment(B const& b, segment_type& s, bool& sp1_clipped, bool& sp2_clipped) const
+ inline bool clip_segment(Box const& b, segment_type& s, bool& sp1_clipped, bool& sp2_clipped) const
{
- typedef typename select_coordinate_type<B, P>::type coordinate_type;
+ typedef typename select_coordinate_type<Box, Point>::type coordinate_type;
double t1 = 0;
double t2 = 1;
@@ -101,8 +103,6 @@
sp1_clipped = t1 > 0;
sp2_clipped = t2 < 1;
- // TODO: maybe round coordinates in case of integer? define some round_traits<> or so?
- // Take boost-round of Fernando
if (sp2_clipped)
{
set<1, 0>(s, get<0, 0>(s) + t2 * dx);
@@ -121,8 +121,8 @@
return false;
}
- template<typename L, typename OutputIterator>
- inline void add(L& line_out, OutputIterator out) const
+ template<typename Linestring, typename OutputIterator>
+ inline void apply(Linestring& line_out, OutputIterator out) const
{
if (!boost::empty(line_out))
{
@@ -132,6 +132,8 @@
}
}
};
+
+
}} // namespace strategy::intersection
@@ -147,7 +149,7 @@
\tparam Linestring linestring-type, for example a vector of points, matching the output-iterator type,
the points should also match the input-iterator type
\tparam Box box type
- \tparam Strategy strategy, a clipping strategy which should implement the methods "clip_segment" and "add"
+ \tparam Strategy strategy, a clipping strategy which should implement the methods "clip_segment" and "apply"
*/
template
<
@@ -197,14 +199,14 @@
if (!strategy.clip_segment(b, s, c1, c2))
{
- strategy.add(line_out, out);
+ strategy.apply(line_out, out);
}
else
{
// a. If necessary, finish the line and add a start a new one
if (c1)
{
- strategy.add(line_out, out);
+ strategy.apply(line_out, out);
}
// b. Add p1 only if it is the first point, then add p2
@@ -217,14 +219,14 @@
// c. If c2 is clipped, finish the line
if (c2)
{
- strategy.add(line_out, out);
+ strategy.apply(line_out, out);
}
}
}
// Add last part
- strategy.add(line_out, out);
+ strategy.apply(line_out, out);
return out;
}
@@ -233,4 +235,4 @@
} // namespace ggl
-#endif // GGL_ALGORITHMS_INTERSECTION_LINESTRING_HPP
+#endif // GGL_ALGORITHMS_OVERLAY_CLIP_LINESTRING_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/copy_segments.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/copy_segments.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/copy_segments.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -19,7 +19,8 @@
#include <ggl/algorithms/overlay/intersection_point.hpp>
#include <ggl/iterators/ever_circling_iterator.hpp>
-#include <ggl/iterators/vertex_iterator.hpp>
+
+#include <ggl/iterators/range_type.hpp>
namespace ggl
@@ -37,8 +38,8 @@
SegmentIdentifier const& seg_id, int to_index,
RangeOut& current_output)
{
+ typedef typename boost::range_const_iterator<Ring>::type iterator;
- typedef typename ggl::vertex_iterator<Ring, true>::type iterator;
typedef ggl::ever_circling_iterator<iterator> ec_iterator;
// The problem: sometimes we want to from "3" to "2" -> end = "3" -> end == begin
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/enrich_intersection_points.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/enrich_intersection_points.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/enrich_intersection_points.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_ALGORITHMS_ENRICH_INTERSECTION_POINTS_HPP
-#define GGL_ALGORITHMS_ENRICH_INTERSECTION_POINTS_HPP
+#ifndef GGL_ALGORITHMS_OVERLAY_ENRICH_INTERSECTION_POINTS_HPP
+#define GGL_ALGORITHMS_OVERLAY_ENRICH_INTERSECTION_POINTS_HPP
#include <cstddef>
#include <algorithm>
@@ -498,4 +498,4 @@
} // namespace ggl
-#endif // GGL_ALGORITHMS_ENRICH_INTERSECTION_POINTS_HPP
+#endif // GGL_ALGORITHMS_OVERLAY_ENRICH_INTERSECTION_POINTS_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/get_intersection_points.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/get_intersection_points.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/get_intersection_points.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,13 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_ALGORITHMS_GET_INTERSECTION_POINTS_HPP
-#define GGL_ALGORITHMS_GET_INTERSECTION_POINTS_HPP
+#ifndef GGL_ALGORITHMS_OVERLAY_GET_INTERSECTION_POINTS_HPP
+#define GGL_ALGORITHMS_OVERLAY_GET_INTERSECTION_POINTS_HPP
+
+/*!
+\defgroup overlay overlay helper operations (getting intersection points, etc)
+*/
+
#include <cstddef>
@@ -32,6 +37,8 @@
#include <ggl/geometries/box.hpp>
+#include <ggl/iterators/range_type.hpp>
+
#include <ggl/strategies/cartesian/cart_intersect.hpp>
#include <ggl/strategies/intersection_result.hpp>
@@ -199,13 +206,13 @@
bool& trivial)
{
- typedef typename ggl::vertex_iterator
+ typedef typename boost::range_const_iterator
<
- Geometry1, true
+ typename ggl::range_type<Geometry1>::type
>::type range1_iterator;
- typedef typename ggl::vertex_iterator
+ typedef typename boost::range_const_iterator
<
- Geometry2, true
+ typename ggl::range_type<Geometry2>::type
>::type range2_iterator;
int const dir1 = sec1.directions[0];
@@ -471,7 +478,7 @@
// 1) EITHER the two points are lying on one side of the box (! 0 && the same)
// 2) OR same in Y-direction
// 3) OR all points are inside the box (0)
- if (! (
+ /*if (! (
(current_side[0] != 0 && current_side[0] == previous_side[0])
|| (current_side[1] != 0 && current_side[1] == previous_side[1])
|| (current_side[0] == 0
@@ -479,7 +486,8 @@
&& previous_side[0] == 0
&& previous_side[1] == 0)
)
- )
+ )*/
+ if (true)
{
segment_identifier seg_id(source_id1,
multi_index, ring_index, index);
@@ -489,7 +497,7 @@
segment_type, box_segment_type, IntersectionPoints
> relater;
- // Todo: depending on code some relations can be left out
+ // Depending on code some relations can be left out
relater::apply(segment, left, seg_id,
segment_identifier(source_id2, -1, -1, 0),
intersection_points, trivial);
@@ -507,14 +515,24 @@
}
}
-
+private:
template<std::size_t Index, typename Point>
static inline int get_side(Box const& box, Point const& point)
{
- // Note: border has to be included because of boundary cases
-
- if (get<Index>(point) <= get<min_corner, Index>(box)) return -1;
- else if (get<Index>(point) >= get<max_corner, Index>(box)) return 1;
+ // Inside -> 0
+ // Outside -> -1 (left/below) or 1 (right/above)
+ // On border -> -2 (left/lower) or 2 (right/upper)
+ // The only purpose of the value is to not be the same,
+ // and to denote if it is inside (0)
+
+ typename coordinate_type<Point>::type const& c = get<Index>(point);
+ typename coordinate_type<Box>::type const& left = get<min_corner, Index>(box);
+ typename coordinate_type<Box>::type const& right = get<max_corner, Index>(box);
+
+ if (ggl::math::equals(c, left)) return -2;
+ else if (ggl::math::equals(c, right)) return 2;
+ else if (c < left) return -1;
+ else if (c > right) return 1;
else return 0;
}
@@ -619,6 +637,21 @@
>
{};
+template<typename Polygon, typename Ring, typename IntersectionPoints>
+struct get_intersection_points
+ <
+ polygon_tag, ring_tag, false, false,
+ Polygon, Ring,
+ IntersectionPoints
+ >
+ : detail::get_intersection_points::get_ips_generic
+ <
+ Polygon,
+ Ring,
+ IntersectionPoints
+ >
+{};
+
template
<
typename LineString1,
@@ -684,10 +717,7 @@
inline bool get_intersection_points(Geometry1 const& geometry1,
Geometry2 const& geometry2, IntersectionPoints& intersection_points)
{
- concept::check<const Geometry1>();
- concept::check<const Geometry2>();
-
- assert_dimension_equal<Geometry1, Geometry2>();
+ concept::check_concepts_and_equal_dimensions<const Geometry1, const Geometry2>();
typedef typename boost::remove_const<Geometry1>::type ncg1_type;
typedef typename boost::remove_const<Geometry2>::type ncg2_type;
@@ -724,4 +754,4 @@
} // namespace ggl
-#endif // GGL_ALGORITHMS_GET_INTERSECTION_POINTS_HPP
+#endif // GGL_ALGORITHMS_OVERLAY_GET_INTERSECTION_POINTS_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/intersection_point.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/intersection_point.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/intersection_point.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -15,8 +15,8 @@
#include <ggl/core/access.hpp>
#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/strategies/distance.hpp>
#include <ggl/strategies/distance_result.hpp>
-#include <ggl/strategies/strategy_traits.hpp>
#include <ggl/algorithms/overlay/segment_identifier.hpp>
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/merge_intersection_points.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/merge_intersection_points.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/merge_intersection_points.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_ALGORITHMS_MERGE_INTERSECTION_POINTS_HPP
-#define GGL_ALGORITHMS_MERGE_INTERSECTION_POINTS_HPP
+#ifndef GGL_ALGORITHMS_OVERLAY_MERGE_INTERSECTION_POINTS_HPP
+#define GGL_ALGORITHMS_OVERLAY_MERGE_INTERSECTION_POINTS_HPP
#include <algorithm>
@@ -19,6 +19,7 @@
#include <ggl/core/coordinate_type.hpp>
#include <ggl/algorithms/equals.hpp>
+#include <ggl/algorithms/overlay/intersection_point.hpp>
namespace ggl
@@ -79,7 +80,6 @@
bool has_flag = false;
// Note, this is done n*m, in case of collinearity, but it is only done if not trivial
- // or if there
bool middle = false;
for (tvit_type tvit = boost::begin(it->info);
! middle && tvit != boost::end(it->info);
@@ -251,4 +251,4 @@
} // namespace ggl
-#endif // GGL_ALGORITHMS_MERGE_INTERSECTION_POINTS_HPP
+#endif // GGL_ALGORITHMS_OVERLAY_MERGE_INTERSECTION_POINTS_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/segment_identifier.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/segment_identifier.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/segment_identifier.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -16,7 +16,6 @@
#include <ggl/core/coordinate_dimension.hpp>
#include <ggl/strategies/distance_result.hpp>
-#include <ggl/strategies/strategy_traits.hpp>
namespace ggl
{
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/self_intersection_points.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/self_intersection_points.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/self_intersection_points.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_ALGORITHMS_SELF_INTERSECTION_POINTS_HPP
-#define GGL_ALGORITHMS_SELF_INTERSECTION_POINTS_HPP
+#ifndef GGL_ALGORITHMS_OVERLAY_SELF_INTERSECTION_POINTS_HPP
+#define GGL_ALGORITHMS_OVERLAY_SELF_INTERSECTION_POINTS_HPP
#include <cstddef>
@@ -168,4 +168,4 @@
} // namespace ggl
-#endif // GGL_ALGORITHMS_SELF_INTERSECTION_POINTS_HPP
+#endif // GGL_ALGORITHMS_OVERLAY_SELF_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/sort_interior_rings.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/sort_interior_rings.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,128 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_ALGORITHMS_OVERLAY_SORT_INTERIOR_RINGS_HPP
+#define GGL_ALGORITHMS_OVERLAY_SORT_INTERIOR_RINGS_HPP
+
+#include <algorithm>
+#include <vector>
+
+#include <ggl/algorithms/area.hpp>
+#include <ggl/algorithms/within.hpp>
+#include <ggl/algorithms/detail/point_on_border.hpp>
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay {
+
+struct sortable
+{
+ int index; // zero-based (ZB) index to ring in rings
+ double area;
+ int index_of_parent; // ZB index to parent-ring
+ std::vector<int> index_of_holes; // ZB index to holes
+
+ inline sortable(int i, double a)
+ : index(i)
+ , area(a)
+ , index_of_parent(-1)
+ {}
+
+ inline bool operator<(sortable const& other) const
+ {
+ // sort in reverse order
+ return area > other.area;
+ }
+};
+
+
+
+template<typename Container>
+void sort_interior_rings(Container const& rings, std::vector<sortable>& sorted_rings, int factor)
+{
+ typedef typename boost::range_value<Container>::type ring_type;
+ typedef typename ggl::point_type<ring_type>::type point_type;
+
+ // Because of the whole followed procedure, the orientations (cw or ccw)
+ // of parents and holes are OK, and their areas are positive (parents)
+ // or negative (children)
+
+ // Create a copy (without copying geometries), with area (and envelope)
+ std::size_t n = 0;
+ for (typename boost::range_const_iterator<Container>::type
+ it = boost::begin(rings);
+ it != boost::end(rings);
+ ++it, ++n)
+ {
+ sorted_rings.push_back(sortable(n, factor * ggl::area(*it)));
+ }
+
+ // Sort in reverse order -> largest rings first, holes (neg. area) last
+ std::sort(sorted_rings.begin(), sorted_rings.end());
+
+ // Check which holes are in which polygons
+ for (std::size_t hole = 1; hole < n; hole++)
+ {
+ // It is a hole if its area is negative
+ if (sorted_rings[hole].area < 0 || factor < 0)
+ {
+ // So check if it is lying in one of the earlier rings
+ bool parent_found = false;
+ for (std::size_t parent = 0;
+ parent < hole
+ && ! parent_found
+ && sorted_rings[parent].area > 0;
+ parent++)
+ {
+ // note that "hole" is indexed in sorted rings,
+ // so make new "h" that is indexed in original rings
+ int const h = sorted_rings[hole].index;
+ int const p = sorted_rings[parent].index;
+
+ point_type point;
+ ggl::point_on_border(rings[h], point);
+ if (ggl::within(point, rings[p]))
+ {
+ // Update registration
+ sorted_rings[hole].index_of_parent = p;
+ sorted_rings[parent].index_of_holes.push_back(h);
+ parent_found = true;
+ }
+ }
+ }
+ }
+
+ /***
+ for (std::size_t i = 0; i < n; i++)
+ {
+ std::cout << "i: " << i
+ << " area: " << sorted_rings[i].area
+ << " count: " << rings[sorted_rings[i].index].size()
+ << " parent: " << sorted_rings[i].index_of_parent
+ << " holes: ";
+ for (int j = 0; j < boost::size(sorted_rings[i].index_of_holes); j++)
+ {
+ std::cout << " " << sorted_rings[i].index_of_holes[j];
+ }
+ std::cout << std::endl;
+ }
+ ***/
+}
+
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_SORT_INTERIOR_RINGS_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/traverse.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/traverse.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/traverse.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -17,6 +17,8 @@
#include <ggl/algorithms/overlay/copy_segments.hpp>
+#include <ggl/strategies/side.hpp>
+
#include <ggl/geometries/concepts/check.hpp>
#ifdef GGL_DEBUG_INTERSECTION
@@ -46,28 +48,20 @@
>
struct on_direction
{
- on_direction(IntersectionPoint const& ip, int direction)
+ typedef typename strategy_side
+ <
+ typename cs_tag<IntersectionPoint>::type
+ >::type side;
+
+ inline on_direction(IntersectionPoint const& ip, int direction)
: m_ip(ip)
, m_direction(direction)
{}
- // TEMP: convenient COPY of side
- template <typename P1, typename P2, typename P>
- static inline int side(P1 const& p1, P2 const& p2, P const& p)
- {
- typedef typename select_coordinate_type<P, P1>::type T;
-
- T dx = get<0>(p2) - get<0>(p1);
- T dy = get<1>(p2) - get<1>(p1);
- T dpx = get<0>(p) - get<0>(p1);
- T dpy = get<1>(p) - get<1>(p1);
- T product = dx * dpy - dy * dpx;
- return product > 0 ? 1 : product < 0 ? -1 : 0;
- }
inline bool operator()(IntersectionInfo const& first, IntersectionInfo const& second) const
{
- int dir = side(m_ip, first->other_point, second->other_point);
+ int dir = side::apply(m_ip, first->other_point, second->other_point);
return m_direction == dir;
}
Deleted: sandbox/ggl/formal_review_request/boost/ggl/algorithms/selected.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/selected.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,281 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_ALGORITHMS_SELECTED_HPP
-#define GGL_ALGORITHMS_SELECTED_HPP
-
-#include <cmath>
-#include <cstddef>
-
-#include <boost/range/functions.hpp>
-#include <boost/range/metafunctions.hpp>
-
-#include <ggl/algorithms/within.hpp>
-#include <ggl/core/access.hpp>
-#include <ggl/core/topological_dimension.hpp>
-
-#include <ggl/geometries/concepts/check.hpp>
-
-
-/*!
-\defgroup selected selection: check if a geometry is "selected" by a point
-
-Checks if one geometry is selected by a point lying within or in the neighborhood of that geometry
-
-\par Geometries:
-- POINT: checks if points are CLOSE TO each other (< search_radius)
-- LINESTRING: checks if selection point is CLOSE TO linestring (< search_radius)
-- RING: checks if selection point is INSIDE the ring, search radius is ignored
-- POLYGON: checks if selection point is INSIDE the polygon, but not inside any of its holes
-
-*/
-
-namespace ggl
-{
-
-/*!
- \ingroup impl
- */
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace selected {
-
-/*!
-\details Checks, per dimension, if d[I] not larger than search distance. If true for all
-dimensions then returns true. If larger stops immediately and returns false.
-Calculate during this process the sum, which is only valid if returning true
-*/
-template <typename P1, typename P2, typename T, std::size_t D, std::size_t N>
-struct differences_loop
-{
- static inline bool apply(P1 const& p1, P2 const& p2, T const& distance, T& sum)
- {
- typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
-
- coordinate_type const c1 = boost::numeric_cast<coordinate_type>(get<D>(p1));
- coordinate_type const c2 = boost::numeric_cast<coordinate_type>(get<D>(p2));
-
- T const d = std::abs(c1 - c2);
- if (d > distance)
- {
- return false;
- }
- sum += d * d;
- return differences_loop<P1, P2, T, D + 1, N>::apply(p1, p2, distance, sum);
- }
-};
-
-template <typename P1, typename P2, typename T, std::size_t N>
-struct differences_loop<P1, P2, T, N, N>
-{
- static inline bool apply(P1 const&, P2 const&, T const&, T&)
- {
- return true;
- }
-};
-
-
-
-template <typename S, typename P, typename T, std::size_t D, std::size_t N>
-struct outside_loop
-{
- static inline bool apply(S const& seg, P const& point, T const& distance)
- {
- typedef typename select_coordinate_type<S, P>::type coordinate_type;
-
- coordinate_type const v = boost::numeric_cast<coordinate_type>(get<D>(point));
- coordinate_type const s1 = get<0, D>(seg);
- coordinate_type const s2 = get<1, D>(seg);
-
- // Out of reach if left/bottom or right/top of both points making up the segment
- // I know and currently accept that these comparisons/calculations are done twice per point
-
- if ((v < s1 - distance && v < s2 - distance) || (v > s1 + distance && v > s2 + distance))
- {
- return true;
- }
- return outside_loop<S, P, T, D + 1, N>::apply(seg, point, distance);
- }
-};
-
-template <typename S, typename P, typename T, std::size_t N>
-struct outside_loop<S, P, T, N, N>
-{
- static inline bool apply(S const&, P const&, T const&)
- {
- return false;
- }
-};
-
-
-template <typename P1, typename P2, typename T>
-struct close_to_point
-{
- static inline bool apply(P1 const& point, P1 const& selection_point, T const& search_radius)
- {
- assert_dimension_equal<P1, P2>();
-
- T sum = 0;
- if (differences_loop
- <
- P1, P2, T, 0, dimension<P1>::type::value
- >::apply(point, selection_point, search_radius, sum))
- {
- return sum <= search_radius * search_radius;
- }
-
- return false;
- }
-};
-
-template <typename S, typename P, typename T>
-struct close_to_segment
-{
- static inline bool apply(S const& seg, P const& selection_point, T const& search_radius)
- {
- assert_dimension_equal<S, P>();
-
- if (! outside_loop
- <
- S, P, T, 0, dimension<P>::type::value
- >::apply(seg, selection_point, search_radius))
- {
- // Not outside, calculate dot product/square distance to segment.
- // Call corresponding strategy
- typedef typename strategy_distance_segment
- <
- typename cs_tag<P>::type,
- typename cs_tag<S>::type,
- P,
- S
- >::type strategy_type;
- typedef typename strategy_type::return_type return_type;
-
- strategy_type strategy;
- return_type result = strategy(selection_point, seg);
- return result < search_radius;
- }
-
- return false;
- }
-};
-
-template <typename R, typename P, typename T>
-struct close_to_range
-{
- static inline bool apply(R const& range, P const& selection_point, T const& search_radius)
- {
- assert_dimension_equal<R, P>();
-
- std::size_t const n = boost::size(range);
- if (n == 0)
- {
- // Line with zero points, never close
- return false;
- }
-
- typedef typename point_type<R>::type point_type;
- typedef typename boost::range_const_iterator<R>::type iterator_type;
-
- iterator_type it = boost::begin(range);
- if (n == 1)
- {
- // Line with one point ==> close to point
- return close_to_point<P, point_type, T>::apply(*it, selection_point, search_radius);
- }
-
- iterator_type previous = it++;
- while(it != boost::end(range))
- {
- typedef segment<const point_type> segment_type;
- segment_type s(*previous, *it);
- if (close_to_segment<segment_type, P, T>::apply(s, selection_point, search_radius))
- {
- return true;
- }
- previous = it++;
- }
-
- return false;
- }
-};
-
-template <typename Tag, typename G, typename P, typename T>
-struct use_within
-{
- static inline bool apply(G const& geometry, P const& selection_point, T const& search_radius)
- {
- return ggl::within(selection_point, geometry);
- }
-};
-
-}} // namespace detail::selected
-#endif // DOXYGEN_NO_DETAIL
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-/*!
- \tparam TD topological dimension
- */
-template <typename Tag, typename G, std::size_t D, typename P, typename T>
-struct selected
-{
-};
-
-template <typename P1, typename P2, typename T>
-struct selected<point_tag, P1, 0, P2, T> : detail::selected::close_to_point<P1, P2, T> { };
-
-// SEGMENT, TODO HERE (close_to_segment)
-
-template <typename L, typename P, typename T>
-struct selected<linestring_tag, L, 1, P, T> : detail::selected::close_to_range<L, P, T> { };
-
-template <typename Tag, typename G, typename P, typename T>
-struct selected<Tag, G, 2, P, T> : detail::selected::use_within<Tag, G, P, T> { };
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-/*!
- \brief Checks if one geometry is selected by a point lying within or in the neighborhood of that geometry
- \ingroup selected
- \tparam Geometry type of geometry to check
- \tparam Point type of point to check
- \tparam T type of search radius
- \param geometry geometry which might be located in the neighborhood
- \param selection_point point to select the geometry
- \param search_radius for points/linestrings: defines radius of "neighborhood" to find things in
- \return true if point is within or close to the other geometry
-
- */
-template<typename Geometry, typename Point, typename RadiusType>
-inline bool selected(Geometry const& geometry,
- Point const& selection_point,
- RadiusType const& search_radius)
-{
- concept::check<const Geometry>();
- concept::check<const Point>();
-
- typedef dispatch::selected
- <
- typename tag<Geometry>::type,
- Geometry,
- topological_dimension<Geometry>::value,
- Point,
- RadiusType
- > selector_type;
-
- return selector_type::apply(geometry, selection_point, search_radius);
-}
-
-} // namespace ggl
-
-#endif // GGL_ALGORITHMS_SELECTED_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/simplify.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/simplify.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/simplify.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -20,7 +20,6 @@
#include <ggl/geometries/concepts/check.hpp>
-#include <ggl/strategies/strategies.hpp>
#include <ggl/strategies/agnostic/simplify_douglas_peucker.hpp>
#include <ggl/strategies/concepts/simplify_concept.hpp>
@@ -29,26 +28,38 @@
/*!
-\defgroup simplify simplification (generalization)
+\defgroup simplify simplify: remove points from a geometry, keeping shape (simplification or generalization)
\par Source description:
-- Wikipedia: given a 'curve' composed of line segments to find a curve not too dissimilar but that has fewer points
+- Wikipedia: given a 'curve' composed of line segments to find a curve
+ not too dissimilar but that has fewer points
\see http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
\par Performance
-Performance is measured on simplification of a collection of rings, such that 10% of the points is kept.
-- 2776 counties of US are simplified in 0.8 seconds (2.5 seconds or 11.5 seconds in 2 other libraries)
-- 3918 zipcode areas of the Netherlands are simplified in 0.03 seconds (0.1 seconds or 0.45 seconds in 2 other libraries)
-
+- Performance is measured on simplification of a collection of rings,
+ such that 10% of the points is kept.
+- 2776 counties of US are simplified in 0.7 seconds
+(http://trac.osgeo.org/ggl/wiki/Performance#Simplify1)
\par Geometries
-- LINESTRING:
-\image html simplify_linestring.png
-- POLYGON: simplifying a valid simple polygon (which never intersects itself) might result in an invalid polygon,
-where the simplified rings intersect themselves or one of the other outer or inner rings.
+- \b linestring:
+\image html svg_simplify_road.png
+This US Road originally contained 34 points, the simplified version contains 7 points
+
+- \b polygon:
+\image html svg_simplify_country.png
+This country (Belgium) originally contained 55 points, the simplified version contains 24 points
+
+\note simplifying a valid simple polygon (which never intersects itself)
+ might result in an invalid polygon, where the simplified rings intersect
+ themselves or one of the other outer or inner rings.
Efficient simplification of a ring/polygon is still an "Open Problem"
(http://maven.smith.edu/~orourke/TOPP/P24.html#Problem.24)
+- \b multi_linestring
+- \b multi_polygon
+
+
*/
namespace ggl
@@ -98,14 +109,18 @@
{
// Call do_container for a linestring / ring
- // For a RING:
- // The first/last point (the closing point of the ring) should maybe be excluded because it
- // lies on a line with second/one but last. Here it is never excluded.
-
- // Note also that, especially if max_distance is too large, the output ring might be self intersecting
- // while the input ring is not, although chances are low in normal polygons
-
- // Finally the inputring might have 4 points (=correct), the output < 4(=wrong)
+ /* For a RING:
+ The first/last point (the closing point of the ring) should maybe
+ be excluded because it lies on a line with second/one but last.
+ Here it is never excluded.
+
+ Note also that, especially if max_distance is too large,
+ the output ring might be self intersecting while the input ring is
+ not, although chances are low in normal polygons
+
+ Finally the inputring might have 4 points (=correct),
+ the output < 4(=wrong)
+ */
if (boost::size(range) <= int(Minimum) || max_distance < 0.0)
{
@@ -144,7 +159,9 @@
exterior_ring(poly_out),
max_distance, strategy);
- interior_rings(poly_out).resize(boost::size(interior_rings(poly_in)));
+ // Note: here a resizeable container is assumed.
+ // Maybe we should make this part of the concept.
+ interior_rings(poly_out).resize(num_interior_rings(poly_in));
iterator_type it_out = boost::begin(interior_rings(poly_out));
@@ -243,14 +260,14 @@
/*!
- \brief Simplify a geometry
+ \brief Simplify a geometry using a specified strategy
\ingroup simplify
- \details This version of simplify simplifies a geometry using a specified strategy
- where the output is of the same geometry type as the input.
\param geometry input geometry, to be simplified
\param out output geometry, simplified version of the input geometry
- \param max_distance distance (in units of input coordinates) of a vertex to other segments to be removed
- \param strategy simplify strategy to be used for simplification, might include point-distance strategy
+ \param max_distance distance (in units of input coordinates) of a vertex
+ to other segments to be removed
+ \param strategy simplify strategy to be used for simplification, might
+ include point-distance strategy
*/
template<typename Geometry, typename Strategy>
inline void simplify(Geometry const& geometry, Geometry& out,
@@ -276,11 +293,18 @@
/*!
\brief Simplify a geometry
\ingroup simplify
- \details This version of simplify simplifies a geometry using the default strategy (Douglas Peucker),
- where the output is of the same geometry type as the input.
+ \note This version of simplify simplifies a geometry using the default
+ strategy (Douglas Peucker),
\param geometry input geometry, to be simplified
\param out output geometry, simplified version of the input geometry
- \param max_distance distance (in units of input coordinates) of a vertex to other segments to be removed
+ \param max_distance distance (in units of input coordinates) of a vertex
+ to other segments to be removed
+ \par Example:
+ The simplify algorithm can be used as following:
+ \dontinclude doxygen_examples.cpp
+ \skip example_simplify_linestring1
+ \line {
+ \until }
*/
template<typename Geometry>
inline void simplify(Geometry const& geometry, Geometry& out,
@@ -295,7 +319,7 @@
cs_tag,
cs_tag,
point_type,
- ggl::segment<const point_type>
+ point_type
>::type ds_strategy_type;
typedef strategy::simplify::douglas_peucker
@@ -308,16 +332,17 @@
/*!
- \brief Simplify a geometry
+ \brief Simplify a geometry, using an output iterator
+ and a specified strategy
\ingroup simplify
- \details The simplify algorithm removes points, keeping the shape as much as possible.
- This version of simplify uses an output iterator and a simplify strategy
- \param geometry the geometry to be simplified, being a ggl::linestring, vector, iterator pair, or any other boost compatible range
+ \param geometry input geometry, to be simplified
\param out output iterator, outputs all simplified points
- \param max_distance distance (in units of input coordinates) of a vertex to other segments to be removed
- \param strategy simplify strategy to be used for simplification, might include point-distance strategy
+ \param max_distance distance (in units of input coordinates) of a vertex
+ to other segments to be removed
+ \param strategy simplify strategy to be used for simplification,
+ might include point-distance strategy
\par Example:
- The simplify algorithm with strategy can be used as following:
+ simplify_inserter with strategy is used as following:
\dontinclude doxygen_examples.cpp
\skip example_simplify_linestring2
\line {
@@ -339,19 +364,12 @@
}
/*!
- \brief Simplify a geometry
+ \brief Simplify a geometry, using an output iterator
\ingroup simplify
- \details The simplify algorithm removes points, keeping the shape as much as possible.
- This version of simplify uses an output iterator
- \param geometry the geometry to be simplified, being a ggl::linestring, vector, iterator pair, or any other boost compatible range
+ \param geometry input geometry, to be simplified
\param out output iterator, outputs all simplified points
- \param max_distance distance (in units of input coordinates) of a vertex to other segments to be removed
- \par Example:
- The simplify algorithm can be used as following:
- \dontinclude doxygen_examples.cpp
- \skip example_simplify_linestring1
- \line {
- \until }
+ \param max_distance distance (in units of input coordinates) of a vertex
+ to other segments to be removed
*/
template<typename Geometry, typename OutputIterator>
inline void simplify_inserter(Geometry const& geometry, OutputIterator out,
@@ -369,11 +387,9 @@
cs_tag,
cs_tag,
point_type,
- ggl::segment<const point_type>
+ point_type
>::type ds_strategy_type;
- //typedef typename ggl::as_range_type<Geometry>::type range_type;
-
typedef strategy::simplify::douglas_peucker
<
point_type, ds_strategy_type
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/transform.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/transform.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/transform.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -25,7 +25,7 @@
#include <ggl/geometries/concepts/check.hpp>
-#include <ggl/strategies/strategies.hpp>
+#include <ggl/strategies/transform.hpp>
/*!
@@ -152,7 +152,7 @@
return false;
}
- interior_rings(poly2).resize(boost::size(interior_rings(poly1)));
+ interior_rings(poly2).resize(num_interior_rings(poly1));
typedef typename boost::range_const_iterator<interior1_type>::type iterator1_type;
typedef typename boost::range_iterator<interior2_type>::type iterator2_type;
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/union.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/union.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,263 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_ALGORITHMS_UNION_HPP
+#define GGL_ALGORITHMS_UNION_HPP
+
+
+#include <boost/mpl/if.hpp>
+
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/reverse_dispatch.hpp>
+#include <ggl/geometries/concepts/check.hpp>
+#include <ggl/algorithms/overlay/assemble.hpp>
+#include <ggl/algorithms/overlay/sort_interior_rings.hpp>
+#include <ggl/algorithms/within.hpp>
+
+
+
+/*!
+\defgroup union union operations (polygon-polygon union)
+\details The union of two geometries A and B is the geometry containing
+ all points belong to either of A or B, but no other elements.
+\par Source description:
+- OGC: Returns a geometric object that represents the Point set union of
+ this geometric object with another Geometry.
+\see http://en.wikipedia.org/wiki/Union_(set_theory)
+\note A union of two rings can result in a polygon having a hole
+
+\par Geometries:
+- \b polygon + \b box -> \b polygon(s)
+\image html svg_union_polygon_box.png
+- \b ring + \b box -> \b polygon(s)
+\image html svg_union_ring_box.png
+- \b ring + \b ring -> \b polygon(s)
+\image html svg_union_ring_ring.png
+- \b polygon + \b ring -> \b polygon(s)
+\image html svg_union_polygon_ring.png
+- combinations above -> \b ring(s).
+ <i>If the output is an ouput iterator of rings, holes are omitted</i>
+
+*/
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay {
+
+
+// Specializations for "take_one" for union
+// "one" should be the outer one, containing the inner one
+
+// for ring and box
+template
+<
+ typename Tag1, typename Geometry1,
+ typename Tag2, typename Geometry2,
+ typename GeometryOut
+>
+struct take_if_1_is_in_2<Tag1, Geometry1, Tag2, Geometry2, GeometryOut, 1>
+{
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ GeometryOut& out
+ )
+ {
+ ggl::convert(geometry2, out);
+ }
+};
+
+
+// spcialize more for polygons
+template
+<
+ typename Tag1, typename Geometry1,
+ typename Geometry2,
+ typename GeometryOut
+>
+struct take_if_1_is_in_2<Tag1, Geometry1, polygon_tag, Geometry2, GeometryOut, 1>
+{
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ GeometryOut& out
+ )
+ {
+ ggl::convert(exterior_ring(geometry2), out);
+ }
+};
+
+
+template
+<
+ typename Geometry, typename GeometryOut, typename Container
+>
+struct add_holes<polygon_tag, Geometry, GeometryOut, Container, 1>
+{
+ static inline void apply(Geometry const& geometry,
+ GeometryOut& out,
+ Container const& holes
+ )
+ {
+ std::vector<sortable> v;
+ sort_interior_rings(holes, v, -1);
+
+ // For a union, if a ring is containing an inner ring, don't take the outer
+ // but leave to the inners.
+ // If the inner is lying in geometry2, don't add it
+
+ std::size_t const n = boost::size(v);
+
+ for (std::size_t i = 0; i < n; i++)
+ {
+ // So, only if no inners:
+ if (boost::size(v[i].index_of_holes) == 0)
+ {
+ bool add = v[i].index_of_parent >= 0;
+ if (! add)
+ {
+ typename ggl::point_type<GeometryOut>::type point;
+ ggl::point_on_border(holes[v[i].index], point);
+ add = ! ggl::within(point, geometry);
+ }
+ if (add)
+ {
+ typename ring_type<GeometryOut>::type hole;
+ ggl::convert(holes[v[i].index], hole);
+ ggl::interior_rings(out).push_back(hole);
+ }
+ }
+ }
+ }
+};
+
+
+
+// "none or both" should be both
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename OutputIterator, typename GeometryOut
+>
+struct take_none_or_both<Geometry1, Geometry2, OutputIterator, GeometryOut, 1>
+{
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ OutputIterator out
+ )
+ {
+ convert_and_output<GeometryOut>(geometry1, out);
+ convert_and_output<GeometryOut>(geometry2, out);
+ }
+};
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Tag1, typename Tag2, typename Tag3,
+ typename G1, typename G2,
+ typename OutputIterator,
+ typename GeometryOut
+>
+struct union_inserter
+ : detail::overlay::overlay_and_assemble
+ <G1, G2, OutputIterator, GeometryOut, 1>
+{
+};
+
+
+template
+<
+ typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
+ typename Geometry1, typename Geometry2,
+ typename OutputIterator, typename GeometryOut
+>
+struct union_inserter_reversed
+{
+ static inline OutputIterator apply(Geometry1 const& g1,
+ Geometry2 const& g2, OutputIterator out)
+ {
+ return union_inserter
+ <
+ GeometryTag2, GeometryTag1, GeometryTag3,
+ Geometry2, Geometry1,
+ OutputIterator, GeometryOut
+ >::apply(g2, g1, out);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+ \brief Combines two geometries which each other
+ \ingroup union
+ \tparam GeometryOut output geometry type, must be specified
+ \tparam Geometry1 first geometry type
+ \tparam Geometry2 second geometry type
+ \tparam OutputIterator output iterator
+ \param geometry1 first geometry
+ \param geometry2 second geometry
+ \param out the output iterator, outputting polygons
+ \return the output iterator
+*/
+template
+<
+ typename GeometryOut,
+ typename Geometry1,
+ typename Geometry2,
+ typename OutputIterator
+>
+inline OutputIterator union_inserter(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ OutputIterator out)
+{
+ concept::check<const Geometry1>();
+ concept::check<const Geometry2>();
+
+ return boost::mpl::if_c
+ <
+ reverse_dispatch<Geometry1, Geometry2>::type::value,
+ dispatch::union_inserter_reversed
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag<GeometryOut>::type,
+ Geometry1,
+ Geometry2,
+ OutputIterator, GeometryOut
+ >,
+ dispatch::union_inserter
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag<GeometryOut>::type,
+ Geometry1,
+ Geometry2,
+ OutputIterator, GeometryOut
+ >
+ >::type::apply(geometry1, geometry2, out);
+}
+
+
+} // ggl
+
+
+#endif //GGL_ALGORITHMS_UNION_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/algorithms/within.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/algorithms/within.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/within.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -25,10 +25,42 @@
#include <ggl/geometries/concepts/check.hpp>
-#include <ggl/strategies/strategies.hpp>
+#include <ggl/strategies/point_in_poly.hpp>
#include <ggl/strategies/concepts/within_concept.hpp>
+/*!
+\defgroup within within detection, a.o. point-in-polygon
+
+\par Source descriptions:
+- OGC: Returns 1 (TRUE) if this geometric object is "spatially within"
+ another Geometry.
+
+\par Performance
+- 2776 within determinations using bounding box and polygon are done
+ in 0.05 seconds (http://trac.osgeo.org/ggl/wiki/Performance#Within1)
+- note that using another strategy the performance can be increased:
+ - winding : 0.093 s
+ - franklin : 0.062 s
+ - Crossings-multiply : 0.047 s
+- but note also that the last two do not detect point-on-border cases
+
+
+\par Example:
+The within algorithm is used as following:
+\dontinclude doxygen_examples.cpp
+\skip example_within
+\line {
+\until }
+\par Geometries:
+- POINT + POLYGON: The well-known point-in-polygon, returning true if
+ a point falls within a polygon (and not
+within one of its holes) \image html within_polygon.png
+- POINT + RING: returns true if point is completely within
+ a ring \image html within_ring.png
+
+*/
+
namespace ggl
{
@@ -42,12 +74,12 @@
\ingroup boolean_relations
\note Should have strategy for e.g. Wrangel
*/
-template
+template
<
- typename Point,
- typename Box,
+ typename Point,
+ typename Box,
typename Strategy,
- std::size_t Dimension,
+ std::size_t Dimension,
std::size_t DimensionCount
>
struct point_in_box
@@ -64,19 +96,19 @@
return point_in_box
<
- Point,
- Box,
+ Point,
+ Box,
Strategy,
- Dimension + 1,
+ Dimension + 1,
DimensionCount
>::apply(p, b, s);
}
};
-template
+template
<
- typename Point,
- typename Box,
+ typename Point,
+ typename Box,
typename Strategy,
std::size_t DimensionCount
>
@@ -89,12 +121,12 @@
};
-template
+template
<
- typename Box1,
- typename Box2,
+ typename Box1,
+ typename Box2,
typename Strategy,
- std::size_t Dimension,
+ std::size_t Dimension,
std::size_t DimensionCount
>
struct box_in_box
@@ -111,19 +143,19 @@
return box_in_box
<
- Box1,
- Box2,
+ Box1,
+ Box2,
Strategy,
- Dimension + 1,
+ Dimension + 1,
DimensionCount
>::apply(b1, b2, s);
}
};
-template
+template
<
- typename Box1,
- typename Box2,
+ typename Box1,
+ typename Box2,
typename Strategy,
std::size_t DimensionCount
>
@@ -141,7 +173,7 @@
{
BOOST_CONCEPT_ASSERT( (ggl::concept::WithinStrategy<Strategy>) );
- static inline bool apply(Point const& point, Ring const& ring,
+ static inline bool apply(Point const& point, Ring const& ring,
Strategy const& strategy)
{
if (boost::size(ring) < 4)
@@ -173,14 +205,14 @@
{
BOOST_CONCEPT_ASSERT( (ggl::concept::WithinStrategy<Strategy>) );
- static inline bool apply(Point const& point, Polygon const& poly,
+ static inline bool apply(Point const& point, Polygon const& poly,
Strategy const& strategy)
{
typedef point_in_ring
<
- Point,
- typename ring_type<Polygon>::type,
+ Point,
+ typename ring_type<Polygon>::type,
Strategy
> per_ring;
@@ -191,7 +223,7 @@
<
typename interior_type<Polygon>::type
>::type it = boost::begin(interior_rings(poly));
- it != boost::end(interior_rings(poly));
+ it != boost::end(interior_rings(poly));
++it)
{
if (per_ring::apply(point, *it, strategy))
@@ -213,15 +245,15 @@
namespace dispatch
{
-template
+template
<
- typename Tag1,
- typename Tag2,
- typename Geometry1,
+ typename Tag1,
+ typename Tag2,
+ typename Geometry1,
typename Geometry2,
typename Strategy
>
-struct within
+struct within
{};
@@ -268,37 +300,14 @@
/*!
- \brief Within check
- \details Examine if one geometry is within another geometry
- (a.o. point in polygon)
- \ingroup boolean_relations
+ \brief Within, examine if a geometry is within another geometry
+ \ingroup within
\param geometry1 geometry which might be within the second geometry
\param geometry2 geometry which might contain the first geometry
- \return true if geometry1 is completely contained within geometry2,
+ \return true if geometry1 is completely contained within geometry2,
else false
\note The default strategy is used for within detection
-\par Source descriptions:
-- OGC: Returns 1 (TRUE) if this geometric object is "spatially within"
- another Geometry.
-
-\par Performance
-2776 within determinations using bounding box and polygon are done
- in 0.09 seconds (other libraries: 0.14 seconds, 3.0 seconds, 3.8)
-
-\par Example:
-The within algorithm is used as following:
-\dontinclude doxygen_examples.cpp
-\skip example_within
-\line {
-\until }
-\par Geometries:
-- POINT + POLYGON: The well-known point-in-polygon, returning true if
- a point falls within a polygon (and not
-within one of its holes) \image html within_polygon.png
-- POINT + RING: returns true if point is completely within
- a ring \image html within_ring.png
-
*/
template<typename Geometry1, typename Geometry2>
inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
@@ -328,12 +337,13 @@
}
/*!
- \brief Within check using a strategy
- \ingroup boolean_relations
+ \brief Within, examine if a geometry is within another geometry,
+ using a specified strategy
+ \ingroup within
\param geometry1 geometry which might be within the second geometry
\param geometry2 geometry which might contain the first geometry
\param strategy strategy to be used
- \return true if geometry1 is completely contained within geometry2,
+ \return true if geometry1 is completely contained within geometry2,
else false
*/
template<typename Geometry1, typename Geometry2, typename Strategy>
Modified: sandbox/ggl/formal_review_request/boost/ggl/core/exterior_ring.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/core/exterior_ring.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/exterior_ring.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -17,25 +17,29 @@
#include <ggl/core/ring_type.hpp>
#include <ggl/core/tag.hpp>
#include <ggl/core/tags.hpp>
+#include <ggl/util/add_const_if_c.hpp>
namespace ggl {
namespace traits {
+
/*!
\brief Traits class defining access to exterior_ring of a polygon
\details Should define const and non const access
\ingroup traits
- \tparam G geometry
+ \tparam Polygon the polygon type
\par Geometries:
- polygon
\par Specializations should provide:
- static inline RING& get(POLY& )
- static inline const RING& get(const POLY& )
*/
-template <typename P>
-struct exterior_ring {};
+template <typename Polygon>
+struct exterior_ring
+{};
+
} // namespace traits
@@ -44,23 +48,35 @@
namespace core_dispatch
{
-template <typename T, typename G>
+
+template <typename Tag, typename Geometry, bool IsConst>
struct exterior_ring {};
-template <typename P>
-struct exterior_ring<polygon_tag, P>
-{
- static inline typename ring_type<polygon_tag, P>::type& get(P& polygon)
- {
- return traits::exterior_ring<P>::get(polygon);
- }
- static inline const typename ring_type<polygon_tag, P>::type& get(const P& polygon)
+template <typename Polygon, bool IsConst>
+struct exterior_ring<polygon_tag, Polygon, IsConst>
+{
+ static inline typename add_const_if_c
+ <
+ IsConst,
+ typename ggl::ring_type
+ <
+ Polygon
+ >::type
+ >::type& apply(typename add_const_if_c
+ <
+ IsConst,
+ Polygon
+ >::type& polygon)
{
- return traits::exterior_ring<P>::get(polygon);
+ return traits::exterior_ring
+ <
+ typename boost::remove_const<Polygon>::type
+ >::get(polygon);
}
};
+
} // namespace core_dispatch
#endif // DOXYGEN_NO_DISPATCH
@@ -73,24 +89,36 @@
\param polygon the polygon to get the exterior ring from
\return a reference to the exterior ring
*/
-template <typename P>
-inline typename ring_type<P>::type& exterior_ring(P& polygon)
+template <typename Polygon>
+inline typename ring_type<Polygon>::type& exterior_ring(Polygon& polygon)
{
- return core_dispatch::exterior_ring<typename tag<P>::type, P>::get(polygon);
+ return core_dispatch::exterior_ring
+ <
+ typename tag<Polygon>::type,
+ Polygon,
+ false
+ >::apply(polygon);
}
+
/*!
\brief Function to get the exterior ring of a polygon (const version)
\ingroup access
\note OGC compliance: instead of ExteriorRing
- \tparam P polygon type
+ \tparam Polygon polygon type
\param polygon the polygon to get the exterior ring from
\return a const reference to the exterior ring
*/
-template <typename P>
-inline const typename ring_type<P>::type& exterior_ring(const P& polygon)
+template <typename Polygon>
+inline const typename ring_type<Polygon>::type& exterior_ring(
+ Polygon const& polygon)
{
- return core_dispatch::exterior_ring<typename tag<P>::type, P>::get(polygon);
+ return core_dispatch::exterior_ring
+ <
+ typename tag<Polygon>::type,
+ Polygon,
+ true
+ >::apply(polygon);
}
Modified: sandbox/ggl/formal_review_request/boost/ggl/core/interior_rings.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/core/interior_rings.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/interior_rings.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -10,11 +10,14 @@
#ifndef GGL_CORE_INTERIOR_RINGS_HPP
#define GGL_CORE_INTERIOR_RINGS_HPP
+#include <cstddef>
+
#include <boost/range/functions.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <ggl/core/tag.hpp>
#include <ggl/core/tags.hpp>
+#include <ggl/util/add_const_if_c.hpp>
namespace ggl
{
@@ -22,35 +25,36 @@
namespace traits
{
- /*!
- \brief Traits class indicating interior container type of a polygon
- \details defines inner container type, so the container containing the interior rings
- \ingroup traits
- \par Geometries:
- - polygon
- \par Specializations should provide:
- - typedef CONTAINER<RING<P> > type (e.g. std::vector<linear_ring<P> >)
- \tparam G geometry
- */
- template <typename G>
- struct interior_type { };
-
-
- /*!
- \brief Traits class defining access to interior_rings of a polygon
- \details defines access (const and non const) to interior ring
- \ingroup traits
- \par Geometries:
- - polygon
- \par Specializations should provide:
- - static inline INTERIOR& get(POLY&)
- - static inline const INTERIOR& get(const POLY&)
- \tparam G geometry
- */
- template <typename G>
- struct interior_rings
- {
- };
+/*!
+ \brief Traits class indicating interior container type of a polygon
+ \details defines inner container type, so the container containing
+ the interior rings
+ \ingroup traits
+ \par Geometries:
+ - polygon
+ \par Specializations should provide:
+ - typedef CONTAINER<RING<P> > type (e.g. std::vector<linear_ring<P> >)
+ \tparam Geometry geometry
+*/
+template <typename Geometry>
+struct interior_type
+{};
+
+
+/*!
+ \brief Traits class defining access to interior_rings of a polygon
+ \details defines access (const and non const) to interior ring
+ \ingroup traits
+ \par Geometries:
+ - polygon
+ \par Specializations should provide:
+ - static inline INTERIOR& get(POLY&)
+ - static inline const INTERIOR& get(const POLY&)
+ \tparam Geometry geometry
+*/
+template <typename Geometry>
+struct interior_rings
+{};
} // namespace traits
@@ -61,58 +65,106 @@
#ifndef DOXYGEN_NO_DISPATCH
namespace core_dispatch
{
- template <typename GeometryTag, typename G> struct interior_type {};
- template <typename P>
- struct interior_type<polygon_tag, P>
+
+template <typename GeometryTag, typename Geometry>
+struct interior_type
+{};
+
+
+template <typename Polygon>
+struct interior_type<polygon_tag, Polygon>
+{
+ typedef typename traits::interior_type
+ <
+ typename boost::remove_const<Polygon>::type
+ >::type type;
+};
+
+
+template
+<
+ typename GeometryTag,
+ typename Geometry,
+ bool IsConst
+>
+struct interior_rings {};
+
+
+template <typename Polygon, bool IsConst>
+struct interior_rings<polygon_tag, Polygon, IsConst>
+{
+ static inline typename add_const_if_c
+ <
+ IsConst,
+ typename interior_type
+ <
+ polygon_tag,
+ Polygon
+ >::type
+ >::type& apply(typename add_const_if_c
+ <
+ IsConst,
+ Polygon
+ >::type& polygon)
{
- typedef typename traits::interior_type<P>::type type;
- };
+ return traits::interior_rings
+ <
+ typename boost::remove_const<Polygon>::type
+ >::get(polygon);
+ }
+};
+template <typename Tag, typename Geometry>
+struct num_interior_rings
+{
+ static inline std::size_t apply(Geometry const&)
+ {
+ return 0;
+ }
- template <typename GeometryTag, typename G>
- struct interior_rings {};
+};
- template <typename P>
- struct interior_rings<polygon_tag, P>
+template <typename Polygon>
+struct num_interior_rings<polygon_tag, Polygon>
+{
+ static inline std::size_t apply(Polygon const& polygon)
{
- static inline typename interior_type<polygon_tag, P>::type& get(P& polygon)
- {
- return traits::interior_rings<P>::get(polygon);
- }
-
- static inline const typename interior_type<polygon_tag, P>::type& get(const P& polygon)
- {
- return traits::interior_rings<P>::get(polygon);
- }
- };
+ return boost::size(interior_rings
+ <
+ polygon_tag, Polygon, true
+ >::apply(polygon));
+ }
+};
} // namespace core_dispatch
#endif
-
-
/*!
- \brief Meta-function defining container type of inner rings of (multi)polygon geometriy
- \details the interior rings should be organized as a container (std::vector, std::deque, boost::array) with
- boost range support. This meta function defines the type of that container.
+ \brief Meta-function defining container type
+ of inner rings of (multi)polygon geometriy
+ \details the interior rings should be organized as a container
+ (std::vector, std::deque, boost::array) with
+ boost range support. This meta function defines the type
+ of that container.
\ingroup core
*/
-template <typename G>
+template <typename Geometry>
struct interior_type
{
- typedef typename boost::remove_const<G>::type ncg;
- typedef typename core_dispatch::interior_type<
- typename tag<G>::type, ncg>::type type;
+ typedef typename core_dispatch::interior_type
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::type type;
};
-
/*!
\brief Function to get the interior rings of a polygon (non const version)
\ingroup access
@@ -121,10 +173,15 @@
\param polygon the polygon to get the interior rings from
\return a reference to the interior rings
*/
-template <typename P>
-inline typename interior_type<P>::type& interior_rings(P& polygon)
+template <typename Polygon>
+inline typename interior_type<Polygon>::type& interior_rings(Polygon& polygon)
{
- return core_dispatch::interior_rings<typename tag<P>::type, P>::get(polygon);
+ return core_dispatch::interior_rings
+ <
+ typename tag<Polygon>::type,
+ Polygon,
+ false
+ >::apply(polygon);
}
@@ -136,10 +193,16 @@
\param polygon the polygon to get the interior rings from
\return a const reference to the interior rings
*/
-template <typename P>
-inline const typename interior_type<P>::type& interior_rings(const P& polygon)
-{
- return core_dispatch::interior_rings<typename tag<P>::type, P>::get(polygon);
+template <typename Polygon>
+inline const typename interior_type<Polygon>::type& interior_rings(
+ Polygon const& polygon)
+{
+ return core_dispatch::interior_rings
+ <
+ typename tag<Polygon>::type,
+ Polygon,
+ true
+ >::apply(polygon);
}
@@ -149,16 +212,23 @@
\ingroup access
\note Defined by OGC as "numInteriorRing". To be consistent with "numPoints"
letter "s" is appended
- \tparam P polygon type
- \param polygon the polygon
- \return the nubmer of interior rings
+ \note Can be used for any geometry, returning 0 for geometries not having
+ interior rings
+ \tparam Geometry geometry type
+ \param geometry the polygon or other geometry
+ \return the number of interior rings of the geometry
*/
-template <typename P>
-inline size_t num_interior_rings(const P& polygon)
+template <typename Geometry>
+inline std::size_t num_interior_rings(Geometry const& geometry)
{
- return boost::size(interior_rings(polygon));
+ return core_dispatch::num_interior_rings
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::apply(geometry);
}
+
}
Modified: sandbox/ggl/formal_review_request/boost/ggl/core/reverse_dispatch.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/core/reverse_dispatch.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/reverse_dispatch.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -26,8 +26,6 @@
{
// Different geometries: reverse_dispatch if second ID < first ID
-// Note: if "boost::mpl::greater is used, with geometry_id instead of geometry_id::type::value,
-// it is not working correctly!!!! TODO: find out why not.
template <std::size_t GeometryId1, std::size_t GeometryId2>
struct reverse_dispatch : boost::mpl::if_c
<
Modified: sandbox/ggl/formal_review_request/boost/ggl/core/ring_type.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/core/ring_type.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/ring_type.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -32,39 +32,38 @@
- polygon
\par Specializations should provide:
- typedef XXX type (e.g. linear_ring<P>)
- \tparam G geometry
+ \tparam Geometry geometry
*/
-template <typename G>
+template <typename Geometry>
struct ring_type
{
// should define type
};
-
-
} // namespace traits
-
#ifndef DOXYGEN_NO_DISPATCH
namespace core_dispatch
{
-template <typename GeometryTag, typename Geometry> struct ring_type
+template <typename GeometryTag, typename Geometry>
+struct ring_type
{};
-
template <typename Polygon>
struct ring_type<polygon_tag, Polygon>
{
- typedef typename traits::ring_type<Polygon>::type type;
-};
-
+ typedef typename traits::ring_type
+ <
+ typename boost::remove_const<Polygon>::type
+ >::type type;
+};
} // namespace core_dispatch
@@ -73,24 +72,23 @@
/*!
\brief Meta-function which defines ring type of (multi)polygon geometry
- \details a polygon contains one exterior ring and zero or more interior rings (holes).
- The type of those rings is assumed to be equal. This meta function retrieves the type
- of such rings.
+ \details a polygon contains one exterior ring
+ and zero or more interior rings (holes).
+ This meta function retrieves the type of the rings
+ \note Exterior ring and interior rings must have the same ring-type.
\ingroup core
*/
template <typename Geometry>
struct ring_type
{
- typedef typename boost::remove_const<Geometry>::type ncg;
typedef typename core_dispatch::ring_type
<
- typename tag<Geometry>::type, ncg
+ typename tag<Geometry>::type,
+ Geometry
>::type type;
};
-
-
}
Modified: sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/geographic/strategies/andoyer.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/geographic/strategies/andoyer.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/geographic/strategies/andoyer.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -10,7 +10,7 @@
#define GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_ANDOYER_HPP
-#include <ggl/strategies/strategy_traits.hpp>
+#include <ggl/strategies/distance.hpp>
#include <ggl/core/radian_access.hpp>
#include <ggl/core/coordinate_type.hpp>
@@ -46,6 +46,8 @@
{
public :
//typedef spherical_distance return_type;
+ typedef P1 first_point_type;
+ typedef P2 second_point_type;
typedef double return_type;
andoyer()
@@ -55,7 +57,7 @@
: m_ellipsoid(f)
{}
- inline return_type operator()(const P1& p1, const P2& p2) const
+ inline return_type apply(const P1& p1, const P2& p2) const
{
return calc(get_as_radian<0>(p1), get_as_radian<1>(p1),
get_as_radian<0>(p2), get_as_radian<1>(p2));
Modified: sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/geographic/strategies/vincenty.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/geographic/strategies/vincenty.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/geographic/strategies/vincenty.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -10,7 +10,7 @@
#define GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_VINCENTY_HPP
-#include <ggl/strategies/strategy_traits.hpp>
+#include <ggl/strategies/distance.hpp>
#include <ggl/core/radian_access.hpp>
#include <ggl/core/coordinate_type.hpp>
@@ -42,11 +42,13 @@
{
public :
//typedef spherical_distance return_type;
+ typedef P1 first_point_type;
+ typedef P2 second_point_type;
typedef double return_type;
- inline return_type operator()(const P1& p1, const P2& p2) const
+ inline return_type apply(P1 const& p1, P2 const& p2) const
{
- return calc(get_as_radian<0>(p1), get_as_radian<1>(p1),
+ return calculate(get_as_radian<0>(p1), get_as_radian<1>(p1),
get_as_radian<0>(p2), get_as_radian<1>(p2));
}
@@ -55,7 +57,7 @@
typedef typename coordinate_type<P2>::type T2;
ggl::detail::ellipsoid m_ellipsoid;
- inline return_type calc(const T1& lon1, const T1& lat1, const T2& lon2, const T2& lat2) const
+ inline return_type calculate(T1 const& lon1, T1 const& lat1, T2 const& lon2, T2 const& lat2) const
{
// lambda: difference in longitude on an auxiliary sphere
double L = lon2 - lon1;
Modified: sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/std_as_linestring.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/std_as_linestring.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/std_as_linestring.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -24,6 +24,11 @@
#include <utility>
+#include <ggl/core/access.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
namespace ggl
{
#ifndef DOXYGEN_NO_DETAIL
Modified: sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/check.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/check.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/check.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -108,6 +108,7 @@
namespace concept {
+#ifndef DOXYGEN_NO_DETAIL
namespace detail {
/*!
@@ -124,6 +125,7 @@
{};
}
+#endif // DOXYGEN_NO_DETAIL
/*!
@@ -138,6 +140,19 @@
}
+/*!
+ \brief Checks, in compile-time, the concept of two geometries, and if they
+ have equal dimensions
+ \ingroup core
+*/
+template <typename Geometry1, typename Geometry2>
+inline void check_concepts_and_equal_dimensions()
+{
+ check<Geometry1>();
+ check<Geometry2>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+}
+
} // namespace concept
Modified: sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/detail/check_append.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/detail/check_append.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/detail/check_append.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -16,9 +16,9 @@
#include <ggl/core/access.hpp>
-
namespace ggl { namespace concept {
+#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
@@ -35,6 +35,7 @@
}
};
+
template <typename Geometry, typename Point>
struct check_append<Geometry, Point, false>
{
@@ -48,7 +49,7 @@
}
};
}
-
+#endif // DOXYGEN_NO_DETAIL
}} // namespace ggl::concept
Modified: sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/detail/check_clear.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/detail/check_clear.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/detail/check_clear.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -16,11 +16,13 @@
#include <ggl/core/access.hpp>
-
namespace ggl { namespace concept {
+
+#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
+
template <typename Geometry, bool UseStd>
struct check_clear
{};
@@ -34,6 +36,7 @@
}
};
+
template <typename Geometry>
struct check_clear<Geometry, false>
{
@@ -46,9 +49,8 @@
}
};
-
}
-
+#endif // DOXYGEN_NO_DETAIL
}} // namespace ggl::concept
Modified: sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/point_concept.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/point_concept.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/concepts/point_concept.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -20,7 +20,7 @@
/*!
\defgroup concepts concept checking
-Concepts are used to apply if pointtypes provide required implementation. Concept checking
+Concepts are used to apply if geometry types or strategies provide required implementation. Concept checking
is done using BCCL (Boost Concept Check Library) and MPL (Meta Programming Library)
*/
Modified: sandbox/ggl/formal_review_request/boost/ggl/ggl.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/ggl.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/ggl.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -57,7 +57,6 @@
#include <ggl/util/copy.hpp>
#include <ggl/util/for_each_coordinate.hpp>
-#include <ggl/util/loop.hpp>
#include <ggl/util/math.hpp>
#include <ggl/util/select_most_precise.hpp>
#include <ggl/util/select_coordinate_type.hpp>
Added: sandbox/ggl/formal_review_request/boost/ggl/iterators/range_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/iterators/range_type.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,82 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. 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 GGL_ITERATORS_RANGE_TYPE_HPP
+#define GGL_ITERATORS_RANGE_TYPE_HPP
+
+#include <boost/type_traits.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename GeometryTag, typename Geometry>
+struct range_type
+{
+ // Even if it is not recognized, define itself as a type.
+ // This enables calling range_type over any range
+ // (not necessarily a geometry)
+
+ // Furthermore, applicable for ring/linestring
+ typedef Geometry type;
+};
+
+
+template <typename Geometry>
+struct range_type<point_tag, Geometry>
+{
+ typedef void type;
+};
+
+
+template <typename Geometry>
+struct range_type<polygon_tag, Geometry>
+{
+ typedef typename ring_type<Geometry>::type type;
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+/*!
+\brief Meta-function defining a type which is a boost-range.
+\details
+- For linestrings and rings, it defines the type itself.
+- For polygons it defines the ring type.
+- For multi-points, it defines the type itself
+- For multi-polygons and multi-linestrings, it defines the single-version
+ (so in the end the linestring and ring-type-of-multi-polygon)
+\ingroup iterators
+*/
+template <typename Geometry>
+struct range_type
+{
+ typedef typename dispatch::range_type
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::type type;
+};
+
+
+} // namespace ggl
+
+
+#endif // GGL_ITERATORS_RANGE_TYPE_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/iterators/vertex_iterator.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/iterators/vertex_iterator.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,112 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_ITERATORS_VERTEX_ITERATOR_HPP
-#define GGL_ITERATORS_VERTEX_ITERATOR_HPP
-
-
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/range/metafunctions.hpp>
-
-
-#include <ggl/core/tag.hpp>
-#include <ggl/core/tags.hpp>
-#include <ggl/core/ring_type.hpp>
-
-
-namespace ggl
-{
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-template <typename Tag, typename Geometry, bool IsConst>
-struct vertex_iterator
-{};
-
-
-template <typename Tag, typename Geometry>
-struct vertex_iterator<Tag, Geometry, true>
-{
- // For most geometries: meta-forward this to boost
- // This enables calling this function using std::vector as well, even if they
- // are not registered.
- // It also requires less specializations
- typedef typename boost::range_const_iterator<Geometry>::type type;
-};
-
-template <typename Tag, typename Geometry>
-struct vertex_iterator<Tag, Geometry, false>
-{
- typedef typename boost::range_iterator<Geometry>::type type;
-};
-
-
-
-
-template <typename Polygon>
-struct vertex_iterator<polygon_tag, Polygon, false>
-{
- typedef typename boost::range_iterator
- <
- typename ggl::ring_type<Polygon>::type
- >::type type;
-};
-
-
-
-template <typename Polygon>
-struct vertex_iterator<polygon_tag, Polygon, true>
-{
- typedef typename boost::range_const_iterator
- <
- typename ggl::ring_type<Polygon>::type
- >::type type;
-};
-
-
-
-
-
-} // namespace dispatch
-#endif
-
-
-/*!
- \brief Meta-function which defines vertex_iterator type
- \details The vertex_iterator meta-function enables approaching
- any geometry with the same type of iterator. It is used within
- the library in conjuction with sections.
- A section defines a part of a geometry (linestring, polygon:
- outer ring or inner ring). The library, at that point, does not
- need to know if it is a polygon, multi-polygon or ring. Using
- this meta-function it still does not need to know that.
- \tparam Geometry the geometry type
- \tparam is_const: true if const iterator is defined, else false
- \ingroup iterators
-*/
-template <typename Geometry, bool IsConst>
-struct vertex_iterator
-{
- typedef typename dispatch::vertex_iterator
- <
- typename tag<Geometry>::type,
- typename boost::remove_const<Geometry>::type,
- IsConst
- >::type type;
-};
-
-
-
-}
-
-
-#endif // GGL_ITERATORS_VERTEX_ITERATOR_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/centroid.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/centroid.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/centroid.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -10,8 +10,11 @@
#define GGL_MULTI_ALGORITHMS_CENTROID_HPP
#include <ggl/algorithms/centroid.hpp>
+#include <ggl/algorithms/num_points.hpp>
#include <ggl/multi/core/point_type.hpp>
#include <ggl/multi/algorithms/detail/multi_sum.hpp>
+#include <ggl/multi/algorithms/num_points.hpp>
+
namespace ggl {
@@ -19,35 +22,35 @@
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace centroid {
+
+/*!
+ \brief Building block of a multi-point, to be used as Policy in the
+ more generec centroid_multi
+*/
template
<
- typename Multi,
typename Point,
typename Strategy
>
-struct centroid_multi_point
+struct centroid_multi_point_state
{
- static inline bool apply(Multi const& multi, Point& centroid,
+ static inline void apply(Point const& point,
Strategy const& strategy, typename Strategy::state_type& state)
{
- assign_zero(centroid);
- int n = 0;
-
- for (typename boost::range_const_iterator<Multi>::type
- it = boost::begin(multi);
- it != boost::end(multi);
- ++it)
- {
- add_point(centroid, *it);
- n++;
- }
- divide_value(centroid, n);
-
- return false;
+ strategy.apply(point, state);
}
};
+
+/*!
+ \brief Generic implementation which calls a policy to calculate the
+ centroid of the total of its single-geometries
+ \details The Policy is, in general, the single-version, with state. So
+ detail::centroid::centroid_polygon_state is used as a policy for this
+ detail::centroid::centroid_multi
+
+*/
template
<
typename Multi,
@@ -57,17 +60,26 @@
>
struct centroid_multi
{
- static inline bool apply(Multi const& multi, Point& centroid,
- Strategy const& strategy, typename Strategy::state_type& state)
+ static inline void apply(Multi const& multi, Point& centroid,
+ Strategy const& strategy)
{
+ // If there is nothing in any of the ranges, it is not possible
+ // to calculate the centroid
+ if (ggl::num_points(multi) == 0)
+ {
+ throw centroid_exception();
+ }
+
+ typename Strategy::state_type state;
+
for (typename boost::range_const_iterator<Multi>::type
it = boost::begin(multi);
it != boost::end(multi);
++it)
{
- Policy::apply(*it, centroid, strategy, state);
+ Policy::apply(*it, strategy, state);
}
- return true;
+ Strategy::result(state, centroid);
}
};
@@ -82,17 +94,21 @@
namespace dispatch
{
-template <typename MultiPolygon, typename Point, typename Strategy>
-struct centroid<multi_polygon_tag, 2, MultiPolygon, Point, Strategy>
+template
+<
+ typename MultiPolygon,
+ typename Point,
+ typename Strategy
+>
+struct centroid<multi_polygon_tag, MultiPolygon, Point, Strategy>
: detail::centroid::centroid_multi
<
MultiPolygon,
Point,
Strategy,
- detail::centroid::centroid_polygon
+ detail::centroid::centroid_polygon_state
<
typename boost::range_value<MultiPolygon>::type,
- Point,
Strategy
>
>
@@ -101,17 +117,21 @@
template
<
- std::size_t Dimensions,
typename MultiPoint,
typename Point,
typename Strategy
>
-struct centroid<multi_point_tag, Dimensions, MultiPoint, Point, Strategy>
- : detail::centroid::centroid_multi_point
+struct centroid<multi_point_tag, MultiPoint, Point, Strategy>
+ : detail::centroid::centroid_multi
<
MultiPoint,
Point,
- Strategy
+ Strategy,
+ detail::centroid::centroid_multi_point_state
+ <
+ typename boost::range_value<MultiPoint>::type,
+ Strategy
+ >
>
{};
@@ -124,3 +144,4 @@
#endif // GGL_MULTI_ALGORITHMS_CENTROID_HPP
+
Modified: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/convex_hull.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/convex_hull.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/convex_hull.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -1,7 +1,6 @@
// Generic Geometry Library
//
// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
// 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)
@@ -10,144 +9,14 @@
#define GGL_MULTI_ALGORITHMS_CONVEX_HULL_HPP
-#include <ggl/util/as_range.hpp>
+#include <ggl/multi/iterators/range_type.hpp>
+#include <ggl/multi/util/for_each_range.hpp>
-#include <ggl/multi/core/tags.hpp>
-#include <ggl/multi/core/is_multi.hpp>
-#include <ggl/multi/core/point_type.hpp>
+// Note that this file is, furthermore, empty,
+// there is no specialization necessary
+// as this is in fact done by for_each_range
-#include <ggl/algorithms/convex_hull.hpp>
-
-
-namespace ggl {
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace convex_hull {
-
-
-template
-<
- typename MultiGeometry,
- order_selector Order
->
-struct multi_inserter
-{
- template <typename OutputIterator>
- static inline OutputIterator apply(MultiGeometry const& multi,
- OutputIterator out)
- {
- using namespace boost;
-
- typedef typename point_type<MultiGeometry>::type point;
- typename strategy_convex_hull
- <
- typename cs_tag<point>::type,
- point
- >::type strategy;
-
- typedef typename range_const_iterator<MultiGeometry>::type iterator;
- typedef typename range_value<MultiGeometry>::type single;
- for(iterator it = begin(multi); it != end(multi); ++it)
- {
- strategy.add_range(as_range
- <typename as_range_type<single>::type>(*it));
- }
- strategy.handle_input();
-
- strategy.get(out, Order == clockwise);
- return out;
- }
-};
-
-
-
-template
-<
- typename Geometry,
- typename OutputGeometry
->
-struct multi_hull_to_geometry
-{
- static inline void apply(Geometry const& geometry, OutputGeometry& out)
- {
- multi_inserter
- <
- Geometry,
- ggl::point_order<OutputGeometry>::value
- >::apply(geometry,
- std::back_inserter(
- ggl::as_range
- <
- typename ggl::as_range_type<OutputGeometry>::type
- >(out)));
- }
-};
-
-
-}} // namespace detail::convex_hull
-
-#endif
-
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-
-// Specialize for multi's
-template
-<
- typename MultiTag,
- order_selector Order,
- typename MultiGeometry
->
-struct convex_hull_inserter<MultiTag, Order, true, MultiGeometry>
- : detail::convex_hull::multi_inserter<MultiGeometry, Order>
-{};
-
-
-// Specialize for point
-template
-<
- order_selector Order,
- typename MultiPoint
->
-struct convex_hull_inserter<multi_point_tag, Order, true, MultiPoint>
- : detail::convex_hull::hull_inserter<MultiPoint, Order>
-{};
-
-
-// Versions outputting to a ring or polygon
-template <typename MultiTag, typename MultiGeometry, typename Output>
-struct convex_hull
-<
- MultiTag, true,
- MultiGeometry, Output
->
- : detail::convex_hull::multi_hull_to_geometry<MultiGeometry, Output>
-{};
-
-
-template <typename MultiGeometry, typename Output>
-struct convex_hull
-<
- multi_point_tag, true,
- MultiGeometry, Output
->
- : detail::convex_hull::hull_to_geometry<MultiGeometry, Output>
-{};
-
-
-
-
-
-} // namespace dispatch
-#endif
-
-
-} // namespace ggl
+// Might therefore be obsoleted.
#endif // GGL_MULTI_ALGORITHMS_CONVEX_HULL_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/distance.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/distance.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/distance.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -20,6 +20,7 @@
#include <ggl/multi/core/point_type.hpp>
#include <ggl/algorithms/distance.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
namespace ggl {
@@ -39,9 +40,18 @@
using namespace boost;
return_type mindist = make_distance_result<return_type>(
- numeric::bounds<typename select_coordinate_type<Geometry, MultiGeometry>::type>::highest());
- typedef typename range_const_iterator<MultiGeometry>::type iterator;
- for(iterator it = begin(multi); it != end(multi); ++it)
+ numeric::bounds
+ <
+ typename select_coordinate_type
+ <
+ Geometry,
+ MultiGeometry
+ >::type
+ >::highest());
+
+ for(typename range_const_iterator<MultiGeometry>::type it = begin(multi);
+ it != end(multi);
+ ++it)
{
return_type dist = ggl::distance(geometry, *it);
if (dist < mindist)
@@ -64,10 +74,15 @@
{
using namespace boost;
- return_type mindist
- = make_distance_result<return_type>(
- numeric::bounds<typename select_coordinate_type<Multi1,
- Multi2>::type>::highest());
+ return_type mindist = make_distance_result<return_type>(
+ numeric::bounds
+ <
+ typename select_coordinate_type
+ <
+ Multi1,
+ Multi2
+ >::type
+ >::highest());
for(typename range_const_iterator<Multi1>::type it = begin(multi1);
it != end(multi1);
Modified: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/envelope.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/envelope.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/envelope.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -25,38 +25,36 @@
namespace detail { namespace envelope {
-template<typename MultiLinestring, typename Box, typename Strategy>
+template<typename MultiLinestring, typename Box>
struct envelope_multi_linestring
{
- static inline void apply(MultiLinestring const& mp, Box& mbr,
- Strategy const& strategy)
+ static inline void apply(MultiLinestring const& mp, Box& mbr)
{
- typename Strategy::state_type state(mbr);
+ assign_inverse(mbr);
for (typename boost::range_const_iterator<MultiLinestring>::type
it = mp.begin();
it != mp.end();
++it)
{
- envelope_range_state(*it, strategy, state);
+ envelope_range_additional(*it, mbr);
}
}
};
// version for multi_polygon: outer linear_ring's of all polygons
-template<typename MultiPolygon, typename Box, typename Strategy>
+template<typename MultiPolygon, typename Box>
struct envelope_multi_polygon
{
- static inline void apply(MultiPolygon const& mp, Box& mbr,
- Strategy const& strategy)
+ static inline void apply(MultiPolygon const& mp, Box& mbr)
{
- typename Strategy::state_type state(mbr);
+ assign_inverse(mbr);
for (typename boost::range_const_iterator<MultiPolygon>::type
it = mp.begin();
it != mp.end();
++it)
{
- envelope_range_state(exterior_ring(*it), strategy, state);
+ envelope_range_additional(exterior_ring(*it), mbr);
}
}
};
@@ -71,20 +69,32 @@
namespace dispatch
{
-template <typename Multi, typename Box, typename Strategy>
-struct envelope<multi_point_tag, box_tag, Multi, Box, Strategy>
- : detail::envelope::envelope_range<Multi, Box, Strategy>
+template
+<
+ typename Multi, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope<multi_point_tag, box_tag, Multi, Box, StrategyLess, StrategyGreater>
+ : detail::envelope::envelope_range<Multi, Box>
{};
-template <typename Multi, typename Box, typename Strategy>
-struct envelope<multi_linestring_tag, box_tag, Multi, Box, Strategy>
- : detail::envelope::envelope_multi_linestring<Multi, Box, Strategy>
+template
+<
+ typename Multi, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope<multi_linestring_tag, box_tag, Multi, Box, StrategyLess, StrategyGreater>
+ : detail::envelope::envelope_multi_linestring<Multi, Box>
{};
-template <typename Multi, typename Box, typename Strategy>
-struct envelope<multi_polygon_tag, box_tag, Multi, Box, Strategy>
- : detail::envelope::envelope_multi_polygon<Multi, Box, Strategy>
+template
+<
+ typename Multi, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope<multi_polygon_tag, box_tag, Multi, Box, StrategyLess, StrategyGreater>
+ : detail::envelope::envelope_multi_polygon<Multi, Box>
{};
Modified: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/for_each.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/for_each.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/for_each.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -37,13 +37,13 @@
struct for_each_multi
{
static inline Functor apply(
- typename c_nc<MultiGeometry, IsConst>::type& multi,
+ typename add_const_if_c<IsConst, MultiGeometry>::type& multi,
Functor f)
{
- typedef typename c_nc_range
+ typedef typename range_iterator_const_if_c
<
- MultiGeometry,
- IsConst
+ IsConst,
+ MultiGeometry
>::type iterator_type;
for(iterator_type it = boost::begin(multi);
Modified: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/get_section.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/get_section.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/get_section.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -32,7 +32,10 @@
template <typename MultiPolygon, typename Section>
struct get_section<multi_polygon_tag, MultiPolygon, Section>
{
- typedef typename ggl::vertex_iterator<MultiPolygon, true>::type iterator_type;
+ typedef typename boost::range_const_iterator
+ <
+ typename ggl::range_type<MultiPolygon>::type
+ >::type iterator_type;
static inline void apply(MultiPolygon const& multi_polygon, Section const& section,
iterator_type& begin, iterator_type& end)
Modified: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/intersection.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/intersection.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/intersection.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -36,6 +36,10 @@
// todo: implement this
};
+
+} // namespace dispatch
+#endif
+
} // namespace ggl
Modified: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/overlay/get_intersection_points.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/overlay/get_intersection_points.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/overlay/get_intersection_points.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -15,7 +15,7 @@
#include <ggl/multi/algorithms/get_section.hpp>
#include <ggl/multi/algorithms/sectionalize.hpp>
-#include <ggl/multi/iterators/vertex_iterator.hpp>
+#include <ggl/multi/iterators/range_type.hpp>
#include <ggl/algorithms/overlay/get_intersection_points.hpp>
Modified: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/simplify.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/simplify.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/simplify.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -15,7 +15,7 @@
#include <ggl/multi/core/tags.hpp>
#include <ggl/multi/core/is_multi.hpp>
-#include <ggl/multi/util/as_range.hpp>
+#include <ggl/multi/iterators/range_type.hpp>
#include <ggl/algorithms/simplify.hpp>
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/iterators/range_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/iterators/range_type.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,57 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. 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 GGL_MULTI_ITERATORS_RANGE_TYPE_HPP
+#define GGL_MULTI_ITERATORS_RANGE_TYPE_HPP
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/multi/core/is_multi.hpp>
+
+#include <ggl/iterators/range_type.hpp>
+
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// multi-point acts itself as a range
+template <typename Geometry>
+struct range_type<multi_point_tag, Geometry>
+{
+ typedef Geometry type;
+};
+
+
+template <typename Geometry>
+struct range_type<multi_linestring_tag, Geometry>
+{
+ typedef typename boost::range_value<Geometry>::type type;
+};
+
+
+template <typename Geometry>
+struct range_type<multi_polygon_tag, Geometry>
+{
+ // Call its single-version
+ typedef typename ggl::ring_type
+ <
+ typename boost::range_value<Geometry>::type
+ >::type type;
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ITERATORS_RANGE_TYPE_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/multi/iterators/vertex_iterator.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/multi/iterators/vertex_iterator.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,59 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_MULTI_ITERATORS_VERTEX_ITERATOR_HPP
-#define GGL_MULTI_ITERATORS_VERTEX_ITERATOR_HPP
-
-
-
-#include <ggl/iterators/vertex_iterator.hpp>
-
-
-namespace ggl
-{
-
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-
-template <typename MultiPolygon>
-struct vertex_iterator<multi_polygon_tag, MultiPolygon, false>
-{
- typedef typename boost::range_value<MultiPolygon>::type polygon_type;
- typedef typename boost::range_iterator
- <
- typename ggl::ring_type<polygon_type>::type
- >::type type;
-};
-
-
-template <typename MultiPolygon>
-struct vertex_iterator<multi_polygon_tag, MultiPolygon, true>
-{
- typedef typename boost::range_value<MultiPolygon>::type polygon_type;
- typedef typename boost::range_const_iterator
- <
- typename ggl::ring_type<polygon_type>::type
- >::type type;
-};
-
-
-
-
-} // namespace dispatch
-#endif
-
-
-
-}
-
-
-#endif // GGL_MULTI_ITERATORS_VERTEX_ITERATOR_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/multi.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,58 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Mateusz Loskot 2009
+// 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 GGL_MULTI_HPP
+#define GGL_MULTI_HPP
+
+
+#include <ggl/multi/core/geometry_id.hpp>
+#include <ggl/multi/core/is_multi.hpp>
+#include <ggl/multi/core/point_type.hpp>
+#include <ggl/multi/core/ring_type.hpp>
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/multi/core/topological_dimension.hpp>
+
+
+#include <ggl/multi/algorithms/area.hpp>
+#include <ggl/multi/algorithms/centroid.hpp>
+#include <ggl/multi/algorithms/convex_hull.hpp>
+#include <ggl/multi/algorithms/correct.hpp>
+#include <ggl/multi/algorithms/distance.hpp>
+#include <ggl/multi/algorithms/envelope.hpp>
+#include <ggl/multi/algorithms/for_each.hpp>
+#include <ggl/multi/algorithms/get_section.hpp>
+#include <ggl/multi/algorithms/intersection.hpp>
+#include <ggl/multi/algorithms/length.hpp>
+#include <ggl/multi/algorithms/num_points.hpp>
+#include <ggl/multi/algorithms/perimeter.hpp>
+#include <ggl/multi/algorithms/remove_holes_if.hpp>
+#include <ggl/multi/algorithms/sectionalize.hpp>
+#include <ggl/multi/algorithms/simplify.hpp>
+#include <ggl/multi/algorithms/transform.hpp>
+#include <ggl/multi/algorithms/within.hpp>
+#include <ggl/multi/algorithms/detail/modify_with_predicate.hpp>
+#include <ggl/multi/algorithms/detail/multi_sum.hpp>
+#include <ggl/multi/algorithms/overlay/copy_segments.hpp>
+#include <ggl/multi/algorithms/overlay/get_intersection_points.hpp>
+
+
+#include <ggl/multi/geometries/multi_linestring.hpp>
+#include <ggl/multi/geometries/multi_point.hpp>
+#include <ggl/multi/geometries/multi_polygon.hpp>
+
+#include <ggl/multi/iterators/range_type.hpp>
+
+#include <ggl/multi/strategies/centroid.hpp>
+#include <ggl/multi/strategies/cartesian/centroid_average.hpp>
+
+#include <ggl/multi/util/write_dsv.hpp>
+
+
+
+#endif // GGL_MULTI_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/strategies/cartesian/centroid_average.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/strategies/cartesian/centroid_average.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,96 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_MULTI_STRATEGIES_CARTESIAN_CENTROID_AVERAGE_HPP
+#define GGL_MULTI_STRATEGIES_CARTESIAN_CENTROID_AVERAGE_HPP
+
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/type_traits.hpp>
+
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/arithmetic/arithmetic.hpp>
+#include <ggl/strategies/centroid.hpp>
+#include <ggl/util/copy.hpp>
+
+
+namespace ggl
+{
+
+namespace strategy { namespace centroid_ {
+
+
+template
+<
+ typename PointCentroid,
+ typename Point = PointCentroid
+>
+class centroid_average
+{
+private :
+
+ /*! subclass to keep state */
+ class sum
+ {
+ friend class centroid_average;
+ int count;
+ PointCentroid centroid;
+
+ public :
+ inline sum()
+ : count(0)
+ {
+ assign_zero(centroid);
+ }
+ };
+
+public :
+ typedef sum state_type;
+ typedef PointCentroid centroid_point_type;
+ typedef Point point_type;
+
+ static inline void apply(Point const& p, sum& state)
+ {
+ add_point(state.centroid, p);
+ state.count++;
+ }
+
+ static inline void result(sum const& state, PointCentroid& centroid)
+ {
+ centroid = state.centroid;
+ divide_value(centroid, state.count);
+ }
+
+};
+
+
+}} // namespace strategy::centroid
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+
+template <typename Point, typename Geometry>
+struct strategy_centroid<cartesian_tag, multi_point_tag, 2, Point, Geometry>
+{
+ typedef strategy::centroid_::centroid_average
+ <
+ Point,
+ typename point_type<Geometry>::type
+ > type;
+};
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_STRATEGIES_CARTESIAN_CENTROID_AVERAGE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/strategies/centroid.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/strategies/centroid.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,38 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_MULTI_STRATEGY_CENTROID_HPP
+#define GGL_MULTI_STRATEGY_CENTROID_HPP
+
+#include <ggl/strategies/cartesian/centroid_bashein_detmer.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+template <typename Point, typename Geometry>
+struct strategy_centroid<cartesian_tag, multi_polygon_tag, 2, Point, Geometry>
+{
+ typedef strategy::centroid_::bashein_detmer
+ <
+ Point,
+ typename point_type<Geometry>::type
+ > type;
+};
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_STRATEGY_CENTROID_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/multi/util/as_range.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/multi/util/as_range.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,40 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. 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 GGL_MULTI_UTIL_AS_RANGE_HPP
-#define GGL_MULTI_UTIL_AS_RANGE_HPP
-
-
-#include <boost/range/functions.hpp>
-#include <boost/range/metafunctions.hpp>
-
-#include <ggl/multi/core/is_multi.hpp>
-
-#include <ggl/util/as_range.hpp>
-
-namespace ggl {
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-
-template <typename Tag, typename Geometry>
-struct as_range_type<Tag, true, Geometry>
-{
- typedef typename ggl::as_range_type
- <
- typename boost::range_value<Geometry>::type
- > type;
-};
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-} // namespace ggl
-
-#endif // GGL_MULTI_UTIL_AS_RANGE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/util/for_each_range.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/util/for_each_range.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,81 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_MULTI_UTIL_FOR_EACH_RANGE_HPP
+#define GGL_MULTI_UTIL_FOR_EACH_RANGE_HPP
+
+
+#include <ggl/util/for_each_range.hpp>
+#include <ggl/util/range_iterator_const_if_c.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace for_each {
+
+
+template <typename Multi, typename Actor, bool IsConst>
+struct fe_range_multi
+{
+ static inline void apply(
+ typename add_const_if_c<IsConst, Multi>::type& multi,
+ Actor& actor)
+ {
+ for (typename range_iterator_const_if_c<IsConst, Multi>::type
+ it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ ggl::for_each_range(*it, actor);
+ }
+ }
+};
+
+
+
+}} // namespace detail::for_each
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Geometry, typename Actor, bool IsConst>
+struct for_each_range<multi_linestring_tag, true, Geometry, Actor, IsConst>
+ : detail::for_each::fe_range_multi<Geometry, Actor, IsConst>
+{};
+
+
+template <typename Geometry, typename Actor, bool IsConst>
+struct for_each_range<multi_polygon_tag, true, Geometry, Actor, IsConst>
+ : detail::for_each::fe_range_multi<Geometry, Actor, IsConst>
+{};
+
+
+template <typename MultiPoint, typename Actor, bool IsConst>
+struct for_each_range<multi_point_tag, true, MultiPoint, Actor, IsConst>
+ : detail::for_each::fe_range_range<MultiPoint, Actor, IsConst>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_UTIL_FOR_EACH_RANGE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/policies/compare.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/policies/compare.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,205 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2009, 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 GGL_POLICIES_COMPARE_HPP
+#define GGL_POLICIES_COMPARE_HPP
+
+
+#include <ggl/strategies/compare.hpp>
+#include <ggl/util/math.hpp>
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace compare {
+
+
+template
+<
+ int Direction,
+ typename Point,
+ typename Strategy,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct compare_loop
+{
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ Strategy, Direction, Point, Dimension
+ >::type compare_type;
+
+ typedef typename ggl::coordinate_type<Point>::type coordinate_type;
+
+ static inline bool apply(Point const& left, Point const& right)
+ {
+ coordinate_type const& cleft = ggl::get<Dimension>(left);
+ coordinate_type const& cright = ggl::get<Dimension>(right);
+
+ if (ggl::math::equals(cleft, cright))
+ {
+ return compare_loop
+ <
+ Direction, Point, Strategy,
+ Dimension + 1, DimensionCount
+ >::apply(left, right);
+ }
+ else
+ {
+ compare_type compare;
+ return compare(cleft, cright);
+ }
+ }
+};
+
+template
+<
+ int Direction,
+ typename Point,
+ typename Strategy,
+ std::size_t DimensionCount
+>
+struct compare_loop<Direction, Point, Strategy, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Point const&, Point const&)
+ {
+ return false;
+ }
+};
+
+
+template <int Direction, typename Point, typename Strategy>
+struct compare_in_all_dimensions
+{
+ inline bool operator()(Point const& left, Point const& right) const
+ {
+ return detail::compare::compare_loop
+ <
+ Direction, Point, Strategy,
+ 0, ggl::dimension<Point>::type::value
+ >::apply(left, right);
+ }
+};
+
+
+template
+<
+ typename Point,
+ typename Strategy,
+ std::size_t Dimension
+>
+class compare_in_one_dimension
+{
+ Strategy compare;
+
+public :
+ inline bool operator()(Point const& left, Point const& right) const
+ {
+ typedef typename ggl::coordinate_type<Point>::type coordinate_type;
+
+ coordinate_type const& cleft = get<Dimension>(left);
+ coordinate_type const& cright = get<Dimension>(right);
+ return compare(cleft, cright);
+ }
+};
+
+}} // namespace detail::compare
+
+#endif
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ int Direction,
+ typename Point,
+ typename Strategy,
+ int Dimension
+>
+struct compare_geometries
+ : detail::compare::compare_in_one_dimension
+ <
+ Point,
+ typename strategy::compare::detail::select_strategy
+ <
+ Strategy, Direction, Point, Dimension
+ >::type,
+ Dimension
+ >
+{};
+
+
+// Specialization with -1: compare in all dimensions
+template <int Direction, typename Point, typename Strategy>
+struct compare_geometries<Direction, Point, Strategy, -1>
+ : detail::compare::compare_in_all_dimensions<Direction, Point, Strategy>
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+ \brief Less functor, to sort points in ascending order.
+ \details This functor compares points and orders them on x,
+ then on y, then on z coordinate.
+ \tparam Geometry the geometry
+ \tparam Dimension the dimension to sort on, defaults to -1,
+ indicating ALL dimensions. That's to say, first on x,
+ on equal x-es then on y, etc.
+ If a dimension is specified, only that dimension is considered
+ \tparam Strategy, defaults to the default comparison strategies
+ related to the point coordinate system. If specified, the specified
+ strategy is used. This can e.g. be std::less<double>.
+*/
+template
+<
+ typename Point,
+ int Dimension = -1,
+ typename Strategy = strategy::compare::default_strategy
+>
+struct less
+ : dispatch::compare_geometries
+ <
+ 1, // indicates ascending
+ Point,
+ Strategy,
+ Dimension
+ >
+{};
+
+
+/*!
+ \brief Greater functor
+ \see Less functor
+*/
+template
+<
+ typename Point,
+ int Dimension = -1,
+ typename Strategy = strategy::compare::default_strategy
+>
+struct greater
+ : dispatch::compare_geometries
+ <
+ -1, // indicates descending
+ Point,
+ Strategy,
+ Dimension
+ >
+{};
+
+
+} // namespace ggl
+
+#endif // GGL_POLICIES_COMPARE_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_convex_hull.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_convex_hull.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,305 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_STRATEGIES_AGNOSTIC_CONVEX_HULL_HPP
-#define GGL_STRATEGIES_AGNOSTIC_CONVEX_HULL_HPP
-
-
-#include <cstddef>
-#include <algorithm>
-#include <vector>
-
-#include <boost/range/functions.hpp>
-#include <boost/concept_check.hpp> // for ignore-variable
-
-#include <ggl/core/cs.hpp>
-#include <ggl/strategies/strategy_traits.hpp>
-
-#include <ggl/util/less.hpp>
-
-
-
-// TODO: Temporary, comparing tests, this can be removed in the end
-#if defined(GGL_USE_SMOOTH_SORT)
-# include "SmoothSort.hpp"
-#elif defined(GGL_USE_MERGE_SORT)
-# include "MergeSort.hpp"
-#else
-#endif
-
-namespace ggl
-{
-
-namespace strategy { namespace convex_hull {
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail
-{
-
-template <typename Range, typename RangeIterator, typename Strategy>
-static inline void get_extremes(const Range& range,
- RangeIterator& min_it, RangeIterator& max_it,
- const Strategy& strategy)
-{
- min_it = boost::begin(range);
- max_it = boost::begin(range);
-
- for (RangeIterator it = boost::begin(range) + 1; it != boost::end(range); ++it)
- {
- if (strategy.smaller(*it, *min_it))
- {
- min_it = it;
- }
-
- if (strategy.larger(*it, *max_it))
- {
- max_it = it;
- }
- }
-}
-
-template <typename R>
-static inline void sort(R& range)
-{
- typedef typename boost::range_value<R>::type point_type;
-
-#if defined(USE_SMOOTH_SORT)
- smoothsort::sort
-#elif defined(USE_MERGE_SORT)
- comparing::merge_sort<thread_count>
-#else
- std::sort
-#endif
-
- (boost::begin(range), boost::end(range), ggl::less<point_type>());
-}
-
-} // namespace detail
-#endif // DOXYGEN_NO_DETAIL
-
-
-// Completely reworked version from source at:
-// http://www.ddj.com/architect/201806315
-// also available at http://marknelson.us/2007/08/22/convex
-template <typename P>
-class graham
-{
-private:
-
- typedef typename cs_tag<P>::type cs_tag;
- typedef typename std::vector<P> container;
- typedef typename std::vector<P>::const_iterator iterator;
- typedef typename std::vector<P>::const_reverse_iterator rev_iterator;
-
- container m_lower_hull;
- container m_upper_hull;
- container m_copied_input;
-
-
-public:
-
- // Default constructor, ranges can be added using "add_range" but note they'll be copied
- inline graham()
- {
- }
-
- // Constructor with a range
- template <typename Range>
- inline graham(const Range& range)
- {
- handle_range(range);
- }
-
-
- template <typename OutputIterator>
- inline void get(OutputIterator out, bool clockwise)
- {
- if (clockwise)
- {
- get_range_forward(m_upper_hull, out);
- get_range_reverse(m_lower_hull, out);
- }
- else
- {
- get_range_forward(m_lower_hull, out);
- get_range_reverse(m_upper_hull, out);
- }
- }
-
-
- // TODO:
- // Consider if it is better to create an iterator over a multi, which is then used here,
- // instead of copying the range
- // It makes it slightly more complicated but avoids the copy, which is attractive because
- // multi-polygons (where it is used for) can be large.
- template <typename Range>
- inline void add_range(const Range& range)
- {
- std::copy(boost::begin(range), boost::end(range), std::back_inserter(m_copied_input));
- }
-
- inline void handle_input()
- {
- handle_range(m_copied_input);
- }
-
-
-private:
-
- template <typename Range>
- inline void handle_range(const Range& range)
- {
- typedef typename boost::range_const_iterator<Range>::type range_iterator;
-
- // Polygons with three corners, or closed with 4 points, are always convex
- if (boost::size(range) <= 3)
- {
- for (range_iterator it = boost::begin(range);
- it != boost::end(range);
- ++it)
- {
- m_upper_hull.push_back(*it);
- }
- return;
- }
-
- // Get min/max (in most cases left / right) points
- range_iterator left_it, right_it;
- typename strategy_compare<cs_tag, P, 0>::type comparing;
- detail::get_extremes(range, left_it, right_it, comparing);
-
- // Bounding left/right points
- container lower_points, upper_points;
-
- assign_range(range, left_it, right_it, lower_points, upper_points);
-
- detail::sort(lower_points);
- detail::sort(upper_points);
-
- build_half_hull<-1>(lower_points, m_lower_hull, *left_it, *right_it);
- build_half_hull<1>(upper_points, m_upper_hull, *left_it, *right_it);
- }
-
-
-
- template <typename RangeIterator, typename Range>
- inline void assign_range(const Range& range,
- const RangeIterator& left_it,
- const RangeIterator& right_it,
- container& lower_points,
- container& upper_points)
- {
- typename strategy_side<cs_tag, P>::type side;
- boost::ignore_unused_variable_warning(side);
-
- // Put points in one of the two output sequences
- for (RangeIterator it = boost::begin(range);
- it != boost::end(range);
- ++it)
- {
- if (it != left_it && it != right_it)
- {
- int dir = side.side(*left_it, *right_it, *it);
- switch(dir)
- {
- case 1 : // left
- upper_points.push_back(*it);
- break;
- case -1 : // right
- lower_points.push_back(*it);
- break;
- // zero: on line left-right, never part of hull
- }
- }
- }
- }
-
-
- template <int Factor>
- inline void build_half_hull(const container& input, container& output,
- const P& left, const P& right)
- {
- output.push_back(left);
- for(iterator it = input.begin(); it != input.end(); ++it)
- {
- add_to_hull<Factor>(*it, output);
- }
- add_to_hull<Factor>(right, output);
- }
-
- template <int Factor>
- inline void add_to_hull(const P& p, container& output)
- {
- typename strategy_side<cs_tag, P>::type side;
- boost::ignore_unused_variable_warning(side);
-
- output.push_back(p);
- register std::size_t output_size = output.size();
- while (output_size >= 3)
- {
- rev_iterator rit = output.rbegin();
- const P& last = *rit++;
- const P& last2 = *rit++;
-
- if (Factor * side.side(*rit, last, last2) <= 0)
- {
- // Remove last two points from stack, and add last again
- // This is much faster then erasing the one but last.
- output.pop_back();
- output.pop_back();
- output.push_back(last);
- output_size--;
- }
- else
- {
- return;
- }
- }
- }
-
- template <typename Range, typename OutputIterator>
- inline void get_range_forward(Range const& range, OutputIterator out)
- {
- for (iterator it = range.begin(); it != range.end(); ++it, ++out)
- {
- *out = *it;
- }
- }
-
- template <typename Range, typename OutputIterator>
- inline void get_range_reverse(Range const& range, OutputIterator out)
- {
- // STL Port does not accept iterating from rbegin+1 to rend
- std::size_t size = range.size();
- if (size > 0)
- {
- rev_iterator it = range.rbegin() + 1;
- for (std::size_t i = 1; i < size; ++i, ++it, ++out)
- {
- *out = *it;
- }
- }
- }
-
-};
-
-}} // namespace strategy::convex_hull
-
-
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-template <typename P>
-struct strategy_convex_hull<cartesian_tag, P>
-{
- typedef strategy::convex_hull::graham<P> type;
-};
-#endif
-
-} // namespace ggl
-
-
-#endif // GGL_STRATEGY_AGNOSTIC_CONVEX_HULL_HPP
Copied: sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/hull_graham_andrew.hpp (from r57036, /sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_convex_hull.hpp)
==============================================================================
--- /sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_convex_hull.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/hull_graham_andrew.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -1,13 +1,12 @@
// Generic Geometry Library
//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 2009, Geodan, 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 GGL_STRATEGIES_AGNOSTIC_CONVEX_HULL_HPP
-#define GGL_STRATEGIES_AGNOSTIC_CONVEX_HULL_HPP
+#ifndef GGL_STRATEGIES_AGNOSTIC_CONVEX_GRAHAM_ANDREW_HPP
+#define GGL_STRATEGIES_AGNOSTIC_CONVEX_GRAHAM_ANDREW_HPP
#include <cstddef>
@@ -15,16 +14,20 @@
#include <vector>
#include <boost/range/functions.hpp>
-#include <boost/concept_check.hpp> // for ignore-variable
+#include <boost/range/metafunctions.hpp>
#include <ggl/core/cs.hpp>
-#include <ggl/strategies/strategy_traits.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/strategies/convex_hull.hpp>
-#include <ggl/util/less.hpp>
+#include <ggl/iterators/range_type.hpp>
+#include <ggl/policies/compare.hpp>
+#include <ggl/util/for_each_range.hpp>
-// TODO: Temporary, comparing tests, this can be removed in the end
+
+// Temporary, comparing tests, this can be removed in the end
#if defined(GGL_USE_SMOOTH_SORT)
# include "SmoothSort.hpp"
#elif defined(GGL_USE_MERGE_SORT)
@@ -41,32 +44,136 @@
namespace detail
{
-template <typename Range, typename RangeIterator, typename Strategy>
-static inline void get_extremes(const Range& range,
- RangeIterator& min_it, RangeIterator& max_it,
- const Strategy& strategy)
+
+template
+<
+ typename InputRange,
+ typename RangeIterator,
+ typename StrategyLess,
+ typename StrategyGreater
+>
+struct get_extremes
{
- min_it = boost::begin(range);
- max_it = boost::begin(range);
+ typedef typename point_type<InputRange>::type point_type;
+
+ point_type left, right;
+
+ bool first;
- for (RangeIterator it = boost::begin(range) + 1; it != boost::end(range); ++it)
+ StrategyLess less;
+ StrategyGreater greater;
+
+ get_extremes()
+ : first(true)
+ {}
+
+ inline void apply(InputRange const& range)
{
- if (strategy.smaller(*it, *min_it))
+ // First iterate through this range
+ // (this two-stage approach avoids many point copies,
+ // because iterators are kept in memory. Because iterators are
+ // not persistent (in MSVC) this approach is not applicable
+ // for more ranges together)
+
+ RangeIterator left_it = boost::begin(range);
+ RangeIterator right_it = boost::begin(range);
+
+ for (RangeIterator it = boost::begin(range) + 1;
+ it != boost::end(range);
+ ++it)
{
- min_it = it;
+ if (less(*it, *left_it))
+ {
+ left_it = it;
+ }
+
+ if (greater(*it, *right_it))
+ {
+ right_it = it;
+ }
}
- if (strategy.larger(*it, *max_it))
+ // Then compare with earlier
+ if (first && boost::size(range) > 0)
{
- max_it = it;
+ // First time, assign left/right
+ left = *left_it;
+ right = *right_it;
+ first = false;
+ }
+ else
+ {
+ // Next time, check if this range was left/right from
+ // the extremes already collected
+ if (less(*left_it, left))
+ {
+ left = *left_it;
+ }
+
+ if (greater(*right_it, right))
+ {
+ right = *right_it;
+ }
}
}
-}
+};
+
-template <typename R>
-static inline void sort(R& range)
+template
+<
+ typename InputRange,
+ typename RangeIterator,
+ typename Container,
+ typename SideStrategy
+>
+struct assign_range
{
- typedef typename boost::range_value<R>::type point_type;
+ Container lower_points, upper_points;
+
+ typedef typename point_type<InputRange>::type point_type;
+
+ point_type const& most_left;
+ point_type const& most_right;
+
+ inline assign_range(point_type const& left, point_type const& right)
+ : most_left(left)
+ , most_right(right)
+ {}
+
+ inline void apply(InputRange const& range)
+ {
+ typedef SideStrategy side;
+
+ // Put points in one of the two output sequences
+ for (RangeIterator it = boost::begin(range);
+ it != boost::end(range);
+ ++it)
+ {
+ // check if it is lying most_left or most_right from the line
+
+ int dir = side::apply(most_left, most_right, *it);
+ switch(dir)
+ {
+ case 1 : // left side
+ upper_points.push_back(*it);
+ break;
+ case -1 : // right side
+ lower_points.push_back(*it);
+ break;
+
+ // 0: on line most_left-most_right,
+ // or most_left, or most_right,
+ // -> all never part of hull
+ }
+ }
+ }
+};
+
+
+template <typename Range>
+static inline void sort(Range& range)
+{
+ typedef typename boost::range_value<Range>::type point_type;
#if defined(USE_SMOOTH_SORT)
smoothsort::sort
@@ -79,150 +186,121 @@
(boost::begin(range), boost::end(range), ggl::less<point_type>());
}
+
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
-// Completely reworked version from source at:
-// http://www.ddj.com/architect/201806315
-// also available at http://marknelson.us/2007/08/22/convex
-template <typename P>
-class graham
+/*!
+ \brief Graham scan strategy to calculate convex hull
+ \ingroup convex_hull
+ \note Completely reworked version inspired on the sources listed below
+ \see http://www.ddj.com/architect/201806315
+ \see http://marknelson.us/2007/08/22/convex
+
+ */
+template <typename InputGeometry, typename OutputPoint>
+class graham_andrew
{
-private:
+public :
+ typedef OutputPoint point_type;
+ typedef InputGeometry geometry_type;
- typedef typename cs_tag<P>::type cs_tag;
- typedef typename std::vector<P> container;
- typedef typename std::vector<P>::const_iterator iterator;
- typedef typename std::vector<P>::const_reverse_iterator rev_iterator;
-
- container m_lower_hull;
- container m_upper_hull;
- container m_copied_input;
-
-
-public:
+private:
- // Default constructor, ranges can be added using "add_range" but note they'll be copied
- inline graham()
- {
- }
+ typedef typename cs_tag<point_type>::type cs_tag;
- // Constructor with a range
- template <typename Range>
- inline graham(const Range& range)
- {
- handle_range(range);
- }
+ typedef typename std::vector<point_type> container_type;
+ typedef typename std::vector<point_type>::const_iterator iterator;
+ typedef typename std::vector<point_type>::const_reverse_iterator rev_iterator;
- template <typename OutputIterator>
- inline void get(OutputIterator out, bool clockwise)
+ class partitions
{
- if (clockwise)
- {
- get_range_forward(m_upper_hull, out);
- get_range_reverse(m_lower_hull, out);
- }
- else
- {
- get_range_forward(m_lower_hull, out);
- get_range_reverse(m_upper_hull, out);
- }
- }
+ friend class graham_andrew;
+ container_type m_lower_hull;
+ container_type m_upper_hull;
+ container_type m_copied_input;
+ };
- // TODO:
- // Consider if it is better to create an iterator over a multi, which is then used here,
- // instead of copying the range
- // It makes it slightly more complicated but avoids the copy, which is attractive because
- // multi-polygons (where it is used for) can be large.
- template <typename Range>
- inline void add_range(const Range& range)
- {
- std::copy(boost::begin(range), boost::end(range), std::back_inserter(m_copied_input));
- }
-
- inline void handle_input()
- {
- handle_range(m_copied_input);
- }
+public:
+ typedef partitions state_type;
-private:
- template <typename Range>
- inline void handle_range(const Range& range)
+ inline void apply(InputGeometry const& geometry, partitions& state) const
{
- typedef typename boost::range_const_iterator<Range>::type range_iterator;
-
- // Polygons with three corners, or closed with 4 points, are always convex
- if (boost::size(range) <= 3)
- {
- for (range_iterator it = boost::begin(range);
- it != boost::end(range);
- ++it)
- {
- m_upper_hull.push_back(*it);
- }
- return;
- }
-
+ // First pass.
// Get min/max (in most cases left / right) points
- range_iterator left_it, right_it;
- typename strategy_compare<cs_tag, P, 0>::type comparing;
- detail::get_extremes(range, left_it, right_it, comparing);
-
- // Bounding left/right points
- container lower_points, upper_points;
+ // This makes use of the ggl::less/greater predicates with the optional
+ // direction template parameter to indicate x direction
- assign_range(range, left_it, right_it, lower_points, upper_points);
+ typedef typename range_type<InputGeometry>::type range_type;
- detail::sort(lower_points);
- detail::sort(upper_points);
+ typedef typename boost::range_const_iterator
+ <
+ range_type
+ >::type range_iterator;
+
+ detail::get_extremes
+ <
+ range_type,
+ range_iterator,
+ ggl::less<point_type, 0>,
+ ggl::greater<point_type, 0>
+ > extremes;
+ ggl::for_each_range(geometry, extremes);
- build_half_hull<-1>(lower_points, m_lower_hull, *left_it, *right_it);
- build_half_hull<1>(upper_points, m_upper_hull, *left_it, *right_it);
+ // Bounding left/right points
+ // Second pass, now that extremes are found, assign all points
+ // in either lower, either upper
+ detail::assign_range
+ <
+ range_type,
+ range_iterator,
+ container_type,
+ typename strategy_side<cs_tag>::type
+ > assigner(extremes.left, extremes.right);
+
+ ggl::for_each_range(geometry, assigner);
+
+
+ // Sort both collections, first on x(, then on y)
+ detail::sort(assigner.lower_points);
+ detail::sort(assigner.upper_points);
+
+ // And decide which point should be in the final hull
+ build_half_hull<-1>(assigner.lower_points, state.m_lower_hull,
+ extremes.left, extremes.right);
+ build_half_hull<1>(assigner.upper_points, state.m_upper_hull,
+ extremes.left, extremes.right);
}
-
- template <typename RangeIterator, typename Range>
- inline void assign_range(const Range& range,
- const RangeIterator& left_it,
- const RangeIterator& right_it,
- container& lower_points,
- container& upper_points)
+ template <typename OutputIterator>
+ inline void result(partitions const& state,
+ OutputIterator out, bool clockwise) const
{
- typename strategy_side<cs_tag, P>::type side;
- boost::ignore_unused_variable_warning(side);
-
- // Put points in one of the two output sequences
- for (RangeIterator it = boost::begin(range);
- it != boost::end(range);
- ++it)
+ if (clockwise)
{
- if (it != left_it && it != right_it)
- {
- int dir = side.side(*left_it, *right_it, *it);
- switch(dir)
- {
- case 1 : // left
- upper_points.push_back(*it);
- break;
- case -1 : // right
- lower_points.push_back(*it);
- break;
- // zero: on line left-right, never part of hull
- }
- }
+ get_range_forward(state.m_upper_hull, out);
+ get_range_reverse(state.m_lower_hull, out);
+ }
+ else
+ {
+ get_range_forward(state.m_lower_hull, out);
+ get_range_reverse(state.m_upper_hull, out);
}
}
+private:
+
template <int Factor>
- inline void build_half_hull(const container& input, container& output,
- const P& left, const P& right)
+ static inline void build_half_hull(container_type const& input,
+ container_type& output,
+ point_type const& left, point_type const& right)
{
output.push_back(left);
for(iterator it = input.begin(); it != input.end(); ++it)
@@ -232,21 +310,21 @@
add_to_hull<Factor>(right, output);
}
+
template <int Factor>
- inline void add_to_hull(const P& p, container& output)
+ static inline void add_to_hull(point_type const& p, container_type& output)
{
- typename strategy_side<cs_tag, P>::type side;
- boost::ignore_unused_variable_warning(side);
+ typedef typename strategy_side<cs_tag>::type side;
output.push_back(p);
register std::size_t output_size = output.size();
while (output_size >= 3)
{
rev_iterator rit = output.rbegin();
- const P& last = *rit++;
- const P& last2 = *rit++;
+ point_type const& last = *rit++;
+ point_type const& last2 = *rit++;
- if (Factor * side.side(*rit, last, last2) <= 0)
+ if (Factor * side::apply(*rit, last, last2) <= 0)
{
// Remove last two points from stack, and add last again
// This is much faster then erasing the one but last.
@@ -262,17 +340,21 @@
}
}
- template <typename Range, typename OutputIterator>
- inline void get_range_forward(Range const& range, OutputIterator out)
+
+ template <typename OutputIterator>
+ static inline void get_range_forward(container_type const& range, OutputIterator out)
{
- for (iterator it = range.begin(); it != range.end(); ++it, ++out)
+ for (iterator it = boost::begin(range);
+ it != boost::end(range);
+ ++it, ++out)
{
*out = *it;
}
}
- template <typename Range, typename OutputIterator>
- inline void get_range_reverse(Range const& range, OutputIterator out)
+
+ template <typename OutputIterator>
+ static inline void get_range_reverse(container_type const& range, OutputIterator out)
{
// STL Port does not accept iterating from rbegin+1 to rend
std::size_t size = range.size();
@@ -292,14 +374,14 @@
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-template <typename P>
-struct strategy_convex_hull<cartesian_tag, P>
+template <typename InputGeometry, typename OutputPoint>
+struct strategy_convex_hull<cartesian_tag, InputGeometry, OutputPoint>
{
- typedef strategy::convex_hull::graham<P> type;
+ typedef strategy::convex_hull::graham_andrew<InputGeometry, OutputPoint> type;
};
#endif
} // namespace ggl
-#endif // GGL_STRATEGY_AGNOSTIC_CONVEX_HULL_HPP
+#endif // GGL_STRATEGIES_AGNOSTIC_CONVEX_GRAHAM_ANDREW_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/point_in_poly_winding.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/point_in_poly_winding.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/point_in_poly_winding.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -13,7 +13,7 @@
#include <ggl/util/select_calculation_type.hpp>
-#include <ggl/strategies/strategy_traits.hpp>
+#include <ggl/strategies/point_in_poly.hpp>
@@ -49,9 +49,7 @@
typedef typename strategy_side
<
- typename cs_tag<Point>::type,
- Point,
- PointOfSegment
+ typename cs_tag<Point>::type
>::type strategy_side_type;
@@ -137,7 +135,7 @@
int count = check_segment<1>(point, s1, s2, state);
if (count != 0)
{
- int side = strategy_side_type::side(s1, s2, point);
+ int side = strategy_side_type::apply(s1, s2, point);
if (side == 0)
{
// Point is lying on segment
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/simplify_douglas_peucker.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/simplify_douglas_peucker.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/simplify_douglas_peucker.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -13,7 +13,6 @@
#include <boost/range/functions.hpp>
#include <ggl/core/cs.hpp>
-#include <ggl/geometries/segment.hpp>
#include <ggl/strategies/distance_result.hpp>
#include <ggl/util/copy.hpp>
@@ -66,14 +65,14 @@
/*!
\brief Implements the simplify algorithm.
\ingroup simplify
- \details The douglas_peucker strategy simplifies a linestring, ring or
- vector of points using the well-known Douglas-Peucker algorithm.
+ \details The douglas_peucker strategy simplifies a linestring, ring or
+ vector of points using the well-known Douglas-Peucker algorithm.
For the algorithm, see for example:
\see http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
\see http://www2.dcs.hull.ac.uk/CISRG/projects/Royal-Inst/demos/dp.html
\tparam Point the point type
\tparam PointDistanceStrategy point-segment distance strategy to be used
- \note This strategy uses itself a point-segment-distance strategy which
+ \note This strategy uses itself a point-segment-distance strategy which
can be specified
\author Barend and Maarten, 1995/1996
\author Barend, revised for Generic Geometry Library, 2008
@@ -93,7 +92,7 @@
static inline void consider(iterator_type begin,
iterator_type end,
return_type const& max_dist, int& n,
- PointDistanceStrategy const& ps_distance_strategy)
+ PointDistanceStrategy const& ps_distance_strategy)
{
std::size_t size = end - begin;
@@ -123,17 +122,17 @@
// Find most distance point, compare to the current segment
- ggl::segment<const Point> s(begin->p, last->p);
+ //ggl::segment<const Point> s(begin->p, last->p);
return_type md(-1.0); // any value < 0
iterator_type candidate;
for(iterator_type it = begin + 1; it != last; ++it)
{
- return_type dist = ps_distance_strategy(it->p, s);
+ return_type dist = ps_distance_strategy.apply(it->p, begin->p, last->p);
#ifdef GL_DEBUG_DOUGLAS_PEUCKER
std::cout << "consider " << dsv(it->p)
<< " at " << double(dist)
- << ((dist > max_dist) ? " maybe" : " no")
+ << ((dist > max_dist) ? " maybe" : " no")
<< std::endl;
#endif
@@ -144,7 +143,7 @@
}
}
- // If a point is found, set the include flag
+ // If a point is found, set the include flag
// and handle segments in between recursively
if (md > max_dist)
{
@@ -167,22 +166,22 @@
template <typename Range, typename OutputIterator>
- static inline OutputIterator apply(Range const& range,
- OutputIterator out, double max_distance)
+ static inline OutputIterator apply(Range const& range,
+ OutputIterator out, double max_distance)
{
PointDistanceStrategy strategy;
// Copy coordinates, a vector of references to all points
- std::vector<dp_point_type> ref_candidates(boost::begin(range),
+ std::vector<dp_point_type> ref_candidates(boost::begin(range),
boost::end(range));
- // Include first and last point of line,
+ // Include first and last point of line,
// they are always part of the line
int n = 2;
ref_candidates.front().included = true;
ref_candidates.back().included = true;
- // Get points, recursively, including them if they are further away
+ // Get points, recursively, including them if they are further away
// than the specified distance
typedef typename PointDistanceStrategy::return_type return_type;
@@ -190,9 +189,9 @@
make_distance_result<return_type>(max_distance), n, strategy);
// Copy included elements to the output
- for(typename std::vector<dp_point_type>::const_iterator it
+ for(typename std::vector<dp_point_type>::const_iterator it
= boost::begin(ref_candidates);
- it != boost::end(ref_candidates);
+ it != boost::end(ref_candidates);
++it)
{
if (it->included)
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/area.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/area.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,34 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_STRATEGIES_AREA_HPP
+#define GGL_STRATEGIES_AREA_HPP
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+ \brief Traits class binding an area strategy to a coordinate system
+ \ingroup area
+ \tparam Tag tag of coordinate system
+ \tparam PointOfSegment point-type
+*/
+template <typename Tag, typename PointOfSegment>
+struct strategy_area
+{
+ typedef strategy::not_implemented type;
+};
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_AREA_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/area_result.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/area_result.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/area_result.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -5,13 +5,14 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_AREA_RESULT_HPP
-#define GGL_AREA_RESULT_HPP
+#ifndef GGL_STRATEGIES_AREA_RESULT_HPP
+#define GGL_STRATEGIES_AREA_RESULT_HPP
+#include <ggl/core/cs.hpp>
#include <ggl/core/coordinate_type.hpp>
+#include <ggl/strategies/area.hpp>
#include <ggl/util/select_most_precise.hpp>
-#include <ggl/strategies/strategies.hpp>
namespace ggl
@@ -41,4 +42,4 @@
} // namespace ggl
-#endif // GGL_AREA_RESULT_HPP
+#endif // GGL_STRATEGIES_AREA_RESULT_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/area_by_triangles.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/area_by_triangles.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/area_by_triangles.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_STRATEGY_CARTESIAN_AREA_BY_TRIANGLES_HPP
-#define GGL_STRATEGY_CARTESIAN_AREA_BY_TRIANGLES_HPP
+#ifndef GGL_STRATEGIES_CARTESIAN_AREA_BY_TRIANGLES_HPP
+#define GGL_STRATEGIES_CARTESIAN_AREA_BY_TRIANGLES_HPP
#include <boost/mpl/if.hpp>
@@ -112,4 +112,4 @@
} // namespace ggl
-#endif // GGL_STRATEGY_CARTESIAN_AREA_BY_TRIANGLES_HPP
+#endif // GGL_STRATEGIES_CARTESIAN_AREA_BY_TRIANGLES_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_compare.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_compare.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,66 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_STRATEGY_CARTESIAN_COMPARE_HPP
-#define GGL_STRATEGY_CARTESIAN_COMPARE_HPP
-
-
-#include <ggl/core/cs.hpp>
-#include <ggl/core/access.hpp>
-
-
-#include <ggl/strategies/strategy_traits.hpp>
-
-
-namespace ggl
-{
-namespace strategy
-{
- namespace compare
- {
-
-
- /*!
- \brief Compare (in one direction) strategy for cartesian coordinates
- \ingroup util
- \tparam P point-type
- \tparam D dimension
- */
- template <typename P, size_t D>
- struct euclidian
- {
- static inline bool smaller(const P& p1, const P& p2)
- {
- return get<D>(p1) < get<D>(p2);
- }
-
- static inline bool larger(const P& p1, const P& p2)
- {
- return get<D>(p1) > get<D>(p2);
- }
-
- };
- } // namespace compare
-} // namespace strategy
-
-
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-
-template <typename P, size_t D>
-struct strategy_compare<cartesian_tag, P, D>
-{
- typedef strategy::compare::euclidian<P, D> type;
-};
-
-#endif
-
-
-} // namespace ggl
-
-
-#endif // GGL_STRATEGY_CARTESIAN_COMPARE_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_distance.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_distance.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,248 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_STRATEGY_CARTESIAN_DISTANCE_HPP
-#define GGL_STRATEGY_CARTESIAN_DISTANCE_HPP
-
-
-#include <boost/mpl/if.hpp>
-#include <boost/type_traits.hpp>
-#include <boost/type_traits/remove_const.hpp>
-
-#include <ggl/core/access.hpp>
-#include <ggl/core/point_type.hpp>
-
-#include <ggl/arithmetic/arithmetic.hpp>
-#include <ggl/arithmetic/dot_product.hpp>
-
-#include <ggl/strategies/strategy_traits.hpp>
-#include <ggl/strategies/distance_result.hpp>
-
-#include <ggl/util/select_coordinate_type.hpp>
-#include <ggl/util/copy.hpp>
-
-
-// Helper geometry
-#include <ggl/geometries/segment.hpp>
-
-namespace ggl {
-
-namespace strategy { namespace distance {
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail
-{
-
-template <typename P1, typename P2, size_t I, typename T>
-struct compute_pythagoras
-{
- static inline T apply(P1 const& p1, P2 const& p2)
- {
- T const c1 = boost::numeric_cast<T>(get<I-1>(p2));
- T const c2 = boost::numeric_cast<T>(get<I-1>(p1));
- T const d = c1 - c2;
- return d * d + compute_pythagoras<P1, P2, I-1, T>::apply(p1, p2);
- }
-};
-
-template <typename P1, typename P2, typename T>
-struct compute_pythagoras<P1, P2, 0, T>
-{
- static inline T apply(P1 const&, P2 const&)
- {
- return boost::numeric_cast<T>(0);
- }
-};
-
-}
-#endif
-
-/*!
- \brief Strategy for distance point to point: pythagoras
- \ingroup distance
- \tparam P1 first point type
- \tparam P2 optional, second point type, defaults to first point type
- \par Concepts for P1 and P2:
- - specialized point_traits class
-*/
-template
-<
- typename P1,
- typename P2 = P1,
- typename CalculationType = void
->
-struct pythagoras
-{
- typedef typename
- boost::mpl::if_c
- <
- boost::is_void<CalculationType>::type::value,
- typename select_coordinate_type
- <
- P1,
- P2
- >::type,
- CalculationType
- >::type calculation_type;
-
- typedef P1 point_type;
- typedef cartesian_distance<calculation_type> return_type;
-
-
- inline return_type operator()(P1 const& p1, P2 const& p2) const
- {
-
- BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P1>) );
- BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P2>) );
-
- // Calculate distance using Pythagoras
- // (Leave comment above for Doxygen)
-
- assert_dimension_equal<P1, P2>();
-
- return return_type(detail::compute_pythagoras
- <
- P1, P2,
- dimension<P1>::value,
- calculation_type
- >::apply(p1, p2));
- }
-};
-
-
-/*!
- \brief Strategy for distance point to segment
- \ingroup distance
- \details Calculates distance using projected-point method, and (optionally) Pythagoras
- \author Adapted from: http://geometryalgorithms.com/Archive/algorithm_0102/algorithm_0102.htm
- \tparam P point type
- \tparam SEG segment type
- \tparam S strategy, optional, defaults to pythagoras
- \par Concepts for S:
- - cartesian_distance operator(P,P)
-*/
-template
-<
- typename P,
- typename Segment,
- typename Strategy = pythagoras<P, typename point_type<Segment>::type>
->
-struct xy_point_segment
-{
- typedef P point_type;
- typedef typename select_coordinate_type<P, Segment>::type coordinate_type;
- typedef cartesian_distance<coordinate_type> return_type;
-
- typedef Strategy point_strategy_type;
-
-
- inline return_type operator()(P const& p, Segment const& s) const
- {
- assert_dimension_equal<P, Segment>();
-
- /* Algorithm
- POINT v(x2 - x1, y2 - y1);
- POINT w(px - x1, py - y1);
- c1 = w . v
- c2 = v . v
- b = c1 / c2
- RETURN POINT(x1 + b * vx, y1 + b * vy);
- */
-
- typedef typename boost::remove_const
- <
- typename ggl::point_type<Segment>::type
- >::type segment_point_type;
-
- segment_point_type v, w;
-
- // TODO
- // ASSUMPTION: segment
- // SOLVE THIS USING OTHER FUNCTIONS using get<,>
- copy_coordinates(s.second, v);
- copy_coordinates(p, w);
- subtract_point(v, s.first);
- subtract_point(w, s.first);
-
- Strategy strategy;
-
- coordinate_type c1 = dot_product(w, v);
- if (c1 <= 0)
- {
- return strategy(p, s.first);
- }
- coordinate_type c2 = dot_product(v, v);
- if (c2 <= c1)
- {
- return strategy(p, s.second);
- }
-
- // Even in case of char's, we have to turn to a point<double/float>
- // because of the division.
- coordinate_type b = c1 / c2;
-
- // Note that distances with integer coordinates do NOT work because
- // - the project point is integer
- // - if we solve that, the used distance_strategy cannot handle double points
- segment_point_type projected;
- copy_coordinates(s.first, projected);
- multiply_value(v, b);
- add_point(projected, v);
-
- return strategy(p, projected);
-
- }
-};
-
-}} // namespace strategy::distance
-
-
-
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-template <typename P1, typename P2>
-struct strategy_distance<cartesian_tag, cartesian_tag, P1, P2>
-{
- typedef strategy::distance::pythagoras<P1, P2> type;
-};
-
-template <typename Point, typename Segment>
-struct strategy_distance_segment<cartesian_tag, cartesian_tag, Point, Segment>
-{
- typedef typename point_type<Segment>::type segment_point_type;
-
- typedef strategy::distance::xy_point_segment
- <
- Point,
- Segment,
- typename strategy_distance
- <
- cartesian_tag, cartesian_tag, Point, segment_point_type
- >::type
- > type;
-};
-#endif
-
-
-template <typename P1, typename P2>
-struct strategy_tag<strategy::distance::pythagoras<P1, P2> >
-{
- typedef strategy_tag_distance_point_point type;
-};
-
-template <typename Point, typename Segment, typename PPStrategy>
-struct strategy_tag<strategy::distance::xy_point_segment<Point, Segment, PPStrategy> >
-{
- typedef strategy_tag_distance_point_segment type;
-};
-
-
-
-} // namespace ggl
-
-
-#endif // GGL_STRATEGY_CARTESIAN_DISTANCE_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_envelope.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_envelope.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,63 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_STRATEGY_CARTESIAN_ENVELOPE_HPP
-#define GGL_STRATEGY_CARTESIAN_ENVELOPE_HPP
-
-
-
-#include <ggl/algorithms/combine.hpp>
-
-
-namespace ggl
-{
-namespace strategy
-{
- namespace envelope
- {
- // envelope calculation strategy for xy-points
- template <typename P, typename B>
- struct combine_xy
- {
- struct state
- {
- B& m_box;
- state(B& box) : m_box(box)
- {
- assign_inverse(m_box);
- }
- };
-
- typedef state state_type;
-
- void operator()(const P& p, state_type& s) const
- {
- ggl::combine(s.m_box, p);
- }
- };
- } // namespace envelope
-
-} // namespace strategy
-
-
-
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-template <typename P, typename B>
-struct strategy_envelope<cartesian_tag, cartesian_tag, P, B>
-{
- typedef strategy::envelope::combine_xy<P, B> type;
-};
-
-
-#endif
-
-
-} // namespace ggl
-
-
-#endif // GGL_STRATEGY_CARTESIAN_ENVELOPE_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_intersect.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_intersect.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_intersect.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_STRATEGY_CARTESIAN_INTERSECTION_HPP
-#define GGL_STRATEGY_CARTESIAN_INTERSECTION_HPP
+#ifndef GGL_STRATEGIES_CARTESIAN_INTERSECTION_HPP
+#define GGL_STRATEGIES_CARTESIAN_INTERSECTION_HPP
#include <algorithm>
@@ -351,4 +351,4 @@
} // namespace ggl
-#endif // GGL_STRATEGY_CARTESIAN_INTERSECTION_HPP
+#endif // GGL_STRATEGIES_CARTESIAN_INTERSECTION_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_side.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_side.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,77 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_STRATEGY_CARTESIAN_SIDE_HPP
-#define GGL_STRATEGY_CARTESIAN_SIDE_HPP
-
-
-
-#include <ggl/geometries/segment.hpp>
-
-#include <ggl/util/select_coordinate_type.hpp>
-
-
-
-namespace ggl
-{
-namespace strategy
-{
- namespace side
- {
-
- template <typename P, typename PS>
- struct xy_side
- {
- typedef typename select_coordinate_type<P, PS>::type coordinate_type;
-
- // Check at which side of a segment a point lies:
- // left of segment (> 0), right of segment (< 0), on segment (0)
- // In fact this is twice the area of a triangle
- static inline coordinate_type
- side(segment<const PS> const& s, P const& p)
- {
- coordinate_type const x = get<0>(p);
- coordinate_type const y = get<1>(p);
-
- coordinate_type const sx1 = get<0, 0>(s);
- coordinate_type const sy1 = get<0, 1>(s);
- coordinate_type const sx2 = get<1, 0>(s);
- coordinate_type const sy2 = get<1, 1>(s);
-
- // Todo: might be changed to subtract_point
- coordinate_type dx = sx2 - sx1;
- coordinate_type dy = sy2 - sy1;
- coordinate_type dpx = x - sx1;
- coordinate_type dpy = y - sy1;
- return dx * dpy - dy * dpx;
- }
-
-
- static inline int side(PS const& p0, PS const& p1, P const& p2)
- {
- coordinate_type s = side(segment<const PS>(p0, p1), p2);
- return s > 0 ? 1 : s < 0 ? -1 : 0;
- }
- };
-
- } // namespace side
-} // namespace strategy
-
-
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-template <typename P, typename PS>
-struct strategy_side<cartesian_tag, P, PS>
-{
- typedef strategy::side::xy_side<P, PS> type;
-};
-#endif
-
-} // namespace ggl
-
-
-#endif // GGL_STRATEGY_CARTESIAN_SIDE_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/centroid_bashein_detmer.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/centroid_bashein_detmer.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/centroid_bashein_detmer.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,14 +6,17 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_STRATEGY_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
-#define GGL_STRATEGY_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
+#ifndef GGL_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
+#define GGL_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits.hpp>
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/strategies/centroid.hpp>
#include <ggl/util/select_coordinate_type.hpp>
#include <ggl/util/copy.hpp>
@@ -21,7 +24,10 @@
namespace ggl
{
-namespace strategy { namespace centroid {
+// Note: when calling the namespace "centroid", it sometimes,
+// somehow, in gcc, gives compilation problems (confusion with function centroid).
+
+namespace strategy { namespace centroid_ {
@@ -201,14 +207,32 @@
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-template <typename Point, typename PointOfSegment>
-struct strategy_centroid<cartesian_tag, Point, PointOfSegment>
+
+// Register this strategy for rings and polygons, in two dimensions
+template <typename Point, typename Geometry>
+struct strategy_centroid<cartesian_tag, ring_tag, 2, Point, Geometry>
{
- typedef strategy::centroid::bashein_detmer<Point, PointOfSegment> type;
+ typedef strategy::centroid_::bashein_detmer
+ <
+ Point,
+ typename point_type<Geometry>::type
+ > type;
};
+
+template <typename Point, typename Geometry>
+struct strategy_centroid<cartesian_tag, polygon_tag, 2, Point, Geometry>
+{
+ typedef strategy::centroid_::bashein_detmer
+ <
+ Point,
+ typename point_type<Geometry>::type
+ > type;
+};
+
#endif
+
} // namespace ggl
-#endif // GGL_STRATEGY_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
+#endif // GGL_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/distance_projected_point.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/distance_projected_point.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,168 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
+#define GGL_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/point_type.hpp>
+
+#include <ggl/arithmetic/arithmetic.hpp>
+#include <ggl/arithmetic/dot_product.hpp>
+
+#include <ggl/strategies/tags.hpp>
+#include <ggl/strategies/distance.hpp>
+#include <ggl/strategies/distance_result.hpp>
+#include <ggl/strategies/cartesian/distance_pythagoras.hpp>
+
+#include <ggl/util/select_coordinate_type.hpp>
+#include <ggl/util/copy.hpp>
+
+
+// Helper geometry
+#include <ggl/geometries/segment.hpp>
+
+namespace ggl {
+
+namespace strategy { namespace distance {
+
+
+
+/*!
+ \brief Strategy for distance point to segment
+ \ingroup distance
+ \details Calculates distance using projected-point method, and (optionally) Pythagoras
+ \author Adapted from: http://geometryalgorithms.com/Archive/algorithm_0102/algorithm_0102.htm
+ \tparam P point type
+ \tparam PointOfSegment segment type
+ \tparam Strategy strategy, optional, defaults to pythagoras
+ \par Concepts for Strategy:
+ - cartesian_distance operator(Point,Point)
+*/
+template
+<
+ typename Point,
+ typename PointOfSegment,
+ typename Strategy = pythagoras
+ <
+ Point,
+ typename point_type<PointOfSegment>::type
+ >
+>
+struct xy_point_segment
+{
+ typedef Point point_type;
+ typedef PointOfSegment segment_point_type;
+ typedef typename select_coordinate_type
+ <
+ Point,
+ PointOfSegment
+ >::type coordinate_type;
+ typedef cartesian_distance<coordinate_type> return_type;
+
+ typedef Strategy point_strategy_type;
+
+
+ inline return_type apply(Point const& p,
+ PointOfSegment const& p1, PointOfSegment const& p2) const
+ {
+ assert_dimension_equal<Point, PointOfSegment>();
+
+ /* Algorithm
+ POINT v(x2 - x1, y2 - y1);
+ POINT w(px - x1, py - y1);
+ c1 = w . v
+ c2 = v . v
+ b = c1 / c2
+ RETURN POINT(x1 + b * vx, y1 + b * vy);
+ */
+
+
+ // Take here the first point type. It should have a default constructor.
+ // That is not required for the second point type.
+ Point v, w;
+
+ copy_coordinates(p2, v);
+ copy_coordinates(p, w);
+ subtract_point(v, p1);
+ subtract_point(w, p1);
+
+ Strategy strategy;
+
+ coordinate_type c1 = dot_product(w, v);
+ if (c1 <= 0)
+ {
+ return strategy.apply(p, p1);
+ }
+ coordinate_type c2 = dot_product(v, v);
+ if (c2 <= c1)
+ {
+ return strategy.apply(p, p2);
+ }
+
+ // Even in case of char's, we have to turn to a point<double/float>
+ // because of the division.
+ // TODO
+ coordinate_type b = c1 / c2;
+
+ // Note that distances with integer coordinates do NOT work because
+ // - the project point is integer
+ // - if we solve that, the used distance_strategy cannot handle double points
+ PointOfSegment projected;
+ copy_coordinates(p1, projected);
+ multiply_value(v, b);
+ add_point(projected, v);
+
+ return strategy.apply(p, projected);
+
+ }
+
+};
+
+}} // namespace strategy::distance
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+template <typename Point, typename PointOfSegment>
+struct strategy_distance_segment<cartesian_tag, cartesian_tag, Point, PointOfSegment>
+{
+ typedef typename point_type<PointOfSegment>::type segment_point_type;
+
+ typedef strategy::distance::xy_point_segment
+ <
+ Point,
+ PointOfSegment,
+ typename strategy_distance
+ <
+ cartesian_tag, cartesian_tag, Point, segment_point_type
+ >::type
+ > type;
+};
+#endif
+
+
+template <typename Point, typename PointOfSegment, typename PPStrategy>
+struct strategy_tag<strategy::distance::xy_point_segment<Point, PointOfSegment, PPStrategy> >
+{
+ typedef strategy_tag_distance_point_segment type;
+};
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
Copied: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/distance_pythagoras.hpp (from r57036, /sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_distance.hpp)
==============================================================================
--- /sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_distance.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/distance_pythagoras.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -1,34 +1,27 @@
// Generic Geometry Library
//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. 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 GGL_STRATEGY_CARTESIAN_DISTANCE_HPP
-#define GGL_STRATEGY_CARTESIAN_DISTANCE_HPP
+#ifndef GGL_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
+#define GGL_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
#include <boost/mpl/if.hpp>
#include <boost/type_traits.hpp>
-#include <boost/type_traits/remove_const.hpp>
#include <ggl/core/access.hpp>
-#include <ggl/core/point_type.hpp>
-
-#include <ggl/arithmetic/arithmetic.hpp>
-#include <ggl/arithmetic/dot_product.hpp>
-#include <ggl/strategies/strategy_traits.hpp>
+#include <ggl/strategies/distance.hpp>
#include <ggl/strategies/distance_result.hpp>
-#include <ggl/util/select_coordinate_type.hpp>
+#include <ggl/util/select_calculation_type.hpp>
#include <ggl/util/copy.hpp>
-// Helper geometry
-#include <ggl/geometries/segment.hpp>
namespace ggl {
@@ -38,211 +31,100 @@
namespace detail
{
-template <typename P1, typename P2, size_t I, typename T>
+template <typename Point1, typename Point2, size_t I, typename T>
struct compute_pythagoras
{
- static inline T apply(P1 const& p1, P2 const& p2)
+ static inline T apply(Point1 const& p1, Point2 const& p2)
{
T const c1 = boost::numeric_cast<T>(get<I-1>(p2));
T const c2 = boost::numeric_cast<T>(get<I-1>(p1));
T const d = c1 - c2;
- return d * d + compute_pythagoras<P1, P2, I-1, T>::apply(p1, p2);
+ return d * d + compute_pythagoras<Point1, Point2, I-1, T>::apply(p1, p2);
}
};
-template <typename P1, typename P2, typename T>
-struct compute_pythagoras<P1, P2, 0, T>
+template <typename Point1, typename Point2, typename T>
+struct compute_pythagoras<Point1, Point2, 0, T>
{
- static inline T apply(P1 const&, P2 const&)
+ static inline T apply(Point1 const&, Point2 const&)
{
return boost::numeric_cast<T>(0);
}
};
}
-#endif
+#endif // DOXYGEN_NO_DETAIL
/*!
\brief Strategy for distance point to point: pythagoras
\ingroup distance
- \tparam P1 first point type
- \tparam P2 optional, second point type, defaults to first point type
- \par Concepts for P1 and P2:
+ \tparam Point1 first point type
+ \tparam Point2 optional, second point type, defaults to first point type
+ \par Concepts for Point1 and Point2:
- specialized point_traits class
*/
template
<
- typename P1,
- typename P2 = P1,
+ typename Point1,
+ typename Point2 = Point1,
typename CalculationType = void
>
struct pythagoras
{
- typedef typename
- boost::mpl::if_c
+ typedef typename select_calculation_type
<
- boost::is_void<CalculationType>::type::value,
- typename select_coordinate_type
- <
- P1,
- P2
- >::type,
+ Point1,
+ Point2,
CalculationType
>::type calculation_type;
- typedef P1 point_type;
+ typedef Point1 first_point_type;
+ typedef Point2 second_point_type;
typedef cartesian_distance<calculation_type> return_type;
-
- inline return_type operator()(P1 const& p1, P2 const& p2) const
+ inline return_type apply(Point1 const& p1, Point2 const& p2) const
{
-
- BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P1>) );
- BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P2>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point1>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
// Calculate distance using Pythagoras
// (Leave comment above for Doxygen)
- assert_dimension_equal<P1, P2>();
+ assert_dimension_equal<Point1, Point2>();
return return_type(detail::compute_pythagoras
<
- P1, P2,
- dimension<P1>::value,
+ Point1, Point2,
+ dimension<Point1>::value,
calculation_type
>::apply(p1, p2));
}
};
-/*!
- \brief Strategy for distance point to segment
- \ingroup distance
- \details Calculates distance using projected-point method, and (optionally) Pythagoras
- \author Adapted from: http://geometryalgorithms.com/Archive/algorithm_0102/algorithm_0102.htm
- \tparam P point type
- \tparam SEG segment type
- \tparam S strategy, optional, defaults to pythagoras
- \par Concepts for S:
- - cartesian_distance operator(P,P)
-*/
-template
-<
- typename P,
- typename Segment,
- typename Strategy = pythagoras<P, typename point_type<Segment>::type>
->
-struct xy_point_segment
-{
- typedef P point_type;
- typedef typename select_coordinate_type<P, Segment>::type coordinate_type;
- typedef cartesian_distance<coordinate_type> return_type;
-
- typedef Strategy point_strategy_type;
-
-
- inline return_type operator()(P const& p, Segment const& s) const
- {
- assert_dimension_equal<P, Segment>();
-
- /* Algorithm
- POINT v(x2 - x1, y2 - y1);
- POINT w(px - x1, py - y1);
- c1 = w . v
- c2 = v . v
- b = c1 / c2
- RETURN POINT(x1 + b * vx, y1 + b * vy);
- */
-
- typedef typename boost::remove_const
- <
- typename ggl::point_type<Segment>::type
- >::type segment_point_type;
-
- segment_point_type v, w;
-
- // TODO
- // ASSUMPTION: segment
- // SOLVE THIS USING OTHER FUNCTIONS using get<,>
- copy_coordinates(s.second, v);
- copy_coordinates(p, w);
- subtract_point(v, s.first);
- subtract_point(w, s.first);
-
- Strategy strategy;
-
- coordinate_type c1 = dot_product(w, v);
- if (c1 <= 0)
- {
- return strategy(p, s.first);
- }
- coordinate_type c2 = dot_product(v, v);
- if (c2 <= c1)
- {
- return strategy(p, s.second);
- }
-
- // Even in case of char's, we have to turn to a point<double/float>
- // because of the division.
- coordinate_type b = c1 / c2;
-
- // Note that distances with integer coordinates do NOT work because
- // - the project point is integer
- // - if we solve that, the used distance_strategy cannot handle double points
- segment_point_type projected;
- copy_coordinates(s.first, projected);
- multiply_value(v, b);
- add_point(projected, v);
-
- return strategy(p, projected);
-
- }
-};
-
}} // namespace strategy::distance
-
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-template <typename P1, typename P2>
-struct strategy_distance<cartesian_tag, cartesian_tag, P1, P2>
+template <typename Point1, typename Point2>
+struct strategy_distance<cartesian_tag, cartesian_tag, Point1, Point2>
{
- typedef strategy::distance::pythagoras<P1, P2> type;
+ typedef strategy::distance::pythagoras<Point1, Point2> type;
};
-template <typename Point, typename Segment>
-struct strategy_distance_segment<cartesian_tag, cartesian_tag, Point, Segment>
-{
- typedef typename point_type<Segment>::type segment_point_type;
- typedef strategy::distance::xy_point_segment
- <
- Point,
- Segment,
- typename strategy_distance
- <
- cartesian_tag, cartesian_tag, Point, segment_point_type
- >::type
- > type;
-};
#endif
-template <typename P1, typename P2>
-struct strategy_tag<strategy::distance::pythagoras<P1, P2> >
+template <typename Point1, typename Point2>
+struct strategy_tag<strategy::distance::pythagoras<Point1, Point2> >
{
typedef strategy_tag_distance_point_point type;
};
-template <typename Point, typename Segment, typename PPStrategy>
-struct strategy_tag<strategy::distance::xy_point_segment<Point, Segment, PPStrategy> >
-{
- typedef strategy_tag_distance_point_segment type;
-};
-
} // namespace ggl
-#endif // GGL_STRATEGY_CARTESIAN_DISTANCE_HPP
+#endif // GGL_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/point_in_poly_crossings_multiply.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/point_in_poly_crossings_multiply.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/point_in_poly_crossings_multiply.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -5,8 +5,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_STRATEGY_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
-#define GGL_STRATEGY_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
+#ifndef GGL_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
+#define GGL_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
#include <ggl/core/coordinate_type.hpp>
@@ -106,97 +106,4 @@
} // namespace ggl
-#ifdef ORIGINAL_CODE
-
-See http://tog.acm.org/resources/GraphicsGems/gemsiv/ptpoly_haines/ptinpoly.c
-
-/* ======= Crossings Multiply algorithm =================================== */
-
-/*
- * This version is usually somewhat faster than the original published in
- * Graphics Gems IV; by turning the division for testing the X axis crossing
- * into a tricky multiplication test this part of the test became faster,
- * which had the additional effect of making the test for "both to left or
- * both to right" a bit slower for triangles than simply computing the
- * intersection each time. The main increase is in triangle testing speed,
- * which was about 15% faster; all other polygon complexities were pretty much
- * the same as before. On machines where division is very expensive (not the
- * case on the HP 9000 series on which I tested) this test should be much
- * faster overall than the old code. Your mileage may (in fact, will) vary,
- * depending on the machine and the test data, but in general I believe this
- * code is both shorter and faster. This test was inspired by unpublished
- * Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson.
- * Related work by Samosky is in:
- *
- * Samosky, Joseph, "SectionView: A system for interactively specifying and
- * visualizing sections through three-dimensional medical image data",
- * M.S. Thesis, Department of Electrical Engineering and Computer Science,
- * Massachusetts Institute of Technology, 1993.
- *
- */
-
-/* Shoot a test ray along +X axis. The strategy is to compare vertex Y values
- * to the testing point's Y and quickly discard edges which are entirely to one
- * side of the test ray. Note that CONVEX and WINDING code can be added as
- * for the CrossingsTest() code; it is left out here for clarity.
- *
- * Input 2D polygon _pgon_ with _numverts_ number of vertices and test point
- * _point_, returns 1 if inside, 0 if outside.
- */
-int CrossingsMultiplyTest( pgon, numverts, point )
-double pgon[][2] ;
-int numverts ;
-double point[2] ;
-{
-register int j, yflag0, yflag1, inside_flag ;
-register double ty, tx, *vtx0, *vtx1 ;
-
- tx = point[X] ;
- ty = point[Y] ;
-
- vtx0 = pgon[numverts-1] ;
- /* get test bit for above/below X axis */
- yflag0 = ( vtx0[Y] >= ty ) ;
- vtx1 = pgon[0] ;
-
- inside_flag = 0 ;
- for ( j = numverts+1 ; --j ; ) {
-
- yflag1 = ( vtx1[Y] >= ty ) ;
- /* Check if endpoints straddle (are on opposite sides) of X axis
- * (i.e. the Y's differ); if so, +X ray could intersect this edge.
- * The old test also checked whether the endpoints are both to the
- * right or to the left of the test point. However, given the faster
- * intersection point computation used below, this test was found to
- * be a break-even proposition for most polygons and a loser for
- * triangles (where 50% or more of the edges which survive this test
- * will cross quadrants and so have to have the X intersection computed
- * anyway). I credit Joseph Samosky with inspiring me to try dropping
- * the "both left or both right" part of my code.
- */
- if ( yflag0 != yflag1 ) {
- /* Check intersection of pgon segment with +X ray.
- * Note if >= point's X; if so, the ray hits it.
- * The division operation is avoided for the ">=" test by checking
- * the sign of the first vertex wrto the test point; idea inspired
- * by Joseph Samosky's and Mark Haigh-Hutchinson's different
- * polygon inclusion tests.
- */
- if ( ((vtx1[Y]-ty) * (vtx0[X]-vtx1[X]) >=
- (vtx1[X]-tx) * (vtx0[Y]-vtx1[Y])) == yflag1 ) {
- inside_flag = !inside_flag ;
- }
- }
-
- /* Move to the next pair of vertices, retaining info as possible. */
- yflag0 = yflag1 ;
- vtx0 = vtx1 ;
- vtx1 += 2 ;
- }
-
- return( inside_flag ) ;
-}
-#endif
-
-
-#endif // GGL_STRATEGY_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
+#endif // GGL_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/point_in_poly_franklin.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/point_in_poly_franklin.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/point_in_poly_franklin.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_STRATEGY_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
-#define GGL_STRATEGY_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
+#ifndef GGL_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
+#define GGL_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
#include <ggl/core/coordinate_type.hpp>
@@ -101,4 +101,4 @@
} // namespace ggl
-#endif // GGL_STRATEGY_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
+#endif // GGL_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
Copied: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/side_by_triangle.hpp (from r57147, /sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_side.hpp)
==============================================================================
--- /sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_side.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/side_by_triangle.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_STRATEGY_CARTESIAN_SIDE_HPP
-#define GGL_STRATEGY_CARTESIAN_SIDE_HPP
+#ifndef GGL_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
+#define GGL_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
@@ -24,37 +24,46 @@
namespace side
{
- template <typename P, typename PS>
- struct xy_side
+ // Check at which side of a segment a point lies:
+ // left of segment (> 0), right of segment (< 0), on segment (0)
+ // In fact this is twice the area of a triangle
+ struct side_by_triangle
{
- typedef typename select_coordinate_type<P, PS>::type coordinate_type;
- // Check at which side of a segment a point lies:
- // left of segment (> 0), right of segment (< 0), on segment (0)
- // In fact this is twice the area of a triangle
- static inline coordinate_type
- side(segment<const PS> const& s, P const& p)
+ // Template member functions, because it is not always trivial
+ // or convenient to explicitly mention the typenames in the
+ // strategy-struct itself.
+
+ // Types can be all three different.
+
+ template <typename P1, typename P2, typename P>
+ static inline int apply(P1 const& p1, P2 const& p2, P const& p)
{
+ typedef typename select_most_precise
+ <
+ typename select_most_precise
+ <
+ typename coordinate_type<P1>::type,
+ typename coordinate_type<P2>::type
+ >::type,
+ typename coordinate_type<P>::type
+ >::type coordinate_type;
+
coordinate_type const x = get<0>(p);
coordinate_type const y = get<1>(p);
- coordinate_type const sx1 = get<0, 0>(s);
- coordinate_type const sy1 = get<0, 1>(s);
- coordinate_type const sx2 = get<1, 0>(s);
- coordinate_type const sy2 = get<1, 1>(s);
-
- // Todo: might be changed to subtract_point
- coordinate_type dx = sx2 - sx1;
- coordinate_type dy = sy2 - sy1;
- coordinate_type dpx = x - sx1;
- coordinate_type dpy = y - sy1;
- return dx * dpy - dy * dpx;
- }
+ coordinate_type const sx1 = get<0>(p1);
+ coordinate_type const sy1 = get<1>(p1);
+ coordinate_type const sx2 = get<0>(p2);
+ coordinate_type const sy2 = get<1>(p2);
+
+ coordinate_type const dx = sx2 - sx1;
+ coordinate_type const dy = sy2 - sy1;
+ coordinate_type const dpx = x - sx1;
+ coordinate_type const dpy = y - sy1;
+ coordinate_type s = dx * dpy - dy * dpx;
- static inline int side(PS const& p0, PS const& p1, P const& p2)
- {
- coordinate_type s = side(segment<const PS>(p0, p1), p2);
return s > 0 ? 1 : s < 0 ? -1 : 0;
}
};
@@ -64,14 +73,14 @@
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-template <typename P, typename PS>
-struct strategy_side<cartesian_tag, P, PS>
+template <>
+struct strategy_side<cartesian_tag>
{
- typedef strategy::side::xy_side<P, PS> type;
+ typedef strategy::side::side_by_triangle type;
};
#endif
} // namespace ggl
-#endif // GGL_STRATEGY_CARTESIAN_SIDE_HPP
+#endif // GGL_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/centroid.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/centroid.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,45 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_STRATEGIES_CENTROID_HPP
+#define GGL_STRATEGIES_CENTROID_HPP
+
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+ \brief Traits class binding a centroid calculation strategy to a coordinate system
+ \ingroup centroid
+ \tparam CsTag tag of coordinate system, for specialization
+ \tparam GeometryTag tag of geometry, for specialization
+ \tparam Dimension dimension of geometry, for specialization
+ \tparam Point point-type
+ \tparam Geometry
+*/
+template
+<
+ typename CsTag,
+ typename GeometryTag,
+ std::size_t Dimension,
+ typename Point,
+ typename Geometry
+>
+struct strategy_centroid
+{
+ typedef strategy::not_implemented type;
+};
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_CENTROID_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/compare.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/compare.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,157 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, 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 GGL_STRATEGIES_COMPARE_HPP
+#define GGL_STRATEGIES_COMPARE_HPP
+
+#include <cstddef>
+#include <functional>
+
+#include <boost/mpl/if.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/coordinate_type.hpp>
+
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+
+/*!
+ \brief Traits class binding a comparing strategy to a coordinate system
+ \ingroup util
+ \tparam Tag tag of coordinate system of point-type
+ \tparam Direction direction to compare on: 1 for less (-> ascending order)
+ and -1 for greater (-> descending order)
+ \tparam Point point-type
+ \tparam CoordinateSystem coordinate sytem of point
+ \tparam Dimension: the dimension to compare on
+*/
+template
+<
+ typename Tag,
+ int Direction,
+ typename Point,
+ typename CoordinateSystem,
+ std::size_t Dimension
+>
+struct strategy_compare
+{
+ typedef strategy::not_implemented type;
+};
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+// For compare we add defaults specializations,
+// because they defaultly redirect to std::less/std::greater
+template
+<
+ typename Tag,
+ typename Point,
+ typename CoordinateSystem,
+ std::size_t Dimension
+>
+struct strategy_compare<Tag, 1, Point, CoordinateSystem, Dimension>
+{
+ typedef std::less<typename coordinate_type<Point>::type> type;
+};
+
+
+template
+<
+ typename Tag,
+ typename Point,
+ typename CoordinateSystem,
+ std::size_t Dimension
+>
+struct strategy_compare<Tag, -1, Point, CoordinateSystem, Dimension>
+{
+ typedef std::greater<typename coordinate_type<Point>::type> type;
+};
+
+
+#endif
+
+
+
+namespace strategy { namespace compare {
+
+
+
+/*!
+ \brief Default strategy, indicates the default strategy for comparisons
+ \details The default strategy for comparisons defer in most cases
+ to std::less (for ascending) and std::greater (for descending).
+ However, if a spherical coordinate system is used, and comparison
+ is done on longitude, it will take another strategy handling circular
+*/
+struct default_strategy {};
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail {
+
+template <typename Type>
+struct is_default : boost::false_type
+{};
+
+
+template <>
+struct is_default<default_strategy> : boost::true_type
+{};
+
+
+/*!
+ \brief Meta-function to select strategy
+ \details If "default_strategy" is specified, it will take the
+ traits-registered class for the specified coordinate system.
+ If another strategy is explicitly specified, it takes that one.
+*/
+template
+<
+ typename Strategy,
+ int Direction,
+ typename Point,
+ std::size_t Dimension
+>
+struct select_strategy
+{
+ typedef typename
+ boost::mpl::if_
+ <
+ is_default<Strategy>,
+ typename strategy_compare
+ <
+ typename cs_tag<Point>::type,
+ Direction,
+ Point,
+ typename coordinate_system<Point>::type,
+ Dimension
+ >::type,
+ Strategy
+ >::type type;
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace strategy::compare
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_COMPARE_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/area_concept.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/area_concept.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/area_concept.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -37,17 +37,17 @@
{
static void apply()
{
- Strategy const* st;
+ Strategy const* str;
// 4) must implement an init-method
- state_type s = st->init();
+ state_type st = str->init();
- // 5) must implement a static method apply with the following signature
- spoint_type *sp;
- Strategy::apply(*sp, *sp, s);
+ // 5) must implement a method apply with the following signature
+ spoint_type const* sp;
+ str->apply(*sp, *sp, st);
// 6) must implement a static method result with the following signature
- return_type r = Strategy::result(s);
+ return_type r = str->result(st);
boost::ignore_unused_variable_warning(r);
}
};
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/centroid_concept.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/centroid_concept.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/centroid_concept.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -17,7 +17,7 @@
/*!
- \brief Checks strategy for area
+ \brief Checks strategy for centroid
\ingroup concepts
*/
template <typename Strategy>
@@ -37,17 +37,18 @@
{
static void apply()
{
- state_type *s;
+ Strategy *str;
+ state_type *st;
// 4) must implement a static method apply,
// getting two segment-points
- spoint_type *sp;
- Strategy::apply(*sp, *sp, *s);
+ spoint_type const* sp;
+ str->apply(*sp, *sp, *st);
// 5) must implement a static method result
// getting the centroid
point_type *c;
- bool r = Strategy::result(*s, *c);
+ bool r = str->result(*st, *c);
boost::ignore_unused_variable_warning(r);
}
};
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/convex_hull_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/convex_hull_concept.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,66 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. 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 GGL_STRATEGIES_CONCEPTS_CONVEX_HULL_CONCEPT_HPP
+#define GGL_STRATEGIES_CONCEPTS_CONVEX_HULL_CONCEPT_HPP
+
+
+#include <vector>
+
+#include <boost/concept_check.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+ \brief Checks strategy for convex_hull
+ \ingroup concepts
+*/
+template <typename Strategy>
+class ConvexHullStrategy
+{
+
+ // 1) must define state_type
+ typedef typename Strategy::state_type state_type;
+
+ // 2) must define point_type
+ typedef typename Strategy::point_type point_type;
+
+ // 3) must define geometry_type
+ typedef typename Strategy::geometry_type geometry_type;
+
+ struct check_methods
+ {
+ static void apply()
+ {
+ Strategy const* str;
+
+ state_type* st;
+ geometry_type* sp;
+ std::vector<point_type> *v;
+
+ // 4) must implement a method apply, iterating over a range
+ str->apply(*sp, *st);
+
+ // 5) must implement a method result, with an output iterator
+ str->result(*st, std::back_inserter(*v), true);
+ }
+ };
+
+public :
+ BOOST_CONCEPT_USAGE(ConvexHullStrategy)
+ {
+ check_methods::apply();
+ }
+};
+
+
+
+}} // namespace ggl::concept
+
+#endif // GGL_STRATEGIES_CONCEPTS_CONVEX_HULL_CONCEPT_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/distance_concept.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/distance_concept.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/distance_concept.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -29,25 +29,32 @@
{
private :
- // 1) must define point_type
- typedef typename Strategy::point_type ptype;
+ // 1) must define first_point_type
+ typedef typename Strategy::first_point_type ptype1;
BOOST_CONCEPT_ASSERT
(
- (concept::ConstPoint<ptype>)
+ (concept::ConstPoint<ptype1>)
+ );
+
+ // 2) must define second_point_type
+ typedef typename Strategy::second_point_type ptype2;
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstPoint<ptype2>)
);
- // 2) must define return_type
+ // 3) must define return_type
typedef typename Strategy::return_type rtype;
- // 3) must implement static method () with arguments
+ // 4) must implement apply with arguments
struct apply_checker
{
static void check()
{
- Strategy s;
- ptype *p1;
- ptype *p2;
- rtype r = s(*p1, *p2);
+ Strategy* s;
+ ptype1 *p1;
+ ptype2 *p2;
+ rtype r = s->apply(*p1, *p2);
boost::ignore_unused_variable_warning(r);
}
@@ -77,10 +84,17 @@
(concept::ConstPoint<ptype>)
);
- // 2) must define return_type
+ // 2) must define segment_point_type
+ typedef typename Strategy::segment_point_type sptype;
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstPoint<sptype>)
+ );
+
+ // 3) must define return_type
typedef typename Strategy::return_type rtype;
- // 3) must define underlying point-distance-strategy
+ // 4) must define underlying point-distance-strategy
typedef typename Strategy::point_strategy_type stype;
BOOST_CONCEPT_ASSERT
(
@@ -88,15 +102,17 @@
);
- // 4) must implement static method () with arguments
+ // 5) must implement method apply with arguments
struct apply_checker
{
static void check()
{
- Strategy s;
- ptype *p1;
- ptype *p2;
- rtype r = s(*p1, ggl::segment<const ptype>(*p1, *p2));
+ Strategy *s;
+ ptype *p;
+ sptype *sp1;
+ sptype *sp2;
+
+ rtype r = s->apply(*p, *sp1, *sp2);
boost::ignore_unused_variable_warning(r);
}
};
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/simplify_concept.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/simplify_concept.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/simplify_concept.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -37,16 +37,20 @@
(concept::PointSegmentDistanceStrategy<ds_type>)
);
- // 2) must implement static method apply with arguments
- // - Range
- // - OutputIterator
- // - floating point value
struct apply_checker
{
static void check()
{
- std::vector<typename ds_type::point_type> *v;
- Strategy::apply(*v, std::back_inserter(*v), 1.0);
+ Strategy *str;
+ std::vector<typename ds_type::point_type> const* v1;
+ std::vector<typename ds_type::point_type> * v2;
+
+ // 2) must implement method apply with arguments
+ // - Range
+ // - OutputIterator
+ // - floating point value
+ str->apply(*v1, std::back_inserter(*v2), 1.0);
+ boost::ignore_unused_variable_warning(str);
}
};
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/within_concept.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/within_concept.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/concepts/within_concept.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -33,22 +33,32 @@
// 3) must define point_type, of polygon (segments)
typedef typename Strategy::segment_point_type spoint_type;
- // 4) must implement a static method apply with the following signature
- typedef bool (*ApplyType)(point_type const&,
- spoint_type const&, spoint_type const&,
- state_type &);
- // 5) must implement a static method result with the following signature
- typedef bool (*ResultType)(state_type const&) ;
+ struct check_methods
+ {
+ static void apply()
+ {
+ Strategy const* str;
+
+ state_type* st;
+ point_type const* p;
+ spoint_type const* sp;
+
+ // 4) must implement a method apply
+ // having a point, two segment-points, and state
+ str->apply(*p, *sp, *sp, *st);
+
+ // 5) must implement a method result
+ str->result(*st);
+ boost::ignore_unused_variable_warning(str);
+ }
+ };
+
public :
BOOST_CONCEPT_USAGE(WithinStrategy)
{
- ApplyType a = &Strategy::apply;
- ResultType r = &Strategy::result;
-
- boost::ignore_unused_variable_warning(a);
- boost::ignore_unused_variable_warning(r);
+ check_methods::apply();
}
};
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/convex_hull.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/convex_hull.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,37 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_STRATEGIES_CONVEX_HULL_HPP
+#define GGL_STRATEGIES_CONVEX_HULL_HPP
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+
+
+/*!
+ \brief Traits class binding a convex hull calculation strategy to a coordinate system
+ \ingroup convex_hull
+ \tparam Tag tag of coordinate system
+ \tparam Geometry the geometry type (hull operates internally per hull over geometry)
+ \tparam Point point-type of output points
+*/
+template <typename Tag, typename Geometry, typename Point>
+struct strategy_convex_hull
+{
+ typedef strategy::not_implemented type;
+};
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_CONVEX_HULL_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/distance.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/distance.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,53 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_STRATEGIES_DISTANCE_HPP
+#define GGL_STRATEGIES_DISTANCE_HPP
+
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+ \brief Traits class binding a distance strategy to a (possibly two) coordinate system(s)
+ \ingroup distance
+ \tparam T1 tag of coordinate system of first point type
+ \tparam T2 tag of coordinate system of second point type
+ \tparam P1 first point-type
+ \tparam P2 second point-type
+*/
+template <typename T1, typename T2, typename P1, typename P2>
+struct strategy_distance
+{
+ typedef strategy::not_implemented type;
+};
+
+/*!
+ \brief Traits class binding a distance-to-segment strategy to a (possibly two) coordinate system(s)
+ \ingroup distance
+ \tparam CsTag1 tag of coordinate system of point type
+ \tparam CsTag2 tag of coordinate system of segment type, usually same as CsTag1
+ \tparam Point point-type
+ \tparam Segment segment-type
+*/
+template <typename CsTag1, typename CsTag2, typename Point, typename Segment>
+struct strategy_distance_segment
+{
+ typedef strategy::not_implemented type;
+};
+
+
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_DISTANCE_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/distance_result.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/distance_result.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/distance_result.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -12,12 +12,15 @@
#include <utility>
#include <cmath>
#include <limits>
-#include <iostream>
+// #include <iostream>
#include <boost/mpl/if.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/strategies/distance.hpp>
#include <ggl/util/select_most_precise.hpp>
@@ -239,6 +242,32 @@
#endif
+
+/*!
+ \brief Shortcut to define return type of distance strategy
+ \ingroup distance
+ \tparam Geometry1 first geometry
+ \tparam Geometry2 second geometry
+ */
+template <typename Geometry1, typename Geometry2 = Geometry1>
+struct distance_result
+{
+ typedef typename point_type<Geometry1>::type point_type1;
+ typedef typename point_type<Geometry2>::type point_type2;
+ typedef typename strategy_distance
+ <
+ typename cs_tag<point_type1>::type,
+ typename cs_tag<point_type2>::type,
+ point_type1,
+ point_type2
+ >::type strategy_type;
+ typedef typename strategy_type::return_type type;
+};
+
+
+
+
+
/*!
\brief Object generator to create instance which can be compared
\ingroup distance
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/intersection_result.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/intersection_result.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/intersection_result.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_INTERSECTION_RESULT_HPP
-#define GGL_INTERSECTION_RESULT_HPP
+#ifndef GGL_STRATEGIES_INTERSECTION_RESULT_HPP
+#define GGL_STRATEGIES_INTERSECTION_RESULT_HPP
#if defined(HAVE_MATRIX_AS_STRING)
#include <string>
@@ -164,4 +164,4 @@
} // namespace ggl
-#endif // GGL_INTERSECTION_RESULT_HPP
+#endif // GGL_STRATEGIES_INTERSECTION_RESULT_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/length_result.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/length_result.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/length_result.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -5,8 +5,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_LENGTH_RESULT_HPP
-#define GGL_LENGTH_RESULT_HPP
+#ifndef GGL_STRATEGIES_LENGTH_RESULT_HPP
+#define GGL_STRATEGIES_LENGTH_RESULT_HPP
#include <ggl/core/coordinate_type.hpp>
@@ -37,4 +37,4 @@
} // namespace ggl
-#endif // GGL_LENGTH_RESULT_HPP
+#endif // GGL_STRATEGIES_LENGTH_RESULT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/parse.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/parse.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,36 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_STRATEGIES_PARSE_HPP
+#define GGL_STRATEGIES_PARSE_HPP
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+
+/*!
+ \brief Tagraits class binding a parsing strategy to a coordinate system
+ \ingroup parse
+ \tparam Tag tag of coordinate system of point-type
+ \tparam CoordinateSystem coordinate system
+*/
+template <typename Tag, typename CoordinateSystem>
+struct strategy_parse
+{
+ typedef strategy::not_implemented type;
+};
+
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_PARSE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/point_in_poly.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/point_in_poly.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,36 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_STRATEGIES_POINT_IN_POLY_HPP
+#define GGL_STRATEGIES_POINT_IN_POLY_HPP
+
+#include <ggl/strategies/tags.hpp>
+
+namespace ggl
+{
+
+
+/*!
+ \brief Traits class binding a within determination strategy to a coordinate system
+ \ingroup within
+ \tparam TagPoint tag of coordinate system of point-type
+ \tparam TagSegment tag of coordinate system of segment-type
+ \tparam Point point-type of input points
+ \tparam PointOfSegment point-type of input segment-points
+*/
+template <typename TagPoint, typename TagSegment, typename Point, typename PointOfSegment>
+struct strategy_within
+{
+ typedef strategy::not_implemented type;
+};
+
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_POINT_IN_POLY_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/side.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/side.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,34 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_STRATEGIES_SIDE_HPP
+#define GGL_STRATEGIES_SIDE_HPP
+
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+ \brief Traits class binding a side determination strategy to a coordinate system
+ \ingroup util
+ \tparam Tag tag of coordinate system of point-type
+*/
+template <typename Tag>
+struct strategy_side
+{
+ typedef strategy::not_implemented type;
+};
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_SIDE_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/area_huiller.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/area_huiller.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/area_huiller.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -89,7 +89,7 @@
if (! ggl::math::equals(get<0>(p1), get<0>(p2)))
{
// Distance p1 p2
- double a = state.distance_over_unit_sphere(p1, p2);
+ double a = state.distance_over_unit_sphere.apply(p1, p2);
// Sides on unit sphere to south pole
double b = 0.5 * math::pi - ggl::get_as_radian<1>(p2);
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/compare_circular.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/compare_circular.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,154 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. 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 GGL_STRATEGIES_SPHERICAL_COMPARE_SPHERICAL_HPP
+#define GGL_STRATEGIES_SPHERICAL_COMPARE_SPHERICAL_HPP
+
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/tags.hpp>
+
+
+#include <ggl/strategies/compare.hpp>
+
+
+namespace ggl
+{
+
+namespace strategy { namespace compare {
+
+
+namespace detail {
+
+
+template <typename Units>
+struct shift
+{
+};
+
+
+template <>
+struct shift<degree>
+{
+ static inline double full() { return 360.0; }
+ static inline double half() { return 180.0; }
+};
+
+template <>
+struct shift<radian>
+{
+ static inline double full() { return ggl::math::two_pi; }
+ static inline double half() { return ggl::math::pi; }
+};
+
+} // namespace detail
+
+/*!
+ \brief Compare (in one direction) strategy for spherical coordinates
+ \ingroup util
+ \tparam Point point-type
+ \tparam Dimension dimension
+*/
+template <typename CoordinateType, typename Units, typename Compare>
+struct circular_comparator
+{
+ static inline CoordinateType put_in_range(CoordinateType const& c,
+ double min_border, double max_border)
+ {
+ CoordinateType value = c;
+ while (value < min_border)
+ {
+ value += detail::shift<Units>::full();
+ }
+ while (value > max_border)
+ {
+ value -= detail::shift<Units>::full();
+ }
+ return value;
+ }
+
+ inline bool operator()(CoordinateType const& c1, CoordinateType const& c2) const
+ {
+ Compare compare;
+
+ // Check situation that one of them is e.g. std::numeric_limits.
+ static const double full = detail::shift<Units>::full();
+ double mx = 10.0 * full;
+ if (c1 < -mx || c1 > mx || c2 < -mx || c2 > mx)
+ {
+ // do normal comparison, using circular is not useful
+ return compare(c1, c2);
+ }
+
+ static const double half = full / 2.0;
+ CoordinateType v1 = put_in_range(c1, -half, half);
+ CoordinateType v2 = put_in_range(c2, -half, half);
+
+ // Two coordinates on a circle are
+ // at max <= half a circle away from each other.
+ // So if it is more, shift origin.
+ CoordinateType diff = std::abs(v1 - v2);
+ if (diff > half)
+ {
+ v1 = put_in_range(v1, 0, full);
+ v2 = put_in_range(v2, 0, full);
+ }
+
+ return compare(v1, v2);
+ }
+};
+
+
+}} // namespace strategy::compare
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+// Specialize for the longitude (dim 0)
+template
+<
+ typename Point,
+ template<typename> class CoordinateSystem,
+ typename Units
+>
+struct strategy_compare<spherical_tag, 1, Point, CoordinateSystem<Units>, 0>
+{
+ typedef typename coordinate_type<Point>::type coordinate_type;
+ typedef strategy::compare::circular_comparator
+ <
+ coordinate_type,
+ Units,
+ std::less<coordinate_type>
+ > type;
+};
+
+template
+<
+ typename Point,
+ template<typename> class CoordinateSystem,
+ typename Units
+>
+struct strategy_compare<spherical_tag, -1, Point, CoordinateSystem<Units>, 0>
+{
+ typedef typename coordinate_type<Point>::type coordinate_type;
+ typedef strategy::compare::circular_comparator
+ <
+ coordinate_type,
+ Units,
+ std::greater<coordinate_type>
+ > type;
+};
+
+
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_SPHERICAL_COMPARE_SPHERICAL_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/distance_cross_track.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/distance_cross_track.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/distance_cross_track.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,10 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_STRATEGY_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
-#define GGL_STRATEGY_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
+#ifndef GGL_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
+#define GGL_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
+
+#include <boost/concept/requires.hpp>
#include <ggl/core/cs.hpp>
@@ -15,9 +17,8 @@
#include <ggl/core/radian_access.hpp>
-#include <ggl/strategies/strategy_traits.hpp>
-
-#include <ggl/strategies/distance_result.hpp>
+#include <ggl/strategies/distance.hpp>
+#include <ggl/strategies/concepts/distance_concept.hpp>
#include <ggl/util/math.hpp>
//#include <ggl/util/write_dsv.hpp>
@@ -26,97 +27,96 @@
namespace ggl
{
-namespace strategy
+
+namespace strategy { namespace distance {
+
+/*!
+ \brief Strategy functor for distance point to segment calculation
+ \ingroup distance
+ \details Class which calculates the distance of a point to a segment, using latlong points
+ \see http://williams.best.vwh.net/avform.htm
+ \tparam P point type
+ \tparam S segment type
+*/
+template <typename Point, typename PointOfSegment>
+class cross_track
{
+public :
+ typedef double return_type;
+ typedef Point point_type;
+ typedef PointOfSegment segment_point_type;
+
+ typedef typename strategy_distance
+ <
+ typename ggl::cs_tag<Point>::type,
+ typename ggl::cs_tag<Point>::type,
+ Point, Point
+ >::type point_strategy_type;
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (ggl::concept::PointDistanceStrategy<point_strategy_type>)
+ );
+
+
+
+ inline cross_track(double r = 1.0)
+ : m_radius(r)
+ , m_strategy(1.0) // Keep this 1.0 and not r
+ {}
+
- namespace distance
+ // It might be useful in the future
+ // to overload constructor with strategy info.
+ // crosstrack(...) {}
+
+
+ inline return_type apply(Point const& p,
+ PointOfSegment const& sp1, PointOfSegment const& sp2) const
{
+ // http://williams.best.vwh.net/avform.htm#XTE
+ double d1 = m_strategy.apply(sp1, p);
+
+ // Actually, calculation of d2 not necessary if we know that the projected point is on the great circle...
+ double d2 = m_strategy.apply(sp2, p);
- /*!
- \brief Strategy functor for distance point to segment calculation
- \ingroup distance
- \details Class which calculates the distance of a point to a segment, using latlong points
- \see http://williams.best.vwh.net/avform.htm
- \tparam P point type
- \tparam S segment type
- */
- template <typename P, typename S>
- class cross_track
- {
- public :
- typedef double return_type;
- typedef P point_type;
- typedef typename strategy_distance
- <
- typename ggl::cs_tag<P>::type,
- typename ggl::cs_tag<P>::type,
- P, P
- >::type point_strategy_type;
-
-
- inline cross_track(double r = 1.0)
- : m_radius(r)
- , m_strategy(1.0) // Keep this 1.0 and not r
- {}
-
-
- // It might be useful in the future
- // to overload constructor with strategy info.
-
-
- inline return_type operator()(P const& p, S const& s) const
- {
- // ASSUMPTION: segment
- // However, this is normally called from internal functions
- // Future: solve this using other functions using get<,>
- return calc(p, s.first, s.second);
- }
-
- private :
- double m_radius;
-
- // Point-point distances are calculated in radians, on the unit sphere
- point_strategy_type m_strategy;
-
- /// Calculate course (bearing) between two points. Might be moved to a "course formula" ...
- inline double course(P const& p1, P const& p2) const
- {
- // http://williams.best.vwh.net/avform.htm#Crs
- double dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1);
- double cos_p2lat = cos(get_as_radian<1>(p2));
-
- // "An alternative formula, not requiring the pre-computation of d"
- return atan2(sin(dlon) * cos_p2lat,
- cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2))
- - sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon));
- }
-
- inline return_type calc(P const& p, P const& sp1, P const& sp2) const
- {
- // http://williams.best.vwh.net/avform.htm#XTE
-
- double d1 = m_strategy(sp1, p);
-
- // Actually, calculation of d2 not necessary if we know that the projected point is on the great circle...
- double d2 = m_strategy(sp2, p);
-
- double crs_AD = course(sp1, p);
- double crs_AB = course(sp1, sp2);
- double XTD = std::abs(asin(sin(d1) * sin(crs_AD - crs_AB)));
+ double crs_AD = course(sp1, p);
+ double crs_AB = course(sp1, sp2);
+ double XTD = std::abs(asin(sin(d1) * sin(crs_AD - crs_AB)));
//std::cout << "Course " << dsv(sp1) << " to " << dsv(p) << " " << crs_AD * ggl::math::r2d << std::endl;
//std::cout << "Course " << dsv(sp1) << " to " << dsv(sp2) << " " << crs_AB * ggl::math::r2d << std::endl;
//std::cout << "XTD: " << (XTD * 6373.0) << " d1: " << (d1 * 6373.0) << " d2: " << (d2 * 6373.0) << std::endl;
- // Return shortest distance, either to projected point on segment sp1-sp2, or to sp1, or to sp2
- return return_type(m_radius * (std::min)((std::min)(d1, d2), XTD));
- }
- };
+ // Return shortest distance, either to projected point on segment sp1-sp2, or to sp1, or to sp2
+ return return_type(m_radius * (std::min)((std::min)(d1, d2), XTD));
+ }
+
+private :
+ double m_radius;
+
+ // Point-point distances are calculated in radians, on the unit sphere
+ point_strategy_type m_strategy;
+
+ /// Calculate course (bearing) between two points. Might be moved to a "course formula" ...
+ inline double course(Point const& p1, Point const& p2) const
+ {
+ // http://williams.best.vwh.net/avform.htm#Crs
+ double dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1);
+ double cos_p2lat = cos(get_as_radian<1>(p2));
+
+ // "An alternative formula, not requiring the pre-computation of d"
+ return atan2(sin(dlon) * cos_p2lat,
+ cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2))
+ - sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon));
+ }
+
+};
+
- } // namespace distance
+}} // namespace strategy::distance
-} // namespace strategy
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
@@ -155,4 +155,4 @@
} // namespace ggl
-#endif // GGL_STRATEGY_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
+#endif // GGL_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/distance_haversine.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/distance_haversine.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/distance_haversine.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_STRATEGY_SPHERICAL_DISTANCE_HPP
-#define GGL_STRATEGY_SPHERICAL_DISTANCE_HPP
+#ifndef GGL_STRATEGIES_SPHERICAL_DISTANCE_HAVERSINE_HPP
+#define GGL_STRATEGIES_SPHERICAL_DISTANCE_HAVERSINE_HPP
#include <ggl/core/cs.hpp>
@@ -15,72 +15,70 @@
#include <ggl/core/radian_access.hpp>
-#include <ggl/strategies/strategy_traits.hpp>
+#include <ggl/strategies/distance.hpp>
#include <ggl/strategies/distance_result.hpp>
-#include <ggl/util/get_cs_as_radian.hpp>
-
-
namespace ggl
{
-namespace strategy
-{
-
- namespace distance
- {
-
- /*!
- \brief Distance calculation for spherical coordinates on a perfect sphere using haversine
- \ingroup distance
- \tparam P1 first point type
- \tparam P2 optional second point type
- \author Adapted from: http://williams.best.vwh.net/avform.htm
- \see http://en.wikipedia.org/wiki/Great-circle_distance
- \note It says: <em>The great circle distance d between two points with coordinates {lat1,lon1} and {lat2,lon2} is given by:
- d=acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lon1-lon2))
- A mathematically equivalent formula, which is less subject to rounding error for short distances is:
- d=2*asin(sqrt((sin((lat1-lat2)/2))^2 + cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))</em>
- */
- template <typename P1, typename P2 = P1>
- class haversine
- {
- public :
- typedef double return_type;
- typedef P1 point_type;
-
- inline haversine(double r = 1.0)
- : m_radius(r)
- {}
-
- inline return_type operator()(P1 const& p1, P2 const& p2) const
- {
- return calc(get_as_radian<0>(p1), get_as_radian<1>(p1),
- get_as_radian<0>(p2), get_as_radian<1>(p2));
- }
-
- private :
- double m_radius;
- typedef typename coordinate_type<P1>::type T1;
- typedef typename coordinate_type<P2>::type T2;
-
- inline return_type calc(T1 const& lon1, T1 const& lat1, T2 const& lon2, T2 const& lat2) const
- {
- double a = math::hav(lat2 - lat1) + cos(lat1) * cos(lat2) * math::hav(lon2 - lon1);
- double c = 2.0 * asin(sqrt(a));
- return return_type(m_radius * c);
- }
- };
+namespace strategy { namespace distance {
+/*!
+ \brief Distance calculation for spherical coordinates
+ on a perfect sphere using haversine
+ \ingroup distance
+ \tparam P1 first point type
+ \tparam P2 optional second point type
+ \author Adapted from: http://williams.best.vwh.net/avform.htm
+ \see http://en.wikipedia.org/wiki/Great-circle_distance
+ \note It says: <em>The great circle distance d between two
+ points with coordinates {lat1,lon1} and {lat2,lon2} is given by:
+ d=acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lon1-lon2))
+ A mathematically equivalent formula, which is less subject
+ to rounding error for short distances is:
+ d=2*asin(sqrt((sin((lat1-lat2)/2))^2
+ + cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
+ </em>
+*/
+template <typename Point1, typename Point2 = Point1>
+class haversine
+{
+public :
+ typedef Point1 first_point_type;
+ typedef Point2 second_point_type;
+ typedef double return_type;
+
+ inline haversine(double r = 1.0)
+ : m_radius(r)
+ {}
- } // namespace distance
-
-
+ inline return_type apply(Point1 const& p1, Point2 const& p2) const
+ {
+ return calculate(get_as_radian<0>(p1), get_as_radian<1>(p1),
+ get_as_radian<0>(p2), get_as_radian<1>(p2));
+ }
+
+private :
+ double m_radius;
+ typedef typename coordinate_type<Point1>::type coordinate_type1;
+ typedef typename coordinate_type<Point2>::type coordinate_type2;
+
+ inline return_type calculate(coordinate_type1 const& lon1,
+ coordinate_type1 const& lat1,
+ coordinate_type2 const& lon2,
+ coordinate_type2 const& lat2) const
+ {
+ double a = math::hav(lat2 - lat1)
+ + cos(lat1) * cos(lat2) * math::hav(lon2 - lon1);
+ double c = 2.0 * asin(sqrt(a));
+ return return_type(m_radius * c);
+ }
+};
-} // namespace strategy
+}} // namespace strategy::distance
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
@@ -114,4 +112,4 @@
} // namespace ggl
-#endif // GGL_STRATEGY_SPHERICAL_DISTANCE_HPP
+#endif // GGL_STRATEGIES_SPHERICAL_DISTANCE_HAVERSINE_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/sph_envelope.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/sph_envelope.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,175 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_GEOMETRY_STRATEGIES_SPHERICAL_SPH_ENVELOPE_HPP
-#define GGL_GEOMETRY_STRATEGIES_SPHERICAL_SPH_ENVELOPE_HPP
-
-#include <boost/numeric/conversion/bounds.hpp>
-#include <boost/numeric/conversion/cast.hpp>
-
-// NOTE: maybe evaluate/rework this using new "compare" strategy
-// - implement "compare" for latlong (e.g. return true if distance-difference < 90 deg, so 170 < -170 but 90 > -180)
-
-
-namespace ggl
-{
-namespace strategy
-{
- namespace envelope
- {
- // envelope calculation strategy for latlong-points
- namespace shift
- {
- template <typename D>
- struct shifted
- {
- };
-
- template<>
- struct shifted<radian>
- {
- inline static double shift() { return math::two_pi; }
- };
- template<>
- struct shifted<degree>
- {
- inline static double shift() { return 360.0; }
- };
-
- }
-
- /*!
- \par Algorithm:
- The envelope of latlong-points cannot be implemented as for xy-points. Suppose the
- envelope of the Aleutian Islands must be calculated. The span from 170E to 170W, from -170 to 170.
- Of course the real envelope is not -170..170 but 170..-170.
- On the other hand, there might be geometries that indeed span from -170 to 170. If there are
- two points, it is not known. If there are points in between, we probably should take the shorter
- range. So we do that for the moment.
- We shift coordinates and do as if we live in a world with longitude coordinates from 0 - 360,
- where 0 is still at Greenwich. Longitude ranges are then calculated twice: one for real world,
- one for the shifted world.
- The shortest range is taken for the bounding box. This might have coordinates > 180
- */
-
- template <typename P, typename B>
- struct grow_ll
- {
-
- struct state
- {
- typedef typename coordinate_type<B>::type T;
- bool has_west;
- T min_lat, max_lat;
- T min_lon1, min_lon2, max_lon1, max_lon2;
- B& mbr;
-
- state(B& b)
- : mbr(b)
- , has_west(false)
- , min_lat(boost::numeric::bounds<T>::highest())
- , min_lon1(boost::numeric::bounds<T>::highest())
- , min_lon2(boost::numeric::bounds<T>::highest())
- , max_lat(boost::numeric::bounds<T>::lowest())
- , max_lon1(boost::numeric::bounds<T>::lowest())
- , max_lon2(boost::numeric::bounds<T>::lowest())
- {}
-
- template <typename T>
- void take_minmax(const T& value, T& min_value, T& max_value)
- {
- if (value < min_value)
- {
- min_value = value;
- }
- if (value > max_value)
- {
- max_value = value;
- }
- }
-
- void grow(const P& p)
- {
- // For latitude, we can take the min/max
- take_minmax(get<1>(p), min_lat, max_lat);
-
-
- // For longitude, we do the same...
- take_minmax(get<0>(p), min_lon1, max_lon1);
-
- // But we also add 360 (2pi) if it is negative
- T value = get<0>(p);
- while(value < 0)
- {
- has_west = true;
- value += shift::shifted<typename coordinate_system<P>::type::units>::shift();
- }
- while (value > math::two_pi)
- {
- value -= shift::shifted<typename coordinate_system<P>::type::units>::shift();
- }
- take_minmax(value, min_lon2, max_lon2);
- }
-
- ~state()
- //void envelope(box<PB>& mbr)
- {
- // For latitude it is easy
- set<min_corner, 1>(mbr, min_lat);
- set<max_corner, 1>(mbr, max_lat);
-
- if (! has_west)
- {
- set<min_corner, 0>(mbr, min_lon1);
- set<max_corner, 0>(mbr, max_lon1);
- }
- else
- {
- // Get both ranges
- T diff1 = max_lon1 - min_lon1;
- T diff2 = max_lon2 - min_lon2;
-
- //std::cout << "range 1: " << min_lon1 * math::r2d << ".." << max_lon1 * math::r2d << std::endl;
- //std::cout << "range 2: " << min_lon2 * math::r2d << ".." << max_lon2 * math::r2d << std::endl;
-
- if (diff1 <= diff2)
- {
- set<min_corner, 0>(mbr, min_lon1);
- set<max_corner, 0>(mbr, max_lon1);
- }
- else
- {
- set<min_corner, 0>(mbr, min_lon2);
- set<max_corner, 0>(mbr, max_lon2);
- }
- }
- }
- };
-
- typedef state state_type;
-
- void operator()(const P& p, state_type& s) const
- {
- s.grow(p);
- }
- };
- } // namespace envelope
-} // namespace strategy
-
-
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-template <typename P, typename B>
-struct strategy_envelope<geographic_tag, geographic_tag, P, B>
-{
- typedef strategy::envelope::grow_ll<P, B> type;
-};
-#endif
-
-} // namespace ggl
-
-#endif // GGL_GEOMETRY_STRATEGIES_SPHERICAL_SPH_ENVELOPE_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/strategies.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/strategies.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/strategies.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -10,26 +10,34 @@
#define GGL_STRATEGIES_HPP
-#include <ggl/strategies/strategy_traits.hpp>
+#include <ggl/strategies/tags.hpp>
+
+#include <ggl/strategies/area.hpp>
+#include <ggl/strategies/centroid.hpp>
+#include <ggl/strategies/compare.hpp>
+#include <ggl/strategies/convex_hull.hpp>
+#include <ggl/strategies/distance.hpp>
+#include <ggl/strategies/parse.hpp>
+#include <ggl/strategies/point_in_poly.hpp>
+#include <ggl/strategies/side.hpp>
+#include <ggl/strategies/transform.hpp>
#include <ggl/strategies/cartesian/area_by_triangles.hpp>
#include <ggl/strategies/cartesian/centroid_bashein_detmer.hpp>
-#include <ggl/strategies/cartesian/cart_compare.hpp>
-#include <ggl/strategies/cartesian/cart_distance.hpp>
-#include <ggl/strategies/cartesian/cart_envelope.hpp>
-#include <ggl/strategies/cartesian/cart_side.hpp>
+#include <ggl/strategies/cartesian/distance_pythagoras.hpp>
+#include <ggl/strategies/cartesian/distance_projected_point.hpp>
#include <ggl/strategies/cartesian/point_in_poly_franklin.hpp>
#include <ggl/strategies/cartesian/point_in_poly_crossings_multiply.hpp>
+#include <ggl/strategies/cartesian/side_by_triangle.hpp>
+#include <ggl/strategies/spherical/area_huiller.hpp>
#include <ggl/strategies/spherical/distance_haversine.hpp>
#include <ggl/strategies/spherical/distance_cross_track.hpp>
+#include <ggl/strategies/spherical/compare_circular.hpp>
-#include <ggl/strategies/spherical/area_huiller.hpp>
-#include <ggl/strategies/spherical/sph_envelope.hpp>
-
-#include <ggl/strategies/agnostic/agn_convex_hull.hpp>
-#include <ggl/strategies/agnostic/simplify_douglas_peucker.hpp>
+#include <ggl/strategies/agnostic/hull_graham_andrew.hpp>
#include <ggl/strategies/agnostic/point_in_poly_winding.hpp>
+#include <ggl/strategies/agnostic/simplify_douglas_peucker.hpp>
#include <ggl/strategies/strategy_transform.hpp>
Deleted: sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_traits.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_traits.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,231 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_STRATEGIES_STRATEGY_TRAITS_HPP
-#define GGL_STRATEGIES_STRATEGY_TRAITS_HPP
-
-#include <ggl/core/cs.hpp>
-#include <ggl/strategies/distance_result.hpp>
-
-// File containing strategy traits classes, to be specialized in other files
-// (This file might be splitted resulting into several small files)
-
-namespace ggl
-{
-
-namespace strategy
-{
- /*!
- \brief Indicate compiler/library user that strategy is not implemented.
- \details The strategy_traits class define strategies for point types or for point type
- combinations. If there is no implementation for that specific point type, or point type
- combination, the calculation cannot be done. To indicate this, this not_implemented
- class is used as a typedef stub.
-
- */
- struct not_implemented {};
-}
-
-
-/*!
- \brief Traits class binding an area strategy to a coordinate system
- \ingroup area
- \tparam T tag of coordinate system
- \tparam P point-type
-*/
-template <typename T, typename P>
-struct strategy_area
-{
- typedef strategy::not_implemented type;
-};
-
-/*!
- \brief Traits class binding a distance strategy to a (possibly two) coordinate system(s)
- \ingroup distance
- \tparam T1 tag of coordinate system of first point type
- \tparam T2 tag of coordinate system of second point type
- \tparam P1 first point-type
- \tparam P2 second point-type
-*/
-template <typename T1, typename T2, typename P1, typename P2>
-struct strategy_distance
-{
- typedef strategy::not_implemented type;
-};
-
-/*!
- \brief Traits class binding a distance-to-segment strategy to a (possibly two) coordinate system(s)
- \ingroup distance
- \tparam CsTag1 tag of coordinate system of point type
- \tparam CsTag2 tag of coordinate system of segment type, usually same as CsTag1
- \tparam Point point-type
- \tparam Segment segment-type
-*/
-template <typename CsTag1, typename CsTag2, typename Point, typename Segment>
-struct strategy_distance_segment
-{
- typedef strategy::not_implemented type;
-};
-
-
-/*!
- \brief Traits class binding a centroid calculation strategy to a coordinate system
- \ingroup centroid
- \tparam T tag of coordinate system
- \tparam P point-type
- \tparam PS segment point-type
-*/
-template <typename T, typename P, typename PS>
-struct strategy_centroid
-{
- typedef strategy::not_implemented type;
-};
-
-
-/*!
- \brief Traits class binding envelope strategy to a coordinate system
- \ingroup envelope
- \tparam TP tag of coordinate system of point
- \tparam TB tag of coordinate system of box, usually same as TP
- \tparam P point-type
- \tparam B box-type
-*/
-template <typename TP, typename TB, typename P, typename B>
-struct strategy_envelope
-{
- typedef strategy::not_implemented type;
-};
-
-
-/*!
- \brief Traits class binding a convex hull calculation strategy to a coordinate system
- \ingroup convex_hull
- \tparam T tag of coordinate system
- \tparam P point-type of input points
-*/
-template <typename T, typename P>
-struct strategy_convex_hull
-{
- typedef strategy::not_implemented type;
-};
-
-
-/*!
- \brief Traits class binding a within determination strategy to a coordinate system
- \ingroup within
- \tparam TP tag of coordinate system of point-type
- \tparam TS tag of coordinate system of segment-type
- \tparam P point-type of input points
- \tparam PS point-type of input segment-points
-*/
-template <typename TP, typename TS, typename P, typename PS>
-struct strategy_within
-{
- typedef strategy::not_implemented type;
-};
-
-
-/*!
- \brief Traits class binding a side determination strategy to a coordinate system
- \ingroup util
- \tparam T tag of coordinate system of point-type
- \tparam P point-type of input points
- \tparam PS point-type of input points
-*/
-template <typename T, typename P, typename PS = P>
-struct strategy_side
-{
- typedef strategy::not_implemented type;
-};
-
-
-
-/*!
- \brief Traits class binding a comparing strategy to a coordinate system
- \ingroup util
- \tparam T tag of coordinate system of point-type
- \tparam P point-type
- \tparam D dimension to compare
-*/
-template <typename T, typename P, size_t D>
-struct strategy_compare
-{
- typedef strategy::not_implemented type;
-};
-
-
-/*!
- \brief Traits class binding a transformation strategy to a coordinate system
- \ingroup transform
- \details Can be specialized
- - per coordinate system family (tag)
- - per coordinate system (or groups of them)
- - per dimension
- - per point type
- \tparam CS_TAG 1,2 coordinate system tags
- \tparam CS 1,2 coordinate system
- \tparam D 1, 2 dimension
- \tparam P 1, 2 point type
- */
-template <typename CS_TAG1, typename CS_TAG2,
- typename CS1, typename CS2,
- size_t D1, size_t D2,
- typename P1, typename P2>
-struct strategy_transform
-{
- typedef strategy::not_implemented type;
-};
-
-
-/*!
- \brief Traits class binding a parsing strategy to a coordinate system
- \ingroup parse
- \tparam T tag of coordinate system of point-type
- \tparam CS coordinate system
-*/
-template <typename T, typename CS>
-struct strategy_parse
-{
- typedef strategy::not_implemented type;
-};
-
-
-
-
-/*!
- \brief Shortcut to define return type of distance strategy
- \ingroup distance
- \tparam G1 first geometry
- \tparam G2 second geometry
- */
-template <typename G1, typename G2 = G1>
-struct distance_result
-{
- typedef typename point_type<G1>::type P1;
- typedef typename point_type<G2>::type P2;
- typedef typename strategy_distance<
- typename cs_tag<P1>::type,
- typename cs_tag<P2>::type, P1, P2>::type S;
- typedef typename S::return_type type;
-};
-
-
-
-struct strategy_tag_unknown {};
-struct strategy_tag_distance_point_point {};
-struct strategy_tag_distance_point_segment {};
-
-template <typename T>
-struct strategy_tag
-{
- typedef strategy_tag_unknown type;
-};
-
-} // namespace ggl
-
-#endif // GGL_STRATEGIES_STRATEGY_TRAITS_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_transform.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_transform.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_transform.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,8 +6,8 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_STRATEGY_TRANSFORM_HPP
-#define GGL_STRATEGY_TRANSFORM_HPP
+#ifndef GGL_STRATEGIES_STRATEGY_TRANSFORM_HPP
+#define GGL_STRATEGIES_STRATEGY_TRANSFORM_HPP
#include <cstddef>
#include <cmath>
@@ -355,4 +355,4 @@
} // namespace ggl
-#endif // GGL_STRATEGY_TRANSFORM_HPP
+#endif // GGL_STRATEGIES_STRATEGY_TRANSFORM_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/tags.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/tags.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,44 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_STRATEGIES_TAGS_HPP
+#define GGL_STRATEGIES_TAGS_HPP
+
+
+namespace ggl
+{
+
+namespace strategy
+{
+ /*!
+ \brief Indicate compiler/library user that strategy is not implemented.
+ \details Strategies are defined for point types or for point type
+ combinations. If there is no implementation for that specific point type, or point type
+ combination, the calculation cannot be done. To indicate this, this not_implemented
+ class is used as a typedef stub.
+
+ */
+ struct not_implemented {};
+}
+
+
+
+
+struct strategy_tag_unknown {};
+struct strategy_tag_distance_point_point {};
+struct strategy_tag_distance_point_segment {};
+
+template <typename T>
+struct strategy_tag
+{
+ typedef strategy_tag_unknown type;
+};
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_TAGS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/transform.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/transform.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,50 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_STRATEGIES_TRANSFORM_HPP
+#define GGL_STRATEGIES_TRANSFORM_HPP
+
+#include <cstddef>
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+ \brief Traits class binding a transformation strategy to a coordinate system
+ \ingroup transform
+ \details Can be specialized
+ - per coordinate system family (tag)
+ - per coordinate system (or groups of them)
+ - per dimension
+ - per point type
+ \tparam CoordinateSystemTag 1,2 coordinate system tags
+ \tparam CoordinateSystem 1,2 coordinate system
+ \tparam D 1, 2 dimension
+ \tparam Point 1, 2 point type
+ */
+template
+<
+ typename CoordinateSystemTag1, typename CoordinateSystemTag2,
+ typename CoordinateSystem1, typename CoordinateSystem2,
+ std::size_t Dimension1, std::size_t Dimension2,
+ typename Point1, typename Point2
+>
+struct strategy_transform
+{
+ typedef strategy::not_implemented type;
+};
+
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_TRANSFORM_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/matrix_transformers.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/matrix_transformers.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/matrix_transformers.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -6,11 +6,11 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef GGL_STRATEGIES_MATRIX_TRANSFORMERS_HPP
-#define GGL_STRATEGIES_MATRIX_TRANSFORMERS_HPP
+#ifndef GGL_STRATEGIES_TRANSFORM_MATRIX_TRANSFORMERS_HPP
+#define GGL_STRATEGIES_TRANSFORM_MATRIX_TRANSFORMERS_HPP
-// Remove the ublas checking, otherwise the inverse might fail
+// Remove the ublas checking, otherwise the inverse might fail
// (while nothing seems to be wrong)
#define BOOST_UBLAS_TYPE_CHECK 0
@@ -359,4 +359,4 @@
} // namespace ggl
-#endif // GGL_STRATEGIES_MATRIX_TRANSFORMERS_HPP
+#endif // GGL_STRATEGIES_TRANSFORM_MATRIX_TRANSFORMERS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/add_const_if_c.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/add_const_if_c.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,50 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. 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 GGL_UTIL_ADD_CONST_IF_C_HPP
+#define GGL_UTIL_ADD_CONST_IF_C_HPP
+
+
+#include <boost/mpl/if.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+ \brief Meta-function to define a const or non const type
+ \ingroup utility
+ \details If the boolean template parameter is true, the type parameter
+ will be defined as const, otherwise it will be defined as it was.
+ This meta-function is used to have one implementation for both
+ const and non const references
+ \note This traits class is completely independant from GGL and might be a
+ separate addition to Boost
+ \note Used in ggl::for_each
+ \par Example
+ \code
+ void foo(typename add_const_if_c<IsConst, Point>::type& point)
+ \endcode
+*/
+template <bool IsConst, typename Type>
+struct add_const_if_c
+{
+ typedef typename boost::mpl::if_c
+ <
+ IsConst,
+ const Type,
+ Type
+ >::type type;
+};
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_UTIL_ADD_CONST_IF_C_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/util/as_range.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/util/as_range.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/as_range.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -14,116 +14,85 @@
#include <ggl/core/exterior_ring.hpp>
#include <ggl/core/is_multi.hpp>
-#include <ggl/core/ring_type.hpp>
#include <ggl/core/tag.hpp>
#include <ggl/core/tags.hpp>
-namespace ggl {
+#include <ggl/util/add_const_if_c.hpp>
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch
-{
-template <typename GeometryTag, bool IsMulti, typename Geometry>
-struct as_range_type
-{
- typedef Geometry type;
-};
+namespace ggl {
-template <typename Geometry>
-struct as_range_type<polygon_tag, false, Geometry>
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
{
- typedef typename ring_type<Geometry>::type type;
-};
-
-template <typename GeometryTag, typename Geometry, typename Range>
+template <typename GeometryTag, typename Geometry, typename Range, bool IsConst>
struct as_range
{
- static inline Range & get(Geometry & input)
+ static inline typename add_const_if_c<IsConst, Range>::type& get(
+ typename add_const_if_c<IsConst, Geometry>::type& input)
{
return input;
}
};
-template <typename Geometry, typename Range>
-struct as_range<polygon_tag, Geometry, Range>
-{
- static inline Range & get(Geometry & input)
- {
- return exterior_ring(input);
- }
-};
-
-
-template <typename GeometryTag, typename Geometry, typename Range>
-struct as_range_const
-{
- static inline Range const& get(Geometry const& input)
- {
- return input;
- }
-};
-template <typename Geometry, typename Range>
-struct as_range_const<polygon_tag, Geometry, Range>
+template <typename Geometry, typename Range, bool IsConst>
+struct as_range<polygon_tag, Geometry, Range, IsConst>
{
- static inline Range const& get(Geometry const& input)
+ static inline typename add_const_if_c<IsConst, Range>::type& get(
+ typename add_const_if_c<IsConst, Geometry>::type& input)
{
return exterior_ring(input);
}
};
+
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
/*!
-\brief Meta-function utility returning either type itself, or outer ring
- \details Utility to handle polygon's outer ring as a range
-\ingroup utility
-*/
-template <typename Geometry>
-struct as_range_type
-{
- typedef typename dispatch::as_range_type
- <
- typename tag<Geometry>::type,
- is_multi<Geometry>::type::value,
- Geometry
- >::type type;
-};
-
-/*!
\brief Function getting either the range (ring, linestring) itself
-or the outer ring
- \details Utility to handle polygon's outer ring as a range
+or the outer ring (polygon)
+\details Utility to handle polygon's outer ring as a range
\ingroup utility
*/
template <typename Range, typename Geometry>
-inline Range const& as_range(Geometry const& input)
+inline Range& as_range(Geometry& input)
{
- return dispatch::as_range_const
+ return dispatch::as_range
<
typename tag<Geometry>::type,
Geometry,
- Range
+ Range,
+ false
>::get(input);
}
+
+/*!
+\brief Function getting either the range (ring, linestring) itself
+or the outer ring (polygon), const version
+\details Utility to handle polygon's outer ring as a range
+\ingroup utility
+*/
template <typename Range, typename Geometry>
-inline Range& as_range(Geometry& input)
+inline Range const& as_range(Geometry const& input)
{
return dispatch::as_range
<
typename tag<Geometry>::type,
Geometry,
- Range
+ Range,
+ true
>::get(input);
}
+
} // namespace ggl
+
#endif // GGL_UTIL_AS_RANGE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/for_each_range.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/for_each_range.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,116 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// 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 GGL_UTIL_FOR_EACH_RANGE_HPP
+#define GGL_UTIL_FOR_EACH_RANGE_HPP
+
+
+#include <boost/concept/requires.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/is_multi.hpp>
+
+#include <ggl/util/add_const_if_c.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace for_each {
+
+
+template <typename Range, typename Actor, bool IsConst>
+struct fe_range_range
+{
+ static inline void apply(
+ typename add_const_if_c<IsConst, Range>::type& range,
+ Actor& actor)
+ {
+ actor.apply(range);
+ }
+};
+
+
+template <typename Polygon, typename Actor, bool IsConst>
+struct fe_range_polygon
+{
+ static inline void apply(
+ typename add_const_if_c<IsConst, Polygon>::type& polygon,
+ Actor& actor)
+ {
+ actor.apply(exterior_ring(polygon));
+
+ // TODO: If some flag says true, also do the inner rings.
+ // for convex hull, it's not necessary
+ }
+};
+
+
+}} // namespace detail::for_each
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Tag,
+ bool IsMulti,
+ typename Geometry,
+ typename Actor,
+ bool IsConst
+>
+struct for_each_range {};
+
+
+template <typename Linestring, typename Actor, bool IsConst>
+struct for_each_range<linestring_tag, false, Linestring, Actor, IsConst>
+ : detail::for_each::fe_range_range<Linestring, Actor, IsConst>
+{};
+
+
+template <typename Ring, typename Actor, bool IsConst>
+struct for_each_range<ring_tag, false, Ring, Actor, IsConst>
+ : detail::for_each::fe_range_range<Ring, Actor, IsConst>
+{};
+
+
+template <typename Polygon, typename Actor, bool IsConst>
+struct for_each_range<polygon_tag, false, Polygon, Actor, IsConst>
+ : detail::for_each::fe_range_polygon<Polygon, Actor, IsConst>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template <typename Geometry, typename Actor>
+inline void for_each_range(Geometry const& geometry, Actor& actor)
+{
+ dispatch::for_each_range
+ <
+ typename tag<Geometry>::type,
+ is_multi<Geometry>::type::value,
+ Geometry,
+ Actor,
+ true
+ >::apply(geometry, actor);
+}
+
+
+} // namespace ggl
+
+
+#endif // GGL_UTIL_FOR_EACH_RANGE_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/util/get_cs_as_radian.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/util/get_cs_as_radian.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,43 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Bruno Lalande 2008, 2009
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. 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 GGL_UTIL_GET_CS_AS_RADIAN_HPP
-#define GGL_UTIL_GET_CS_AS_RADIAN_HPP
-
-#include <ggl/core/cs.hpp>
-
-namespace ggl {
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail {
-
- template <typename CoordinateSystem>
- struct get_cs_as_radian {};
-
- template <typename Units>
- struct get_cs_as_radian<cs::geographic<Units> >
- {
- typedef cs::geographic<radian> type;
- };
-
- template <typename Units>
- struct get_cs_as_radian<cs::spherical<Units> >
- {
- typedef cs::spherical<radian> type;
- };
-
-} // namespace detail
-#endif
-
-
-
-
-} // namespace ggl
-
-#endif // GGL_UTIL_GET_CS_AS_RADIAN_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/util/less.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/util/less.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,64 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_UTIL_LESS_HPP
-#define GGL_UTIL_LESS_HPP
-
-
-namespace ggl
-{
-
-/*!
- \brief Less predicate for usage in e.g. std::map
-*/
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail
-{
-
-template <typename P, std::size_t Dimension, std::size_t DimensionCount>
-struct less
-{
- static inline bool apply(P const& left, P const& right)
- {
- typedef typename ggl::coordinate_type<P>::type coordinate_type;
- coordinate_type const cleft = ggl::get<Dimension>(left);
- coordinate_type const cright = ggl::get<Dimension>(right);
-
- return ggl::math::equals(cleft, cright)
- ? less<P, Dimension + 1, DimensionCount>::apply(left, right)
- : cleft < cright;
- ;
- }
-};
-
-template <typename P, std::size_t DimensionCount>
-struct less<P, DimensionCount, DimensionCount>
-{
- static inline bool apply(P const&, P const&)
- {
- return false;
- }
-};
-
-}
-#endif
-
-template <typename P>
-struct less
-{
- inline bool operator()(P const& left, P const& right) const
- {
- return detail::less<P, 0,
- ggl::dimension<P>::type::value>::apply(left, right);
- }
-};
-
-} // namespace ggl
-
-#endif // GGL_UTIL_LESS_HPP
Deleted: sandbox/ggl/formal_review_request/boost/ggl/util/loop.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/util/loop.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
+++ (empty file)
@@ -1,85 +0,0 @@
-// Generic Geometry Library
-//
-// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
-// Copyright Bruno Lalande 2008, 2009
-// 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 GGL_UTIL_LOOP_HPP
-#define GGL_UTIL_LOOP_HPP
-
-#include <boost/range/functions.hpp>
-#include <boost/range/metafunctions.hpp>
-
-#include <ggl/geometries/segment.hpp>
-
-namespace ggl
-{
-
-/*!
- \brief Loops through segments of a container and call specified functor for all segments.
- \ingroup loop
- \details for_each like implementation to:
- - walk over const segments of a linestring/polygon
- - be able to break out the loop (if the functor returns false)
- - have a const functor and keep state in separate state-object
- - we still keep the "functor" here so it might be a function or an object, at this place
- - in most algorithms the typename F::state_type is used; in those places it must be an object
-
- \tparam R range type, for example a vector, linestring, linear_ring
- \tparam F functor type, class or function, not modified by the algorithm
- \tparam S state type, might be modified
- \param range range (linestring iterator pair,vector,list,deque) containing points
- \param functor functor which is called at each const segment
- \param state state, specified separately from the strategy functor
- \return false if the functor returns false, otherwise true
- \par Concepts
- - \a V
- - const_iterator begin()
- - const_iterator end()
- - value_type
- - \a F
- - <em>if it is a function functor</em>: bool \b function (const segment&, state&)
- - <em>if it is a class functor</em>: bool operator()(const segment&, state&) const
- - \a S
- - no specific requirements here, requirments given by F
- \note Some algorithms from the Generic Geometry Library, for example within, centroid,
- use this method.
- \par Examples:
- First example, using a class functor
- \dontinclude doxygen_examples.cpp
- \skip example_loop1
- \line {
- \until //:\\
- Second example, using a function functor and latlong coordinates
- \dontinclude doxygen_examples.cpp
- \skip example_loop2
- \line {
- \until //:\\
-*/
-template<typename R, typename F, typename S>
-inline bool loop(R const& range, F const& functor, S& state)
-{
- typedef typename boost::range_const_iterator<R>::type iterator_type;
-
- iterator_type it = boost::begin(range);
- if (it != boost::end(range))
- {
- iterator_type previous = it++;
- while(it != boost::end(range))
- {
- segment<const typename boost::range_value<R>::type> s(*previous, *it);
- if (! functor(s, state))
- {
- return false;
- }
- previous = it++;
- }
- }
- return true;
-}
-
-} // namespace ggl
-
-#endif // GGL_UTIL_LOOP_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/util/math.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/util/math.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/math.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -56,13 +56,15 @@
/*!
\brief returns true if both arguments are equal.
-
- equals returns true if both arguments are equal.
+ \ingroup utility
\param a first argument
\param b second argument
\return true if a == b
- \note If both a and b are of an integral type, comparison is done by ==. If one of the types
- is floating point, comparison is done by abs and comparing with epsilon.
+ \note If both a and b are of an integral type, comparison is done by ==.
+ If one of the types is floating point, comparison is done by abs and
+ comparing with epsilon. If one of the types is non-fundamental, it might
+ be a high-precision number and comparison is done using the == operator
+ of that class.
*/
template <typename T1, typename T2>
@@ -85,6 +87,7 @@
/*!
\brief Calculates the haversine of an angle
+ \ingroup utility
\note See http://en.wikipedia.org/wiki/Haversine_formula
haversin(alpha) = sin2(alpha/2)
*/
@@ -98,7 +101,7 @@
/*!
\brief Short utility to return the square
-
+\ingroup utility
\param value Value to calculate the square from
\return The squared value
*/
Added: sandbox/ggl/formal_review_request/boost/ggl/util/range_iterator_const_if_c.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/range_iterator_const_if_c.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -0,0 +1,45 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. 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 GGL_UTIL_RANGE_ITERATOR_CONST_IF_C_HPP
+#define GGL_UTIL_RANGE_ITERATOR_CONST_IF_C_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+ \brief Meta-function to define a const or non const boost range iterator
+ \ingroup utility
+ \details Is used to have one implementation for both const and non const
+ range iterators
+ \note This traits class is completely independant from GGL and might be a
+ separate addition to Boost
+ \note Used in ggl::for_each
+*/
+template <bool IsConst, typename Range>
+struct range_iterator_const_if_c
+{
+ typedef typename boost::mpl::if_c
+ <
+ IsConst,
+ typename boost::range_const_iterator<Range>::type,
+ typename boost::range_iterator<Range>::type
+ >::type type;
+};
+
+
+} // namespace ggl
+
+
+#endif // GGL_UTIL_RANGE_ITERATOR_CONST_IF_C_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/util/select_calculation_type.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/util/select_calculation_type.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/select_calculation_type.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -14,19 +14,16 @@
#include <ggl/util/select_coordinate_type.hpp>
-/*!
-\defgroup utility utility: utilities
-*/
namespace ggl
{
/*!
- \brief Utility selecting the "calculation" type
+ \brief Meta-function selecting the "calculation" type
\details Based on two input point types, and an input calculation type,
- (which usually defaults to void), this meta-function selects the
- most appropriate:
+ (which defaults to void in the calling function), this meta-function
+ selects the most appropriate:
- if calculation type is specified, that one is used,
- if it is void, the most precise of the two points is used
\ingroup utility
@@ -47,6 +44,8 @@
>::type type;
};
+
} // namespace ggl
+
#endif // GGL_UTIL_SELECT_CALCULATION_TYPE_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/util/select_coordinate_type.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/util/select_coordinate_type.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/select_coordinate_type.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -13,8 +13,9 @@
#include <ggl/core/coordinate_type.hpp>
#include <ggl/util/select_most_precise.hpp>
+
/*!
-\defgroup utility utility: utilities
+\defgroup utility utility: utility meta-functions and functions
*/
namespace ggl
@@ -22,7 +23,8 @@
/*!
- \brief Utility selecting the most precise coordinate type of two geometries
+ \brief Meta-function selecting the most precise coordinate type
+ of two geometries
\ingroup utility
*/
template <typename T1, typename T2>
@@ -35,6 +37,8 @@
>::type type;
};
+
} // namespace ggl
+
#endif // GGL_UTIL_SELECT_COORDINATE_TYPE_HPP
Modified: sandbox/ggl/formal_review_request/boost/ggl/util/select_most_precise.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/util/select_most_precise.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/select_most_precise.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -13,10 +13,6 @@
#include <boost/type_traits.hpp>
-/*!
-\defgroup utility utility: utilities
-*/
-
namespace ggl
{
@@ -92,7 +88,7 @@
/*!
- \brief Traits class to select, of two types, the most accurate type for
+ \brief Meta-function to select, of two types, the most accurate type for
calculations
\ingroup utility
\details select_most_precise classes, compares two types on compile time.
@@ -104,7 +100,7 @@
type from two types. It takes the most accurate, but does not promote
afterwards.
\note This traits class is completely independant from GGL and might be a
- separate (small) library in Boost
+ separate addition to Boost
\note If the input is a non-fundamental type, it might be a calculation
type such as a GMP-value or another high precision value. Therefore,
if one is non-fundamental, that one is chosen.
Modified: sandbox/ggl/formal_review_request/boost/ggl/util/write_dsv.hpp
==============================================================================
--- sandbox/ggl/formal_review_request/boost/ggl/util/write_dsv.hpp (original)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/write_dsv.hpp 2009-11-02 10:50:56 EST (Mon, 02 Nov 2009)
@@ -167,8 +167,6 @@
os << settings.list_open;
- // TODO: check EMPTY here
-
for (iterator_type it = boost::begin(range);
it != boost::end(range);
++it)
@@ -317,26 +315,18 @@
#endif // DOXYGEN_NO_DISPATCH
-/*!
-\brief Generic geometry template manipulator class, takes corresponding output class from traits class
-\ingroup dsv
-\details Stream manipulator, streams geometry classes as \ref DSV streams
-\par Example:
-Small example showing how to use the dsv class
-\dontinclude doxygen_examples.cpp
-\skip example_as_dsv_point
-\line {
-\until }
-\note the template parameter must be specified. If that is inconvient, users might use streamdsv
-which streams geometries as manipulators, or the object generator make_dsv
-*/
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dsv {
+
+
+
template <typename Geometry>
class dsv_manipulator
{
public:
inline dsv_manipulator(Geometry const& g,
- detail::dsv::dsv_settings const& settings)
+ dsv_settings const& settings)
: m_geometry(g)
, m_settings(settings)
{}
@@ -358,15 +348,24 @@
private:
Geometry const& m_geometry;
- detail::dsv::dsv_settings m_settings;
+ dsv_settings m_settings;
};
+}} // namespace detail::dsv
+#endif // DOXYGEN_NO_DETAIL
+
+
/*!
\brief Main DSV-streaming function
-\ingroup dsv
+\details DSV stands for Delimiter Separated Values. Geometries can be streamed
+ as DSV. There are defaults for all separators.
+\note Useful for examples and testing purposes
+\note With this function GeoJSON objects can be created, using the right
+ delimiters
+\ingroup utility
*/
template <typename Geometry>
-inline dsv_manipulator<Geometry> dsv(Geometry const& geometry
+inline detail::dsv::dsv_manipulator<Geometry> dsv(Geometry const& geometry
, std::string const& coordinate_separator = ", "
, std::string const& point_open = "("
, std::string const& point_close = ")"
@@ -378,7 +377,7 @@
{
concept::check<const Geometry>();
- return dsv_manipulator<Geometry>(geometry,
+ return detail::dsv::dsv_manipulator<Geometry>(geometry,
detail::dsv::dsv_settings(coordinate_separator,
point_open, point_close, point_separator,
list_open, list_close, list_separator));
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