Updated Boost libraries
This commit is contained in:
@@ -18,6 +18,8 @@
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/range/functions.hpp>
|
||||
#include <boost/range/metafunctions.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
@@ -26,6 +28,7 @@
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/geometries/variant.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/calculate_null.hpp>
|
||||
#include <boost/geometry/algorithms/detail/calculate_sum.hpp>
|
||||
@@ -49,41 +52,33 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace area
|
||||
{
|
||||
|
||||
template<typename Box, typename Strategy>
|
||||
struct box_area
|
||||
{
|
||||
typedef typename coordinate_type<Box>::type return_type;
|
||||
|
||||
static inline return_type apply(Box const& box, Strategy const&)
|
||||
template <typename Box, typename Strategy>
|
||||
static inline typename coordinate_type<Box>::type
|
||||
apply(Box const& box, Strategy const&)
|
||||
{
|
||||
// Currently only works for 2D Cartesian boxes
|
||||
assert_dimension<Box, 2>();
|
||||
|
||||
return_type const dx = get<max_corner, 0>(box)
|
||||
- get<min_corner, 0>(box);
|
||||
return_type const dy = get<max_corner, 1>(box)
|
||||
- get<min_corner, 1>(box);
|
||||
|
||||
return dx * dy;
|
||||
return (get<max_corner, 0>(box) - get<min_corner, 0>(box))
|
||||
* (get<max_corner, 1>(box) - get<min_corner, 1>(box));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Ring,
|
||||
iterate_direction Direction,
|
||||
closure_selector Closure,
|
||||
typename Strategy
|
||||
closure_selector Closure
|
||||
>
|
||||
struct ring_area
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT( (geometry::concept::AreaStrategy<Strategy>) );
|
||||
|
||||
typedef typename Strategy::return_type type;
|
||||
|
||||
static inline type apply(Ring const& ring, Strategy const& strategy)
|
||||
template <typename Ring, typename Strategy>
|
||||
static inline typename Strategy::return_type
|
||||
apply(Ring const& ring, Strategy const& strategy)
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT( (geometry::concept::AreaStrategy<Strategy>) );
|
||||
assert_dimension<Ring, 2>();
|
||||
|
||||
// Ignore warning (because using static method sometimes) on strategy
|
||||
@@ -92,10 +87,10 @@ struct ring_area
|
||||
// An open ring has at least three points,
|
||||
// A closed ring has at least four points,
|
||||
// if not, there is no (zero) area
|
||||
if (boost::size(ring)
|
||||
if (int(boost::size(ring))
|
||||
< core_detail::closure::minimum_ring_size<Closure>::value)
|
||||
{
|
||||
return type();
|
||||
return typename Strategy::return_type();
|
||||
}
|
||||
|
||||
typedef typename reversible_view<Ring const, Direction>::type rview_type;
|
||||
@@ -136,71 +131,75 @@ namespace dispatch
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Strategy = typename strategy::area::services::default_strategy
|
||||
<
|
||||
typename cs_tag
|
||||
<
|
||||
typename point_type<Geometry>::type
|
||||
>::type,
|
||||
typename point_type<Geometry>::type
|
||||
>::type,
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct area
|
||||
: detail::calculate_null
|
||||
<
|
||||
typename Strategy::return_type,
|
||||
Geometry,
|
||||
Strategy
|
||||
> {};
|
||||
struct area : detail::calculate_null
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline typename Strategy::return_type apply(Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
return calculate_null::apply<typename Strategy::return_type>(geometry, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Strategy
|
||||
>
|
||||
struct area<Geometry, Strategy, box_tag>
|
||||
: detail::area::box_area<Geometry, Strategy>
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct area<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, void>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<typename Strategy::return_type>
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy): m_strategy(strategy) {}
|
||||
|
||||
template <typename Geometry>
|
||||
typename Strategy::return_type operator()(Geometry const& geometry) const
|
||||
{
|
||||
return dispatch::area<Geometry>::apply(geometry, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Variant, typename Strategy>
|
||||
static inline typename Strategy::return_type
|
||||
apply(Variant const& variant_geometry, Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy), variant_geometry);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
struct area<Geometry, box_tag> : detail::area::box_area
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Ring,
|
||||
typename Strategy
|
||||
>
|
||||
struct area<Ring, Strategy, ring_tag>
|
||||
template <typename Ring>
|
||||
struct area<Ring, ring_tag>
|
||||
: detail::area::ring_area
|
||||
<
|
||||
Ring,
|
||||
order_as_direction<geometry::point_order<Ring>::value>::value,
|
||||
geometry::closure<Ring>::value,
|
||||
Strategy
|
||||
geometry::closure<Ring>::value
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Polygon,
|
||||
typename Strategy
|
||||
>
|
||||
struct area<Polygon, Strategy, polygon_tag>
|
||||
: detail::calculate_polygon_sum
|
||||
<
|
||||
template <typename Polygon>
|
||||
struct area<Polygon, polygon_tag> : detail::calculate_polygon_sum
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline typename Strategy::return_type apply(Polygon const& polygon, Strategy const& strategy)
|
||||
{
|
||||
return calculate_polygon_sum::apply<
|
||||
typename Strategy::return_type,
|
||||
Polygon,
|
||||
Strategy,
|
||||
detail::area::ring_area
|
||||
<
|
||||
typename ring_type<Polygon const>::type,
|
||||
order_as_direction<geometry::point_order<Polygon>::value>::value,
|
||||
geometry::closure<Polygon>::value,
|
||||
Strategy
|
||||
geometry::closure<Polygon>::value
|
||||
>
|
||||
>
|
||||
{};
|
||||
>(polygon, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
@@ -243,10 +242,7 @@ inline typename default_area_result<Geometry>::type area(Geometry const& geometr
|
||||
|
||||
// detail::throw_on_empty_input(geometry);
|
||||
|
||||
return dispatch::area
|
||||
<
|
||||
Geometry
|
||||
>::apply(geometry, strategy_type());
|
||||
return dispatch::area<Geometry>::apply(geometry, strategy_type());
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -281,11 +277,7 @@ inline typename Strategy::return_type area(
|
||||
|
||||
// detail::throw_on_empty_input(geometry);
|
||||
|
||||
return dispatch::area
|
||||
<
|
||||
Geometry,
|
||||
Strategy
|
||||
>::apply(geometry, strategy);
|
||||
return dispatch::area<Geometry>::apply(geometry, strategy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/clear.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint.hpp>
|
||||
#include <boost/geometry/arithmetic/arithmetic.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
@@ -75,15 +76,23 @@ inline void buffer_box(BoxIn const& box_in, T const& distance, BoxOut& box_out)
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename TagIn, typename TagOut, typename Input, typename T, typename Output>
|
||||
struct buffer {};
|
||||
template
|
||||
<
|
||||
typename Input,
|
||||
typename Output,
|
||||
typename TagIn = typename tag<Input>::type,
|
||||
typename TagOut = typename tag<Output>::type
|
||||
>
|
||||
struct buffer: not_implemented<TagIn, TagOut>
|
||||
{};
|
||||
|
||||
|
||||
template <typename BoxIn, typename T, typename BoxOut>
|
||||
struct buffer<box_tag, box_tag, BoxIn, T, BoxOut>
|
||||
template <typename BoxIn, typename BoxOut>
|
||||
struct buffer<BoxIn, BoxOut, box_tag, box_tag>
|
||||
{
|
||||
static inline void apply(BoxIn const& box_in, T const& distance,
|
||||
T const& , BoxIn& box_out)
|
||||
template <typename Distance>
|
||||
static inline void apply(BoxIn const& box_in, Distance const& distance,
|
||||
Distance const& , BoxIn& box_out)
|
||||
{
|
||||
detail::buffer::buffer_box(box_in, distance, box_out);
|
||||
}
|
||||
@@ -122,10 +131,7 @@ inline void buffer(Input const& geometry_in, Output& geometry_out,
|
||||
|
||||
dispatch::buffer
|
||||
<
|
||||
typename tag<Input>::type,
|
||||
typename tag<Output>::type,
|
||||
Input,
|
||||
Distance,
|
||||
Output
|
||||
>::apply(geometry_in, distance, chord_length, geometry_out);
|
||||
}
|
||||
@@ -152,10 +158,7 @@ Output return_buffer(Input const& geometry, T const& distance, T const& chord_le
|
||||
|
||||
dispatch::buffer
|
||||
<
|
||||
typename tag<Input>::type,
|
||||
typename tag<Output>::type,
|
||||
Input,
|
||||
T,
|
||||
Output
|
||||
>::apply(geometry, distance, chord_length, geometry_out);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/algorithms/distance.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/strategies/centroid.hpp>
|
||||
#include <boost/geometry/strategies/concepts/centroid_concept.hpp>
|
||||
@@ -77,9 +78,9 @@ public:
|
||||
namespace detail { namespace centroid
|
||||
{
|
||||
|
||||
template<typename Point, typename PointCentroid, typename Strategy>
|
||||
struct centroid_point
|
||||
{
|
||||
template<typename Point, typename PointCentroid, typename Strategy>
|
||||
static inline void apply(Point const& point, PointCentroid& centroid,
|
||||
Strategy const&)
|
||||
{
|
||||
@@ -127,9 +128,9 @@ struct centroid_box_calculator<Box, Point, DimensionCount, DimensionCount>
|
||||
};
|
||||
|
||||
|
||||
template<typename Box, typename Point, typename Strategy>
|
||||
struct centroid_box
|
||||
{
|
||||
template<typename Box, typename Point, typename Strategy>
|
||||
static inline void apply(Box const& box, Point& centroid,
|
||||
Strategy const&)
|
||||
{
|
||||
@@ -173,9 +174,10 @@ inline bool range_ok(Range const& range, Point& centroid)
|
||||
/*!
|
||||
\brief Calculate the centroid of a ring.
|
||||
*/
|
||||
template<typename Ring, closure_selector Closure, typename Strategy>
|
||||
template <closure_selector Closure>
|
||||
struct centroid_range_state
|
||||
{
|
||||
template<typename Ring, typename Strategy>
|
||||
static inline void apply(Ring const& ring,
|
||||
Strategy const& strategy, typename Strategy::state_type& state)
|
||||
{
|
||||
@@ -196,21 +198,17 @@ struct centroid_range_state
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Range, typename Point, closure_selector Closure, typename Strategy>
|
||||
template <closure_selector Closure>
|
||||
struct centroid_range
|
||||
{
|
||||
template<typename Range, typename Point, typename Strategy>
|
||||
static inline void apply(Range const& range, Point& centroid,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (range_ok(range, centroid))
|
||||
{
|
||||
typename Strategy::state_type state;
|
||||
centroid_range_state
|
||||
<
|
||||
Range,
|
||||
Closure,
|
||||
Strategy
|
||||
>::apply(range, strategy, state);
|
||||
centroid_range_state<Closure>::apply(range, strategy, state);
|
||||
strategy.result(state, centroid);
|
||||
}
|
||||
}
|
||||
@@ -222,20 +220,14 @@ struct centroid_range
|
||||
\note Because outer ring is clockwise, inners are counter clockwise,
|
||||
triangle approach is OK and works for polygons with rings.
|
||||
*/
|
||||
template<typename Polygon, typename Strategy>
|
||||
struct centroid_polygon_state
|
||||
{
|
||||
typedef typename ring_type<Polygon>::type ring_type;
|
||||
|
||||
template<typename Polygon, typename Strategy>
|
||||
static inline void apply(Polygon const& poly,
|
||||
Strategy const& strategy, typename Strategy::state_type& state)
|
||||
{
|
||||
typedef centroid_range_state
|
||||
<
|
||||
ring_type,
|
||||
geometry::closure<ring_type>::value,
|
||||
Strategy
|
||||
> per_ring;
|
||||
typedef typename ring_type<Polygon>::type ring_type;
|
||||
typedef centroid_range_state<geometry::closure<ring_type>::value> per_ring;
|
||||
|
||||
per_ring::apply(exterior_ring(poly), strategy, state);
|
||||
|
||||
@@ -248,20 +240,16 @@ struct centroid_polygon_state
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Polygon, typename Point, typename Strategy>
|
||||
struct centroid_polygon
|
||||
{
|
||||
template<typename Polygon, typename Point, typename Strategy>
|
||||
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);
|
||||
centroid_polygon_state::apply(poly, strategy, state);
|
||||
strategy.result(state, centroid);
|
||||
}
|
||||
}
|
||||
@@ -278,58 +266,35 @@ namespace dispatch
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry,
|
||||
typename Point,
|
||||
typename Strategy
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct centroid {};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Point,
|
||||
typename Strategy
|
||||
>
|
||||
struct centroid<point_tag, Geometry, Point, Strategy>
|
||||
: detail::centroid::centroid_point<Geometry, Point, Strategy>
|
||||
struct centroid: not_implemented<Tag>
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box,
|
||||
typename Point,
|
||||
typename Strategy
|
||||
>
|
||||
struct centroid<box_tag, Box, Point, Strategy>
|
||||
: detail::centroid::centroid_box<Box, Point, Strategy>
|
||||
template <typename Geometry>
|
||||
struct centroid<Geometry, point_tag>
|
||||
: detail::centroid::centroid_point
|
||||
{};
|
||||
|
||||
template <typename Ring, typename Point, typename Strategy>
|
||||
struct centroid<ring_tag, Ring, Point, Strategy>
|
||||
: detail::centroid::centroid_range
|
||||
<
|
||||
Ring,
|
||||
Point,
|
||||
geometry::closure<Ring>::value,
|
||||
Strategy
|
||||
>
|
||||
template <typename Box>
|
||||
struct centroid<Box, box_tag>
|
||||
: detail::centroid::centroid_box
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename Point, typename Strategy>
|
||||
struct centroid<linestring_tag, Linestring, Point, Strategy>
|
||||
: detail::centroid::centroid_range
|
||||
<
|
||||
Linestring,
|
||||
Point,
|
||||
closed,
|
||||
Strategy
|
||||
>
|
||||
template <typename Ring>
|
||||
struct centroid<Ring, ring_tag>
|
||||
: detail::centroid::centroid_range<geometry::closure<Ring>::value>
|
||||
{};
|
||||
|
||||
template <typename Linestring>
|
||||
struct centroid<Linestring, linestring_tag>
|
||||
: detail::centroid::centroid_range<closed>
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename Point, typename Strategy>
|
||||
struct centroid<polygon_tag, Polygon, Point, Strategy>
|
||||
: detail::centroid::centroid_polygon<Polygon, Point, Strategy>
|
||||
template <typename Polygon>
|
||||
struct centroid<Polygon, polygon_tag>
|
||||
: detail::centroid::centroid_polygon
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
@@ -365,13 +330,7 @@ inline void centroid(Geometry const& geometry, Point& c,
|
||||
|
||||
// Call dispatch apply method. That one returns true if centroid
|
||||
// should be taken from state.
|
||||
dispatch::centroid
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Point,
|
||||
Strategy
|
||||
>::apply(geometry, c, strategy);
|
||||
dispatch::centroid<Geometry>::apply(geometry, c, strategy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,18 +40,13 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace convex_hull
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
order_selector Order,
|
||||
typename Strategy
|
||||
>
|
||||
template <order_selector Order>
|
||||
struct hull_insert
|
||||
{
|
||||
|
||||
// Member template function (to avoid inconvenient declaration
|
||||
// of output-iterator-type, from hull_to_geometry)
|
||||
template <typename OutputIterator>
|
||||
template <typename Geometry, typename OutputIterator, typename Strategy>
|
||||
static inline OutputIterator apply(Geometry const& geometry,
|
||||
OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
@@ -63,22 +58,15 @@ struct hull_insert
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Strategy
|
||||
>
|
||||
struct hull_to_geometry
|
||||
{
|
||||
template <typename OutputGeometry>
|
||||
template <typename Geometry, typename OutputGeometry, typename Strategy>
|
||||
static inline void apply(Geometry const& geometry, OutputGeometry& out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
hull_insert
|
||||
<
|
||||
Geometry,
|
||||
geometry::point_order<OutputGeometry>::value,
|
||||
Strategy
|
||||
geometry::point_order<OutputGeometry>::value
|
||||
>::apply(geometry,
|
||||
std::back_inserter(
|
||||
// Handle linestring, ring and polygon the same:
|
||||
@@ -113,21 +101,16 @@ namespace dispatch
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Strategy = typename detail::convex_hull::default_strategy<Geometry>::type,
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct convex_hull
|
||||
: detail::convex_hull::hull_to_geometry<Geometry, Strategy>
|
||||
: detail::convex_hull::hull_to_geometry
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box,
|
||||
typename Strategy
|
||||
>
|
||||
struct convex_hull<Box, Strategy, box_tag>
|
||||
template <typename Box>
|
||||
struct convex_hull<Box, box_tag>
|
||||
{
|
||||
template <typename OutputGeometry>
|
||||
template <typename OutputGeometry, typename Strategy>
|
||||
static inline void apply(Box const& box, OutputGeometry& out,
|
||||
Strategy const& )
|
||||
{
|
||||
@@ -149,13 +132,9 @@ struct convex_hull<Box, Strategy, box_tag>
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
order_selector Order,
|
||||
typename Geometry, typename Strategy
|
||||
>
|
||||
template <order_selector Order>
|
||||
struct convex_hull_insert
|
||||
: detail::convex_hull::hull_insert<Geometry, Order, Strategy>
|
||||
: detail::convex_hull::hull_insert<Order>
|
||||
{};
|
||||
|
||||
|
||||
@@ -181,11 +160,7 @@ inline void convex_hull(Geometry const& geometry,
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch::convex_hull
|
||||
<
|
||||
Geometry,
|
||||
Strategy
|
||||
>::apply(geometry, out, strategy);
|
||||
dispatch::convex_hull<Geometry>::apply(geometry, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
@@ -232,8 +207,7 @@ inline OutputIterator convex_hull_insert(Geometry const& geometry,
|
||||
|
||||
return dispatch::convex_hull_insert
|
||||
<
|
||||
geometry::point_order<Geometry>::value,
|
||||
Geometry, Strategy
|
||||
geometry::point_order<Geometry>::value
|
||||
>::apply(geometry, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
@@ -119,10 +119,8 @@ struct correct_ring
|
||||
|
||||
typedef detail::area::ring_area
|
||||
<
|
||||
Ring,
|
||||
order_as_direction<geometry::point_order<Ring>::value>::value,
|
||||
geometry::closure<Ring>::value,
|
||||
strategy_type
|
||||
geometry::closure<Ring>::value
|
||||
> ring_area_type;
|
||||
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ namespace boost { namespace geometry
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename ReturnType, typename Geometry, typename Strategy>
|
||||
struct calculate_null
|
||||
{
|
||||
template<typename ReturnType, typename Geometry, typename Strategy>
|
||||
static inline ReturnType apply(Geometry const& , Strategy const&)
|
||||
{
|
||||
return ReturnType();
|
||||
|
||||
@@ -26,16 +26,9 @@ namespace detail
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename ReturnType,
|
||||
typename Polygon,
|
||||
typename Strategy,
|
||||
typename Policy
|
||||
>
|
||||
class calculate_polygon_sum
|
||||
{
|
||||
template <typename Rings>
|
||||
template <typename ReturnType, typename Policy, typename Rings, typename Strategy>
|
||||
static inline ReturnType sum_interior_rings(Rings const& rings, Strategy const& strategy)
|
||||
{
|
||||
ReturnType sum = ReturnType();
|
||||
@@ -47,10 +40,11 @@ class calculate_polygon_sum
|
||||
}
|
||||
|
||||
public :
|
||||
template <typename ReturnType, typename Policy, typename Polygon, typename Strategy>
|
||||
static inline ReturnType apply(Polygon const& poly, Strategy const& strategy)
|
||||
{
|
||||
return Policy::apply(exterior_ring(poly), strategy)
|
||||
+ sum_interior_rings(interior_rings(poly), strategy)
|
||||
+ sum_interior_rings<ReturnType, Policy>(interior_rings(poly), strategy)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/covered_by.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
@@ -165,6 +166,19 @@ struct box_box<Box1, Box2, DimensionCount, DimensionCount>
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2
|
||||
>
|
||||
struct reverse_covered_by
|
||||
{
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return ! geometry::covered_by(geometry1, geometry2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Internal utility function to detect of boxes are disjoint
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/util/add_const_if_c.hpp>
|
||||
#include <boost/geometry/views/box_view.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
|
||||
@@ -0,0 +1,371 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2012 Barend Gehrels, 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_DETAIL_GET_LEFT_TURNS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
|
||||
|
||||
#include <boost/geometry/iterators/ever_circling_iterator.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// TODO: move this to /util/
|
||||
template <typename T>
|
||||
static inline std::pair<T, T> ordered_pair(T const& first, T const& second)
|
||||
{
|
||||
return first < second ? std::make_pair(first, second) : std::make_pair(second, first);
|
||||
}
|
||||
|
||||
template <typename AngleInfo>
|
||||
inline void debug_left_turn(AngleInfo const& ai, AngleInfo const& previous)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_OCCUPATION
|
||||
std::cout << "Angle: " << (ai.incoming ? "i" : "o")
|
||||
<< " " << si(ai.seg_id)
|
||||
<< " " << (math::r2d * (ai.angle) )
|
||||
<< " turn: " << ai.turn_index << "[" << ai.operation_index << "]"
|
||||
;
|
||||
|
||||
if (ai.turn_index != previous.turn_index
|
||||
|| ai.operation_index != previous.operation_index)
|
||||
{
|
||||
std::cout << " diff: " << math::r2d * math::abs(previous.angle - ai.angle);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename AngleInfo>
|
||||
inline void debug_left_turn(std::string const& caption, AngleInfo const& ai, AngleInfo const& previous,
|
||||
int code = -99, int code2 = -99, int code3 = -99, int code4 = -99)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_OCCUPATION
|
||||
std::cout << " " << caption
|
||||
<< " turn: " << ai.turn_index << "[" << ai.operation_index << "]"
|
||||
<< " " << si(ai.seg_id)
|
||||
<< " " << (ai.incoming ? "i" : "o")
|
||||
<< " " << (math::r2d * (ai.angle) )
|
||||
<< " turn: " << previous.turn_index << "[" << previous.operation_index << "]"
|
||||
<< " " << si(previous.seg_id)
|
||||
<< " " << (previous.incoming ? "i" : "o")
|
||||
<< " " << (math::r2d * (previous.angle) )
|
||||
;
|
||||
|
||||
if (code != -99)
|
||||
{
|
||||
std::cout << " code: " << code << " , " << code2 << " , " << code3 << " , " << code4;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <typename Operation>
|
||||
inline bool include_operation(Operation const& op,
|
||||
segment_identifier const& outgoing_seg_id,
|
||||
segment_identifier const& incoming_seg_id)
|
||||
{
|
||||
return op.seg_id == outgoing_seg_id
|
||||
&& op.other_id == incoming_seg_id
|
||||
&& (op.operation == detail::overlay::operation_union
|
||||
||op.operation == detail::overlay::operation_continue)
|
||||
;
|
||||
}
|
||||
|
||||
template <typename Turn>
|
||||
inline bool process_include(segment_identifier const& outgoing_seg_id, segment_identifier const& incoming_seg_id,
|
||||
int turn_index, Turn& turn,
|
||||
std::set<int>& keep_indices, int priority)
|
||||
{
|
||||
bool result = false;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (include_operation(turn.operations[i], outgoing_seg_id, incoming_seg_id))
|
||||
{
|
||||
turn.operations[i].include_in_occupation_map = true;
|
||||
if (priority > turn.priority)
|
||||
{
|
||||
turn.priority = priority;
|
||||
}
|
||||
keep_indices.insert(turn_index);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename AngleInfo, typename Turns, typename TurnSegmentIndices>
|
||||
inline bool include_left_turn_of_all(
|
||||
AngleInfo const& outgoing, AngleInfo const& incoming,
|
||||
Turns& turns, TurnSegmentIndices const& turn_segment_indices,
|
||||
std::set<int>& keep_indices, int priority)
|
||||
{
|
||||
segment_identifier const& outgoing_seg_id = turns[outgoing.turn_index].operations[outgoing.operation_index].seg_id;
|
||||
segment_identifier const& incoming_seg_id = turns[incoming.turn_index].operations[incoming.operation_index].seg_id;
|
||||
|
||||
if (outgoing.turn_index == incoming.turn_index)
|
||||
{
|
||||
return process_include(outgoing_seg_id, incoming_seg_id, outgoing.turn_index, turns[outgoing.turn_index], keep_indices, priority);
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
std::pair<segment_identifier, segment_identifier> pair = ordered_pair(outgoing_seg_id, incoming_seg_id);
|
||||
typename boost::range_iterator<TurnSegmentIndices const>::type it = turn_segment_indices.find(pair);
|
||||
if (it != turn_segment_indices.end())
|
||||
{
|
||||
for (std::set<int>::const_iterator sit = it->second.begin(); sit != it->second.end(); ++sit)
|
||||
{
|
||||
if (process_include(outgoing_seg_id, incoming_seg_id, *sit, turns[*sit], keep_indices, priority))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <std::size_t Index, typename Turn>
|
||||
inline bool corresponds(Turn const& turn, segment_identifier const& seg_id)
|
||||
{
|
||||
return turn.operations[Index].operation == detail::overlay::operation_union
|
||||
&& turn.operations[Index].seg_id == seg_id;
|
||||
}
|
||||
|
||||
|
||||
template <typename Turns, typename TurnSegmentIndices>
|
||||
inline bool prefer_by_other(Turns const& turns,
|
||||
TurnSegmentIndices const& turn_segment_indices,
|
||||
std::set<int>& indices)
|
||||
{
|
||||
std::map<segment_identifier, int> map;
|
||||
for (std::set<int>::const_iterator sit = indices.begin();
|
||||
sit != indices.end();
|
||||
++sit)
|
||||
{
|
||||
map[turns[*sit].operations[0].seg_id]++;
|
||||
map[turns[*sit].operations[1].seg_id]++;
|
||||
}
|
||||
|
||||
std::set<segment_identifier> segment_occuring_once;
|
||||
for (std::map<segment_identifier, int>::const_iterator mit = map.begin();
|
||||
mit != map.end();++mit)
|
||||
{
|
||||
if (mit->second == 1)
|
||||
{
|
||||
segment_occuring_once.insert(mit->first);
|
||||
}
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_PREFER
|
||||
std::cout << si(mit->first) << " " << mit->second << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (segment_occuring_once.size() == 2)
|
||||
{
|
||||
// Try to find within all turns a turn with these two segments
|
||||
|
||||
std::set<segment_identifier>::const_iterator soo_it = segment_occuring_once.begin();
|
||||
segment_identifier front = *soo_it;
|
||||
soo_it++;
|
||||
segment_identifier back = *soo_it;
|
||||
|
||||
std::pair<segment_identifier, segment_identifier> pair = ordered_pair(front, back);
|
||||
|
||||
typename boost::range_iterator<TurnSegmentIndices const>::type it = turn_segment_indices.find(pair);
|
||||
if (it != turn_segment_indices.end())
|
||||
{
|
||||
// debug_turns_by_indices("Found", it->second);
|
||||
// Check which is the union/continue
|
||||
segment_identifier good;
|
||||
for (std::set<int>::const_iterator sit = it->second.begin(); sit != it->second.end(); ++sit)
|
||||
{
|
||||
if (turns[*sit].operations[0].operation == detail::overlay::operation_union)
|
||||
{
|
||||
good = turns[*sit].operations[0].seg_id;
|
||||
}
|
||||
else if (turns[*sit].operations[1].operation == detail::overlay::operation_union)
|
||||
{
|
||||
good = turns[*sit].operations[1].seg_id;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_PREFER
|
||||
std::cout << "Good: " << si(good) << std::endl;
|
||||
#endif
|
||||
|
||||
// Find in indexes-to-keep this segment with the union. Discard the other one
|
||||
std::set<int> ok_indices;
|
||||
for (std::set<int>::const_iterator sit = indices.begin(); sit != indices.end(); ++sit)
|
||||
{
|
||||
if (corresponds<0>(turns[*sit], good) || corresponds<1>(turns[*sit], good))
|
||||
{
|
||||
ok_indices.insert(*sit);
|
||||
}
|
||||
}
|
||||
if (ok_indices.size() > 0 && ok_indices.size() < indices.size())
|
||||
{
|
||||
indices = ok_indices;
|
||||
std::cout << "^";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Turns>
|
||||
inline void prefer_by_priority(Turns const& turns, std::set<int>& indices)
|
||||
{
|
||||
// Find max prio
|
||||
int min_prio = 1024, max_prio = 0;
|
||||
for (std::set<int>::const_iterator sit = indices.begin(); sit != indices.end(); ++sit)
|
||||
{
|
||||
if (turns[*sit].priority > max_prio)
|
||||
{
|
||||
max_prio = turns[*sit].priority;
|
||||
}
|
||||
if (turns[*sit].priority < min_prio)
|
||||
{
|
||||
min_prio = turns[*sit].priority;
|
||||
}
|
||||
}
|
||||
|
||||
if (min_prio == max_prio)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Only keep indices with high prio
|
||||
std::set<int> ok_indices;
|
||||
for (std::set<int>::const_iterator sit = indices.begin(); sit != indices.end(); ++sit)
|
||||
{
|
||||
if (turns[*sit].priority >= max_prio)
|
||||
{
|
||||
ok_indices.insert(*sit);
|
||||
}
|
||||
}
|
||||
if (ok_indices.size() > 0 && ok_indices.size() < indices.size())
|
||||
{
|
||||
indices = ok_indices;
|
||||
std::cout << "%";
|
||||
}
|
||||
}
|
||||
|
||||
template <typename AngleInfo, typename Angles, typename Turns, typename TurnSegmentIndices>
|
||||
inline void calculate_left_turns(Angles const& angles,
|
||||
Turns& turns, TurnSegmentIndices const& turn_segment_indices,
|
||||
std::set<int>& keep_indices)
|
||||
{
|
||||
bool debug_indicate_size = false;
|
||||
|
||||
typedef typename strategy::side::services::default_strategy
|
||||
<
|
||||
typename cs_tag<typename AngleInfo::point_type>::type
|
||||
>::type side_strategy;
|
||||
|
||||
std::size_t i = 0;
|
||||
std::size_t n = boost::size(angles);
|
||||
|
||||
typedef geometry::ever_circling_range_iterator<Angles const> circling_iterator;
|
||||
circling_iterator cit(angles);
|
||||
|
||||
debug_left_turn(*cit, *cit);
|
||||
for(circling_iterator prev = cit++; i < n; prev = cit++, i++)
|
||||
{
|
||||
debug_left_turn(*cit, *prev);
|
||||
|
||||
bool const include = ! geometry::math::equals(prev->angle, cit->angle)
|
||||
&& ! prev->incoming
|
||||
&& cit->incoming;
|
||||
|
||||
if (include)
|
||||
{
|
||||
// Go back to possibly include more same left outgoing angles:
|
||||
// Because we check on side too we can take a large "epsilon"
|
||||
circling_iterator back = prev - 1;
|
||||
|
||||
typename AngleInfo::angle_type eps = 0.00001;
|
||||
int b = 1;
|
||||
for(std::size_t d = 0;
|
||||
math::abs(prev->angle - back->angle) < eps
|
||||
&& ! back->incoming
|
||||
&& d < n;
|
||||
d++)
|
||||
{
|
||||
--back;
|
||||
++b;
|
||||
}
|
||||
|
||||
// Same but forward to possibly include more incoming angles
|
||||
int f = 1;
|
||||
circling_iterator forward = cit + 1;
|
||||
for(std::size_t d = 0;
|
||||
math::abs(cit->angle - forward->angle) < eps
|
||||
&& forward->incoming
|
||||
&& d < n;
|
||||
d++)
|
||||
{
|
||||
++forward;
|
||||
++f;
|
||||
}
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_OCCUPATION
|
||||
std::cout << "HANDLE " << b << "/" << f << " ANGLES" << std::endl;
|
||||
#endif
|
||||
for(circling_iterator bit = prev; bit != back; --bit)
|
||||
{
|
||||
int code = side_strategy::apply(bit->direction_point, prev->intersection_point, prev->direction_point);
|
||||
int code2 = side_strategy::apply(prev->direction_point, bit->intersection_point, bit->direction_point);
|
||||
for(circling_iterator fit = cit; fit != forward; ++fit)
|
||||
{
|
||||
int code3 = side_strategy::apply(fit->direction_point, cit->intersection_point, cit->direction_point);
|
||||
int code4 = side_strategy::apply(cit->direction_point, fit->intersection_point, fit->direction_point);
|
||||
|
||||
int priority = 2;
|
||||
if (code == -1 && code2 == 1)
|
||||
{
|
||||
// This segment is lying right of the other one.
|
||||
// Cannot ignore it (because of robustness, see a.o. #rt_p21 from unit test).
|
||||
// But if we find more we can prefer later by priority
|
||||
// (a.o. necessary for #rt_o2 from unit test)
|
||||
priority = 1;
|
||||
}
|
||||
|
||||
bool included = include_left_turn_of_all(*bit, *fit, turns, turn_segment_indices, keep_indices, priority);
|
||||
debug_left_turn(included ? "KEEP" : "SKIP", *fit, *bit, code, code2, code3, code4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_indicate_size)
|
||||
{
|
||||
std::cout << " size=" << keep_indices.size();
|
||||
}
|
||||
|
||||
if (keep_indices.size() >= 2)
|
||||
{
|
||||
prefer_by_other(turns, turn_segment_indices, keep_indices);
|
||||
}
|
||||
if (keep_indices.size() >= 2)
|
||||
{
|
||||
prefer_by_priority(turns, keep_indices);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
|
||||
@@ -0,0 +1,329 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2012 Barend Gehrels, 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_DETAIL_OCCUPATION_INFO_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OCCUPATION_INFO_HPP
|
||||
|
||||
#if ! defined(NDEBUG)
|
||||
// #define BOOST_GEOMETRY_DEBUG_BUFFER_OCCUPATION
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
#include <boost/geometry/iterators/closing_iterator.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/get_left_turns.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename P>
|
||||
class relaxed_less
|
||||
{
|
||||
typedef typename geometry::coordinate_type<P>::type coordinate_type;
|
||||
|
||||
coordinate_type epsilon;
|
||||
|
||||
public :
|
||||
|
||||
inline relaxed_less()
|
||||
{
|
||||
// TODO: adapt for ttmath, and maybe build the map in another way
|
||||
// (e.g. exact constellations of segment-id's), maybe adaptive.
|
||||
epsilon = std::numeric_limits<double>::epsilon() * 100.0;
|
||||
}
|
||||
|
||||
inline bool operator()(P const& a, P const& b) const
|
||||
{
|
||||
coordinate_type const dx = math::abs(geometry::get<0>(a) - geometry::get<0>(b));
|
||||
coordinate_type const dy = math::abs(geometry::get<1>(a) - geometry::get<1>(b));
|
||||
|
||||
|
||||
if (dx < epsilon && dy < epsilon)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (dx < epsilon)
|
||||
{
|
||||
return geometry::get<1>(a) < geometry::get<1>(b);
|
||||
}
|
||||
|
||||
return geometry::get<0>(a) < geometry::get<0>(b);
|
||||
}
|
||||
|
||||
inline bool equals(P const& a, P const& b) const
|
||||
{
|
||||
typedef typename geometry::coordinate_type<P>::type coordinate_type;
|
||||
|
||||
coordinate_type const dx = math::abs(geometry::get<0>(a) - geometry::get<0>(b));
|
||||
coordinate_type const dy = math::abs(geometry::get<1>(a) - geometry::get<1>(b));
|
||||
|
||||
return dx < epsilon && dy < epsilon;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <typename T, typename P1, typename P2>
|
||||
inline T calculate_angle(P1 const& from_point, P2 const& to_point)
|
||||
{
|
||||
typedef P1 vector_type;
|
||||
vector_type v = from_point;
|
||||
geometry::subtract_point(v, to_point);
|
||||
return atan2(geometry::get<1>(v), geometry::get<0>(v));
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Vector>
|
||||
inline Iterator advance_circular(Iterator it, Vector const& vector, segment_identifier& seg_id, bool forward = true)
|
||||
{
|
||||
int const increment = forward ? 1 : -1;
|
||||
if (it == boost::begin(vector) && increment < 0)
|
||||
{
|
||||
it = boost::end(vector);
|
||||
seg_id.segment_index = boost::size(vector);
|
||||
}
|
||||
it += increment;
|
||||
seg_id.segment_index += increment;
|
||||
if (it == boost::end(vector))
|
||||
{
|
||||
seg_id.segment_index = 0;
|
||||
it = boost::begin(vector);
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
template <typename Point, typename T>
|
||||
struct angle_info
|
||||
{
|
||||
typedef T angle_type;
|
||||
typedef Point point_type;
|
||||
|
||||
segment_identifier seg_id;
|
||||
int turn_index;
|
||||
int operation_index;
|
||||
Point intersection_point;
|
||||
Point direction_point;
|
||||
T angle;
|
||||
bool incoming;
|
||||
};
|
||||
|
||||
template <typename AngleInfo>
|
||||
class occupation_info
|
||||
{
|
||||
typedef std::vector<AngleInfo> collection_type;
|
||||
|
||||
struct angle_sort
|
||||
{
|
||||
inline bool operator()(AngleInfo const& left, AngleInfo const& right) const
|
||||
{
|
||||
// In this case we can compare even double using equals
|
||||
// return geometry::math::equals(left.angle, right.angle)
|
||||
return left.angle == right.angle
|
||||
? int(left.incoming) < int(right.incoming)
|
||||
: left.angle < right.angle
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
public :
|
||||
collection_type angles;
|
||||
private :
|
||||
bool m_occupied;
|
||||
bool m_calculated;
|
||||
|
||||
inline bool is_occupied()
|
||||
{
|
||||
if (boost::size(angles) <= 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::sort(angles.begin(), angles.end(), angle_sort());
|
||||
|
||||
typedef geometry::closing_iterator<collection_type const> closing_iterator;
|
||||
closing_iterator vit(angles);
|
||||
closing_iterator end(angles, true);
|
||||
|
||||
closing_iterator prev = vit++;
|
||||
for( ; vit != end; prev = vit++)
|
||||
{
|
||||
if (! geometry::math::equals(prev->angle, vit->angle)
|
||||
&& ! prev->incoming
|
||||
&& vit->incoming)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public :
|
||||
inline occupation_info()
|
||||
: m_occupied(false)
|
||||
, m_calculated(false)
|
||||
{}
|
||||
|
||||
template <typename PointC, typename Point1, typename Point2>
|
||||
inline void add(PointC const& map_point, Point1 const& direction_point, Point2 const& intersection_point,
|
||||
int turn_index, int operation_index,
|
||||
segment_identifier const& seg_id, bool incoming)
|
||||
{
|
||||
//std::cout << "-> adding angle " << geometry::wkt(direction_point) << " .. " << geometry::wkt(intersection_point) << " " << int(incoming) << std::endl;
|
||||
if (geometry::equals(direction_point, intersection_point))
|
||||
{
|
||||
//std::cout << "EQUAL! Skipping" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
AngleInfo info;
|
||||
info.incoming = incoming;
|
||||
info.angle = calculate_angle<typename AngleInfo::angle_type>(direction_point, map_point);
|
||||
info.seg_id = seg_id;
|
||||
info.turn_index = turn_index;
|
||||
info.operation_index = operation_index;
|
||||
info.intersection_point = intersection_point;
|
||||
info.direction_point = direction_point;
|
||||
angles.push_back(info);
|
||||
|
||||
m_calculated = false;
|
||||
}
|
||||
|
||||
inline bool occupied()
|
||||
{
|
||||
if (! m_calculated)
|
||||
{
|
||||
m_occupied = is_occupied();
|
||||
m_calculated = true;
|
||||
}
|
||||
return m_occupied;
|
||||
}
|
||||
|
||||
template <typename Turns, typename TurnSegmentIndices>
|
||||
inline void get_left_turns(
|
||||
Turns& turns, TurnSegmentIndices const& turn_segment_indices,
|
||||
std::set<int>& keep_indices)
|
||||
{
|
||||
std::sort(angles.begin(), angles.end(), angle_sort());
|
||||
calculate_left_turns<AngleInfo>(angles, turns, turn_segment_indices, keep_indices);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, typename Ring, typename Info>
|
||||
inline void add_incoming_and_outgoing_angles(Point const& map_point, Point const& intersection_point,
|
||||
Ring const& ring,
|
||||
int turn_index,
|
||||
int operation_index,
|
||||
segment_identifier seg_id,
|
||||
Info& info)
|
||||
{
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
Ring const
|
||||
>::type iterator_type;
|
||||
|
||||
int const n = boost::size(ring);
|
||||
if (seg_id.segment_index >= n || seg_id.segment_index < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
segment_identifier real_seg_id = seg_id;
|
||||
iterator_type it = boost::begin(ring) + seg_id.segment_index;
|
||||
|
||||
// TODO: if we use turn-info ("to", "middle"), we know if to advance without resorting to equals
|
||||
relaxed_less<Point> comparator;
|
||||
|
||||
if (comparator.equals(intersection_point, *it))
|
||||
{
|
||||
// It should be equal only once. But otherwise we skip it (in "add")
|
||||
it = advance_circular(it, ring, seg_id, false);
|
||||
}
|
||||
|
||||
info.add(map_point, *it, intersection_point, turn_index, operation_index, real_seg_id, true);
|
||||
|
||||
if (comparator.equals(intersection_point, *it))
|
||||
{
|
||||
it = advance_circular(it, ring, real_seg_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't upgrade the ID
|
||||
it = advance_circular(it, ring, seg_id);
|
||||
}
|
||||
for (int defensive_check = 0;
|
||||
comparator.equals(intersection_point, *it) && defensive_check < n;
|
||||
defensive_check++)
|
||||
{
|
||||
it = advance_circular(it, ring, real_seg_id);
|
||||
}
|
||||
|
||||
info.add(map_point, *it, intersection_point, turn_index, operation_index, real_seg_id, false);
|
||||
}
|
||||
|
||||
|
||||
// Map in two senses of the word: it is a std::map where the key is a point.
|
||||
// Per point an "occupation_info" record is kept
|
||||
// Used for the buffer (but will also be used for intersections/unions having complex self-tangencies)
|
||||
template <typename Point, typename OccupationInfo>
|
||||
class occupation_map
|
||||
{
|
||||
public :
|
||||
typedef std::map<Point, OccupationInfo, relaxed_less<Point> > map_type;
|
||||
|
||||
map_type map;
|
||||
std::set<int> turn_indices;
|
||||
|
||||
inline OccupationInfo& find_or_insert(Point const& point, Point& mapped_point)
|
||||
{
|
||||
typename map_type::iterator it = map.find(point);
|
||||
if (it == boost::end(map))
|
||||
{
|
||||
std::pair<typename map_type::iterator, bool> pair
|
||||
= map.insert(std::make_pair(point, OccupationInfo()));
|
||||
it = pair.first;
|
||||
}
|
||||
mapped_point = it->first;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
inline bool contains(Point const& point) const
|
||||
{
|
||||
typename map_type::const_iterator it = map.find(point);
|
||||
return it != boost::end(map);
|
||||
}
|
||||
|
||||
inline bool contains_turn_index(int index) const
|
||||
{
|
||||
return turn_indices.count(index) > 0;
|
||||
}
|
||||
|
||||
inline void insert_turn_index(int index)
|
||||
{
|
||||
turn_indices.insert(index);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OCCUPATION_INFO_HPP
|
||||
@@ -9,6 +9,8 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/convert_ring.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
|
||||
|
||||
@@ -73,6 +75,21 @@ inline OutputIterator add_rings(SelectionMap const& map,
|
||||
OutputIterator out)
|
||||
{
|
||||
typedef typename SelectionMap::const_iterator iterator;
|
||||
typedef typename SelectionMap::mapped_type property_type;
|
||||
typedef typename property_type::area_type area_type;
|
||||
|
||||
area_type const zero = 0;
|
||||
std::size_t const min_num_points = core_detail::closure::minimum_ring_size
|
||||
<
|
||||
geometry::closure
|
||||
<
|
||||
typename boost::range_value
|
||||
<
|
||||
RingCollection const
|
||||
>::type
|
||||
>::value
|
||||
>::value;
|
||||
|
||||
|
||||
for (iterator it = boost::begin(map);
|
||||
it != boost::end(map);
|
||||
@@ -99,7 +116,15 @@ inline OutputIterator add_rings(SelectionMap const& map,
|
||||
*child_it, mit->second.reversed, true);
|
||||
}
|
||||
}
|
||||
*out++ = result;
|
||||
|
||||
// Only add rings if they satisfy minimal requirements.
|
||||
// This cannot be done earlier (during traversal), not
|
||||
// everything is figured out yet (sum of positive/negative rings)
|
||||
if (geometry::num_points(result) >= min_num_points
|
||||
&& math::larger(geometry::area(result), zero))
|
||||
{
|
||||
*out++ = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
||||
+4
-3
@@ -130,7 +130,7 @@ struct assign_visitor
|
||||
return;
|
||||
}
|
||||
|
||||
if (outer.real_area > 0)
|
||||
if (math::larger(outer.real_area, 0))
|
||||
{
|
||||
if (inner.real_area < 0 || m_check_for_orientation)
|
||||
{
|
||||
@@ -317,13 +317,14 @@ template
|
||||
>
|
||||
inline void assign_parents(Geometry const& geometry,
|
||||
RingCollection const& collection,
|
||||
RingMap& ring_map)
|
||||
RingMap& ring_map,
|
||||
bool check_for_orientation)
|
||||
{
|
||||
// Call it with an empty geometry
|
||||
// (ring_map should be empty for source_id==1)
|
||||
|
||||
Geometry empty;
|
||||
assign_parents(geometry, empty, collection, ring_map, true);
|
||||
assign_parents(geometry, empty, collection, ring_map, check_for_orientation);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+11
-2
@@ -32,9 +32,18 @@ struct calculate_distance_policy
|
||||
{
|
||||
static bool const include_no_turn = false;
|
||||
static bool const include_degenerate = false;
|
||||
static bool const include_opposite = false;
|
||||
|
||||
template <typename Point1, typename Point2, typename Info>
|
||||
static inline void apply(Info& info, Point1 const& p1, Point2 const& p2)
|
||||
template
|
||||
<
|
||||
typename Info,
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
>
|
||||
static inline void apply(Info& info, Point1 const& p1, Point2 const& p2,
|
||||
IntersectionInfo const&, DirInfo const&)
|
||||
{
|
||||
info.operations[0].enriched.distance
|
||||
= geometry::comparable_distance(info.point, p1);
|
||||
|
||||
+16
-5
@@ -77,12 +77,23 @@ struct convert_ring<polygon_tag>
|
||||
}
|
||||
else
|
||||
{
|
||||
interior_rings(destination).resize(
|
||||
interior_rings(destination).size() + 1);
|
||||
geometry::convert(source, interior_rings(destination).back());
|
||||
if (reverse)
|
||||
// Avoid adding interior rings which are invalid
|
||||
// because of its number of points:
|
||||
std::size_t const min_num_points
|
||||
= core_detail::closure::minimum_ring_size
|
||||
<
|
||||
geometry::closure<Destination>::value
|
||||
>::value;
|
||||
|
||||
if (geometry::num_points(source) >= min_num_points)
|
||||
{
|
||||
boost::reverse(interior_rings(destination).back());
|
||||
interior_rings(destination).resize(
|
||||
interior_rings(destination).size() + 1);
|
||||
geometry::convert(source, interior_rings(destination).back());
|
||||
if (reverse)
|
||||
{
|
||||
boost::reverse(interior_rings(destination).back());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -55,14 +55,14 @@ struct copy_segment_point_range
|
||||
if (second)
|
||||
{
|
||||
index++;
|
||||
if (index >= boost::size(range))
|
||||
if (index >= int(boost::size(range)))
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Exception?
|
||||
if (index >= boost::size(range))
|
||||
if (index >= int(boost::size(range)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
+3
-3
@@ -78,7 +78,7 @@ struct copy_segments_ring
|
||||
int const from_index = seg_id.segment_index + 1;
|
||||
|
||||
// Sanity check
|
||||
BOOST_ASSERT(from_index < boost::size(view));
|
||||
BOOST_ASSERT(from_index < int(boost::size(view)));
|
||||
|
||||
ec_iterator it(boost::begin(view), boost::end(view),
|
||||
boost::begin(view) + from_index);
|
||||
@@ -89,7 +89,7 @@ struct copy_segments_ring
|
||||
typedef typename boost::range_difference<Ring>::type size_type;
|
||||
size_type const count = from_index <= to_index
|
||||
? to_index - from_index + 1
|
||||
: boost::size(view) - from_index + to_index + 1;
|
||||
: int(boost::size(view)) - from_index + to_index + 1;
|
||||
|
||||
for (size_type i = 0; i < count; ++i, ++it)
|
||||
{
|
||||
@@ -117,7 +117,7 @@ struct copy_segments_linestring
|
||||
int const from_index = seg_id.segment_index + 1;
|
||||
|
||||
// Sanity check
|
||||
if (from_index > to_index || from_index < 0 || to_index >= boost::size(ls))
|
||||
if (from_index > to_index || from_index < 0 || to_index >= int(boost::size(ls)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ inline char method_char(detail::overlay::method_type const& method)
|
||||
case method_touch_interior : return 'm';
|
||||
case method_collinear : return 'c';
|
||||
case method_equal : return 'e';
|
||||
case method_error : return '!';
|
||||
default : return '?';
|
||||
}
|
||||
}
|
||||
@@ -42,6 +43,7 @@ inline char operation_char(detail::overlay::operation_type const& operation)
|
||||
case operation_intersection : return 'i';
|
||||
case operation_blocked : return 'x';
|
||||
case operation_continue : return 'c';
|
||||
case operation_opposite : return 'o';
|
||||
default : return '?';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,12 +279,12 @@ class follow
|
||||
{
|
||||
// In case of turn point at the same location, we want to have continue/blocked LAST
|
||||
// because that should be followed (intersection) or skipped (difference).
|
||||
// By chance the enumeration is ordered like that but we keep the safe way here.
|
||||
inline int operation_order(Turn const& turn) const
|
||||
{
|
||||
operation_type const& operation = turn.operations[0].operation;
|
||||
switch(operation)
|
||||
{
|
||||
case operation_opposite : return 0;
|
||||
case operation_none : return 0;
|
||||
case operation_union : return 1;
|
||||
case operation_intersection : return 2;
|
||||
|
||||
@@ -83,7 +83,7 @@ struct get_ring<polygon_tag>
|
||||
BOOST_ASSERT
|
||||
(
|
||||
id.ring_index >= -1
|
||||
&& id.ring_index < boost::size(interior_rings(polygon))
|
||||
&& id.ring_index < int(boost::size(interior_rings(polygon)))
|
||||
);
|
||||
return id.ring_index < 0
|
||||
? exterior_ring(polygon)
|
||||
|
||||
+170
-32
@@ -250,9 +250,15 @@ struct touch : public base_turn_handler
|
||||
int const side_pk_q2 = SideStrategy::apply(qj, qk, pk);
|
||||
int const side_pk_p = SideStrategy::apply(pi, pj, pk);
|
||||
int const side_qk_q = SideStrategy::apply(qi, qj, qk);
|
||||
|
||||
bool const both_continue = side_pk_p == 0 && side_qk_q == 0;
|
||||
bool const robustness_issue_in_continue = both_continue && side_pk_q2 != 0;
|
||||
|
||||
bool const q_turns_left = side_qk_q == 1;
|
||||
bool const block_q = side_qk_p1 == 0
|
||||
&& ! same(side_qi_p1, side_qk_q);
|
||||
&& ! same(side_qi_p1, side_qk_q)
|
||||
&& ! robustness_issue_in_continue
|
||||
;
|
||||
|
||||
// If Pk at same side as Qi/Qk
|
||||
// (the "or" is for collinear case)
|
||||
@@ -278,7 +284,7 @@ struct touch : public base_turn_handler
|
||||
if (side_pk_q1 == 0)
|
||||
{
|
||||
ti.operations[0].operation = operation_blocked;
|
||||
// Q turns right -> union (both independant),
|
||||
// Q turns right -> union (both independent),
|
||||
// Q turns left -> intersection
|
||||
ti.operations[1].operation = block_q ? operation_blocked
|
||||
: q_turns_left ? operation_intersection
|
||||
@@ -463,6 +469,45 @@ struct equal : public base_turn_handler
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TurnInfo,
|
||||
typename AssignPolicy
|
||||
>
|
||||
struct equal_opposite : public base_turn_handler
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename OutputIterator,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
>
|
||||
static inline void apply(Point1 const& pi, Point2 const& qi,
|
||||
/* by value: */ TurnInfo tp,
|
||||
OutputIterator& out,
|
||||
IntersectionInfo const& intersection_info,
|
||||
DirInfo const& dir_info)
|
||||
{
|
||||
// For equal-opposite segments, normally don't do anything.
|
||||
if (AssignPolicy::include_opposite)
|
||||
{
|
||||
tp.method = method_equal;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
tp.operations[i].operation = operation_opposite;
|
||||
}
|
||||
for (unsigned int i = 0; i < intersection_info.count; i++)
|
||||
{
|
||||
geometry::convert(intersection_info.intersections[i], tp.point);
|
||||
AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename TurnInfo,
|
||||
@@ -494,6 +539,13 @@ struct collinear : public base_turn_handler
|
||||
- if P arrives and P turns right: intersection for P
|
||||
- if Q arrives and Q turns left: union for Q (=intersection for P)
|
||||
- if Q arrives and Q turns right: intersection for Q (=union for P)
|
||||
|
||||
ROBUSTNESS: p and q are collinear, so you would expect
|
||||
that side qk//p1 == pk//q1. But that is not always the case
|
||||
in near-epsilon ranges. Then decision logic is different.
|
||||
If p arrives, q is further, so the angle qk//p1 is (normally)
|
||||
more precise than pk//p1
|
||||
|
||||
*/
|
||||
template
|
||||
<
|
||||
@@ -516,12 +568,18 @@ struct collinear : public base_turn_handler
|
||||
// Should not be 0, this is checked before
|
||||
BOOST_ASSERT(arrival != 0);
|
||||
|
||||
int const side_p = SideStrategy::apply(pi, pj, pk);
|
||||
int const side_q = SideStrategy::apply(qi, qj, qk);
|
||||
|
||||
// If p arrives, use p, else use q
|
||||
int const side_p_or_q = arrival == 1
|
||||
? SideStrategy::apply(pi, pj, pk)
|
||||
: SideStrategy::apply(qi, qj, qk)
|
||||
? side_p
|
||||
: side_q
|
||||
;
|
||||
|
||||
int const side_pk = SideStrategy::apply(qi, qj, pk);
|
||||
int const side_qk = SideStrategy::apply(pi, pj, qk);
|
||||
|
||||
// See comments above,
|
||||
// resulting in a strange sort of mathematic rule here:
|
||||
// The arrival-info multiplied by the relevant side
|
||||
@@ -529,7 +587,15 @@ struct collinear : public base_turn_handler
|
||||
|
||||
int const product = arrival * side_p_or_q;
|
||||
|
||||
if(product == 0)
|
||||
// Robustness: side_p is supposed to be equal to side_pk (because p/q are collinear)
|
||||
// and side_q to side_qk
|
||||
bool const robustness_issue = side_pk != side_p || side_qk != side_q;
|
||||
|
||||
if (robustness_issue)
|
||||
{
|
||||
handle_robustness(ti, arrival, side_p, side_q, side_pk, side_qk);
|
||||
}
|
||||
else if(product == 0)
|
||||
{
|
||||
both(ti, operation_continue);
|
||||
}
|
||||
@@ -538,6 +604,38 @@ struct collinear : public base_turn_handler
|
||||
ui_else_iu(product == 1, ti);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void handle_robustness(TurnInfo& ti, int arrival,
|
||||
int side_p, int side_q, int side_pk, int side_qk)
|
||||
{
|
||||
// We take the longer one, i.e. if q arrives in p (arrival == -1),
|
||||
// then p exceeds q and we should take p for a union...
|
||||
|
||||
bool use_p_for_union = arrival == -1;
|
||||
|
||||
// ... unless one of the sides consistently directs to the other side
|
||||
int const consistent_side_p = side_p == side_pk ? side_p : 0;
|
||||
int const consistent_side_q = side_q == side_qk ? side_q : 0;
|
||||
if (arrival == -1 && (consistent_side_p == -1 || consistent_side_q == 1))
|
||||
{
|
||||
use_p_for_union = false;
|
||||
}
|
||||
if (arrival == 1 && (consistent_side_p == 1 || consistent_side_q == -1))
|
||||
{
|
||||
use_p_for_union = true;
|
||||
}
|
||||
|
||||
//std::cout << "ROBUSTNESS -> Collinear "
|
||||
// << " arr: " << arrival
|
||||
// << " dir: " << side_p << " " << side_q
|
||||
// << " rev: " << side_pk << " " << side_qk
|
||||
// << " cst: " << cside_p << " " << cside_q
|
||||
// << std::boolalpha << " " << use_p_for_union
|
||||
// << std::endl;
|
||||
|
||||
ui_else_iu(use_p_for_union, ti);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template
|
||||
@@ -583,6 +681,7 @@ private :
|
||||
TurnInfo& tp, IntersectionInfo const& intersection_info)
|
||||
{
|
||||
int const side_rk_r = SideStrategy::apply(ri, rj, rk);
|
||||
operation_type blocked = operation_blocked;
|
||||
switch(side_rk_r)
|
||||
{
|
||||
|
||||
@@ -596,15 +695,24 @@ private :
|
||||
break;
|
||||
case 0 :
|
||||
// No turn on opposite collinear: block, do not traverse
|
||||
// But this "xx" is ignored here, it is useless to include
|
||||
// two operation blocked, so the whole point does not need
|
||||
// But this "xx" is usually ignored, it is useless to include
|
||||
// two operations blocked, so the whole point does not need
|
||||
// to be generated.
|
||||
// So return false to indicate nothing is to be done.
|
||||
return false;
|
||||
if (AssignPolicy::include_opposite)
|
||||
{
|
||||
tp.operations[Index].operation = operation_opposite;
|
||||
blocked = operation_opposite;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// The other direction is always blocked when collinear opposite
|
||||
tp.operations[1 - Index].operation = operation_blocked;
|
||||
tp.operations[1 - Index].operation = blocked;
|
||||
|
||||
// If P arrives within Q, set info on P (which is done above, index=0),
|
||||
// this turn-info belongs to the second intersection point, index=1
|
||||
@@ -633,32 +741,45 @@ public:
|
||||
IntersectionInfo const& intersection_info,
|
||||
DirInfo const& dir_info)
|
||||
{
|
||||
/*
|
||||
std::cout << "arrivals: "
|
||||
<< dir_info.arrival[0]
|
||||
<< "/" << dir_info.arrival[1]
|
||||
<< std::endl;
|
||||
*/
|
||||
|
||||
TurnInfo tp = tp_model;
|
||||
|
||||
tp.method = method_collinear;
|
||||
|
||||
// If P arrives within Q, there is a turn dependant on P
|
||||
// If P arrives within Q, there is a turn dependent on P
|
||||
if (dir_info.arrival[0] == 1
|
||||
&& set_tp<0>(pi, pj, pk, tp, intersection_info))
|
||||
{
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
|
||||
*out++ = tp;
|
||||
}
|
||||
|
||||
// If Q arrives within P, there is a turn dependant on Q
|
||||
// If Q arrives within P, there is a turn dependent on Q
|
||||
if (dir_info.arrival[1] == 1
|
||||
&& set_tp<1>(qi, qj, qk, tp, intersection_info))
|
||||
{
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
|
||||
*out++ = tp;
|
||||
}
|
||||
|
||||
if (AssignPolicy::include_opposite)
|
||||
{
|
||||
// Handle cases not yet handled above
|
||||
if ((dir_info.arrival[1] == -1 && dir_info.arrival[0] == 0)
|
||||
|| (dir_info.arrival[0] == -1 && dir_info.arrival[1] == 0))
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
tp.operations[i].operation = operation_opposite;
|
||||
}
|
||||
for (unsigned int i = 0; i < intersection_info.count; i++)
|
||||
{
|
||||
geometry::convert(intersection_info.intersections[i], tp.point);
|
||||
AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -722,9 +843,17 @@ struct assign_null_policy
|
||||
{
|
||||
static bool const include_no_turn = false;
|
||||
static bool const include_degenerate = false;
|
||||
static bool const include_opposite = false;
|
||||
|
||||
template <typename Point1, typename Point2, typename Info>
|
||||
static inline void apply(Info& , Point1 const& , Point2 const& )
|
||||
template
|
||||
<
|
||||
typename Info,
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
>
|
||||
static inline void apply(Info& , Point1 const& , Point2 const&, IntersectionInfo const&, DirInfo const&)
|
||||
{}
|
||||
|
||||
};
|
||||
@@ -763,8 +892,9 @@ struct get_turn_info
|
||||
|
||||
typedef typename si::segment_intersection_strategy_type strategy;
|
||||
|
||||
|
||||
|
||||
// Intersect pi-pj with qi-qj
|
||||
// The points pk and qk are only used do determine more information
|
||||
// about the turn.
|
||||
template <typename OutputIterator>
|
||||
static inline OutputIterator apply(
|
||||
Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
@@ -796,7 +926,7 @@ struct get_turn_info
|
||||
{
|
||||
only_convert<TurnInfo>::apply(tp,
|
||||
result.template get<0>());
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -824,7 +954,7 @@ struct get_turn_info
|
||||
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
}
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -838,7 +968,7 @@ struct get_turn_info
|
||||
|
||||
policy::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -853,7 +983,7 @@ struct get_turn_info
|
||||
|
||||
policy::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -871,10 +1001,18 @@ struct get_turn_info
|
||||
|
||||
policy::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
*out++ = tp;
|
||||
}
|
||||
// If they ARE opposite, don't do anything.
|
||||
else
|
||||
{
|
||||
equal_opposite
|
||||
<
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, qi,
|
||||
tp, out, result.template get<0>(), result.template get<1>());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'c' :
|
||||
@@ -906,7 +1044,7 @@ struct get_turn_info
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
}
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
*out++ = tp;
|
||||
}
|
||||
else
|
||||
@@ -927,7 +1065,7 @@ struct get_turn_info
|
||||
if (AssignPolicy::include_degenerate)
|
||||
{
|
||||
only_convert<TurnInfo>::apply(tp, result.template get<0>());
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,7 +495,7 @@ struct get_turns_cs
|
||||
int source_id1, Range const& range,
|
||||
int source_id2, Box const& box,
|
||||
Turns& turns,
|
||||
InterruptPolicy& ,
|
||||
InterruptPolicy& interrupt_policy,
|
||||
int multi_index = -1, int ring_index = -1)
|
||||
{
|
||||
if (boost::size(range) <= 1)
|
||||
@@ -557,7 +557,7 @@ struct get_turns_cs
|
||||
get_turns_with_box(seg_id, source_id2,
|
||||
*prev, *it, *next,
|
||||
bp[0], bp[1], bp[2], bp[3],
|
||||
turns);
|
||||
turns, interrupt_policy);
|
||||
// Future performance enhancement:
|
||||
// return if told by the interrupt policy
|
||||
}
|
||||
@@ -596,7 +596,8 @@ private:
|
||||
box_point_type const& bp2,
|
||||
box_point_type const& bp3,
|
||||
// Output
|
||||
Turns& turns)
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy)
|
||||
{
|
||||
// Depending on code some relations can be left out
|
||||
|
||||
@@ -622,6 +623,12 @@ private:
|
||||
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 3);
|
||||
TurnPolicy::apply(rp0, rp1, rp2, bp3, bp0, bp1,
|
||||
ti, std::back_inserter(turns));
|
||||
|
||||
if (InterruptPolicy::enabled)
|
||||
{
|
||||
interrupt_policy.apply(turns);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
+32
-1
@@ -252,6 +252,32 @@ private :
|
||||
: order == 1;
|
||||
}
|
||||
|
||||
inline bool consider_ix_ix(Indexed const& left, Indexed const& right
|
||||
, std::string const& // header
|
||||
) const
|
||||
{
|
||||
// Take first intersection, then blocked.
|
||||
if (left.subject.operation == operation_intersection
|
||||
&& right.subject.operation == operation_blocked)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (left.subject.operation == operation_blocked
|
||||
&& right.subject.operation == operation_intersection)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Default case, should not occur
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
|
||||
std::cout << "ix/ix unhandled" << std::endl;
|
||||
#endif
|
||||
//debug_consider(0, left, right, header, false, "-> return", ret);
|
||||
|
||||
return left.index < right.index;
|
||||
}
|
||||
|
||||
|
||||
inline bool consider_iu_iu(Indexed const& left, Indexed const& right,
|
||||
std::string const& header) const
|
||||
@@ -446,6 +472,11 @@ public :
|
||||
{
|
||||
return consider_iu_iu(left, right, "iu/iu");
|
||||
}
|
||||
else if (m_turn_points[left.index].combination(operation_intersection, operation_blocked)
|
||||
&& m_turn_points[right.index].combination(operation_intersection, operation_blocked))
|
||||
{
|
||||
return consider_ix_ix(left, right, "ix/ix");
|
||||
}
|
||||
else if (m_turn_points[left.index].both(operation_intersection)
|
||||
&& m_turn_points[right.index].both(operation_intersection))
|
||||
{
|
||||
@@ -493,7 +524,7 @@ public :
|
||||
<< "/" << operation_char(m_turn_points[right.index].operations[0].operation)
|
||||
<< operation_char(m_turn_points[right.index].operations[1].operation)
|
||||
<< " " << " Take " << left.index << " < " << right.index
|
||||
<< std::cout;
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
return default_order;
|
||||
|
||||
+117
-161
@@ -41,14 +41,14 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace intersection
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment1, typename Segment2,
|
||||
typename OutputIterator, typename PointOut,
|
||||
typename Strategy
|
||||
>
|
||||
template <typename PointOut>
|
||||
struct intersection_segment_segment_point
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Segment1, typename Segment2,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(Segment1 const& segment1,
|
||||
Segment2 const& segment2, OutputIterator out,
|
||||
Strategy const& )
|
||||
@@ -77,14 +77,14 @@ struct intersection_segment_segment_point
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring1, typename Linestring2,
|
||||
typename OutputIterator, typename PointOut,
|
||||
typename Strategy
|
||||
>
|
||||
template <typename PointOut>
|
||||
struct intersection_linestring_linestring_point
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Linestring1, typename Linestring2,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(Linestring1 const& linestring1,
|
||||
Linestring2 const& linestring2, OutputIterator out,
|
||||
Strategy const& )
|
||||
@@ -112,22 +112,12 @@ struct intersection_linestring_linestring_point
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename LineString, typename Areal,
|
||||
bool ReverseAreal,
|
||||
typename OutputIterator, typename LineStringOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
typename LineStringOut,
|
||||
overlay_type OverlayType
|
||||
>
|
||||
struct intersection_of_linestring_with_areal
|
||||
{
|
||||
typedef detail::overlay::follow
|
||||
<
|
||||
LineStringOut,
|
||||
LineString,
|
||||
Areal,
|
||||
OverlayType
|
||||
> follower;
|
||||
|
||||
#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
|
||||
template <typename Turn, typename Operation>
|
||||
static inline void debug_follow(Turn const& turn, Operation op,
|
||||
@@ -145,6 +135,11 @@ struct intersection_of_linestring_with_areal
|
||||
}
|
||||
#endif
|
||||
|
||||
template
|
||||
<
|
||||
typename LineString, typename Areal,
|
||||
typename OutputIterator, typename Strategy
|
||||
>
|
||||
static inline OutputIterator apply(LineString const& linestring, Areal const& areal,
|
||||
OutputIterator out,
|
||||
Strategy const& )
|
||||
@@ -154,6 +149,14 @@ struct intersection_of_linestring_with_areal
|
||||
return out;
|
||||
}
|
||||
|
||||
typedef detail::overlay::follow
|
||||
<
|
||||
LineStringOut,
|
||||
LineString,
|
||||
Areal,
|
||||
OverlayType
|
||||
> follower;
|
||||
|
||||
typedef typename point_type<LineStringOut>::type point_type;
|
||||
|
||||
typedef detail::overlay::traversal_turn_info<point_type> turn_info;
|
||||
@@ -220,18 +223,22 @@ namespace dispatch
|
||||
|
||||
template
|
||||
<
|
||||
// tag dispatching:
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
// orientation
|
||||
// metafunction finetuning helpers:
|
||||
bool Areal1, bool Areal2, bool ArealOut,
|
||||
// real types
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
// orientation
|
||||
bool Reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
bool Reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
|
||||
bool ReverseOut = detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
// tag dispatching:
|
||||
typename TagIn1 = typename geometry::tag<Geometry1>::type,
|
||||
typename TagIn2 = typename geometry::tag<Geometry2>::type,
|
||||
typename TagOut = typename geometry::tag<GeometryOut>::type,
|
||||
// metafunction finetuning helpers:
|
||||
bool Areal1 = geometry::is_areal<Geometry1>::value,
|
||||
bool Areal2 = geometry::is_areal<Geometry2>::value,
|
||||
bool ArealOut = geometry::is_areal<GeometryOut>::value
|
||||
>
|
||||
struct intersection_insert
|
||||
{
|
||||
@@ -245,122 +252,103 @@ struct intersection_insert
|
||||
|
||||
template
|
||||
<
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename TagIn1, typename TagIn2, typename TagOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
TagIn1, TagIn2, TagOut,
|
||||
true, true, true,
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
TagIn1, TagIn2, TagOut,
|
||||
true, true, true
|
||||
> : detail::overlay::overlay
|
||||
<Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, OverlayType, Strategy>
|
||||
<Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, GeometryOut, OverlayType>
|
||||
{};
|
||||
|
||||
|
||||
// Any areal type with box:
|
||||
template
|
||||
<
|
||||
typename TagIn, typename TagOut,
|
||||
typename Geometry, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename TagIn, typename TagOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
TagIn, box_tag, TagOut,
|
||||
true, true, true,
|
||||
Geometry, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
TagIn, box_tag, TagOut,
|
||||
true, true, true
|
||||
> : detail::overlay::overlay
|
||||
<Geometry, Box, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, OverlayType, Strategy>
|
||||
<Geometry, Box, Reverse1, Reverse2, ReverseOut, GeometryOut, OverlayType>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment1, typename Segment2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
segment_tag, segment_tag, point_tag,
|
||||
false, false, false,
|
||||
Segment1, Segment2,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType, Strategy
|
||||
> : detail::intersection::intersection_segment_segment_point
|
||||
<
|
||||
Segment1, Segment2,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
segment_tag, segment_tag, point_tag,
|
||||
false, false, false
|
||||
> : detail::intersection::intersection_segment_segment_point<GeometryOut>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring1, typename Linestring2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
linestring_tag, linestring_tag, point_tag,
|
||||
false, false, false,
|
||||
Linestring1, Linestring2,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType, Strategy
|
||||
> : detail::intersection::intersection_linestring_linestring_point
|
||||
<
|
||||
Linestring1, Linestring2,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
linestring_tag, linestring_tag, point_tag,
|
||||
false, false, false
|
||||
> : detail::intersection::intersection_linestring_linestring_point<GeometryOut>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
linestring_tag, box_tag, linestring_tag,
|
||||
false, true, false,
|
||||
Linestring, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
linestring_tag, box_tag, linestring_tag,
|
||||
false, true, false
|
||||
>
|
||||
{
|
||||
template <typename OutputIterator, typename Strategy>
|
||||
static inline OutputIterator apply(Linestring const& linestring,
|
||||
Box const& box, OutputIterator out, Strategy const& )
|
||||
{
|
||||
@@ -375,27 +363,23 @@ struct intersection_insert
|
||||
template
|
||||
<
|
||||
typename Linestring, typename Polygon,
|
||||
bool ReverseLinestring, bool ReversePolygon, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
bool ReverseLinestring, bool ReversePolygon, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
linestring_tag, polygon_tag, linestring_tag,
|
||||
false, true, false,
|
||||
Linestring, Polygon,
|
||||
ReverseLinestring, ReversePolygon, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
ReverseLinestring, ReversePolygon, ReverseOut,
|
||||
linestring_tag, polygon_tag, linestring_tag,
|
||||
false, true, false
|
||||
> : detail::intersection::intersection_of_linestring_with_areal
|
||||
<
|
||||
Linestring, Polygon,
|
||||
ReversePolygon,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
GeometryOut,
|
||||
OverlayType
|
||||
>
|
||||
{};
|
||||
|
||||
@@ -403,49 +387,44 @@ struct intersection_insert
|
||||
template
|
||||
<
|
||||
typename Linestring, typename Ring,
|
||||
bool ReverseLinestring, bool ReverseRing, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
bool ReverseLinestring, bool ReverseRing, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
linestring_tag, ring_tag, linestring_tag,
|
||||
false, true, false,
|
||||
Linestring, Ring,
|
||||
ReverseLinestring, ReverseRing, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
ReverseLinestring, ReverseRing, ReverseOut,
|
||||
linestring_tag, ring_tag, linestring_tag,
|
||||
false, true, false
|
||||
> : detail::intersection::intersection_of_linestring_with_areal
|
||||
<
|
||||
Linestring, Ring,
|
||||
ReverseRing,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
GeometryOut,
|
||||
OverlayType
|
||||
>
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
segment_tag, box_tag, linestring_tag,
|
||||
false, true, false,
|
||||
Segment, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
segment_tag, box_tag, linestring_tag,
|
||||
false, true, false
|
||||
>
|
||||
{
|
||||
template <typename OutputIterator, typename Strategy>
|
||||
static inline OutputIterator apply(Segment const& segment,
|
||||
Box const& box, OutputIterator out, Strategy const& )
|
||||
{
|
||||
@@ -460,25 +439,24 @@ struct intersection_insert
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2,
|
||||
bool Areal1, bool Areal2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename PointOut,
|
||||
typename PointOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename Tag1, typename Tag2,
|
||||
bool Areal1, bool Areal2
|
||||
>
|
||||
struct intersection_insert
|
||||
<
|
||||
Tag1, Tag2, point_tag,
|
||||
Areal1, Areal2, false,
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, PointOut,
|
||||
PointOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
Tag1, Tag2, point_tag,
|
||||
Areal1, Areal2, false
|
||||
>
|
||||
{
|
||||
template <typename OutputIterator, typename Strategy>
|
||||
static inline OutputIterator apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2, OutputIterator out, Strategy const& )
|
||||
{
|
||||
@@ -504,29 +482,22 @@ struct intersection_insert
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
|
||||
bool Areal1, bool Areal2, bool ArealOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename Geometry1, typename Geometry2, typename GeometryOut,
|
||||
overlay_type OverlayType,
|
||||
typename Strategy
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct intersection_insert_reversed
|
||||
{
|
||||
template <typename OutputIterator, typename Strategy>
|
||||
static inline OutputIterator apply(Geometry1 const& g1,
|
||||
Geometry2 const& g2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return intersection_insert
|
||||
<
|
||||
GeometryTag2, GeometryTag1, GeometryTag3,
|
||||
Areal2, Areal1, ArealOut,
|
||||
Geometry2, Geometry1,
|
||||
Reverse2, Reverse1, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Geometry2, Geometry1, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
Reverse2, Reverse1, ReverseOut
|
||||
>::apply(g2, g1, out, strategy);
|
||||
}
|
||||
};
|
||||
@@ -561,35 +532,20 @@ inline OutputIterator insert(Geometry1 const& geometry1,
|
||||
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
geometry::dispatch::intersection_insert_reversed
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value,
|
||||
overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
OutputIterator, GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value
|
||||
>,
|
||||
geometry::dispatch::intersection_insert
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
OutputIterator, GeometryOut,
|
||||
GeometryOut,
|
||||
OverlayType,
|
||||
Strategy
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
|
||||
>
|
||||
>::type::apply(geometry1, geometry2, out, strategy);
|
||||
}
|
||||
|
||||
@@ -134,12 +134,12 @@ template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
overlay_type Direction,
|
||||
typename Strategy
|
||||
typename GeometryOut,
|
||||
overlay_type Direction
|
||||
>
|
||||
struct overlay
|
||||
{
|
||||
template <typename OutputIterator, typename Strategy>
|
||||
static inline OutputIterator apply(
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
OutputIterator out,
|
||||
@@ -233,7 +233,7 @@ std::cout << "traverse" << std::endl;
|
||||
std::cout << "map_turns: " << timer.elapsed() << std::endl;
|
||||
#endif
|
||||
|
||||
typedef ring_properties<typename geometry::point_type<Geometry1>::type> properties;
|
||||
typedef ring_properties<typename geometry::point_type<GeometryOut>::type> properties;
|
||||
|
||||
std::map<ring_identifier, properties> selected;
|
||||
select_rings<Direction>(geometry1, geometry2, map, selected, ! turn_points.empty());
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
#include <boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
#include <boost/geometry/algorithms/num_points.hpp>
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
@@ -233,6 +235,7 @@ public :
|
||||
detail::overlay::operation_type operation,
|
||||
Turns& turns, Rings& rings)
|
||||
{
|
||||
typedef typename boost::range_value<Rings>::type ring_type;
|
||||
typedef typename boost::range_iterator<Turns>::type turn_iterator;
|
||||
typedef typename boost::range_value<Turns>::type turn_type;
|
||||
typedef typename boost::range_iterator
|
||||
@@ -240,6 +243,12 @@ public :
|
||||
typename turn_type::container_type
|
||||
>::type turn_operation_iterator_type;
|
||||
|
||||
std::size_t const min_num_points
|
||||
= core_detail::closure::minimum_ring_size
|
||||
<
|
||||
geometry::closure<ring_type>::value
|
||||
>::value;
|
||||
|
||||
std::size_t size_at_start = boost::size(rings);
|
||||
|
||||
typename Backtrack::state_type state;
|
||||
@@ -267,7 +276,7 @@ public :
|
||||
{
|
||||
set_visited_for_continue(*it, *iit);
|
||||
|
||||
typename boost::range_value<Rings>::type current_output;
|
||||
ring_type current_output;
|
||||
detail::overlay::append_no_duplicates(current_output,
|
||||
it->point, true);
|
||||
|
||||
@@ -376,7 +385,10 @@ public :
|
||||
{
|
||||
iit->visited.set_finished();
|
||||
detail::overlay::debug_traverse(*current, *iit, "->Finished");
|
||||
rings.push_back(current_output);
|
||||
if (geometry::num_points(current_output) >= min_num_points)
|
||||
{
|
||||
rings.push_back(current_output);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@ enum operation_type
|
||||
operation_union,
|
||||
operation_intersection,
|
||||
operation_blocked,
|
||||
operation_continue
|
||||
operation_continue,
|
||||
operation_opposite
|
||||
};
|
||||
|
||||
|
||||
@@ -102,6 +103,12 @@ struct turn_info
|
||||
{
|
||||
return has12(type, type);
|
||||
}
|
||||
|
||||
inline bool has(operation_type type) const
|
||||
{
|
||||
return this->operations[0].operation == type
|
||||
|| this->operations[1].operation == type;
|
||||
}
|
||||
|
||||
inline bool combination(operation_type type1, operation_type type2) const
|
||||
{
|
||||
@@ -114,10 +121,13 @@ struct turn_info
|
||||
{
|
||||
return both(operation_blocked);
|
||||
}
|
||||
inline bool opposite() const
|
||||
{
|
||||
return both(operation_opposite);
|
||||
}
|
||||
inline bool any_blocked() const
|
||||
{
|
||||
return this->operations[0].operation == operation_blocked
|
||||
|| this->operations[1].operation == operation_blocked;
|
||||
return has(operation_blocked);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -153,12 +153,12 @@ class partition_one_collection
|
||||
static inline void next_level(Box const& box,
|
||||
InputCollection const& collection,
|
||||
index_vector_type const& input,
|
||||
int level, int min_elements,
|
||||
int level, std::size_t min_elements,
|
||||
Policy& policy, VisitBoxPolicy& box_policy)
|
||||
{
|
||||
if (boost::size(input) > 0)
|
||||
{
|
||||
if (boost::size(input) > min_elements && level < 100)
|
||||
if (std::size_t(boost::size(input)) > min_elements && level < 100)
|
||||
{
|
||||
sub_divide::apply(box, collection, input, level + 1,
|
||||
min_elements, policy, box_policy);
|
||||
@@ -176,7 +176,7 @@ public :
|
||||
InputCollection const& collection,
|
||||
index_vector_type const& input,
|
||||
int level,
|
||||
int min_elements,
|
||||
std::size_t min_elements,
|
||||
Policy& policy, VisitBoxPolicy& box_policy)
|
||||
{
|
||||
box_policy.apply(box, level);
|
||||
@@ -230,13 +230,13 @@ class partition_two_collections
|
||||
index_vector_type const& input1,
|
||||
InputCollection const& collection2,
|
||||
index_vector_type const& input2,
|
||||
int level, int min_elements,
|
||||
int level, std::size_t min_elements,
|
||||
Policy& policy, VisitBoxPolicy& box_policy)
|
||||
{
|
||||
if (boost::size(input1) > 0 && boost::size(input2) > 0)
|
||||
{
|
||||
if (boost::size(input1) > min_elements
|
||||
&& boost::size(input2) > min_elements
|
||||
if (std::size_t(boost::size(input1)) > min_elements
|
||||
&& std::size_t(boost::size(input2)) > min_elements
|
||||
&& level < 100)
|
||||
{
|
||||
sub_divide::apply(box, collection1, input1, collection2,
|
||||
@@ -257,7 +257,7 @@ public :
|
||||
InputCollection const& collection1, index_vector_type const& input1,
|
||||
InputCollection const& collection2, index_vector_type const& input2,
|
||||
int level,
|
||||
int min_elements,
|
||||
std::size_t min_elements,
|
||||
Policy& policy, VisitBoxPolicy& box_policy)
|
||||
{
|
||||
box_policy.apply(box, level);
|
||||
@@ -335,11 +335,11 @@ public :
|
||||
template <typename InputCollection, typename VisitPolicy>
|
||||
static inline void apply(InputCollection const& collection,
|
||||
VisitPolicy& visitor,
|
||||
int min_elements = 16,
|
||||
std::size_t min_elements = 16,
|
||||
VisitBoxPolicy box_visitor = visit_no_policy()
|
||||
)
|
||||
{
|
||||
if (boost::size(collection) > min_elements)
|
||||
if (std::size_t(boost::size(collection)) > min_elements)
|
||||
{
|
||||
index_vector_type index_vector;
|
||||
Box total;
|
||||
@@ -377,12 +377,12 @@ public :
|
||||
static inline void apply(InputCollection const& collection1,
|
||||
InputCollection const& collection2,
|
||||
VisitPolicy& visitor,
|
||||
int min_elements = 16,
|
||||
std::size_t min_elements = 16,
|
||||
VisitBoxPolicy box_visitor = visit_no_policy()
|
||||
)
|
||||
{
|
||||
if (boost::size(collection1) > min_elements
|
||||
&& boost::size(collection2) > min_elements)
|
||||
if (std::size_t(boost::size(collection1)) > min_elements
|
||||
&& std::size_t(boost::size(collection2)) > min_elements)
|
||||
{
|
||||
index_vector_type index_vector1, index_vector2;
|
||||
Box total;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint.hpp>
|
||||
|
||||
|
||||
@@ -50,7 +51,8 @@ struct get_point
|
||||
template<typename Point, std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct midpoint_helper
|
||||
{
|
||||
static inline bool apply(Point& p, Point const& p1, Point const& p2)
|
||||
template <typename InputPoint>
|
||||
static inline bool apply(Point& p, InputPoint const& p1, InputPoint const& p2)
|
||||
{
|
||||
typename coordinate_type<Point>::type const two = 2;
|
||||
set<Dimension>(p,
|
||||
@@ -63,7 +65,8 @@ struct midpoint_helper
|
||||
template <typename Point, std::size_t DimensionCount>
|
||||
struct midpoint_helper<Point, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline bool apply(Point& , Point const& , Point const& )
|
||||
template <typename InputPoint>
|
||||
static inline bool apply(Point& , InputPoint const& , InputPoint const& )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -102,7 +105,7 @@ struct point_on_range
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
point = *boost::begin(range);
|
||||
geometry::detail::conversion::convert_point_to_point(*boost::begin(range), point);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -254,7 +254,7 @@ struct sectionalize_part
|
||||
Range const& range,
|
||||
ring_identifier ring_id)
|
||||
{
|
||||
if (boost::size(range) <= index)
|
||||
if (int(boost::size(range)) <= index)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -56,19 +56,11 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
|
||||
|
||||
return geometry::dispatch::intersection_insert
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
OutputIterator, GeometryOut,
|
||||
GeometryOut,
|
||||
overlay_difference,
|
||||
Strategy
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
|
||||
>::apply(geometry1, geometry2, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/detail/for_each_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
|
||||
#include <boost/geometry/algorithms/within.hpp>
|
||||
@@ -44,15 +45,57 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace disjoint
|
||||
{
|
||||
|
||||
template<typename Geometry>
|
||||
struct check_each_ring_for_within
|
||||
{
|
||||
bool has_within;
|
||||
Geometry const& m_geometry;
|
||||
|
||||
inline check_each_ring_for_within(Geometry const& g)
|
||||
: has_within(false)
|
||||
, m_geometry(g)
|
||||
{}
|
||||
|
||||
template <typename Range>
|
||||
inline void apply(Range const& range)
|
||||
{
|
||||
typename geometry::point_type<Range>::type p;
|
||||
geometry::point_on_border(p, range);
|
||||
if (geometry::within(p, m_geometry))
|
||||
{
|
||||
has_within = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename FirstGeometry, typename SecondGeometry>
|
||||
inline bool rings_containing(FirstGeometry const& geometry1,
|
||||
SecondGeometry const& geometry2)
|
||||
{
|
||||
check_each_ring_for_within<FirstGeometry> checker(geometry1);
|
||||
geometry::detail::for_each_range(geometry2, checker);
|
||||
return checker.has_within;
|
||||
}
|
||||
|
||||
|
||||
struct assign_disjoint_policy
|
||||
{
|
||||
// We want to include all points:
|
||||
static bool const include_no_turn = true;
|
||||
static bool const include_degenerate = true;
|
||||
static bool const include_opposite = true;
|
||||
|
||||
// We don't assign extra info:
|
||||
template <typename Point1, typename Point2, typename Info>
|
||||
static inline void apply(Info& , Point1 const& , Point2 const& )
|
||||
template
|
||||
<
|
||||
typename Info,
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo,
|
||||
typename DirInfo
|
||||
>
|
||||
static inline void apply(Info& , Point1 const& , Point2 const&,
|
||||
IntersectionInfo const&, DirInfo const&)
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -107,8 +150,6 @@ struct disjoint_segment
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct general_areal
|
||||
{
|
||||
@@ -119,20 +160,10 @@ struct general_areal
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef typename geometry::point_type<Geometry1>::type point_type;
|
||||
|
||||
// If there is no intersection of segments, they might located
|
||||
// inside each other
|
||||
point_type p1;
|
||||
geometry::point_on_border(p1, geometry1);
|
||||
if (geometry::within(p1, geometry2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
typename geometry::point_type<Geometry1>::type p2;
|
||||
geometry::point_on_border(p2, geometry2);
|
||||
if (geometry::within(p2, geometry1))
|
||||
if (rings_containing(geometry1, geometry2)
|
||||
|| rings_containing(geometry2, geometry1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -153,68 +184,82 @@ namespace dispatch
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
std::size_t DimensionCount
|
||||
std::size_t DimensionCount = dimension<Geometry1>::type::value,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct disjoint
|
||||
: detail::disjoint::general_areal<Geometry1, Geometry2>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, std::size_t DimensionCount>
|
||||
struct disjoint<point_tag, point_tag, Point1, Point2, DimensionCount>
|
||||
: detail::disjoint::point_point<Point1, Point2, 0, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount>
|
||||
struct disjoint<box_tag, box_tag, Box1, Box2, DimensionCount>
|
||||
: detail::disjoint::box_box<Box1, Box2, 0, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point, typename Box, std::size_t DimensionCount>
|
||||
struct disjoint<point_tag, box_tag, Point, Box, DimensionCount>
|
||||
: detail::disjoint::point_box<Point, Box, 0, DimensionCount>
|
||||
{};
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
struct disjoint<linestring_tag, linestring_tag, Linestring1, Linestring2, 2>
|
||||
: detail::disjoint::disjoint_linear<Linestring1, Linestring2>
|
||||
{};
|
||||
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
struct disjoint<segment_tag, segment_tag, Linestring1, Linestring2, 2>
|
||||
: detail::disjoint::disjoint_segment<Linestring1, Linestring2>
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename Segment>
|
||||
struct disjoint<linestring_tag, segment_tag, Linestring, Segment, 2>
|
||||
: detail::disjoint::disjoint_linear<Linestring, Segment>
|
||||
{};
|
||||
|
||||
|
||||
// If reversal is needed, perform it
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
std::size_t DimensionCount
|
||||
std::size_t DimensionCount,
|
||||
typename Tag1, typename Tag2
|
||||
>
|
||||
struct disjoint_reversed
|
||||
struct disjoint<Geometry1, Geometry2, DimensionCount, Tag1, Tag2, true>
|
||||
: disjoint<Geometry2, Geometry1, DimensionCount, Tag2, Tag1, false>
|
||||
{
|
||||
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
|
||||
{
|
||||
return disjoint
|
||||
<
|
||||
GeometryTag2, GeometryTag1,
|
||||
Geometry2, Geometry1,
|
||||
DimensionCount
|
||||
DimensionCount,
|
||||
Tag2, Tag1
|
||||
>::apply(g2, g1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, std::size_t DimensionCount, bool Reverse>
|
||||
struct disjoint<Point1, Point2, DimensionCount, point_tag, point_tag, Reverse>
|
||||
: detail::disjoint::point_point<Point1, Point2, 0, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount, bool Reverse>
|
||||
struct disjoint<Box1, Box2, DimensionCount, box_tag, box_tag, Reverse>
|
||||
: detail::disjoint::box_box<Box1, Box2, 0, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point, typename Box, std::size_t DimensionCount, bool Reverse>
|
||||
struct disjoint<Point, Box, DimensionCount, point_tag, box_tag, Reverse>
|
||||
: detail::disjoint::point_box<Point, Box, 0, DimensionCount>
|
||||
{};
|
||||
|
||||
template <typename Point, typename Ring, std::size_t DimensionCount, bool Reverse>
|
||||
struct disjoint<Point, Ring, DimensionCount, point_tag, ring_tag, Reverse>
|
||||
: detail::disjoint::reverse_covered_by<Point, Ring>
|
||||
{};
|
||||
|
||||
template <typename Point, typename Polygon, std::size_t DimensionCount, bool Reverse>
|
||||
struct disjoint<Point, Polygon, DimensionCount, point_tag, polygon_tag, Reverse>
|
||||
: detail::disjoint::reverse_covered_by<Point, Polygon>
|
||||
{};
|
||||
|
||||
template <typename Linestring1, typename Linestring2, bool Reverse>
|
||||
struct disjoint<Linestring1, Linestring2, 2, linestring_tag, linestring_tag, Reverse>
|
||||
: detail::disjoint::disjoint_linear<Linestring1, Linestring2>
|
||||
{};
|
||||
|
||||
template <typename Linestring1, typename Linestring2, bool Reverse>
|
||||
struct disjoint<Linestring1, Linestring2, 2, segment_tag, segment_tag, Reverse>
|
||||
: detail::disjoint::disjoint_segment<Linestring1, Linestring2>
|
||||
{};
|
||||
|
||||
template <typename Linestring, typename Segment, bool Reverse>
|
||||
struct disjoint<Linestring, Segment, 2, linestring_tag, segment_tag, Reverse>
|
||||
: detail::disjoint::disjoint_linear<Linestring, Segment>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
@@ -241,26 +286,7 @@ inline bool disjoint(Geometry1 const& geometry1,
|
||||
Geometry2 const
|
||||
>();
|
||||
|
||||
return boost::mpl::if_c
|
||||
<
|
||||
reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
dispatch::disjoint_reversed
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
dimension<Geometry1>::type::value
|
||||
>,
|
||||
dispatch::disjoint
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
dimension<Geometry1>::type::value
|
||||
>
|
||||
>::type::apply(geometry1, geometry2);
|
||||
return dispatch::disjoint<Geometry1, Geometry2>::apply(geometry1, geometry2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ struct point_to_range
|
||||
// check if other segments are closer
|
||||
for (++prev, ++it; it != boost::end(view); ++prev, ++it)
|
||||
{
|
||||
return_type const ds = ps_strategy.apply(point, *prev, *it);
|
||||
return_type const ds = eps_strategy.apply(point, *prev, *it);
|
||||
if (geometry::math::equals(ds, zero))
|
||||
{
|
||||
return ds;
|
||||
@@ -369,7 +369,10 @@ struct distance
|
||||
<
|
||||
segment_tag,
|
||||
Point,
|
||||
typename point_type<Linestring>::type
|
||||
typename point_type<Linestring>::type,
|
||||
typename cs_tag<Point>::type,
|
||||
typename cs_tag<typename point_type<Linestring>::type>::type,
|
||||
Strategy
|
||||
>::type ps_strategy_type;
|
||||
|
||||
return detail::distance::point_to_range
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/expand.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
@@ -35,9 +35,9 @@ namespace detail { namespace envelope
|
||||
|
||||
|
||||
/// Calculate envelope of an 2D or 3D segment
|
||||
template<typename Geometry, typename Box>
|
||||
struct envelope_expand_one
|
||||
{
|
||||
template<typename Geometry, typename Box>
|
||||
static inline void apply(Geometry const& geometry, Box& mbr)
|
||||
{
|
||||
assign_inverse(mbr);
|
||||
@@ -63,10 +63,10 @@ inline void envelope_range_additional(Range const& range, Box& mbr)
|
||||
|
||||
|
||||
/// Generic range dispatching struct
|
||||
template <typename Range, typename Box>
|
||||
struct envelope_range
|
||||
{
|
||||
/// Calculate envelope of range using a strategy
|
||||
template <typename Range, typename Box>
|
||||
static inline void apply(Range const& range, Box& mbr)
|
||||
{
|
||||
assign_inverse(mbr);
|
||||
@@ -82,122 +82,54 @@ namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// Note, the strategy is for future use (less/greater -> compare spherical
|
||||
// using other methods), defaults are OK for now.
|
||||
// However, they are already in the template methods
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2,
|
||||
typename Geometry, typename Box,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
typename Geometry,
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct envelope
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry>)
|
||||
);
|
||||
};
|
||||
struct envelope: not_implemented<Tag>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point, typename Box,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct envelope
|
||||
<
|
||||
point_tag, box_tag,
|
||||
Point, Box,
|
||||
StrategyLess, StrategyGreater
|
||||
>
|
||||
: detail::envelope::envelope_expand_one<Point, Box>
|
||||
template <typename Point>
|
||||
struct envelope<Point, point_tag>
|
||||
: detail::envelope::envelope_expand_one
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename BoxIn, typename BoxOut,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct envelope
|
||||
<
|
||||
box_tag, box_tag,
|
||||
BoxIn, BoxOut,
|
||||
StrategyLess, StrategyGreater
|
||||
>
|
||||
: detail::envelope::envelope_expand_one<BoxIn, BoxOut>
|
||||
template <typename Box>
|
||||
struct envelope<Box, box_tag>
|
||||
: detail::envelope::envelope_expand_one
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment, typename Box,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct envelope
|
||||
<
|
||||
segment_tag, box_tag,
|
||||
Segment, Box,
|
||||
StrategyLess, StrategyGreater
|
||||
>
|
||||
: detail::envelope::envelope_expand_one<Segment, Box>
|
||||
template <typename Segment>
|
||||
struct envelope<Segment, segment_tag>
|
||||
: detail::envelope::envelope_expand_one
|
||||
{};
|
||||
|
||||
|
||||
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 Linestring>
|
||||
struct envelope<Linestring, linestring_tag>
|
||||
: detail::envelope::envelope_range
|
||||
{};
|
||||
|
||||
|
||||
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 Ring>
|
||||
struct envelope<Ring, ring_tag>
|
||||
: detail::envelope::envelope_range
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Polygon, typename Box,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct envelope
|
||||
<
|
||||
polygon_tag, box_tag,
|
||||
Polygon, Box,
|
||||
StrategyLess, StrategyGreater
|
||||
>
|
||||
template <typename Polygon>
|
||||
struct envelope<Polygon, polygon_tag>
|
||||
: detail::envelope::envelope_range
|
||||
{
|
||||
template <typename Box>
|
||||
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
|
||||
>::apply(exterior_ring(poly), mbr);
|
||||
detail::envelope::envelope_range::apply(exterior_ring(poly), mbr);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -228,12 +160,7 @@ inline void envelope(Geometry const& geometry, Box& mbr)
|
||||
concept::check<Geometry const>();
|
||||
concept::check<Box>();
|
||||
|
||||
dispatch::envelope
|
||||
<
|
||||
typename tag<Geometry>::type, typename tag<Box>::type,
|
||||
Geometry, Box,
|
||||
void, void
|
||||
>::apply(geometry, mbr);
|
||||
dispatch::envelope<Geometry>::apply(geometry, mbr);
|
||||
}
|
||||
|
||||
|
||||
@@ -259,12 +186,7 @@ inline Box return_envelope(Geometry const& geometry)
|
||||
concept::check<Box>();
|
||||
|
||||
Box mbr;
|
||||
dispatch::envelope
|
||||
<
|
||||
typename tag<Geometry>::type, typename tag<Box>::type,
|
||||
Geometry, Box,
|
||||
void, void
|
||||
>::apply(geometry, mbr);
|
||||
dispatch::envelope<Geometry>::apply(geometry, mbr);
|
||||
return mbr;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
@@ -30,6 +28,7 @@
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/detail/not.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
// For trivial checks
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
@@ -51,13 +50,12 @@ namespace detail { namespace equals
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1,
|
||||
typename Box2,
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2)
|
||||
{
|
||||
if (!geometry::math::equals(get<min_corner, Dimension>(box1), get<min_corner, Dimension>(box2))
|
||||
@@ -65,13 +63,14 @@ struct box_box
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return box_box<Box1, Box2, Dimension + 1, DimensionCount>::apply(box1, box2);
|
||||
return box_box<Dimension + 1, DimensionCount>::apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount>
|
||||
struct box_box<Box1, Box2, DimensionCount, DimensionCount>
|
||||
template <std::size_t DimensionCount>
|
||||
struct box_box<DimensionCount, DimensionCount>
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline bool apply(Box1 const& , Box2 const& )
|
||||
{
|
||||
return true;
|
||||
@@ -103,9 +102,10 @@ struct length_check
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename TrivialCheck>
|
||||
template <typename TrivialCheck>
|
||||
struct equals_by_collection
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
if (! TrivialCheck::apply(geometry1, geometry2))
|
||||
@@ -152,17 +152,42 @@ namespace dispatch
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
std::size_t DimensionCount
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type,
|
||||
std::size_t DimensionCount = dimension<Geometry1>::type::value,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct equals
|
||||
struct equals: not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
||||
|
||||
template <typename P1, typename P2, std::size_t DimensionCount>
|
||||
struct equals<point_tag, point_tag, P1, P2, DimensionCount>
|
||||
// If reversal is needed, perform it
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1, typename Tag2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
|
||||
: equals<Geometry2, Geometry1, Tag2, Tag1, DimensionCount, false>
|
||||
{
|
||||
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
|
||||
{
|
||||
return equals
|
||||
<
|
||||
Geometry2, Geometry1,
|
||||
Tag2, Tag1,
|
||||
DimensionCount,
|
||||
false
|
||||
>::apply(g2, g1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename P1, typename P2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<P1, P2, point_tag, point_tag, DimensionCount, Reverse>
|
||||
: geometry::detail::not_
|
||||
<
|
||||
P1,
|
||||
@@ -172,93 +197,48 @@ struct equals<point_tag, point_tag, P1, P2, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount>
|
||||
struct equals<box_tag, box_tag, Box1, Box2, DimensionCount>
|
||||
: detail::equals::box_box<Box1, Box2, 0, DimensionCount>
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<Box1, Box2, box_tag, box_tag, DimensionCount, Reverse>
|
||||
: detail::equals::box_box<0, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring1, typename Ring2>
|
||||
struct equals<ring_tag, ring_tag, Ring1, Ring2, 2>
|
||||
: detail::equals::equals_by_collection
|
||||
<
|
||||
Ring1, Ring2,
|
||||
detail::equals::area_check
|
||||
>
|
||||
template <typename Ring1, typename Ring2, bool Reverse>
|
||||
struct equals<Ring1, Ring2, ring_tag, ring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon1, typename Polygon2>
|
||||
struct equals<polygon_tag, polygon_tag, Polygon1, Polygon2, 2>
|
||||
: detail::equals::equals_by_collection
|
||||
<
|
||||
Polygon1, Polygon2,
|
||||
detail::equals::area_check
|
||||
>
|
||||
template <typename Polygon1, typename Polygon2, bool Reverse>
|
||||
struct equals<Polygon1, Polygon2, polygon_tag, polygon_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename LineString1, typename LineString2>
|
||||
struct equals<linestring_tag, linestring_tag, LineString1, LineString2, 2>
|
||||
: detail::equals::equals_by_collection
|
||||
<
|
||||
LineString1, LineString2,
|
||||
detail::equals::length_check
|
||||
>
|
||||
template <typename LineString1, typename LineString2, bool Reverse>
|
||||
struct equals<LineString1, LineString2, linestring_tag, linestring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::length_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Ring>
|
||||
struct equals<polygon_tag, ring_tag, Polygon, Ring, 2>
|
||||
: detail::equals::equals_by_collection
|
||||
<
|
||||
Polygon, Ring,
|
||||
detail::equals::area_check
|
||||
>
|
||||
template <typename Polygon, typename Ring, bool Reverse>
|
||||
struct equals<Polygon, Ring, polygon_tag, ring_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring, typename Box>
|
||||
struct equals<ring_tag, box_tag, Ring, Box, 2>
|
||||
: detail::equals::equals_by_collection
|
||||
<
|
||||
Ring, Box,
|
||||
detail::equals::area_check
|
||||
>
|
||||
template <typename Ring, typename Box, bool Reverse>
|
||||
struct equals<Ring, Box, ring_tag, box_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Box>
|
||||
struct equals<polygon_tag, box_tag, Polygon, Box, 2>
|
||||
: detail::equals::equals_by_collection
|
||||
<
|
||||
Polygon, Box,
|
||||
detail::equals::area_check
|
||||
>
|
||||
template <typename Polygon, typename Box, bool Reverse>
|
||||
struct equals<Polygon, Box, polygon_tag, box_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct equals_reversed
|
||||
{
|
||||
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
|
||||
{
|
||||
return equals
|
||||
<
|
||||
Tag2, Tag1,
|
||||
Geometry2, Geometry1,
|
||||
DimensionCount
|
||||
>::apply(g2, g1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
@@ -289,26 +269,7 @@ inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
Geometry2 const
|
||||
>();
|
||||
|
||||
return boost::mpl::if_c
|
||||
<
|
||||
reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
dispatch::equals_reversed
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
dimension<Geometry1>::type::value
|
||||
>,
|
||||
dispatch::equals
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
dimension<Geometry1>::type::value
|
||||
>
|
||||
>::type::apply(geometry1, geometry2);
|
||||
return dispatch::equals<Geometry1, Geometry2>::apply(geometry1, geometry2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
@@ -38,26 +39,26 @@ namespace detail { namespace expand
|
||||
|
||||
template
|
||||
<
|
||||
typename Box, typename Point,
|
||||
typename StrategyLess, typename StrategyGreater,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct point_loop
|
||||
{
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyLess, 1, Point, Dimension
|
||||
>::type less_type;
|
||||
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyGreater, -1, Point, Dimension
|
||||
>::type greater_type;
|
||||
|
||||
typedef typename select_coordinate_type<Point, Box>::type coordinate_type;
|
||||
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box& box, Point const& source)
|
||||
{
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyLess, 1, Point, Dimension
|
||||
>::type less_type;
|
||||
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyGreater, -1, Point, Dimension
|
||||
>::type greater_type;
|
||||
|
||||
typedef typename select_coordinate_type<Point, Box>::type coordinate_type;
|
||||
|
||||
less_type less;
|
||||
greater_type greater;
|
||||
|
||||
@@ -75,7 +76,6 @@ struct point_loop
|
||||
|
||||
point_loop
|
||||
<
|
||||
Box, Point,
|
||||
StrategyLess, StrategyGreater,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(box, source);
|
||||
@@ -85,49 +85,47 @@ struct point_loop
|
||||
|
||||
template
|
||||
<
|
||||
typename Box, typename Point,
|
||||
typename StrategyLess, typename StrategyGreater,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct point_loop
|
||||
<
|
||||
Box, Point,
|
||||
StrategyLess, StrategyGreater,
|
||||
DimensionCount, DimensionCount
|
||||
>
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box&, Point const&) {}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box, typename Geometry,
|
||||
typename StrategyLess, typename StrategyGreater,
|
||||
std::size_t Index,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct indexed_loop
|
||||
{
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyLess, 1, Box, Dimension
|
||||
>::type less_type;
|
||||
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyGreater, -1, Box, Dimension
|
||||
>::type greater_type;
|
||||
|
||||
typedef typename select_coordinate_type
|
||||
<
|
||||
Box,
|
||||
Geometry
|
||||
>::type coordinate_type;
|
||||
|
||||
|
||||
template <typename Box, typename Geometry>
|
||||
static inline void apply(Box& box, Geometry const& source)
|
||||
{
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyLess, 1, Box, Dimension
|
||||
>::type less_type;
|
||||
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyGreater, -1, Box, Dimension
|
||||
>::type greater_type;
|
||||
|
||||
typedef typename select_coordinate_type
|
||||
<
|
||||
Box,
|
||||
Geometry
|
||||
>::type coordinate_type;
|
||||
|
||||
less_type less;
|
||||
greater_type greater;
|
||||
|
||||
@@ -145,7 +143,6 @@ struct indexed_loop
|
||||
|
||||
indexed_loop
|
||||
<
|
||||
Box, Geometry,
|
||||
StrategyLess, StrategyGreater,
|
||||
Index, Dimension + 1, DimensionCount
|
||||
>::apply(box, source);
|
||||
@@ -155,17 +152,16 @@ struct indexed_loop
|
||||
|
||||
template
|
||||
<
|
||||
typename Box, typename Geometry,
|
||||
typename StrategyLess, typename StrategyGreater,
|
||||
std::size_t Index, std::size_t DimensionCount
|
||||
>
|
||||
struct indexed_loop
|
||||
<
|
||||
Box, Geometry,
|
||||
StrategyLess, StrategyGreater,
|
||||
Index, DimensionCount, DimensionCount
|
||||
>
|
||||
{
|
||||
template <typename Box, typename Geometry>
|
||||
static inline void apply(Box&, Geometry const&) {}
|
||||
};
|
||||
|
||||
@@ -174,23 +170,21 @@ struct indexed_loop
|
||||
// Changes a box such that the other box is also contained by the box
|
||||
template
|
||||
<
|
||||
typename Box, typename Geometry,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct expand_indexed
|
||||
{
|
||||
template <typename Box, typename Geometry>
|
||||
static inline void apply(Box& box, Geometry const& geometry)
|
||||
{
|
||||
indexed_loop
|
||||
<
|
||||
Box, Geometry,
|
||||
StrategyLess, StrategyGreater,
|
||||
0, 0, dimension<Geometry>::type::value
|
||||
>::apply(box, geometry);
|
||||
|
||||
indexed_loop
|
||||
<
|
||||
Box, Geometry,
|
||||
StrategyLess, StrategyGreater,
|
||||
1, 0, dimension<Geometry>::type::value
|
||||
>::apply(box, geometry);
|
||||
@@ -206,11 +200,13 @@ namespace dispatch
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename BoxOut, typename Geometry,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
typename GeometryOut, typename Geometry,
|
||||
typename StrategyLess = strategy::compare::default_strategy,
|
||||
typename StrategyGreater = strategy::compare::default_strategy,
|
||||
typename TagOut = typename tag<GeometryOut>::type,
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct expand
|
||||
struct expand: not_implemented<TagOut, Tag>
|
||||
{};
|
||||
|
||||
|
||||
@@ -220,10 +216,9 @@ template
|
||||
typename BoxOut, typename Point,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct expand<point_tag, BoxOut, Point, StrategyLess, StrategyGreater>
|
||||
struct expand<BoxOut, Point, StrategyLess, StrategyGreater, box_tag, point_tag>
|
||||
: detail::expand::point_loop
|
||||
<
|
||||
BoxOut, Point,
|
||||
StrategyLess, StrategyGreater,
|
||||
0, dimension<Point>::type::value
|
||||
>
|
||||
@@ -236,9 +231,8 @@ template
|
||||
typename BoxOut, typename BoxIn,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct expand<box_tag, BoxOut, BoxIn, StrategyLess, StrategyGreater>
|
||||
: detail::expand::expand_indexed
|
||||
<BoxOut, BoxIn, StrategyLess, StrategyGreater>
|
||||
struct expand<BoxOut, BoxIn, StrategyLess, StrategyGreater, box_tag, box_tag>
|
||||
: detail::expand::expand_indexed<StrategyLess, StrategyGreater>
|
||||
{};
|
||||
|
||||
template
|
||||
@@ -246,9 +240,8 @@ template
|
||||
typename Box, typename Segment,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct expand<segment_tag, Box, Segment, StrategyLess, StrategyGreater>
|
||||
: detail::expand::expand_indexed
|
||||
<Box, Segment, StrategyLess, StrategyGreater>
|
||||
struct expand<Box, Segment, StrategyLess, StrategyGreater, box_tag, segment_tag>
|
||||
: detail::expand::expand_indexed<StrategyLess, StrategyGreater>
|
||||
{};
|
||||
|
||||
|
||||
@@ -279,13 +272,7 @@ inline void expand(Box& box, Geometry const& geometry,
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
|
||||
|
||||
dispatch::expand
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Box,
|
||||
Geometry,
|
||||
StrategyLess, StrategyGreater
|
||||
>::apply(box, geometry);
|
||||
dispatch::expand<Box, Geometry>::apply(box, geometry);
|
||||
}
|
||||
***/
|
||||
|
||||
@@ -305,13 +292,7 @@ inline void expand(Box& box, Geometry const& geometry)
|
||||
{
|
||||
concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
|
||||
|
||||
dispatch::expand
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Box, Geometry,
|
||||
strategy::compare::default_strategy,
|
||||
strategy::compare::default_strategy
|
||||
>::apply(box, geometry);
|
||||
dispatch::expand<Box, Geometry>::apply(box, geometry);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
@@ -39,53 +41,55 @@ namespace detail { namespace for_each
|
||||
{
|
||||
|
||||
|
||||
template <typename Point, typename Functor, bool IsConst>
|
||||
struct fe_point_per_point
|
||||
{
|
||||
static inline Functor apply(
|
||||
typename add_const_if_c<IsConst, Point>::type& point, Functor f)
|
||||
template <typename Point, typename Functor>
|
||||
static inline void apply(Point& point, Functor& f)
|
||||
{
|
||||
f(point);
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, typename Functor, bool IsConst>
|
||||
struct fe_point_per_segment
|
||||
{
|
||||
static inline Functor apply(
|
||||
typename add_const_if_c<IsConst, Point>::type& , Functor f)
|
||||
template <typename Point, typename Functor>
|
||||
static inline void apply(Point& , Functor& f)
|
||||
{
|
||||
// TODO: if non-const, we should extract the points from the segment
|
||||
// and call the functor on those two points
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Range, typename Functor, bool IsConst>
|
||||
struct fe_range_per_point
|
||||
{
|
||||
static inline Functor apply(
|
||||
typename add_const_if_c<IsConst, Range>::type& range,
|
||||
Functor f)
|
||||
template <typename Range, typename Functor>
|
||||
static inline void apply(Range& range, Functor& f)
|
||||
{
|
||||
return (std::for_each(boost::begin(range), boost::end(range), f));
|
||||
// The previous implementation called the std library:
|
||||
// return (std::for_each(boost::begin(range), boost::end(range), f));
|
||||
// But that is not accepted for capturing lambda's.
|
||||
// It needs to do it like that to return the state of Functor f (f is passed by value in std::for_each).
|
||||
|
||||
// So we now loop manually.
|
||||
|
||||
for (typename boost::range_iterator<Range>::type it = boost::begin(range); it != boost::end(range); ++it)
|
||||
{
|
||||
f(*it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Range, typename Functor, bool IsConst>
|
||||
struct fe_range_per_segment
|
||||
{
|
||||
static inline Functor apply(
|
||||
typename add_const_if_c<IsConst, Range>::type& range,
|
||||
Functor f)
|
||||
template <typename Range, typename Functor>
|
||||
static inline void apply(Range& range, Functor& f)
|
||||
{
|
||||
typedef typename add_const_if_c
|
||||
<
|
||||
IsConst,
|
||||
is_const<Range>::value,
|
||||
typename point_type<Range>::type
|
||||
>::type point_type;
|
||||
|
||||
@@ -97,65 +101,41 @@ struct fe_range_per_segment
|
||||
f(s);
|
||||
previous = it++;
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, typename Functor, bool IsConst>
|
||||
struct fe_polygon_per_point
|
||||
{
|
||||
typedef typename add_const_if_c<IsConst, Polygon>::type poly_type;
|
||||
|
||||
static inline Functor apply(poly_type& poly, Functor f)
|
||||
template <typename Polygon, typename Functor>
|
||||
static inline void apply(Polygon& poly, Functor& f)
|
||||
{
|
||||
typedef fe_range_per_point
|
||||
<
|
||||
typename ring_type<Polygon>::type,
|
||||
Functor,
|
||||
IsConst
|
||||
> per_ring;
|
||||
fe_range_per_point::apply(exterior_ring(poly), f);
|
||||
|
||||
f = per_ring::apply(exterior_ring(poly), f);
|
||||
|
||||
typename interior_return_type<poly_type>::type rings
|
||||
typename interior_return_type<Polygon>::type rings
|
||||
= interior_rings(poly);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
f = per_ring::apply(*it, f);
|
||||
fe_range_per_point::apply(*it, f);
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, typename Functor, bool IsConst>
|
||||
struct fe_polygon_per_segment
|
||||
{
|
||||
typedef typename add_const_if_c<IsConst, Polygon>::type poly_type;
|
||||
|
||||
static inline Functor apply(poly_type& poly, Functor f)
|
||||
template <typename Polygon, typename Functor>
|
||||
static inline void apply(Polygon& poly, Functor& f)
|
||||
{
|
||||
typedef fe_range_per_segment
|
||||
<
|
||||
typename ring_type<Polygon>::type,
|
||||
Functor,
|
||||
IsConst
|
||||
> per_ring;
|
||||
fe_range_per_segment::apply(exterior_ring(poly), f);
|
||||
|
||||
f = per_ring::apply(exterior_ring(poly), f);
|
||||
|
||||
typename interior_return_type<poly_type>::type rings
|
||||
typename interior_return_type<Polygon>::type rings
|
||||
= interior_rings(poly);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
f = per_ring::apply(*it, f);
|
||||
fe_range_per_segment::apply(*it, f);
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -171,68 +151,66 @@ namespace dispatch
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry,
|
||||
typename Functor,
|
||||
bool IsConst
|
||||
typename Tag = typename tag_cast<typename tag<Geometry>::type, multi_tag>::type
|
||||
>
|
||||
struct for_each_point {};
|
||||
|
||||
|
||||
template <typename Point, typename Functor, bool IsConst>
|
||||
struct for_each_point<point_tag, Point, Functor, IsConst>
|
||||
: detail::for_each::fe_point_per_point<Point, Functor, IsConst>
|
||||
struct for_each_point: not_implemented<Tag>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Linestring, typename Functor, bool IsConst>
|
||||
struct for_each_point<linestring_tag, Linestring, Functor, IsConst>
|
||||
: detail::for_each::fe_range_per_point<Linestring, Functor, IsConst>
|
||||
template <typename Point>
|
||||
struct for_each_point<Point, point_tag>
|
||||
: detail::for_each::fe_point_per_point
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring, typename Functor, bool IsConst>
|
||||
struct for_each_point<ring_tag, Ring, Functor, IsConst>
|
||||
: detail::for_each::fe_range_per_point<Ring, Functor, IsConst>
|
||||
template <typename Linestring>
|
||||
struct for_each_point<Linestring, linestring_tag>
|
||||
: detail::for_each::fe_range_per_point
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Functor, bool IsConst>
|
||||
struct for_each_point<polygon_tag, Polygon, Functor, IsConst>
|
||||
: detail::for_each::fe_polygon_per_point<Polygon, Functor, IsConst>
|
||||
template <typename Ring>
|
||||
struct for_each_point<Ring, ring_tag>
|
||||
: detail::for_each::fe_range_per_point
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
struct for_each_point<Polygon, polygon_tag>
|
||||
: detail::for_each::fe_polygon_per_point
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry,
|
||||
typename Functor,
|
||||
bool IsConst
|
||||
typename Tag = typename tag_cast<typename tag<Geometry>::type, multi_tag>::type
|
||||
>
|
||||
struct for_each_segment {};
|
||||
struct for_each_segment: not_implemented<Tag>
|
||||
{};
|
||||
|
||||
template <typename Point, typename Functor, bool IsConst>
|
||||
struct for_each_segment<point_tag, Point, Functor, IsConst>
|
||||
: detail::for_each::fe_point_per_segment<Point, Functor, IsConst>
|
||||
template <typename Point>
|
||||
struct for_each_segment<Point, point_tag>
|
||||
: detail::for_each::fe_point_per_segment
|
||||
{};
|
||||
|
||||
|
||||
template <typename Linestring, typename Functor, bool IsConst>
|
||||
struct for_each_segment<linestring_tag, Linestring, Functor, IsConst>
|
||||
: detail::for_each::fe_range_per_segment<Linestring, Functor, IsConst>
|
||||
template <typename Linestring>
|
||||
struct for_each_segment<Linestring, linestring_tag>
|
||||
: detail::for_each::fe_range_per_segment
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring, typename Functor, bool IsConst>
|
||||
struct for_each_segment<ring_tag, Ring, Functor, IsConst>
|
||||
: detail::for_each::fe_range_per_segment<Ring, Functor, IsConst>
|
||||
template <typename Ring>
|
||||
struct for_each_segment<Ring, ring_tag>
|
||||
: detail::for_each::fe_range_per_segment
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Functor, bool IsConst>
|
||||
struct for_each_segment<polygon_tag, Polygon, Functor, IsConst>
|
||||
: detail::for_each::fe_polygon_per_segment<Polygon, Functor, IsConst>
|
||||
template <typename Polygon>
|
||||
struct for_each_segment<Polygon, polygon_tag>
|
||||
: detail::for_each::fe_polygon_per_segment
|
||||
{};
|
||||
|
||||
|
||||
@@ -240,35 +218,6 @@ struct for_each_segment<polygon_tag, Polygon, Functor, IsConst>
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brf_for_each{point}
|
||||
\details \det_for_each{point}
|
||||
\ingroup for_each
|
||||
\param geometry \param_geometry
|
||||
\param f \par_for_each_f{const point}
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Functor \tparam_functor
|
||||
|
||||
\qbk{distinguish,const version}
|
||||
\qbk{[include reference/algorithms/for_each_point.qbk]}
|
||||
\qbk{[heading Example]}
|
||||
\qbk{[for_each_point_const] [for_each_point_const_output]}
|
||||
*/
|
||||
template<typename Geometry, typename Functor>
|
||||
inline Functor for_each_point(Geometry const& geometry, Functor f)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::for_each_point
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
|
||||
Geometry,
|
||||
Functor,
|
||||
true
|
||||
>::apply(geometry, f);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brf_for_each{point}
|
||||
\details \det_for_each{point}
|
||||
@@ -281,48 +230,15 @@ inline Functor for_each_point(Geometry const& geometry, Functor f)
|
||||
\qbk{[include reference/algorithms/for_each_point.qbk]}
|
||||
\qbk{[heading Example]}
|
||||
\qbk{[for_each_point] [for_each_point_output]}
|
||||
\qbk{[for_each_point_const] [for_each_point_const_output]}
|
||||
*/
|
||||
template<typename Geometry, typename Functor>
|
||||
inline Functor for_each_point(Geometry& geometry, Functor f)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
return dispatch::for_each_point
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
|
||||
Geometry,
|
||||
Functor,
|
||||
false
|
||||
>::apply(geometry, f);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brf_for_each{segment}
|
||||
\details \det_for_each{segment}
|
||||
\ingroup for_each
|
||||
\param geometry \param_geometry
|
||||
\param f \par_for_each_f{const segment}
|
||||
\tparam Geometry \tparam_geometry
|
||||
\tparam Functor \tparam_functor
|
||||
|
||||
\qbk{distinguish,const version}
|
||||
\qbk{[include reference/algorithms/for_each_segment.qbk]}
|
||||
\qbk{[heading Example]}
|
||||
\qbk{[for_each_segment_const] [for_each_segment_const_output]}
|
||||
*/
|
||||
template<typename Geometry, typename Functor>
|
||||
inline Functor for_each_segment(Geometry const& geometry, Functor f)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::for_each_segment
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
|
||||
Geometry,
|
||||
Functor,
|
||||
true
|
||||
>::apply(geometry, f);
|
||||
dispatch::for_each_point<Geometry>::apply(geometry, f);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
@@ -336,19 +252,16 @@ inline Functor for_each_segment(Geometry const& geometry, Functor f)
|
||||
\tparam Functor \tparam_functor
|
||||
|
||||
\qbk{[include reference/algorithms/for_each_segment.qbk]}
|
||||
\qbk{[heading Example]}
|
||||
\qbk{[for_each_segment_const] [for_each_segment_const_output]}
|
||||
*/
|
||||
template<typename Geometry, typename Functor>
|
||||
inline Functor for_each_segment(Geometry& geometry, Functor f)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
return dispatch::for_each_segment
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
|
||||
Geometry,
|
||||
Functor,
|
||||
false
|
||||
>::apply(geometry, f);
|
||||
dispatch::for_each_segment<Geometry>::apply(geometry, f);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,15 +22,14 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace intersection
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2,
|
||||
typename BoxOut,
|
||||
typename Strategy,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
template <std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct intersection_box_box
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2, typename BoxOut,
|
||||
typename Strategy
|
||||
>
|
||||
static inline bool apply(Box1 const& box1,
|
||||
Box2 const& box2, BoxOut& box_out,
|
||||
Strategy const& strategy)
|
||||
@@ -50,23 +49,19 @@ struct intersection_box_box
|
||||
set<min_corner, Dimension>(box_out, min1 < min2 ? min2 : min1);
|
||||
set<max_corner, Dimension>(box_out, max1 > max2 ? max2 : max1);
|
||||
|
||||
return intersection_box_box
|
||||
<
|
||||
Box1, Box2, BoxOut, Strategy,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(box1, box2, box_out, strategy);
|
||||
return intersection_box_box<Dimension + 1, DimensionCount>
|
||||
::apply(box1, box2, box_out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2,
|
||||
typename BoxOut,
|
||||
typename Strategy,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct intersection_box_box<Box1, Box2, BoxOut, Strategy, DimensionCount, DimensionCount>
|
||||
template <std::size_t DimensionCount>
|
||||
struct intersection_box_box<DimensionCount, DimensionCount>
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2, typename BoxOut,
|
||||
typename Strategy
|
||||
>
|
||||
static inline bool apply(Box1 const&, Box2 const&, BoxOut&, Strategy const&)
|
||||
{
|
||||
return true;
|
||||
@@ -86,15 +81,14 @@ namespace dispatch
|
||||
// By default, all is forwarded to the intersection_insert-dispatcher
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2, typename TagOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
typename Tag1 = typename geometry::tag<Geometry1>::type,
|
||||
typename Tag2 = typename geometry::tag<Geometry2>::type,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct intersection
|
||||
{
|
||||
typedef std::back_insert_iterator<GeometryOut> output_iterator;
|
||||
|
||||
template <typename GeometryOut, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
GeometryOut& geometry_out,
|
||||
@@ -104,17 +98,8 @@ struct intersection
|
||||
|
||||
intersection_insert
|
||||
<
|
||||
Tag1, Tag2, typename geometry::tag<OneOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<OneOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry1>::value, false>::value,
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, false>::value,
|
||||
detail::overlay::do_reverse<geometry::point_order<OneOut>::value>::value,
|
||||
output_iterator, OneOut,
|
||||
overlay_intersection,
|
||||
Strategy
|
||||
Geometry1, Geometry2, OneOut,
|
||||
overlay_intersection
|
||||
>::apply(geometry1, geometry2, std::back_inserter(geometry_out), strategy);
|
||||
|
||||
return true;
|
||||
@@ -123,50 +108,50 @@ struct intersection
|
||||
};
|
||||
|
||||
|
||||
// If reversal is needed, perform it
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2,
|
||||
typename BoxOut,
|
||||
typename Strategy
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1, typename Tag2
|
||||
>
|
||||
struct intersection
|
||||
<
|
||||
box_tag, box_tag, box_tag,
|
||||
Box1, Box2, BoxOut,
|
||||
Strategy
|
||||
> : public detail::intersection::intersection_box_box
|
||||
<
|
||||
Box1, Box2, BoxOut,
|
||||
Strategy,
|
||||
0, geometry::dimension<Box1>::value
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2, typename TagOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
Geometry1, Geometry2,
|
||||
Tag1, Tag2,
|
||||
true
|
||||
>
|
||||
struct intersection_reversed
|
||||
: intersection<Geometry2, Geometry1, Tag2, Tag1, false>
|
||||
{
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
GeometryOut& geometry_out,
|
||||
Strategy const& strategy)
|
||||
template <typename GeometryOut, typename Strategy>
|
||||
static inline bool apply(
|
||||
Geometry1 const& g1,
|
||||
Geometry2 const& g2,
|
||||
GeometryOut& out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return intersection
|
||||
<
|
||||
Tag2, Tag1, TagOut,
|
||||
Geometry2, Geometry1,
|
||||
GeometryOut, Strategy
|
||||
>::apply(geometry2, geometry1, geometry_out, strategy);
|
||||
return intersection<
|
||||
Geometry2, Geometry1,
|
||||
Tag2, Tag1,
|
||||
false
|
||||
>::apply(g2, g1, out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2, bool Reverse
|
||||
>
|
||||
struct intersection
|
||||
<
|
||||
Box1, Box2,
|
||||
box_tag, box_tag,
|
||||
Reverse
|
||||
> : public detail::intersection::intersection_box_box
|
||||
<
|
||||
0, geometry::dimension<Box1>::value
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
@@ -210,24 +195,10 @@ inline bool intersection(Geometry1 const& geometry1,
|
||||
> strategy;
|
||||
|
||||
|
||||
return boost::mpl::if_c
|
||||
<
|
||||
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
dispatch::intersection_reversed
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
Geometry1, Geometry2, GeometryOut, strategy
|
||||
>,
|
||||
dispatch::intersection
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
Geometry1, Geometry2, GeometryOut, strategy
|
||||
>
|
||||
>::type::apply(geometry1, geometry2, geometry_out, strategy());
|
||||
return dispatch::intersection<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, geometry_out, strategy());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -43,9 +43,10 @@ namespace detail { namespace length
|
||||
{
|
||||
|
||||
|
||||
template<typename Segment, typename Strategy>
|
||||
template<typename Segment>
|
||||
struct segment_length
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline typename default_length_result<Segment>::type apply(
|
||||
Segment const& segment, Strategy const& strategy)
|
||||
{
|
||||
@@ -63,11 +64,12 @@ struct segment_length
|
||||
\note for_each could be used here, now that point_type is changed by boost
|
||||
range iterator
|
||||
*/
|
||||
template<typename Range, typename Strategy, closure_selector Closure>
|
||||
template<typename Range, closure_selector Closure>
|
||||
struct range_length
|
||||
{
|
||||
typedef typename default_length_result<Range>::type return_type;
|
||||
|
||||
template <typename Strategy>
|
||||
static inline return_type apply(
|
||||
Range const& range, Strategy const& strategy)
|
||||
{
|
||||
@@ -106,28 +108,31 @@ namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Tag, typename Geometry, typename Strategy>
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct length : detail::calculate_null
|
||||
<
|
||||
typename default_length_result<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
{
|
||||
typedef typename default_length_result<Geometry>::type return_type;
|
||||
|
||||
template <typename Strategy>
|
||||
static inline return_type apply(Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
return calculate_null::apply<return_type>(geometry, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry, typename Strategy>
|
||||
struct length<linestring_tag, Geometry, Strategy>
|
||||
: detail::length::range_length<Geometry, Strategy, closed>
|
||||
template <typename Geometry>
|
||||
struct length<Geometry, linestring_tag>
|
||||
: detail::length::range_length<Geometry, closed>
|
||||
{};
|
||||
|
||||
|
||||
// RING: length is currently 0; it might be argued that it is the "perimeter"
|
||||
|
||||
|
||||
template <typename Geometry, typename Strategy>
|
||||
struct length<segment_tag, Geometry, Strategy>
|
||||
: detail::length::segment_length<Geometry, Strategy>
|
||||
template <typename Geometry>
|
||||
struct length<Geometry, segment_tag>
|
||||
: detail::length::segment_length<Geometry>
|
||||
{};
|
||||
|
||||
|
||||
@@ -159,12 +164,7 @@ inline typename default_length_result<Geometry>::type length(
|
||||
point_tag, typename point_type<Geometry>::type
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::length
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
strategy_type
|
||||
>::apply(geometry, strategy_type());
|
||||
return dispatch::length<Geometry>::apply(geometry, strategy_type());
|
||||
}
|
||||
|
||||
|
||||
@@ -190,12 +190,7 @@ inline typename default_length_result<Geometry>::type length(
|
||||
|
||||
// detail::throw_on_empty_input(geometry);
|
||||
|
||||
return dispatch::length
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>::apply(geometry, strategy);
|
||||
return dispatch::length<Geometry>::apply(geometry, strategy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
@@ -35,19 +35,22 @@ namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Tag, typename Geometry>
|
||||
struct num_geometries
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry>)
|
||||
);
|
||||
};
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Tag = typename tag_cast
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
single_tag,
|
||||
multi_tag
|
||||
>::type
|
||||
>
|
||||
struct num_geometries: not_implemented<Tag>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_geometries<single_tag, Geometry>
|
||||
struct num_geometries<Geometry, single_tag>
|
||||
{
|
||||
static inline std::size_t apply(Geometry const&)
|
||||
{
|
||||
@@ -76,16 +79,7 @@ inline std::size_t num_geometries(Geometry const& geometry)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::num_geometries
|
||||
<
|
||||
typename tag_cast
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
single_tag,
|
||||
multi_tag
|
||||
>::type,
|
||||
Geometry
|
||||
>::apply(geometry);
|
||||
return dispatch::num_geometries<Geometry>::apply(geometry);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Tag, typename Geometry>
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct num_interior_rings
|
||||
{
|
||||
static inline std::size_t apply(Geometry const& )
|
||||
@@ -44,7 +44,7 @@ struct num_interior_rings
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
struct num_interior_rings<polygon_tag, Polygon>
|
||||
struct num_interior_rings<Polygon, polygon_tag>
|
||||
{
|
||||
static inline std::size_t apply(Polygon const& polygon)
|
||||
{
|
||||
@@ -74,11 +74,7 @@ struct num_interior_rings<polygon_tag, Polygon>
|
||||
template <typename Geometry>
|
||||
inline std::size_t num_interior_rings(Geometry const& geometry)
|
||||
{
|
||||
return dispatch::num_interior_rings
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry
|
||||
>::apply(geometry);
|
||||
return dispatch::num_interior_rings<Geometry>::apply(geometry);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
@@ -27,6 +26,7 @@
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
|
||||
@@ -38,9 +38,9 @@ namespace detail { namespace num_points
|
||||
{
|
||||
|
||||
|
||||
template <typename Range>
|
||||
struct range_count
|
||||
{
|
||||
template <typename Range>
|
||||
static inline std::size_t apply(Range const& range, bool add_for_open)
|
||||
{
|
||||
std::size_t n = boost::size(range);
|
||||
@@ -60,30 +60,31 @@ struct range_count
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry, std::size_t D>
|
||||
template <std::size_t D>
|
||||
struct other_count
|
||||
{
|
||||
template <typename Geometry>
|
||||
static inline std::size_t apply(Geometry const&, bool)
|
||||
{
|
||||
return D;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Polygon>
|
||||
struct polygon_count
|
||||
struct polygon_count: private range_count
|
||||
{
|
||||
template <typename Polygon>
|
||||
static inline std::size_t apply(Polygon const& poly, bool add_for_open)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
|
||||
std::size_t n = range_count<ring_type>::apply(
|
||||
std::size_t n = range_count::apply(
|
||||
exterior_ring(poly), add_for_open);
|
||||
|
||||
typename interior_return_type<Polygon const>::type rings
|
||||
= interior_rings(poly);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
n += range_count<ring_type>::apply(*it, add_for_open);
|
||||
n += range_count::apply(*it, add_for_open);
|
||||
}
|
||||
|
||||
return n;
|
||||
@@ -98,44 +99,42 @@ struct polygon_count
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename GeometryTag, typename Geometry>
|
||||
struct num_points
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry>)
|
||||
);
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<point_tag, Geometry>
|
||||
: detail::num_points::other_count<Geometry, 1>
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Tag = typename tag_cast<typename tag<Geometry>::type, multi_tag>::type
|
||||
>
|
||||
struct num_points: not_implemented<Tag>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<box_tag, Geometry>
|
||||
: detail::num_points::other_count<Geometry, 4>
|
||||
struct num_points<Geometry, point_tag>
|
||||
: detail::num_points::other_count<1>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<segment_tag, Geometry>
|
||||
: detail::num_points::other_count<Geometry, 2>
|
||||
struct num_points<Geometry, box_tag>
|
||||
: detail::num_points::other_count<4>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<linestring_tag, Geometry>
|
||||
: detail::num_points::range_count<Geometry>
|
||||
struct num_points<Geometry, segment_tag>
|
||||
: detail::num_points::other_count<2>
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<ring_tag, Geometry>
|
||||
: detail::num_points::range_count<Geometry>
|
||||
struct num_points<Geometry, linestring_tag>
|
||||
: detail::num_points::range_count
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<polygon_tag, Geometry>
|
||||
: detail::num_points::polygon_count<Geometry>
|
||||
struct num_points<Geometry, ring_tag>
|
||||
: detail::num_points::range_count
|
||||
{};
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<Geometry, polygon_tag>
|
||||
: detail::num_points::polygon_count
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
@@ -158,11 +157,7 @@ inline std::size_t num_points(Geometry const& geometry, bool add_for_open = fals
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
return dispatch::num_points
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
|
||||
Geometry
|
||||
>::apply(geometry, add_for_open);
|
||||
return dispatch::num_points<Geometry>::apply(geometry, add_for_open);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -32,13 +32,12 @@ namespace detail { namespace overlaps
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1,
|
||||
typename Box2,
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box_loop
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline void apply(Box1 const& b1, Box2 const& b2,
|
||||
bool& overlaps, bool& one_in_two, bool& two_in_one)
|
||||
{
|
||||
@@ -84,8 +83,6 @@ struct box_box_loop
|
||||
|
||||
box_box_loop
|
||||
<
|
||||
Box1,
|
||||
Box2,
|
||||
Dimension + 1,
|
||||
DimensionCount
|
||||
>::apply(b1, b2, overlaps, one_in_two, two_in_one);
|
||||
@@ -94,24 +91,19 @@ struct box_box_loop
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1,
|
||||
typename Box2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box_loop<Box1, Box2, DimensionCount, DimensionCount>
|
||||
struct box_box_loop<DimensionCount, DimensionCount>
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline void apply(Box1 const& , Box2 const&, bool&, bool&, bool&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1,
|
||||
typename Box2
|
||||
>
|
||||
struct box_box
|
||||
{
|
||||
template <typename Box1, typename Box2>
|
||||
static inline bool apply(Box1 const& b1, Box2 const& b2)
|
||||
{
|
||||
bool overlaps = true;
|
||||
@@ -119,8 +111,6 @@ struct box_box
|
||||
bool within2 = true;
|
||||
box_box_loop
|
||||
<
|
||||
Box1,
|
||||
Box2,
|
||||
0,
|
||||
dimension<Box1>::type::value
|
||||
>::apply(b1, b2, overlaps, within1, within2);
|
||||
@@ -148,24 +138,18 @@ namespace dispatch
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1,
|
||||
typename Tag2,
|
||||
typename Geometry1,
|
||||
typename Geometry2
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type
|
||||
>
|
||||
struct overlaps
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
|
||||
, (types<Geometry1, Geometry2>)
|
||||
);
|
||||
};
|
||||
struct overlaps: not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
struct overlaps<box_tag, box_tag, Box1, Box2>
|
||||
: detail::overlaps::box_box<Box1, Box2>
|
||||
struct overlaps<Box1, Box2, box_tag, box_tag>
|
||||
: detail::overlaps::box_box
|
||||
{};
|
||||
|
||||
|
||||
@@ -190,8 +174,6 @@ inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
|
||||
return dispatch::overlaps
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2);
|
||||
|
||||
@@ -33,40 +33,43 @@ namespace dispatch
|
||||
{
|
||||
|
||||
// Default perimeter is 0.0, specializations implement calculated values
|
||||
template <typename Tag, typename Geometry, typename Strategy>
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct perimeter : detail::calculate_null
|
||||
<
|
||||
typename default_length_result<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
{
|
||||
typedef typename default_length_result<Geometry>::type return_type;
|
||||
|
||||
template <typename Geometry, typename Strategy>
|
||||
struct perimeter<ring_tag, Geometry, Strategy>
|
||||
template <typename Strategy>
|
||||
static inline return_type apply(Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
return calculate_null::apply<return_type>(geometry, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct perimeter<Geometry, ring_tag>
|
||||
: detail::length::range_length
|
||||
<
|
||||
Geometry,
|
||||
Strategy,
|
||||
closure<Geometry>::value
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename Strategy>
|
||||
struct perimeter<polygon_tag, Polygon, Strategy>
|
||||
: detail::calculate_polygon_sum
|
||||
<
|
||||
typename default_length_result<Polygon>::type,
|
||||
Polygon,
|
||||
Strategy,
|
||||
detail::length::range_length
|
||||
template <typename Polygon>
|
||||
struct perimeter<Polygon, polygon_tag> : detail::calculate_polygon_sum
|
||||
{
|
||||
typedef typename default_length_result<Polygon>::type return_type;
|
||||
typedef detail::length::range_length
|
||||
<
|
||||
typename ring_type<Polygon>::type,
|
||||
Strategy,
|
||||
closure<Polygon>::value
|
||||
>
|
||||
>
|
||||
{};
|
||||
> policy;
|
||||
|
||||
template <typename Strategy>
|
||||
static inline return_type apply(Polygon const& polygon, Strategy const& strategy)
|
||||
{
|
||||
return calculate_polygon_sum::apply<return_type, policy>(polygon, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// box,n-sphere: to be implemented
|
||||
@@ -100,12 +103,7 @@ inline typename default_length_result<Geometry>::type perimeter(
|
||||
|
||||
// detail::throw_on_empty_input(geometry);
|
||||
|
||||
return dispatch::perimeter
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
strategy_type
|
||||
>::apply(geometry, strategy_type());
|
||||
return dispatch::perimeter<Geometry>::apply(geometry, strategy_type());
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -130,12 +128,7 @@ inline typename default_length_result<Geometry>::type perimeter(
|
||||
|
||||
// detail::throw_on_empty_input(geometry);
|
||||
|
||||
return dispatch::perimeter
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>::apply(geometry, strategy);
|
||||
return dispatch::perimeter<Geometry>::apply(geometry, strategy);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
@@ -32,9 +32,9 @@ namespace detail { namespace reverse
|
||||
{
|
||||
|
||||
|
||||
template <typename Range>
|
||||
struct range_reverse
|
||||
{
|
||||
template <typename Range>
|
||||
static inline void apply(Range& range)
|
||||
{
|
||||
std::reverse(boost::begin(range), boost::end(range));
|
||||
@@ -42,21 +42,20 @@ struct range_reverse
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
struct polygon_reverse
|
||||
struct polygon_reverse: private range_reverse
|
||||
{
|
||||
template <typename Polygon>
|
||||
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));
|
||||
range_reverse::apply(exterior_ring(polygon));
|
||||
|
||||
typename interior_return_type<Polygon>::type rings
|
||||
= interior_rings(polygon);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
per_range::apply(*it);
|
||||
range_reverse::apply(*it);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -71,11 +70,7 @@ namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry
|
||||
>
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct reverse
|
||||
{
|
||||
static inline void apply(Geometry&)
|
||||
@@ -84,20 +79,20 @@ struct reverse
|
||||
|
||||
|
||||
template <typename Ring>
|
||||
struct reverse<ring_tag, Ring>
|
||||
: detail::reverse::range_reverse<Ring>
|
||||
struct reverse<Ring, ring_tag>
|
||||
: detail::reverse::range_reverse
|
||||
{};
|
||||
|
||||
|
||||
template <typename LineString>
|
||||
struct reverse<linestring_tag, LineString>
|
||||
: detail::reverse::range_reverse<LineString>
|
||||
struct reverse<LineString, linestring_tag>
|
||||
: detail::reverse::range_reverse
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
struct reverse<polygon_tag, Polygon>
|
||||
: detail::reverse::polygon_reverse<Polygon>
|
||||
struct reverse<Polygon, polygon_tag>
|
||||
: detail::reverse::polygon_reverse
|
||||
{};
|
||||
|
||||
|
||||
@@ -121,11 +116,7 @@ inline void reverse(Geometry& geometry)
|
||||
{
|
||||
concept::check<Geometry>();
|
||||
|
||||
dispatch::reverse
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry
|
||||
>::apply(geometry);
|
||||
dispatch::reverse<Geometry>::apply(geometry);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <boost/geometry/algorithms/clear.hpp>
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/algorithms/num_interior_rings.hpp>
|
||||
|
||||
|
||||
@@ -43,12 +44,11 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace simplify
|
||||
{
|
||||
|
||||
template<typename Range, typename Strategy>
|
||||
struct simplify_range_insert
|
||||
{
|
||||
template <typename OutputIterator, typename Distance>
|
||||
template<typename Range, typename Strategy, typename OutputIterator, typename Distance>
|
||||
static inline void apply(Range const& range, OutputIterator out,
|
||||
Distance const& max_distance, Strategy const& strategy)
|
||||
Distance const& max_distance, Strategy const& strategy)
|
||||
{
|
||||
if (boost::size(range) <= 2 || max_distance < 0)
|
||||
{
|
||||
@@ -62,12 +62,11 @@ struct simplify_range_insert
|
||||
};
|
||||
|
||||
|
||||
template<typename Range, typename Strategy>
|
||||
struct simplify_copy
|
||||
{
|
||||
template <typename Distance>
|
||||
template <typename Range, typename Strategy, typename Distance>
|
||||
static inline void apply(Range const& range, Range& out,
|
||||
Distance const& , Strategy const& )
|
||||
Distance const& , Strategy const& )
|
||||
{
|
||||
std::copy
|
||||
(
|
||||
@@ -77,10 +76,10 @@ struct simplify_copy
|
||||
};
|
||||
|
||||
|
||||
template<typename Range, typename Strategy, std::size_t Minimum>
|
||||
template<std::size_t Minimum>
|
||||
struct simplify_range
|
||||
{
|
||||
template <typename Distance>
|
||||
template <typename Range, typename Strategy, typename Distance>
|
||||
static inline void apply(Range const& range, Range& out,
|
||||
Distance const& max_distance, Strategy const& strategy)
|
||||
{
|
||||
@@ -101,14 +100,11 @@ struct simplify_range
|
||||
|
||||
if (boost::size(range) <= int(Minimum) || max_distance < 0.0)
|
||||
{
|
||||
simplify_copy<Range, Strategy>::apply
|
||||
(
|
||||
range, out, max_distance, strategy
|
||||
);
|
||||
simplify_copy::apply(range, out, max_distance, strategy);
|
||||
}
|
||||
else
|
||||
{
|
||||
simplify_range_insert<Range, Strategy>::apply
|
||||
simplify_range_insert::apply
|
||||
(
|
||||
range, std::back_inserter(out), max_distance, strategy
|
||||
);
|
||||
@@ -116,10 +112,9 @@ struct simplify_range
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Polygon, typename Strategy>
|
||||
struct simplify_polygon
|
||||
{
|
||||
template <typename Distance>
|
||||
template <typename Polygon, typename Strategy, typename Distance>
|
||||
static inline void apply(Polygon const& poly_in, Polygon& poly_out,
|
||||
Distance const& max_distance, Strategy const& strategy)
|
||||
{
|
||||
@@ -133,9 +128,9 @@ struct simplify_polygon
|
||||
// Note that if there are inner rings, and distance is too large,
|
||||
// they might intersect with the outer ring in the output,
|
||||
// while it didn't in the input.
|
||||
simplify_range<ring_type, Strategy, Minimum>::apply(exterior_ring(poly_in),
|
||||
exterior_ring(poly_out),
|
||||
max_distance, strategy);
|
||||
simplify_range<Minimum>::apply(exterior_ring(poly_in),
|
||||
exterior_ring(poly_out),
|
||||
max_distance, strategy);
|
||||
|
||||
traits::resize
|
||||
<
|
||||
@@ -154,8 +149,7 @@ struct simplify_polygon
|
||||
it_in != boost::end(rings_in);
|
||||
++it_in, ++it_out)
|
||||
{
|
||||
simplify_range<ring_type, Strategy, Minimum>::apply(*it_in,
|
||||
*it_out, max_distance, strategy);
|
||||
simplify_range<Minimum>::apply(*it_in, *it_out, max_distance, strategy);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -169,15 +163,18 @@ struct simplify_polygon
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename Tag, typename Geometry, typename Strategy>
|
||||
struct simplify
|
||||
{
|
||||
};
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct simplify: not_implemented<Tag>
|
||||
{};
|
||||
|
||||
template <typename Point, typename Strategy>
|
||||
struct simplify<point_tag, Point, Strategy>
|
||||
template <typename Point>
|
||||
struct simplify<Point, point_tag>
|
||||
{
|
||||
template <typename Distance>
|
||||
template <typename Distance, typename Strategy>
|
||||
static inline void apply(Point const& point, Point& out,
|
||||
Distance const& , Strategy const& )
|
||||
{
|
||||
@@ -186,22 +183,15 @@ struct simplify<point_tag, Point, Strategy>
|
||||
};
|
||||
|
||||
|
||||
template <typename Linestring, typename Strategy>
|
||||
struct simplify<linestring_tag, Linestring, Strategy>
|
||||
: detail::simplify::simplify_range
|
||||
<
|
||||
Linestring,
|
||||
Strategy,
|
||||
2
|
||||
>
|
||||
template <typename Linestring>
|
||||
struct simplify<Linestring, linestring_tag>
|
||||
: detail::simplify::simplify_range<2>
|
||||
{};
|
||||
|
||||
template <typename Ring, typename Strategy>
|
||||
struct simplify<ring_tag, Ring, Strategy>
|
||||
template <typename Ring>
|
||||
struct simplify<Ring, ring_tag>
|
||||
: detail::simplify::simplify_range
|
||||
<
|
||||
Ring,
|
||||
Strategy,
|
||||
core_detail::closure::minimum_ring_size
|
||||
<
|
||||
geometry::closure<Ring>::value
|
||||
@@ -209,38 +199,29 @@ struct simplify<ring_tag, Ring, Strategy>
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Polygon, typename Strategy>
|
||||
struct simplify<polygon_tag, Polygon, Strategy>
|
||||
template <typename Polygon>
|
||||
struct simplify<Polygon, polygon_tag>
|
||||
: detail::simplify::simplify_polygon
|
||||
<
|
||||
Polygon,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Tag, typename Geometry, typename Strategy>
|
||||
struct simplify_insert
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template <typename Linestring, typename Strategy>
|
||||
struct simplify_insert<linestring_tag, Linestring, Strategy>
|
||||
: detail::simplify::simplify_range_insert
|
||||
<
|
||||
Linestring,
|
||||
Strategy
|
||||
>
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct simplify_insert: not_implemented<Tag>
|
||||
{};
|
||||
|
||||
template <typename Ring, typename Strategy>
|
||||
struct simplify_insert<ring_tag, Ring, Strategy>
|
||||
|
||||
template <typename Linestring>
|
||||
struct simplify_insert<Linestring, linestring_tag>
|
||||
: detail::simplify::simplify_range_insert
|
||||
{};
|
||||
|
||||
template <typename Ring>
|
||||
struct simplify_insert<Ring, ring_tag>
|
||||
: detail::simplify::simplify_range_insert
|
||||
<
|
||||
Ring,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
@@ -275,12 +256,7 @@ inline void simplify(Geometry const& geometry, Geometry& out,
|
||||
|
||||
geometry::clear(out);
|
||||
|
||||
dispatch::simplify
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>::apply(geometry, out, max_distance, strategy);
|
||||
dispatch::simplify<Geometry>::apply(geometry, out, max_distance, strategy);
|
||||
}
|
||||
|
||||
|
||||
@@ -348,12 +324,7 @@ inline void simplify_insert(Geometry const& geometry, OutputIterator out,
|
||||
concept::check<Geometry const>();
|
||||
BOOST_CONCEPT_ASSERT( (geometry::concept::SimplifyStrategy<Strategy>) );
|
||||
|
||||
dispatch::simplify_insert
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
Strategy
|
||||
>::apply(geometry, out, max_distance, strategy);
|
||||
dispatch::simplify_insert<Geometry>::apply(geometry, out, max_distance, strategy);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -387,12 +358,7 @@ inline void simplify_insert(Geometry const& geometry, OutputIterator out,
|
||||
point_type, ds_strategy_type
|
||||
> strategy_type;
|
||||
|
||||
dispatch::simplify_insert
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
strategy_type
|
||||
>::apply(geometry, out, max_distance, strategy_type());
|
||||
dispatch::simplify_insert<Geometry>::apply(geometry, out, max_distance, strategy_type());
|
||||
}
|
||||
|
||||
}} // namespace detail::simplify
|
||||
|
||||
@@ -59,35 +59,20 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
|
||||
|
||||
out = geometry::dispatch::intersection_insert
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
OutputIterator, GeometryOut,
|
||||
GeometryOut,
|
||||
overlay_difference,
|
||||
Strategy
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
|
||||
>::apply(geometry1, geometry2, out, strategy);
|
||||
out = geometry::dispatch::intersection_insert
|
||||
<
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry2, Geometry1,
|
||||
GeometryOut,
|
||||
overlay_difference,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value, true>::value,
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
OutputIterator, GeometryOut,
|
||||
overlay_difference,
|
||||
Strategy
|
||||
geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value
|
||||
>::apply(geometry2, geometry1, out, strategy);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP
|
||||
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
|
||||
#include <boost/geometry/algorithms/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
#include <boost/geometry/algorithms/num_geometries.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace detail { namespace touches
|
||||
{
|
||||
|
||||
template <typename Turn>
|
||||
inline bool ok_for_touch(Turn const& turn)
|
||||
{
|
||||
return turn.both(detail::overlay::operation_union)
|
||||
|| turn.both(detail::overlay::operation_blocked)
|
||||
|| turn.combination(detail::overlay::operation_union, detail::overlay::operation_blocked)
|
||||
;
|
||||
}
|
||||
|
||||
template <typename Turns>
|
||||
inline bool has_only_turns(Turns const& turns)
|
||||
{
|
||||
bool has_touch = false;
|
||||
typedef typename boost::range_iterator<Turns const>::type iterator_type;
|
||||
for (iterator_type it = boost::begin(turns); it != boost::end(turns); ++it)
|
||||
{
|
||||
if (it->has(detail::overlay::operation_intersection))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(it->method)
|
||||
{
|
||||
case detail::overlay::method_crosses:
|
||||
return false;
|
||||
case detail::overlay::method_equal:
|
||||
// Segment spatially equal means: at the right side
|
||||
// the polygon internally overlaps. So return false.
|
||||
return false;
|
||||
case detail::overlay::method_touch:
|
||||
case detail::overlay::method_touch_interior:
|
||||
case detail::overlay::method_collinear:
|
||||
if (ok_for_touch(*it))
|
||||
{
|
||||
has_touch = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case detail::overlay::method_none :
|
||||
case detail::overlay::method_disjoint :
|
||||
case detail::overlay::method_error :
|
||||
break;
|
||||
}
|
||||
}
|
||||
return has_touch;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
/*!
|
||||
\brief \brief_check{has at least one touching point (self-tangency)}
|
||||
\note This function can be called for one geometry (self-tangency) and
|
||||
also for two geometries (touch)
|
||||
\ingroup touches
|
||||
\tparam Geometry \tparam_geometry
|
||||
\param geometry \param_geometry
|
||||
\return \return_check{is self-touching}
|
||||
|
||||
\qbk{distinguish,one geometry}
|
||||
\qbk{[def __one_parameter__]}
|
||||
\qbk{[include reference/algorithms/touches.qbk]}
|
||||
*/
|
||||
template <typename Geometry>
|
||||
inline bool touches(Geometry const& geometry)
|
||||
{
|
||||
concept::check<Geometry const>();
|
||||
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
typename geometry::point_type<Geometry>::type
|
||||
> turn_info;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
typename point_type<Geometry>::type,
|
||||
typename point_type<Geometry>::type,
|
||||
turn_info,
|
||||
detail::overlay::assign_null_policy
|
||||
> policy_type;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
detail::self_get_turn_points::no_interrupt_policy policy;
|
||||
detail::self_get_turn_points::get_turns
|
||||
<
|
||||
Geometry,
|
||||
std::deque<turn_info>,
|
||||
policy_type,
|
||||
detail::self_get_turn_points::no_interrupt_policy
|
||||
>::apply(geometry, turns, policy);
|
||||
|
||||
return detail::touches::has_only_turns(turns);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{have at least one touching point (tangent - non overlapping)}
|
||||
\ingroup touches
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{touch each other}
|
||||
|
||||
\qbk{distinguish,two geometries}
|
||||
\qbk{[include reference/algorithms/touches.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
typename geometry::point_type<Geometry1>::type
|
||||
> turn_info;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
typename point_type<Geometry1>::type,
|
||||
typename point_type<Geometry2>::type,
|
||||
turn_info,
|
||||
detail::overlay::assign_null_policy
|
||||
> policy_type;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
detail::get_turns::no_interrupt_policy policy;
|
||||
boost::geometry::get_turns
|
||||
<
|
||||
false, false,
|
||||
detail::overlay::assign_null_policy
|
||||
>(geometry1, geometry2, turns, policy);
|
||||
|
||||
return detail::touches::has_only_turns(turns)
|
||||
&& ! geometry::detail::disjoint::rings_containing(geometry1, geometry2)
|
||||
&& ! geometry::detail::disjoint::rings_containing(geometry2, geometry1)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP
|
||||
@@ -41,9 +41,9 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace transform
|
||||
{
|
||||
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
struct transform_point
|
||||
{
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
static inline bool apply(Point1 const& p1, Point2& p2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
@@ -52,9 +52,9 @@ struct transform_point
|
||||
};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
struct transform_box
|
||||
{
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
static inline bool apply(Box1 const& b1, Box2& b2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
@@ -91,9 +91,9 @@ struct transform_box
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
struct transform_box_or_segment
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& source, Geometry2& target,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
@@ -133,12 +133,7 @@ inline bool transform_range_out(Range const& range,
|
||||
it != boost::end(range);
|
||||
++it)
|
||||
{
|
||||
if (! transform_point
|
||||
<
|
||||
typename point_type<Range>::type,
|
||||
PointOut,
|
||||
Strategy
|
||||
>::apply(*it, point_out, strategy))
|
||||
if (! transform_point::apply(*it, point_out, strategy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -148,9 +143,9 @@ inline bool transform_range_out(Range const& range,
|
||||
}
|
||||
|
||||
|
||||
template <typename Polygon1, typename Polygon2, typename Strategy>
|
||||
struct transform_polygon
|
||||
{
|
||||
template <typename Polygon1, typename Polygon2, typename Strategy>
|
||||
static inline bool apply(Polygon1 const& poly1, Polygon2& poly2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
@@ -211,9 +206,9 @@ struct select_strategy
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename Range1, typename Range2, typename Strategy>
|
||||
struct transform_range
|
||||
{
|
||||
template <typename Range1, typename Range2, typename Strategy>
|
||||
static inline bool apply(Range1 const& range1,
|
||||
Range2& range2, Strategy const& strategy)
|
||||
{
|
||||
@@ -236,50 +231,50 @@ namespace dispatch
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag1, typename Tag2,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Strategy
|
||||
typename Tag1 = typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
|
||||
typename Tag2 = typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type
|
||||
>
|
||||
struct transform {};
|
||||
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
struct transform<point_tag, point_tag, Point1, Point2, Strategy>
|
||||
: detail::transform::transform_point<Point1, Point2, Strategy>
|
||||
template <typename Point1, typename Point2>
|
||||
struct transform<Point1, Point2, point_tag, point_tag>
|
||||
: detail::transform::transform_point
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template <typename Linestring1, typename Linestring2, typename Strategy>
|
||||
template <typename Linestring1, typename Linestring2>
|
||||
struct transform
|
||||
<
|
||||
linestring_tag, linestring_tag,
|
||||
Linestring1, Linestring2, Strategy
|
||||
Linestring1, Linestring2,
|
||||
linestring_tag, linestring_tag
|
||||
>
|
||||
: detail::transform::transform_range<Linestring1, Linestring2, Strategy>
|
||||
: detail::transform::transform_range
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Range1, typename Range2, typename Strategy>
|
||||
struct transform<ring_tag, ring_tag, Range1, Range2, Strategy>
|
||||
: detail::transform::transform_range<Range1, Range2, Strategy>
|
||||
template <typename Range1, typename Range2>
|
||||
struct transform<Range1, Range2, ring_tag, ring_tag>
|
||||
: detail::transform::transform_range
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Polygon1, typename Polygon2, typename Strategy>
|
||||
struct transform<polygon_tag, polygon_tag, Polygon1, Polygon2, Strategy>
|
||||
: detail::transform::transform_polygon<Polygon1, Polygon2, Strategy>
|
||||
template <typename Polygon1, typename Polygon2>
|
||||
struct transform<Polygon1, Polygon2, polygon_tag, polygon_tag>
|
||||
: detail::transform::transform_polygon
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
struct transform<box_tag, box_tag, Box1, Box2, Strategy>
|
||||
: detail::transform::transform_box<Box1, Box2, Strategy>
|
||||
template <typename Box1, typename Box2>
|
||||
struct transform<Box1, Box2, box_tag, box_tag>
|
||||
: detail::transform::transform_box
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Segment1, typename Segment2, typename Strategy>
|
||||
struct transform<segment_tag, segment_tag, Segment1, Segment2, Strategy>
|
||||
: detail::transform::transform_box_or_segment<Segment1, Segment2, Strategy>
|
||||
template <typename Segment1, typename Segment2>
|
||||
struct transform<Segment1, Segment2, segment_tag, segment_tag>
|
||||
: detail::transform::transform_box_or_segment
|
||||
{
|
||||
};
|
||||
|
||||
@@ -310,14 +305,7 @@ inline bool transform(Geometry1 const& geometry1, Geometry2& geometry2,
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2>();
|
||||
|
||||
typedef dispatch::transform
|
||||
<
|
||||
typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
|
||||
typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
Strategy
|
||||
> transform_type;
|
||||
typedef dispatch::transform<Geometry1, Geometry2> transform_type;
|
||||
|
||||
return transform_type::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
@@ -10,14 +10,13 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
#include <boost/range/metafunctions.hpp>
|
||||
|
||||
#include <boost/geometry/core/is_areal.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
|
||||
|
||||
|
||||
@@ -30,78 +29,70 @@ namespace dispatch
|
||||
|
||||
template
|
||||
<
|
||||
// tag dispatching:
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
// metafunction finetuning helpers:
|
||||
bool Areal1, bool Areal2, bool ArealOut,
|
||||
// real types
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
typename Geometry1, typename Geometry2, typename GeometryOut,
|
||||
typename TagIn1 = typename tag<Geometry1>::type,
|
||||
typename TagIn2 = typename tag<Geometry2>::type,
|
||||
typename TagOut = typename tag<GeometryOut>::type,
|
||||
bool Areal1 = geometry::is_areal<Geometry1>::value,
|
||||
bool Areal2 = geometry::is_areal<Geometry2>::value,
|
||||
bool ArealOut = geometry::is_areal<GeometryOut>::value,
|
||||
bool Reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
bool Reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
|
||||
bool ReverseOut = detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
bool Reverse = geometry::reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct union_insert
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPES
|
||||
, (types<Geometry1, Geometry2, GeometryOut>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct union_insert
|
||||
<
|
||||
TagIn1, TagIn2, TagOut,
|
||||
true, true, true,
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
> : detail::overlay::overlay
|
||||
<Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, overlay_union, Strategy>
|
||||
struct union_insert: not_implemented<TagIn1, TagIn2, TagOut>
|
||||
{};
|
||||
|
||||
|
||||
// If reversal is needed, perform it first
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
|
||||
bool Areal1, bool Areal2, bool ArealOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename Strategy
|
||||
typename Geometry1, typename Geometry2, typename GeometryOut,
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct union_insert_reversed
|
||||
struct union_insert
|
||||
<
|
||||
Geometry1, Geometry2, GeometryOut,
|
||||
TagIn1, TagIn2, TagOut,
|
||||
true, true, true,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
true
|
||||
>: union_insert<Geometry2, Geometry1, GeometryOut>
|
||||
{
|
||||
template <typename OutputIterator, typename Strategy>
|
||||
static inline OutputIterator apply(Geometry1 const& g1,
|
||||
Geometry2 const& g2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return union_insert
|
||||
<
|
||||
GeometryTag2, GeometryTag1, GeometryTag3,
|
||||
Areal2, Areal1, ArealOut,
|
||||
Geometry2, Geometry1,
|
||||
Reverse2, Reverse1, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
Geometry2, Geometry1, GeometryOut
|
||||
>::apply(g2, g1, out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2, typename GeometryOut,
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut
|
||||
>
|
||||
struct union_insert
|
||||
<
|
||||
Geometry1, Geometry2, GeometryOut,
|
||||
TagIn1, TagIn2, TagOut,
|
||||
true, true, true,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
false
|
||||
> : detail::overlay::overlay
|
||||
<Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, GeometryOut, overlay_union>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
@@ -121,40 +112,10 @@ inline OutputIterator insert(Geometry1 const& geometry1,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::mpl::if_c
|
||||
<
|
||||
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
dispatch::union_insert_reversed
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
|
||||
overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>,
|
||||
dispatch::union_insert
|
||||
<
|
||||
typename tag<Geometry1>::type,
|
||||
typename tag<Geometry2>::type,
|
||||
typename tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
||||
overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
|
||||
overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
>::type::apply(geometry1, geometry2, out, strategy);
|
||||
return dispatch::union_insert
|
||||
<
|
||||
Geometry1, Geometry2, GeometryOut
|
||||
>::apply(geometry1, geometry2, out, strategy);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -34,9 +34,9 @@ namespace detail { namespace unique
|
||||
{
|
||||
|
||||
|
||||
template <typename Range, typename ComparePolicy>
|
||||
struct range_unique
|
||||
{
|
||||
template <typename Range, typename ComparePolicy>
|
||||
static inline void apply(Range& range, ComparePolicy const& policy)
|
||||
{
|
||||
typename boost::range_iterator<Range>::type it
|
||||
@@ -52,21 +52,20 @@ struct range_unique
|
||||
};
|
||||
|
||||
|
||||
template <typename Polygon, typename ComparePolicy>
|
||||
struct polygon_unique
|
||||
{
|
||||
template <typename Polygon, typename ComparePolicy>
|
||||
static inline void apply(Polygon& polygon, ComparePolicy const& policy)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
|
||||
typedef range_unique<ring_type, ComparePolicy> per_range;
|
||||
per_range::apply(exterior_ring(polygon), policy);
|
||||
range_unique::apply(exterior_ring(polygon), policy);
|
||||
|
||||
typename interior_return_type<Polygon>::type rings
|
||||
= interior_rings(polygon);
|
||||
for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
||||
{
|
||||
per_range::apply(*it, policy);
|
||||
range_unique::apply(*it, policy);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -85,32 +84,32 @@ namespace dispatch
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Geometry,
|
||||
typename ComparePolicy
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct unique
|
||||
{
|
||||
template <typename ComparePolicy>
|
||||
static inline void apply(Geometry&, ComparePolicy const& )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template <typename Ring, typename ComparePolicy>
|
||||
struct unique<ring_tag, Ring, ComparePolicy>
|
||||
: detail::unique::range_unique<Ring, ComparePolicy>
|
||||
template <typename Ring>
|
||||
struct unique<Ring, ring_tag>
|
||||
: detail::unique::range_unique
|
||||
{};
|
||||
|
||||
|
||||
template <typename LineString, typename ComparePolicy>
|
||||
struct unique<linestring_tag, LineString, ComparePolicy>
|
||||
: detail::unique::range_unique<LineString, ComparePolicy>
|
||||
template <typename LineString>
|
||||
struct unique<LineString, linestring_tag>
|
||||
: detail::unique::range_unique
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename ComparePolicy>
|
||||
struct unique<polygon_tag, Polygon, ComparePolicy>
|
||||
: detail::unique::polygon_unique<Polygon, ComparePolicy>
|
||||
template <typename Polygon>
|
||||
struct unique<Polygon, polygon_tag>
|
||||
: detail::unique::polygon_unique
|
||||
{};
|
||||
|
||||
|
||||
@@ -139,12 +138,7 @@ inline void unique(Geometry& geometry)
|
||||
> policy;
|
||||
|
||||
|
||||
dispatch::unique
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
policy
|
||||
>::apply(geometry, policy());
|
||||
dispatch::unique<Geometry>::apply(geometry, policy());
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
@@ -65,7 +65,7 @@ struct point_in_ring
|
||||
static inline int apply(Point const& point, Ring const& ring,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (boost::size(ring)
|
||||
if (int(boost::size(ring))
|
||||
< core_detail::closure::minimum_ring_size<Closure>::value)
|
||||
{
|
||||
return -1;
|
||||
|
||||
Reference in New Issue
Block a user