Added difference and sym_difference

Added reverse conform std::reverse


[SVN r60001]
This commit is contained in:
Barend Gehrels
2010-02-28 21:20:07 +00:00
parent c74eb479c4
commit 7abd0bb0aa
7 changed files with 266 additions and 117 deletions

View File

@@ -9,6 +9,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DEBUG_TURN_INFO_HPP
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/visit_info.hpp>
namespace boost { namespace geometry

View File

@@ -0,0 +1,53 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
//
// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
#include <algorithm>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/algorithms/reverse.hpp>
/*!
\defgroup difference difference: difference of two geometries
*/
namespace boost { namespace geometry
{
/*!
\ingroup difference
\tparam Geometry geometry type
\param geometry the geometry to make difference
*/
template
<
typename Geometry1,
typename Geometry2,
typename Collection
>
inline void difference(Geometry1 const& geometry1,
Geometry2 geometry2, Collection& output_collection)
{
concept::check<Geometry1 const>();
concept::check<Geometry2>();
reverse(geometry2);
intersection(geometry1, geometry2, output_collection);
}
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP

View File

@@ -654,6 +654,8 @@ private:
namespace dispatch
{
// Because this is "detail" method, and most implementations will use "generic",
// we take the freedom to derive it from "generic".
template
<
typename GeometryTag1, typename GeometryTag2,
@@ -665,8 +667,15 @@ template
typename InterruptPolicy
>
struct get_turns
{
};
: detail::get_turns::get_turns_generic
<
Geometry1,
Geometry2,
Turns,
IntersectionStrategy,
AssignPolicy, InterruptPolicy
>
{};
template
@@ -776,111 +785,6 @@ struct get_turns
};
template
<
typename Ring1,
typename Ring2,
typename Turns,
typename IntersectionStrategy,
typename AssignPolicy,
typename InterruptPolicy
>
struct get_turns
<
ring_tag, ring_tag, false, false,
Ring1, Ring2,
Turns, IntersectionStrategy,
AssignPolicy, InterruptPolicy
>
: detail::get_turns::get_turns_generic
<
Ring1,
Ring2,
Turns,
IntersectionStrategy,
AssignPolicy, InterruptPolicy
>
{};
template
<
typename Polygon1,
typename Polygon2,
typename Turns,
typename IntersectionStrategy,
typename AssignPolicy,
typename InterruptPolicy
>
struct get_turns
<
polygon_tag, polygon_tag, false, false,
Polygon1, Polygon2,
Turns, IntersectionStrategy,
AssignPolicy, InterruptPolicy
>
: detail::get_turns::get_turns_generic
<
Polygon1,
Polygon2,
Turns,
IntersectionStrategy,
AssignPolicy, InterruptPolicy
>
{};
template
<
typename Polygon,
typename Ring,
typename Turns,
typename IntersectionStrategy,
typename AssignPolicy,
typename InterruptPolicy
>
struct get_turns
<
polygon_tag, ring_tag, false, false,
Polygon, Ring,
Turns, IntersectionStrategy,
AssignPolicy, InterruptPolicy
>
: detail::get_turns::get_turns_generic
<
Polygon,
Ring,
Turns,
IntersectionStrategy,
AssignPolicy, InterruptPolicy
>
{};
template
<
typename LineString1,
typename LineString2,
typename Turns,
typename IntersectionStrategy,
typename AssignPolicy,
typename InterruptPolicy
>
struct get_turns
<
linestring_tag, linestring_tag, false, false,
LineString1, LineString2,
Turns, IntersectionStrategy,
AssignPolicy, InterruptPolicy
>
: detail::get_turns::get_turns_generic
<
LineString1,
LineString2,
Turns,
IntersectionStrategy,
AssignPolicy, InterruptPolicy
>
{};
template
<
typename GeometryTag1, typename GeometryTag2,

View File

@@ -0,0 +1,141 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
//
// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP
#include <algorithm>
#include <boost/range.hpp>
#include <boost/range/functions.hpp>
#include <boost/range/metafunctions.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
/*!
\defgroup reverse reverse: reverse a geometry
This is functionally equivalent to the std::reverse algorithm.
For a linestring or a linear ring, it is exactly the same as calling the std::reverse algorithm.
For a polygon or a multi-geometry, all its rings or elements are reversed.
No check on order is applied. So a clockwise polygon (having positive area)
will be made counterclockwise (having negative area).
The first and last points are reversed as well, even if they are closed and the same.
*/
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace reverse
{
template <typename Range>
struct range_reverse
{
static inline void apply(Range& range)
{
std::reverse(boost::begin(range), boost::end(range));
}
};
template <typename Polygon>
struct polygon_reverse
{
static inline void apply(Polygon& polygon)
{
typedef typename geometry::ring_type<Polygon>::type ring_type;
typedef range_reverse<ring_type> per_range;
per_range::apply(exterior_ring(polygon));
for (typename boost::range_iterator
<
typename interior_type<Polygon>::type
>::type it = boost::begin(interior_rings(polygon));
it != boost::end(interior_rings(polygon));
++it)
{
per_range::apply(*it);
}
}
};
}} // namespace detail::reverse
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template
<
typename Tag,
typename Geometry
>
struct reverse
{
static inline void apply(Geometry&)
{}
};
template <typename Ring>
struct reverse<ring_tag, Ring>
: detail::reverse::range_reverse<Ring>
{};
template <typename LineString>
struct reverse<linestring_tag, LineString>
: detail::reverse::range_reverse<LineString>
{};
template <typename Polygon>
struct reverse<polygon_tag, Polygon>
: detail::reverse::polygon_reverse<Polygon>
{};
} // namespace dispatch
#endif
/*!
\ingroup reverse
\tparam Geometry geometry type
\param geometry the geometry to make reverse
*/
template <typename Geometry>
inline void reverse(Geometry& geometry)
{
concept::check<Geometry>();
dispatch::reverse
<
typename tag<Geometry>::type,
Geometry
>::apply(geometry);
}
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP

View File

@@ -0,0 +1,55 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
//
// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
#include <algorithm>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/algorithms/reverse.hpp>
/*!
\defgroup sym_difference sym_difference: sym_difference of two geometries
*/
namespace boost { namespace geometry
{
/*!
\ingroup sym_difference
\tparam Geometry geometry type
\param geometry the geometry to make symmetric difference
*/
template
<
typename Geometry1,
typename Geometry2,
typename Collection
>
inline void sym_difference(Geometry1 geometry1,
Geometry2 geometry2, Collection& output_collection)
{
concept::check<Geometry1>();
concept::check<Geometry2>();
reverse(geometry2);
intersection(geometry1, geometry2, output_collection);
reverse(geometry2);
reverse(geometry1);
intersection(geometry1, geometry2, output_collection);
}
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP

View File

@@ -12,6 +12,8 @@
#include <vector>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
//#include <boost/geometry/geometry.hpp>
#include <boost/geometry/algorithms/envelope.hpp>

View File

@@ -88,20 +88,13 @@ public :
coordinate_type const& c1 = get<0>(p1);
coordinate_type const& c2 = get<1>(p1);
typedef typename geometry::coordinate_type<P2>::type ct2;
/*
set<0>(p2, boost::numeric_cast<ct2>(
c1 * m_matrix(0,0) + c2 * m_matrix(0,1) + m_matrix(0,2)));
set<1>(p2, boost::numeric_cast<ct2>(
c1 * m_matrix(1,0) + c2 * m_matrix(1,1) + m_matrix(1,2)));
*/
coordinate_type p2x = c1 * m_matrix(0,0) + c2 * m_matrix(0,1) + m_matrix(0,2);
coordinate_type p2y = c1 * m_matrix(1,0) + c2 * m_matrix(1,1) + m_matrix(1,2);
set<0>(p2, p2x);
set<1>(p2, p2y);
typedef typename geometry::coordinate_type<P2>::type ct2;
set<0>(p2, boost::numeric_cast<ct2>(p2x));
set<1>(p2, boost::numeric_cast<ct2>(p2y));
return true;
}