Merge branch 'develop' of https://github.com/boostorg/geometry into feature/is_simple

This commit is contained in:
Menelaos Karavelas
2014-05-30 15:12:51 +03:00
33 changed files with 457 additions and 419 deletions

View File

@@ -41,7 +41,10 @@ void test_all()
// Round joins / flat ends:
test_one<multi_linestring_type, buf::join_round, buf::end_flat, polygon>("simplex", simplex, 38.2623, 1.5, 1.5);
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
test_one<multi_linestring_type, buf::join_round, buf::end_flat, polygon>("two_bends", two_bends, 64.6217, 1.5, 1.5);
#endif
// TODO this should be fixed test_one<multi_linestring_type, buf::join_round, buf::end_flat, polygon>("turn_inside", turn_inside, 99, 1.5, 1.5);
test_one<multi_linestring_type, buf::join_round, buf::end_flat, polygon>("two_bends_asym", two_bends, 52.3793, 1.5, 0.75);
@@ -49,8 +52,10 @@ void test_all()
// test_one<multi_linestring_type, buf::join_round, polygon>("turn_inside_asym_neg", turn_inside, 99, +1.5, -1.0);
// Miter / divide joins, various ends
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
test_one<multi_linestring_type, buf::join_round_by_divide, buf::end_flat, polygon>("two_bends", two_bends, 64.6217, 1.5, 1.5);
test_one<multi_linestring_type, buf::join_miter, buf::end_flat, polygon>("two_bends", two_bends, 65.1834, 1.5, 1.5);
#endif
test_one<multi_linestring_type, buf::join_miter, buf::end_round, polygon>("two_bends", two_bends, 75.2917, 1.5, 1.5);
}

View File

@@ -259,7 +259,7 @@ void test_all()
test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("zonethru_05", zonethru, 67.4627, 0.5);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("zonethru_05", zonethru, 68.0000, 0.5);
test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("zonethru_10", zonethru, 93.8508, 1.0, -999, 1);
test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("zonethru_10", zonethru, 93.8508, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("zonethru_10", zonethru, 96.0000, 1.0);
test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("zonethru_15", zonethru, 114.584, 1.5);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("zonethru_15", zonethru, 117.000, 1.5);
@@ -281,18 +281,14 @@ void test_all()
test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_d", rt_d, 18.8726, 0.3);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_d", rt_d, 19.8823, 0.3);
test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_e", rt_e, 14.1866, 0.3);
#if ! defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_e", rt_e, 15.1198, 0.3);
// This does not add anything: test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_f", rt_f, 4.28937, 0.3);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_f", rt_f, 4.60853, 0.3);
#endif
test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_g1", rt_g1, 24.719, 1.0);
#if ! defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_g1", rt_g1, 30.3137, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_g2", rt_g2, 18.5711, 1.0);
#endif
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_g3", rt_g3, 16.5711, 1.0);
test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_h", rt_h, 47.6012, 1.0);
@@ -304,20 +300,16 @@ void test_all()
test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_k", rt_k, 42.0092, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_k", rt_k, 48.0563, 1.0);
// This does not add anything: test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_l", rt_l, 14.1074, 1.0);
#if ! defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_l", rt_l, 19.3995, 1.0);
#endif
test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_m1", rt_m1, 14.1074, 1.0);
#if ! defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_m1", rt_m1, 19.4853, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_m2", rt_m2, 21.4853, 1.0);
// This does not add anything: test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_n", rt_n, 14.1074, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_n", rt_n, 18.4853, 1.0);
#endif
test_one<multi_polygon_type, buf::join_round, buf::end_skip, polygon_type>("rt_o1", rt_o1, 17.536, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_o1", rt_o1, 20.9142, 1.0);
//test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_o1", rt_o1, 20.9142, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_o2", rt_o2, 25.7426, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_o3", rt_o3, 28.8247, 1.0);
@@ -332,36 +324,34 @@ void test_all()
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p7", rt_p7, 26.2279, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p8", rt_p8, 29.0563, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p9", rt_p9, 26.1421, 1.0);
#if ! defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p10", rt_p10, 23.3995, 1.0);
#endif
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p11", rt_p11, 28.7426, 1.0);
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p12", rt_p12, 22.5711, 1.0);
#endif
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p13", rt_p13, 19.9142, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p14", rt_p14, 20.8284, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p15", rt_p15, 23.6569, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p16", rt_p16, 23.4853, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p17", rt_p17, 25.3137, 1.0);
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p18", rt_p18, 23.3137, 1.0);
#endif
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p19", rt_p19, 25.5637, 1.0);
#if defined(BOOST_GEOMETRY_BUFFER_INCLUDE_FAILING_TESTS)
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p20", rt_p20, 25.4853, 1.0);
#endif
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p21", rt_p21, 17.1716, 1.0);
// test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p22", rt_p22, 99, 1.0); TODO fix this one
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_p22", rt_p22, 26.5711, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_q1", rt_q1, 27, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_q2", rt_q2, 26.4853, 1.0);
#if ! defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_r", rt_r, 21.0761, 1.0);
#endif
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_s1", rt_s1, 20.4853, 1.0);
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_s2", rt_s2, 24.6495, 1.0);
#if ! defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
test_one<multi_polygon_type, buf::join_miter, buf::end_skip, polygon_type>("rt_t", rt_t, 15.6569, 1.0);
#endif
}
int point_buffer_count;

View File

@@ -132,8 +132,7 @@ template
>
void test_buffer(std::string const& caseid, Geometry const& geometry,
bool /*check*/, double expected_area,
double distance_left, double distance_right,
int expected_self_tangencies)
double distance_left, double distance_right)
{
namespace bg = boost::geometry;
@@ -283,21 +282,13 @@ void test_buffer(std::string const& caseid, Geometry const& geometry,
// Be sure resulting polygon does not contain
// self-intersections
// But indentation5 should contain 1 self-ip TODO give this check as an argument
if (expected_self_tangencies == 0
&& ! boost::contains(complete.str(), "indentation5_d_r")
&& ! boost::contains(complete.str(), "flower25_d_r")
&& ! boost::contains(complete.str(), "multipoly_rt_d_d_m")
)
BOOST_FOREACH(GeometryOut const& polygon, buffered)
{
BOOST_FOREACH(GeometryOut const& polygon, buffered)
{
BOOST_CHECK_MESSAGE
(
! bg::intersects(polygon),
complete.str() << " output is self-intersecting. "
);
}
BOOST_CHECK_MESSAGE
(
! bg::detail::overlay::has_self_intersections(polygon),
complete.str() << " output is self-intersecting. "
);
}
}
@@ -328,8 +319,7 @@ template
>
void test_one(std::string const& caseid, std::string const& wkt,
double expected_area,
double distance_left, double distance_right = -999,
int expected_self_tangencies = 0)
double distance_left, double distance_right = -999)
{
namespace bg = boost::geometry;
Geometry g;
@@ -352,7 +342,7 @@ void test_one(std::string const& caseid, std::string const& wkt,
test_buffer<GeometryOut, JoinStrategy, EndStrategy>
(caseid, g, false, expected_area,
distance_left, distance_right, expected_self_tangencies);
distance_left, distance_right);
}

View File

@@ -87,7 +87,7 @@ 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 (int(boost::size(ring))
if (boost::size(ring)
< core_detail::closure::minimum_ring_size<Closure>::value)
{
return typename Strategy::return_type();

View File

@@ -21,15 +21,15 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_AREAL_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_AREAL_HPP
#include <iterator>
#include <boost/range.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/interior_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/multi/core/tags.hpp>
@@ -87,15 +87,48 @@ struct disjoint_segment_areal
template <typename Segment, typename Polygon>
struct disjoint_segment_areal<Segment, Polygon, polygon_tag>
class disjoint_segment_areal<Segment, Polygon, polygon_tag>
{
private:
template <typename RingIterator>
static inline bool check_interior_rings(RingIterator first,
RingIterator beyond,
Segment const& segment)
{
for (RingIterator it = first; it != beyond; ++it)
{
if ( !disjoint_range_segment_or_box
<
typename std::iterator_traits
<
RingIterator
>::value_type,
closure<Polygon>::value,
Segment
>::apply(*it, segment) )
{
return false;
}
}
return true;
}
template <typename InteriorRings>
static inline
bool check_interior_rings(InteriorRings const& interior_rings,
Segment const& segment)
{
return check_interior_rings(boost::begin(interior_rings),
boost::end(interior_rings),
segment);
}
public:
static inline bool apply(Segment const& segment, Polygon const& polygon)
{
typedef typename geometry::ring_type<Polygon>::type ring;
typedef typename geometry::interior_return_type
<
Polygon const
>::type interior_rings;
if ( !disjoint_range_segment_or_box
<
@@ -105,18 +138,9 @@ struct disjoint_segment_areal<Segment, Polygon, polygon_tag>
return false;
}
interior_rings const& irings = geometry::interior_rings(polygon);
for (BOOST_AUTO_TPL(it, boost::begin(irings));
it != boost::end(irings); ++it)
if ( !check_interior_rings(geometry::interior_rings(polygon), segment) )
{
if ( !disjoint_range_segment_or_box
<
ring, closure<Polygon>::value, Segment
>::apply(*it, segment) )
{
return false;
}
return false;
}
typename point_type<Segment>::type p;

View File

@@ -26,6 +26,7 @@
#include <boost/numeric/conversion/cast.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/calculation_type.hpp>
#include <boost/geometry/core/access.hpp>
@@ -121,6 +122,18 @@ struct disjoint_segment_box_impl
compute_tmin_tmax_per_dim<I>::apply(p0, p1, box, ti_min, ti_max, diff);
if ( geometry::math::equals(diff, 0) )
{
if ( (geometry::math::equals(t_min.second, 0)
&& t_min.first > ti_max)
||
(geometry::math::equals(t_max.second, 0)
&& t_max.first < ti_min) )
{
return true;
}
}
RelativeDistance t_min_x_diff = t_min.first * diff;
RelativeDistance t_max_x_diff = t_max.first * diff;
@@ -180,6 +193,12 @@ struct disjoint_segment_box_impl
compute_tmin_tmax_per_dim<0>::apply(p0, p1, box,
t_min.first, t_max.first, diff);
if ( geometry::math::equals(diff, 0) )
{
if ( geometry::math::equals(t_min.first, 0) ) { t_min.first = -1; }
if ( geometry::math::equals(t_max.first, 0) ) { t_max.first = 1; }
}
if ( t_min.first > diff || t_max.first < 0 )
{
return true;

View File

@@ -43,7 +43,7 @@ namespace detail { namespace distance
template
<
typename Geometry1,
typename Geometry2,
typename Geometry2 = Geometry1,
typename Tag1 = typename tag_cast
<
typename tag<Geometry1>::type, pointlike_tag
@@ -57,7 +57,7 @@ template
struct default_strategy
: strategy::distance::services::default_strategy
<
segment_tag,
point_tag, segment_tag,
typename point_type<Geometry1>::type,
typename point_type<Geometry2>::type
>
@@ -82,7 +82,7 @@ struct default_strategy
pointlike_tag, pointlike_tag, false
> : strategy::distance::services::default_strategy
<
point_tag,
point_tag, point_tag,
typename point_type<Pointlike1>::type,
typename point_type<Pointlike2>::type
>
@@ -93,13 +93,12 @@ template <typename Pointlike, typename Box>
struct default_strategy<Pointlike, Box, pointlike_tag, box_tag, false>
: strategy::distance::services::default_strategy
<
point_tag,
point_tag, box_tag,
typename point_type<Pointlike>::type,
typename point_type<Box>::type,
cartesian_tag,
cartesian_tag,
void,
box_tag
void
>
{};
@@ -108,13 +107,12 @@ template <typename Box1, typename Box2>
struct default_strategy<Box1, Box2, box_tag, box_tag, false>
: strategy::distance::services::default_strategy
<
box_tag,
box_tag, box_tag,
typename point_type<Box1>::type,
typename point_type<Box2>::type,
cartesian_tag,
cartesian_tag,
void,
box_tag
void
>
{};
@@ -125,7 +123,7 @@ template <typename Geometry1, typename Geometry2, typename Strategy>
struct default_ps_strategy
: strategy::distance::services::default_strategy
<
segment_tag,
point_tag, segment_tag,
typename point_type<Geometry1>::type,
typename point_type<Geometry2>::type,
typename cs_tag<typename point_type<Geometry1>::type>::type,

View File

@@ -234,39 +234,38 @@ private:
}
};
template <typename T, typename LessEqual>
template <typename T, bool IsLess /* true */>
struct compare_less_equal
{
typedef compare_less_equal<T, !IsLess> other;
template <typename T1, typename T2>
inline bool operator()(T1 const& t1, T2 const& t2) const
{
return LessEqual()(cast_to_result<T>::apply(t1),
cast_to_result<T>::apply(t2));
return std::less_equal<T>()(cast_to_result<T>::apply(t1),
cast_to_result<T>::apply(t2));
}
};
template <typename T>
struct less_equal : compare_less_equal<T, std::less_equal<T> >
{};
struct compare_less_equal<T, false>
{
typedef compare_less_equal<T, true> other;
template <typename T1, typename T2>
inline bool operator()(T1 const& t1, T2 const& t2) const
{
return std::greater_equal<T>()(cast_to_result<T>::apply(t1),
cast_to_result<T>::apply(t2));
}
};
template <typename T>
struct greater_equal : compare_less_equal<T, std::greater_equal<T> >
{};
template <typename LessEqual>
struct other_compare
{};
template <typename T>
struct other_compare< less_equal<T> >
{
typedef greater_equal<T> type;
};
template <typename T>
struct other_compare< greater_equal<T> >
{
typedef less_equal<T> type;
typedef typename LessEqual::other type;
};
@@ -487,6 +486,8 @@ private:
PPStrategy const& pp_strategy,
PSStrategy const& ps_strategy)
{
typedef compare_less_equal<ReturnType, true> less_equal;
// assert that the segment has non-negative slope
BOOST_ASSERT( ( math::equals(geometry::get<0>(p0), geometry::get<0>(p1))
&& geometry::get<1>(p0) < geometry::get<1>(p1))
@@ -499,7 +500,7 @@ private:
if ( check_right_left_of_box
<
less_equal<ReturnType>
less_equal
>::apply(p0, p1,
top_left, top_right, bottom_left, bottom_right,
pp_strategy, ps_strategy, result) )
@@ -509,7 +510,7 @@ private:
if ( check_above_below_of_box
<
less_equal<ReturnType>
less_equal
>::apply(p0, p1,
top_left, top_right, bottom_left, bottom_right,
ps_strategy, result) )
@@ -541,6 +542,8 @@ private:
PPStrategy const& pp_strategy,
PSStrategy const& ps_strategy)
{
typedef compare_less_equal<ReturnType, false> greater_equal;
// assert that the segment has negative slope
BOOST_ASSERT( geometry::get<0>(p0) < geometry::get<0>(p1)
&& geometry::get<1>(p0) > geometry::get<1>(p1) );
@@ -549,7 +552,7 @@ private:
if ( check_right_left_of_box
<
greater_equal<ReturnType>
greater_equal
>::apply(p0, p1,
bottom_left, bottom_right, top_left, top_right,
pp_strategy, ps_strategy, result) )
@@ -559,7 +562,7 @@ private:
if ( check_above_below_of_box
<
greater_equal<ReturnType>
greater_equal
>::apply(p1, p0,
top_right, top_left, bottom_right, bottom_left,
ps_strategy, result) )

View File

@@ -96,7 +96,7 @@ template <typename Range, typename RobustPolicy>
inline void clean_closing_dups_and_spikes(Range& range,
RobustPolicy const& robust_policy)
{
int const minsize
std::size_t const minsize
= core_detail::closure::minimum_ring_size
<
geometry::closure<Range>::value

View File

@@ -22,12 +22,12 @@
#include <boost/numeric/conversion/bounds.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/algorithms/append.hpp>
#include <boost/geometry/algorithms/clear.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -116,6 +116,44 @@ struct range_to_range
struct polygon_to_polygon
{
private:
template
<
typename IteratorIn,
typename IteratorOut,
typename Strategy
>
static inline void iterate(IteratorIn begin, IteratorIn end,
IteratorOut it_out,
Strategy const& strategy)
{
for (IteratorIn it_in = begin; it_in != end; ++it_in, ++it_out)
{
range_to_range::apply(*it_out, *it_in, strategy);
}
}
template
<
typename InteriorRingsOut,
typename InteriorRingsIn,
typename Strategy
>
static inline void apply_interior_rings(
InteriorRingsOut& interior_rings_out,
InteriorRingsIn const& interior_rings_in,
Strategy const& strategy)
{
traits::resize<InteriorRingsOut>::apply(interior_rings_out,
boost::size(interior_rings_in));
iterate(
boost::begin(interior_rings_in), boost::end(interior_rings_in),
boost::begin(interior_rings_out),
strategy);
}
public:
template
<
typename Polygon1,
@@ -125,31 +163,11 @@ struct polygon_to_polygon
static inline void apply(Polygon1& destination, Polygon2 const& source,
Strategy const& strategy)
{
typedef range_to_range per_ring;
per_ring::apply(geometry::exterior_ring(destination),
range_to_range::apply(geometry::exterior_ring(destination),
geometry::exterior_ring(source), strategy);
traits::resize
<
typename boost::remove_reference
<
typename traits::interior_mutable_type<Polygon1>::type
>::type
>::apply(interior_rings(destination), num_interior_rings(source));
typename interior_return_type<Polygon1>::type rings_dest
= interior_rings(destination);
typename interior_return_type<Polygon2 const>::type rings_source
= interior_rings(source);
BOOST_AUTO_TPL(it_source, boost::begin(rings_source));
BOOST_AUTO_TPL(it_dest, boost::begin(rings_dest));
for ( ; it_source != boost::end(rings_source); ++it_source, ++it_dest)
{
per_ring::apply(*it_dest, *it_source, strategy);
}
apply_interior_rings(geometry::interior_rings(destination),
geometry::interior_rings(source), strategy);
}
};

View File

@@ -193,7 +193,7 @@ struct point_in_geometry<Ring, ring_tag>
static const iterate_direction direction = order_as_direction<geometry::point_order<Ring>::value>::value;
static const closure_selector closure = geometry::closure<Ring>::value;
if (int(boost::size(ring))
if (boost::size(ring)
< core_detail::closure::minimum_ring_size<closure>::value)
{
return -1;

View File

@@ -241,7 +241,7 @@ length(Geometry const& geometry)
// TODO put this into a resolve_strategy stage
typedef typename strategy::distance::services::default_strategy
<
point_tag, typename point_type<Geometry>::type
point_tag, point_tag, typename point_type<Geometry>::type
>::type strategy_type;
return resolve_variant::length<Geometry>::apply(geometry, strategy_type());

View File

@@ -101,8 +101,7 @@ struct perimeter
{
typedef typename strategy::distance::services::default_strategy
<
point_tag,
typename point_type<Geometry>::type
point_tag, point_tag, typename point_type<Geometry>::type
>::type strategy_type;
return dispatch::perimeter<Geometry>::apply(geometry, strategy_type());

View File

@@ -18,11 +18,9 @@
#include <cstddef>
#include <boost/range.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/mutable_range.hpp>
@@ -35,7 +33,8 @@
#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>
#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
@@ -119,13 +118,54 @@ struct simplify_range
struct simplify_polygon
{
private:
template
<
std::size_t Minimum,
typename IteratorIn,
typename IteratorOut,
typename Distance,
typename Strategy
>
static inline void iterate(IteratorIn begin, IteratorIn end,
IteratorOut it_out,
Distance const& max_distance, Strategy const& strategy)
{
for (IteratorIn it_in = begin; it_in != end; ++it_in, ++it_out)
{
simplify_range<Minimum>::apply(*it_in, *it_out, max_distance, strategy);
}
}
template
<
std::size_t Minimum,
typename InteriorRingsIn,
typename InteriorRingsOut,
typename Distance,
typename Strategy
>
static inline void apply_interior_rings(
InteriorRingsIn const& interior_rings_in,
InteriorRingsOut& interior_rings_out,
Distance const& max_distance, Strategy const& strategy)
{
traits::resize<InteriorRingsOut>::apply(interior_rings_out,
boost::size(interior_rings_in));
iterate<Minimum>(
boost::begin(interior_rings_in), boost::end(interior_rings_in),
boost::begin(interior_rings_out),
max_distance, strategy);
}
public:
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)
{
typedef typename ring_type<Polygon>::type ring_type;
int const Minimum = core_detail::closure::minimum_ring_size
std::size_t const minimum = core_detail::closure::minimum_ring_size
<
geometry::closure<Polygon>::value
>::value;
@@ -133,29 +173,13 @@ 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<Minimum>::apply(exterior_ring(poly_in),
simplify_range<minimum>::apply(exterior_ring(poly_in),
exterior_ring(poly_out),
max_distance, strategy);
traits::resize
<
typename boost::remove_reference
<
typename traits::interior_mutable_type<Polygon>::type
>::type
>::apply(interior_rings(poly_out), num_interior_rings(poly_in));
typename interior_return_type<Polygon const>::type rings_in
= interior_rings(poly_in);
typename interior_return_type<Polygon>::type rings_out
= interior_rings(poly_out);
BOOST_AUTO_TPL(it_out, boost::begin(rings_out));
for (BOOST_AUTO_TPL(it_in, boost::begin(rings_in));
it_in != boost::end(rings_in);
++it_in, ++it_out)
{
simplify_range<Minimum>::apply(*it_in, *it_out, max_distance, strategy);
}
apply_interior_rings<minimum>(interior_rings(poly_in),
interior_rings(poly_out),
max_distance, strategy);
}
};
@@ -258,7 +282,7 @@ struct simplify
typedef typename strategy::distance::services::default_strategy
<
segment_tag, point_type
point_tag, segment_tag, point_type
>::type ds_strategy_type;
typedef strategy::simplify::douglas_peucker
@@ -301,7 +325,7 @@ struct simplify_insert
typedef typename strategy::distance::services::default_strategy
<
segment_tag, point_type
point_tag, segment_tag, point_type
>::type ds_strategy_type;
typedef strategy::simplify::douglas_peucker

View File

@@ -139,7 +139,7 @@ inline void add_value(Point& p, typename detail::param<Point>::type value)
template <typename Point1, typename Point2>
inline void add_point(Point1& p1, Point2 const& p2)
{
BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
BOOST_CONCEPT_ASSERT( (concept::Point<Point1>) );
BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
for_each_coordinate(p1, detail::point_operation<Point2, std::plus>(p2));
@@ -171,7 +171,7 @@ inline void subtract_value(Point& p, typename detail::param<Point>::type value)
template <typename Point1, typename Point2>
inline void subtract_point(Point1& p1, Point2 const& p2)
{
BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
BOOST_CONCEPT_ASSERT( (concept::Point<Point1>) );
BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
for_each_coordinate(p1, detail::point_operation<Point2, std::minus>(p2));
@@ -204,7 +204,7 @@ inline void multiply_value(Point& p, typename detail::param<Point>::type value)
template <typename Point1, typename Point2>
inline void multiply_point(Point1& p1, Point2 const& p2)
{
BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
BOOST_CONCEPT_ASSERT( (concept::Point<Point1>) );
BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
for_each_coordinate(p1, detail::point_operation<Point2, std::multiplies>(p2));
@@ -236,7 +236,7 @@ inline void divide_value(Point& p, typename detail::param<Point>::type value)
template <typename Point1, typename Point2>
inline void divide_point(Point1& p1, Point2 const& p2)
{
BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
BOOST_CONCEPT_ASSERT( (concept::Point<Point1>) );
BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
for_each_coordinate(p1, detail::point_operation<Point2, std::divides>(p2));
@@ -268,7 +268,7 @@ inline void assign_value(Point& p, typename detail::param<Point>::type value)
template <typename Point1, typename Point2>
inline void assign_point(Point1& p1, const Point2& p2)
{
BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
BOOST_CONCEPT_ASSERT( (concept::Point<Point1>) );
BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
for_each_coordinate(p1, detail::point_assignment<Point2>(p2));

View File

@@ -16,7 +16,7 @@
#include <boost/mpl/assert.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/size_t.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/remove_const.hpp>
@@ -93,10 +93,10 @@ template <closure_selector Closure>
struct minimum_ring_size {};
template <>
struct minimum_ring_size<geometry::closed> : boost::mpl::int_<4> {};
struct minimum_ring_size<geometry::closed> : boost::mpl::size_t<4> {};
template <>
struct minimum_ring_size<geometry::open> : boost::mpl::int_<3> {};
struct minimum_ring_size<geometry::open> : boost::mpl::size_t<3> {};
}} // namespace detail::point_order

View File

@@ -229,7 +229,11 @@ public :
// of point-to-segment or point-to-linestring.
// Convenient for geographic coordinate systems especially.
template <typename Point, typename PointOfSegment, typename Strategy>
struct default_strategy<segment_tag, Point, PointOfSegment, cartesian_tag, cartesian_tag, Strategy>
struct default_strategy
<
point_tag, segment_tag, Point, PointOfSegment,
cartesian_tag, cartesian_tag, Strategy
>
{
typedef strategy::distance::projected_point
<
@@ -239,7 +243,7 @@ struct default_strategy<segment_tag, Point, PointOfSegment, cartesian_tag, carte
boost::is_void<Strategy>,
typename default_strategy
<
point_tag, Point, PointOfSegment,
point_tag, point_tag, Point, PointOfSegment,
cartesian_tag, cartesian_tag
>::type,
Strategy

View File

@@ -271,7 +271,10 @@ public :
template <typename Point1, typename Point2>
struct default_strategy<point_tag, Point1, Point2, cartesian_tag, cartesian_tag, void>
struct default_strategy
<
point_tag, point_tag, Point1, Point2, cartesian_tag, cartesian_tag
>
{
typedef pythagoras<> type;
};

View File

@@ -315,10 +315,10 @@ public :
};
template <typename Box1, typename Box2>
template <typename BoxPoint1, typename BoxPoint2>
struct default_strategy
<
box_tag, Box1, Box2, cartesian_tag, cartesian_tag, void, box_tag
box_tag, box_tag, BoxPoint1, BoxPoint2, cartesian_tag, cartesian_tag
>
{
typedef pythagoras_box_box<> type;

View File

@@ -313,8 +313,11 @@ public :
};
template <typename Point, typename Box>
struct default_strategy<point_tag, Point, Box, cartesian_tag, cartesian_tag, void, box_tag>
template <typename Point, typename BoxPoint>
struct default_strategy
<
point_tag, box_tag, Point, BoxPoint, cartesian_tag, cartesian_tag
>
{
typedef pythagoras_point_box<> type;
};

View File

@@ -1,8 +1,13 @@
// 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.
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -70,7 +75,8 @@ struct result_from_distance {};
\brief Traits class binding a default strategy for distance
to one (or possibly two) coordinate system(s)
\ingroup distance
\tparam GeometryTag tag (point/segment) for which this strategy is the default
\tparam GeometryTag1 tag (point/segment/box) for which this strategy is the default
\tparam GeometryTag2 tag (point/segment/box) for which this strategy is the default
\tparam Point1 first point-type
\tparam Point2 second point-type
\tparam CsTag1 tag of coordinate system of first point type
@@ -78,13 +84,13 @@ struct result_from_distance {};
*/
template
<
typename GeometryTag,
typename GeometryTag1,
typename GeometryTag2,
typename Point1,
typename Point2 = Point1,
typename CsTag1 = typename cs_tag<Point1>::type,
typename CsTag2 = typename cs_tag<Point2>::type,
typename UnderlyingStrategy = void,
typename GeometryTag2 = GeometryTag
typename UnderlyingStrategy = void
>
struct default_strategy
{

View File

@@ -284,7 +284,7 @@ struct default_strategy
template <typename Point, typename PointOfSegment, typename Strategy>
struct default_strategy
<
segment_tag, Point, PointOfSegment,
point_tag, segment_tag, Point, PointOfSegment,
spherical_equatorial_tag, spherical_equatorial_tag,
Strategy
>
@@ -297,7 +297,7 @@ struct default_strategy
boost::is_void<Strategy>,
typename default_strategy
<
point_tag, Point, PointOfSegment,
point_tag, point_tag, Point, PointOfSegment,
spherical_equatorial_tag, spherical_equatorial_tag
>::type,
Strategy

View File

@@ -279,7 +279,11 @@ public :
// Register it as the default for point-types
// in a spherical equatorial coordinate system
template <typename Point1, typename Point2>
struct default_strategy<point_tag, Point1, Point2, spherical_equatorial_tag, spherical_equatorial_tag>
struct default_strategy
<
point_tag, point_tag, Point1, Point2,
spherical_equatorial_tag, spherical_equatorial_tag
>
{
typedef strategy::distance::haversine<typename select_coordinate_type<Point1, Point2>::type> type;
};

View File

@@ -680,6 +680,55 @@ inline void test_segment_box()
tester::apply(from_wkt<S>("SEGMENT(4 0,4 4)"),
from_wkt<B>("BOX(0 0,2 2)"),
true);
tester::apply(from_wkt<S>("SEGMENT(0 -2,0 -1)"),
from_wkt<B>("BOX(0 0,1 1)"),
true);
tester::apply(from_wkt<S>("SEGMENT(-2 -2,-2 -1)"),
from_wkt<B>("BOX(0 0,1 1)"),
true);
tester::apply(from_wkt<S>("SEGMENT(-2 -2,-2 -2)"),
from_wkt<B>("BOX(0 0,1 1)"),
true);
tester::apply(from_wkt<S>("SEGMENT(-2 0,-2 0)"),
from_wkt<B>("BOX(0 0,1 1)"),
true);
tester::apply(from_wkt<S>("SEGMENT(0 -2,0 -2)"),
from_wkt<B>("BOX(0 0,1 1)"),
true);
tester::apply(from_wkt<S>("SEGMENT(-2 0,-1 0)"),
from_wkt<B>("BOX(0 0,1 1)"),
true);
// segment degenerates to a point
tester::apply(from_wkt<S>("SEGMENT(0 0,0 0)"),
from_wkt<B>("BOX(0 0,1 1)"),
false);
tester::apply(from_wkt<S>("SEGMENT(1 1,1 1)"),
from_wkt<B>("BOX(0 0,2 2)"),
false);
tester::apply(from_wkt<S>("SEGMENT(2 2,2 2)"),
from_wkt<B>("BOX(0 0,2 2)"),
false);
tester::apply(from_wkt<S>("SEGMENT(2 0,2 0)"),
from_wkt<B>("BOX(0 0,2 2)"),
false);
tester::apply(from_wkt<S>("SEGMENT(0 2,0 2)"),
from_wkt<B>("BOX(0 0,2 2)"),
false);
tester::apply(from_wkt<S>("SEGMENT(2 2,2 2)"),
from_wkt<B>("BOX(0 0,1 1)"),
true);
}
template <typename P>

View File

@@ -72,7 +72,10 @@ void test_distance_point()
BOOST_CHECK_CLOSE(d, return_type(1.4142135), 0.001);
// Test specifying strategy manually
typename services::default_strategy<bg::point_tag, P>::type strategy;
typename services::default_strategy
<
bg::point_tag, bg::point_tag, P
>::type strategy;
d = bg::distance(p1, p2, strategy);
BOOST_CHECK_CLOSE(d, return_type(1.4142135), 0.001);
@@ -93,7 +96,10 @@ void test_distance_point()
{
// test comparability
typedef typename services::default_strategy<bg::point_tag, P>::type strategy_type;
typedef typename services::default_strategy
<
bg::point_tag, bg::point_tag, P
>::type strategy_type;
typedef typename services::comparable_type<strategy_type>::type comparable_strategy_type;
strategy_type strategy;
@@ -143,12 +149,18 @@ void test_distance_segment()
// Test specifying strategy manually:
// 1) point-point-distance
typename bg::strategy::distance::services::default_strategy<bg::point_tag, P>::type pp_strategy;
typename bg::strategy::distance::services::default_strategy
<
bg::point_tag, bg::point_tag, P
>::type pp_strategy;
d1 = bg::distance(p1, seg, pp_strategy);
BOOST_CHECK_CLOSE(d1, return_type(1), 0.001);
// 2) point-segment-distance
typename bg::strategy::distance::services::default_strategy<bg::segment_tag, P>::type ps_strategy;
typename bg::strategy::distance::services::default_strategy
<
bg::point_tag, bg::segment_tag, P
>::type ps_strategy;
d1 = bg::distance(p1, seg, ps_strategy);
BOOST_CHECK_CLOSE(d1, return_type(1), 0.001);

View File

@@ -29,7 +29,7 @@ BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
template <typename P>
template <typename P, typename P2>
void test_addition()
{
P p1;
@@ -39,15 +39,14 @@ void test_addition()
BOOST_CHECK(bg::get<1>(p1) == 12);
BOOST_CHECK(bg::get<2>(p1) == 13);
P p2;
bg::assign_values(p2, 4, 5, 6);
P2 p2(4, 5, 6);
bg::add_point(p1, p2);
BOOST_CHECK(bg::get<0>(p1) == 15);
BOOST_CHECK(bg::get<1>(p1) == 17);
BOOST_CHECK(bg::get<2>(p1) == 19);
}
template <typename P>
template <typename P, typename P2>
void test_subtraction()
{
P p1;
@@ -57,15 +56,14 @@ void test_subtraction()
BOOST_CHECK(bg::get<1>(p1) == -8);
BOOST_CHECK(bg::get<2>(p1) == -7);
P p2;
bg::assign_values(p2, 4, 6, 8);
P2 p2(4, 6, 8);
bg::subtract_point(p1, p2);
BOOST_CHECK(bg::get<0>(p1) == -13);
BOOST_CHECK(bg::get<1>(p1) == -14);
BOOST_CHECK(bg::get<2>(p1) == -15);
}
template <typename P>
template <typename P, typename P2>
void test_multiplication()
{
P p1;
@@ -75,15 +73,14 @@ void test_multiplication()
BOOST_CHECK(bg::get<1>(p1) == 10);
BOOST_CHECK(bg::get<2>(p1) == 15);
P p2;
bg::assign_values(p2, 4, 5, 6);
P2 p2(4, 5, 6);
bg::multiply_point(p1, p2);
BOOST_CHECK(bg::get<0>(p1) == 20);
BOOST_CHECK(bg::get<1>(p1) == 50);
BOOST_CHECK(bg::get<2>(p1) == 90);
}
template <typename P>
template <typename P, typename P2>
void test_division()
{
P p1;
@@ -93,40 +90,41 @@ void test_division()
BOOST_CHECK(bg::get<1>(p1) == 20);
BOOST_CHECK(bg::get<2>(p1) == 30);
P p2;
bg::assign_values(p2, 2, 4, 6);
P2 p2(2, 4, 6);
bg::divide_point(p1, p2);
BOOST_CHECK(bg::get<0>(p1) == 5);
BOOST_CHECK(bg::get<1>(p1) == 5);
BOOST_CHECK(bg::get<2>(p1) == 5);
}
template <typename P>
template <typename P, typename P2>
void test_assign()
{
P p1;
P p2;
P2 p2(12, 34, 56);
bg::assign_values(p1, 12, 34, 56);
bg::assign_point(p2, p1);
BOOST_CHECK(bg::get<0>(p2) == 12);
BOOST_CHECK(bg::get<1>(p2) == 34);
BOOST_CHECK(bg::get<2>(p2) == 56);
bg::assign_point(p1, p2);
BOOST_CHECK(bg::get<0>(p1) == 12);
BOOST_CHECK(bg::get<1>(p1) == 34);
BOOST_CHECK(bg::get<2>(p1) == 56);
bg::assign_value(p2, 78);
BOOST_CHECK(bg::get<0>(p2) == 78);
BOOST_CHECK(bg::get<1>(p2) == 78);
BOOST_CHECK(bg::get<2>(p2) == 78);
bg::assign_value(p1, 78);
BOOST_CHECK(bg::get<0>(p1) == 78);
BOOST_CHECK(bg::get<1>(p1) == 78);
BOOST_CHECK(bg::get<2>(p1) == 78);
}
template <typename P>
void test_all()
{
test_addition<P>();
test_subtraction<P>();
test_multiplication<P>();
test_division<P>();
test_assign<P>();
typedef test::test_const_point P2;
test_addition<P, P2>();
test_subtraction<P, P2>();
test_multiplication<P, P2>();
test_division<P, P2>();
test_assign<P, P2>();
}

View File

@@ -11,5 +11,5 @@
test-suite boost-geometry-policies
:
[ run compare.cpp ]
# [ run rescale_policy.cpp ]
[ run rescale_policy.cpp ]
;

View File

@@ -17,205 +17,31 @@
#include <boost/foreach.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/correct.hpp>
#include <boost/geometry/algorithms/detail/recalculate.hpp>
#include <boost/geometry/algorithms/length.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/strategies/strategies.hpp>
#include <boost/geometry/iterators/point_iterator.hpp>
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#if defined(TEST_WITH_SVG)
# include <boost/geometry/io/svg/svg_mapper.hpp>
#endif
#include <geometry_test_common.hpp>
namespace boost { namespace geometry
{
// Overload with rescale-policy specified (temporary here - to be worked out)
template
<
typename Geometry1,
typename Geometry2,
typename RescalePolicy,
typename GeometryOut
>
inline bool intersection(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RescalePolicy const& rescale_policy,
GeometryOut& geometry_out)
{
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
typedef strategy_intersection
<
typename cs_tag<Geometry1>::type,
Geometry1,
Geometry2,
typename geometry::point_type<Geometry1>::type,
RescalePolicy
> strategy;
return dispatch::intersection
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, rescale_policy, geometry_out, strategy());
}
}} // namespace boost::geometry
template
<
typename OutputType,
typename CalculationType,
typename Geometry1,
typename Geometry2,
typename RescalePolicy
>
typename bg::default_area_result<Geometry1>::type test_intersection(std::string const& caseid,
Geometry1 const& geometry1, Geometry2 const& geometry2,
RescalePolicy const& rescale_policy,
std::size_t expected_count = 0, int expected_point_count = 0,
double expected_length_or_area = 0,
double percentage = 0.0001,
bool debug = false)
{
typedef typename bg::coordinate_type<Geometry1>::type coordinate_type;
typedef typename bg::point_type<Geometry1>::type point_type;
// if (debug)
{
std::cout << std::endl
<< "case " << caseid
<< " " << typeid(coordinate_type).name()
<< " " << string_from_type<coordinate_type>::name()
<< std::endl;
}
std::vector<OutputType> out;
bg::intersection(geometry1, geometry2, rescale_policy, out);
typename bg::default_area_result<Geometry1>::type length_or_area = 0;
int n = 0;
for (typename std::vector<OutputType>::iterator it = out.begin();
it != out.end();
++it)
{
if (expected_point_count > 0)
{
n += bg::num_points(*it, true);
}
length_or_area += bg::area(*it);
if (debug)
{
std::cout << std::setprecision(20) << bg::wkt(*it) << std::endl;
}
}
#if ! defined(BOOST_GEOMETRY_NO_BOOST_TEST)
if (expected_point_count > 0)
{
BOOST_CHECK_MESSAGE(bg::math::abs(n - expected_point_count) < 3,
"intersection: " << caseid
<< " #points expected: " << expected_point_count
<< " detected: " << n
<< " type: " << (type_for_assert_message<Geometry1, Geometry2>())
);
}
if (expected_count > 0)
{
BOOST_CHECK_MESSAGE(out.size() == expected_count,
"intersection: " << caseid
<< " #outputs expected: " << expected_count
<< " detected: " << out.size()
<< " type: " << (type_for_assert_message<Geometry1, Geometry2>())
);
}
double const detected_length_or_area = boost::numeric_cast<double>(length_or_area);
BOOST_CHECK_CLOSE(detected_length_or_area, expected_length_or_area, percentage);
#endif
#if defined(TEST_WITH_SVG)
{
bool const ccw =
bg::point_order<Geometry1>::value == bg::counterclockwise
|| bg::point_order<Geometry2>::value == bg::counterclockwise;
bool const open =
bg::closure<Geometry1>::value == bg::open
|| bg::closure<Geometry2>::value == bg::open;
std::ostringstream filename;
filename << "rescale_policy_intersection_"
<< caseid << "_"
<< string_from_type<coordinate_type>::name()
<< string_from_type<CalculationType>::name()
<< (ccw ? "_ccw" : "")
<< (open ? "_open" : "")
<< ".svg";
std::ofstream svg(filename.str().c_str());
bg::svg_mapper<point_type> mapper(svg, 500, 500);
mapper.add(geometry1);
mapper.add(geometry2);
mapper.map(geometry1, "fill-opacity:0.5;fill:rgb(153,204,0);"
"stroke:rgb(153,204,0);stroke-width:3");
mapper.map(geometry2, "fill-opacity:0.3;fill:rgb(51,51,153);"
"stroke:rgb(51,51,153);stroke-width:3");
for (typename std::vector<OutputType>::const_iterator it = out.begin();
it != out.end(); ++it)
{
mapper.map(*it, "fill-opacity:0.2;stroke-opacity:0.4;fill:rgb(255,0,0);"
"stroke:rgb(255,0,255);stroke-width:8");
}
}
#endif
if (debug)
{
std::cout << "end case " << caseid << std::endl;
}
return length_or_area;
}
template
<
typename RescalePolicy,
typename OutputType,
typename Geometry1,
typename Geometry2
>
typename bg::default_area_result<Geometry1>::type test_one(std::string const& caseid,
std::string const& wkt1, std::string const& wkt2,
std::size_t expected_count = 0, int expected_point_count = 0,
double expected_length_or_area = 0,
double percentage = 0.02,
bool debug = false)
void test_one(std::string const& wkt1, std::string const& wkt2,
std::string const& expected_coordinates)
{
Geometry1 geometry1;
bg::read_wkt(wkt1, geometry1);
@@ -223,21 +49,39 @@ typename bg::default_area_result<Geometry1>::type test_one(std::string const& ca
Geometry2 geometry2;
bg::read_wkt(wkt2, geometry2);
// Reverse if necessary
bg::correct(geometry1);
bg::correct(geometry2);
RescalePolicy rescale_policy
= bg::get_rescale_policy<RescalePolicy>(geometry1, geometry2);
return test_intersection<OutputType, void>(caseid,
geometry1, geometry2,
rescale_policy,
expected_count, expected_point_count,
expected_length_or_area, percentage,
debug);
typedef typename bg::point_type<Geometry1>::type point_type;
typedef typename bg::robust_point_type
<
point_type, RescalePolicy
>::type robust_point_type;
{
robust_point_type robust_point;
bg::recalculate(robust_point, *bg::points_begin(geometry1), rescale_policy);
std::ostringstream out;
out << bg::get<0>(robust_point) << " " << bg::get<1>(robust_point);
BOOST_CHECK_EQUAL(expected_coordinates, out.str());
}
{
// Assuming Geometry1 is a polygon:
typedef bg::model::polygon<robust_point_type> polygon_type;
polygon_type geometry_out;
bg::recalculate(geometry_out, geometry1, rescale_policy);
robust_point_type p = *bg::points_begin(geometry_out);
std::ostringstream out;
out << bg::get<0>(p) << " " << bg::get<1>(p);
BOOST_CHECK_EQUAL(expected_coordinates, out.str());
}
}
static std::string simplex_normal[2] =
{"POLYGON((0 1,2 5,5 3,0 1))",
"POLYGON((3 0,0 3,4 5,3 0))"};
@@ -248,7 +92,7 @@ static std::string simplex_large[2] =
template <bool Rescale, typename P>
void test_rescale()
void test_rescale(std::string const& expected_normal, std::string const& expected_large)
{
typedef bg::model::polygon<P> polygon;
@@ -259,35 +103,29 @@ void test_rescale()
bg::detail::no_rescale_policy
>::type rescale_policy_type;
std::string suffix = Rescale ? "rescale" : "no_rescale";
typedef typename bg::coordinate_type<P>::type coordinate_type;
if (! boost::is_integral<coordinate_type>::type::value)
{
test_one<rescale_policy_type, polygon, polygon, polygon>("simplex_normal_" + suffix,
simplex_normal[0], simplex_normal[1],
1, 7, 5.47363293);
}
test_one<rescale_policy_type, polygon, polygon, polygon>("simplex_large_" + suffix,
test_one<rescale_policy_type, polygon, polygon>(
simplex_normal[0], simplex_normal[1],
expected_normal);
test_one<rescale_policy_type, polygon, polygon>(
simplex_large[0], simplex_large[1],
1, 7, 5473632.93);
expected_large);
}
template <typename T>
void test_all()
void test_all(std::string const& expected_normal, std::string const& expected_large)
{
typedef bg::model::d2::point_xy<T> point_type;
test_rescale<true, point_type>();
test_rescale<false, point_type>();
test_rescale<true, point_type>(expected_normal, expected_large);
//test_rescale<false, point_type>();
}
int test_main(int, char* [])
{
test_all<double>();
test_all<long double>();
test_all<int>();
test_all<boost::long_long_type>();
test_all<double>("-5000000 -3000000", "-5000000 -3000000");
test_all<long double>("-5000000 -3000000", "-5000000 -3000000");
test_all<int>("0 1", "0 1000");
test_all<boost::long_long_type>("0 1", "0 1000");
// test_all<short int>(); // compiles but overflows
return 0;

View File

@@ -1,9 +1,14 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// 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.
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -57,6 +62,15 @@ void test_distance(
>::type return_type;
{
// compile-check if there is a strategy for this type
typedef typename bg::strategy::distance::services::default_strategy
<
bg::point_tag, bg::segment_tag, Point, Point
>::type cross_track_strategy_type;
}
BOOST_CONCEPT_ASSERT
(
(bg::concept::PointSegmentDistanceStrategy<strategy_type, Point, Point>)

View File

@@ -90,7 +90,10 @@ void test_services()
{
// Compile-check if there is a strategy for this type
typedef typename services::default_strategy<bg::point_tag, P1, P2>::type haversine_strategy_type;
typedef typename services::default_strategy
<
bg::point_tag, bg::point_tag, P1, P2
>::type haversine_strategy_type;
}
P1 p1;

View File

@@ -1,9 +1,14 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// 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.
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -50,6 +55,15 @@ void test_services()
namespace bgsd = bg::strategy::distance;
namespace services = bg::strategy::distance::services;
{
// compile-check if there is a strategy for this type
typedef typename services::default_strategy
<
bg::point_tag, bg::segment_tag, P, PS
>::type projected_point_strategy_type;
}
// 1: normal, calculate distance:
typedef bgsd::projected_point<CalculationType> strategy_type;

View File

@@ -122,7 +122,10 @@ void test_services()
{
// Compile-check if there is a strategy for this type
typedef typename services::default_strategy<bg::point_tag, P1, P2>::type pythagoras_strategy_type;
typedef typename services::default_strategy
<
bg::point_tag, bg::point_tag, P1, P2
>::type pythagoras_strategy_type;
}

View File

@@ -17,6 +17,7 @@
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/geometries/register/point.hpp>
// NOTE: since Boost 1.51 the Point type may always be a pointer.
// Therefore the traits class don't need to add a pointer.
@@ -32,10 +33,21 @@ struct test_point
float c1, c2, c3;
};
struct test_const_point
{
test_const_point()
: c1(0.0), c2(0.0), c3(0.0) { }
test_const_point(float c1, float c2, float c3)
: c1(c1), c2(c2), c3(c3) { }
const float c1, c2, c3;
};
} // namespace test
namespace boost { namespace geometry { namespace traits {
template<>
@@ -91,4 +103,9 @@ template<> struct access<test::test_point, 2>
}}} // namespace bg::traits
BOOST_GEOMETRY_REGISTER_POINT_3D_CONST(test::test_const_point,
float,
boost::geometry::cs::cartesian,
c1, c2, c3);
#endif // GEOMETRY_TEST_TEST_COMMON_TEST_POINT_HPP