Merge branch 'rescale_to_integer' of github.com:boostorg/geometry into rescale_to_integer

This commit is contained in:
Barend Gehrels
2014-04-19 20:01:16 +02:00
16 changed files with 2082 additions and 26 deletions

View File

@@ -859,13 +859,15 @@ public:
IntersectionInfo const& intersection_info,
DirInfo const& dir_info,
SidePolicy const& side,
MethodAndOperationsReplacer method_and_operations_replacer)
MethodAndOperationsReplacer method_and_operations_replacer,
bool const is_pk_valid = true, bool const is_qk_valid = true)
{
TurnInfo tp = tp_model;
// If P arrives within Q, there is a turn dependent on P
if (dir_info.arrival[0] == 1
&& set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, intersection_info))
if ( dir_info.arrival[0] == 1
&& is_pk_valid
&& set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, intersection_info) )
{
method_and_operations_replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
@@ -874,8 +876,9 @@ public:
}
// If Q arrives within P, there is a turn dependent on Q
if (dir_info.arrival[1] == 1
&& set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, intersection_info))
if ( dir_info.arrival[1] == 1
&& is_qk_valid
&& set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, intersection_info) )
{
method_and_operations_replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);

View File

@@ -184,10 +184,10 @@ struct get_turn_info_for_endpoint
p_operation0, q_operation0,
tp_model, result, 0, out);
bool result_ignore_ip0 = !opposite ? // <=> ip_count == 1 || ip_count == 2 && !opposite
append0_last :
(append0_last && (p0j || (is_q_last && q0j && q1i)));
// NOTE: based on how collinear is calculated for opposite segments
// NOTE: opposite && ip_count == 1 may be true!
// don't ignore only for collinear opposite
bool result_ignore_ip0 = append0_last && ( ip_count == 1 || !opposite );
if ( p_operation1 == operation_none )
return result_ignore_ip0;
@@ -199,11 +199,8 @@ struct get_turn_info_for_endpoint
p_operation1, q_operation1,
tp_model, result, 1, out);
bool result_ignore_ip1 = !opposite ? // <=> ip_count == 2 && !opposite
append1_last :
(append1_last && (q1j || (is_p_last && p1j && p0i)));
// NOTE: based on how collinear is calculated for opposite segments
// this condition is symmetric to the one above
// don't ignore only for collinear opposite
bool result_ignore_ip1 = append1_last && !opposite /*&& ip_count == 2*/;
return result_ignore_ip0 || result_ignore_ip1;
}

View File

@@ -235,12 +235,13 @@ struct get_turn_info_linear_areal
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
tp, result.template get<0>(), result.template get<1>(), side_calc);
spike_detector<Point1, Point2> spike_detect(side_calc);
// TODO: This isn't correct handling, hence commented out
/*spike_detector<Point1, Point2> spike_detect(side_calc);
if ( tp.operations[0].operation == operation_union
&& spike_detect.is_spike_p())
{
tp.operations[0].operation = operation_continue;
}
}*/
replacer_of_method_and_operations_ec<false> replacer(method_touch);
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
@@ -508,9 +509,7 @@ struct get_turn_info_linear_areal
// IP on the last point of Linear Geometry
if ( EnableLast
&& is_p_last
&& ( ip_count > 1 ? p1j : p0j )
&& (!q0i || (q0i && q1j)) // prevents duplication
&& !q1i ) // prevents duplication
&& ( ip_count > 1 ? (p1j && !q1i) : (p0j && !q0i) ) ) // prevents duplication
{
TurnInfo tp = tp_model;

View File

@@ -352,7 +352,7 @@ struct get_turn_info_linear_linear
AssignPolicy
>::apply(pi, pj, pk, qi, qj, qk,
tp, out, result.template get<0>(), result.template get<1>(), side_calc,
replacer);
replacer, !is_p_last, !is_q_last);
}
}
}

View File

@@ -294,7 +294,7 @@ struct sectionalize_part
section_type section;
bool mark_first_non_duplicated = true;
std::size_t last_non_duplicate_index = 0;
std::size_t last_non_duplicate_index = sections.size();
iterator_type it = boost::begin(range);

View File

@@ -0,0 +1,109 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp>
namespace boost { namespace geometry
{
template <typename Iterator1, typename Iterator2, typename Value>
struct concatenate_iterator
: public boost::iterator_facade
<
concatenate_iterator<Iterator1, Iterator2, Value>,
Value,
boost::forward_traversal_tag
>
{
private:
Iterator1 m_it1, m_end1;
Iterator2 m_it2;
struct enabler {};
public:
typedef Iterator1 first_iterator_type;
typedef Iterator2 second_iterator_type;
// default constructor
concatenate_iterator() {}
// for begin
concatenate_iterator(Iterator1 it1, Iterator1 end1,
Iterator2 it2)
: m_it1(it1), m_end1(end1), m_it2(it2)
{}
// for end
concatenate_iterator(Iterator1 end1, Iterator2 end2)
: m_it1(end1), m_end1(end1), m_it2(end2)
{}
template <typename OtherIt1, typename OtherIt2, typename OtherValue>
concatenate_iterator
(concatenate_iterator<OtherIt1, OtherIt2, OtherValue> const& other,
typename boost::enable_if_c
<
boost::is_convertible<OtherIt1, Iterator1>::value
&& boost::is_convertible<OtherIt2, Iterator2>::value,
enabler
>::type = enabler())
: m_it1(other.m_it1), m_end1(other.m_end1), m_it2(other.m_it2)
{}
private:
friend class boost::iterator_core_access;
template <typename It1, typename It2, typename V>
friend class concatenate_iterator;
Value& dereference() const
{
if ( m_it1 == m_end1 )
{
return *m_it2;
}
return *m_it1;
}
bool equal(concatenate_iterator const& other) const
{
return m_it1 == other.m_it1 && m_it2 == other.m_it2;
}
void increment()
{
if ( m_it1 == m_end1 )
{
++m_it2;
}
else
{
++m_it1;
}
}
};
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP

View File

@@ -0,0 +1,47 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_HPP
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// dispatch for points_begin
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct points_begin
: not_implemented<Geometry>
{};
// dispatch for points_end
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct points_end
: not_implemented<Geometry>
{};
} // namespace core_dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_HPP

View File

@@ -0,0 +1,37 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP
#define BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct point_iterator_type
: not_implemented<Geometry>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP

View File

@@ -0,0 +1,208 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp>
namespace boost { namespace geometry
{
template
<
typename OuterIterator,
typename InnerIterator,
typename Value,
typename AccessInnerBegin,
typename AccessInnerEnd
>
struct flatten_iterator
: public boost::iterator_facade
<
flatten_iterator
<
OuterIterator,
InnerIterator,
Value,
AccessInnerBegin,
AccessInnerEnd>,
Value,
boost::forward_traversal_tag
>
{
private:
OuterIterator m_outer_it, m_outer_end;
InnerIterator m_inner_it;
struct enabler {};
public:
typedef OuterIterator outer_iterator_type;
typedef InnerIterator inner_iterator_type;
// default constructor
flatten_iterator() {}
// for begin
flatten_iterator(OuterIterator outer_it, OuterIterator outer_end)
: m_outer_it(outer_it), m_outer_end(outer_end)
{
advance_through_empty();
}
// for end
flatten_iterator(OuterIterator outer_end)
: m_outer_it(outer_end), m_outer_end(outer_end)
{}
template
<
typename OtherOuterIterator, typename OtherInnerIterator,
typename OtherValue,
typename OtherAccessInnerBegin, typename OtherAccessInnerEnd
>
flatten_iterator(flatten_iterator
<
OtherOuterIterator,
OtherInnerIterator,
OtherValue,
OtherAccessInnerBegin,
OtherAccessInnerEnd
> const& other,
typename boost::enable_if
<
boost::is_convertible<OtherValue*, Value*>,
enabler
>::type = enabler())
: m_outer_it(other.m_outer_it),
m_outer_end(other.m_outer_end),
m_inner_it(other.m_inner_it)
{}
template
<
typename OtherOuterIterator,
typename OtherInnerIterator,
typename OtherValue,
typename OtherAccessInnerBegin,
typename OtherAccessInnerEnd
>
flatten_iterator operator=(flatten_iterator
<
OtherOuterIterator,
OtherInnerIterator,
OtherValue,
OtherAccessInnerBegin,
OtherAccessInnerEnd
> const& other)
{
m_outer_it = other.m_outer_it;
m_outer_end = other.m_outer_end;
m_inner_it = other.m_inner_it;
return *this;
}
private:
friend class boost::iterator_core_access;
template
<
typename Outer,
typename Inner,
typename V,
typename InnerBegin,
typename InnerEnd
>
friend class flatten_iterator;
static inline bool empty(OuterIterator outer_it)
{
return
AccessInnerBegin::apply(*outer_it) == AccessInnerEnd::apply(*outer_it);
}
inline void advance_through_empty()
{
while ( m_outer_it != m_outer_end && empty(m_outer_it) )
{
++m_outer_it;
}
if ( m_outer_it != m_outer_end )
{
m_inner_it = AccessInnerBegin::apply(*m_outer_it);
}
}
Value& dereference() const
{
BOOST_ASSERT( m_outer_it != m_outer_end );
BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
return *m_inner_it;
}
template
<
typename OtherOuterIterator,
typename OtherInnerIterator,
typename OtherValue,
typename OtherAccessInnerBegin,
typename OtherAccessInnerEnd
>
inline bool equal(flatten_iterator
<
OtherOuterIterator,
OtherInnerIterator,
OtherValue,
OtherAccessInnerBegin,
OtherAccessInnerEnd
> const& other) const
{
if ( this->m_outer_it != other.m_outer_it )
{
return false;
}
if ( this->m_outer_it == m_outer_end )
{
return true;
}
return this->m_inner_it == other.m_inner_it;
}
inline void increment()
{
BOOST_ASSERT( m_outer_it != m_outer_end );
BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
++m_inner_it;
if ( m_inner_it == AccessInnerEnd::apply(*m_outer_it) )
{
++m_outer_it;
advance_through_empty();
}
}
};
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP

View File

@@ -0,0 +1,278 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP
#include <boost/utility/enable_if.hpp>
#include <boost/geometry/iterators/dispatch/point_iterator.hpp>
#include <boost/geometry/iterators/point_iterator_type.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// specializations for points_begin
template <typename Linestring>
struct points_begin<Linestring, linestring_tag>
{
static inline typename point_iterator_type<Linestring>::type
apply(Linestring& linestring)
{
return boost::begin(linestring);
}
};
template <typename Ring>
struct points_begin<Ring, ring_tag>
{
static inline typename point_iterator_type<Ring>::type
apply(Ring& ring)
{
return boost::begin(ring);
}
};
template <typename Polygon>
struct points_begin<Polygon, polygon_tag>
{
typedef typename point_iterator_type<Polygon>::type return_type;
static inline return_type apply(Polygon& polygon)
{
typedef typename return_type::second_iterator_type flatten_iterator;
return return_type
(boost::begin(geometry::exterior_ring(polygon)),
boost::end(geometry::exterior_ring(polygon)),
flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
boost::end(geometry::interior_rings(polygon))
)
);
}
};
template <typename MultiPoint>
struct points_begin<MultiPoint, multi_point_tag>
{
static inline typename point_iterator_type<MultiPoint>::type
apply(MultiPoint& multipoint)
{
return boost::begin(multipoint);
}
};
template <typename MultiLinestring>
struct points_begin<MultiLinestring, multi_linestring_tag>
{
static inline typename point_iterator_type<MultiLinestring>::type
apply(MultiLinestring& multilinestring)
{
return typename point_iterator_type
<
MultiLinestring
>::type(boost::begin(multilinestring), boost::end(multilinestring));
}
};
template <typename MultiPolygon>
struct points_begin<MultiPolygon, multi_polygon_tag>
{
static inline typename point_iterator_type<MultiPolygon>::type
apply(MultiPolygon& multipolygon)
{
return typename point_iterator_type
<
MultiPolygon
>::type(boost::begin(multipolygon), boost::end(multipolygon));
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// specializations for points_end
template <typename Linestring>
struct points_end<Linestring, linestring_tag>
{
static inline typename point_iterator_type<Linestring>::type
apply(Linestring& linestring)
{
return boost::end(linestring);
}
};
template <typename Ring>
struct points_end<Ring, ring_tag>
{
static inline typename point_iterator_type<Ring>::type
apply(Ring& ring)
{
return boost::end(ring);
}
};
template <typename Polygon>
struct points_end<Polygon, polygon_tag>
{
typedef typename point_iterator_type<Polygon>::type return_type;
static inline return_type apply(Polygon& polygon)
{
typedef typename return_type::second_iterator_type flatten_iterator;
return return_type
(boost::end(geometry::exterior_ring(polygon)),
flatten_iterator( boost::end(geometry::interior_rings(polygon)) )
);
}
};
template <typename MultiPoint>
struct points_end<MultiPoint, multi_point_tag>
{
static inline typename point_iterator_type<MultiPoint>::type
apply(MultiPoint& multipoint)
{
return boost::end(multipoint);
}
};
template <typename MultiLinestring>
struct points_end<MultiLinestring, multi_linestring_tag>
{
static inline typename point_iterator_type<MultiLinestring>::type
apply(MultiLinestring& multilinestring)
{
return typename point_iterator_type
<
MultiLinestring
>::type(boost::end(multilinestring));
}
};
template <typename MultiPolygon>
struct points_end<MultiPolygon, multi_polygon_tag>
{
static inline typename point_iterator_type<MultiPolygon>::type
apply(MultiPolygon& multipolygon)
{
return typename point_iterator_type
<
MultiPolygon
>::type(boost::end(multipolygon));
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
// MK:: need to add doc here
template <typename Geometry>
class point_iterator
: public dispatch::point_iterator_type<Geometry>::type
{
private:
typedef typename dispatch::point_iterator_type<Geometry>::type base;
base* base_ptr()
{
return this;
}
base const* base_ptr() const
{
return this;
}
template <typename G1, typename G2>
struct is_convertible
: boost::is_convertible
<
typename dispatch::point_iterator_type<G1>::type,
typename dispatch::point_iterator_type<G2>::type
>
{};
struct enabler {};
template <typename OtherGeometry> friend class point_iterator;
template <typename G> friend inline point_iterator<G> points_begin(G&);
template <typename G> friend inline point_iterator<G> points_end(G&);
point_iterator(base const& base_it) : base(base_it) {}
public:
point_iterator() {}
template <typename OtherGeometry>
point_iterator(point_iterator<OtherGeometry> const& other,
typename boost::enable_if
<
is_convertible<OtherGeometry, Geometry>,
enabler
>::type = enabler())
: base(*other.base_ptr())
{}
};
// MK:: need to add doc here
template <typename Geometry>
inline point_iterator<Geometry>
points_begin(Geometry& geometry)
{
return dispatch::points_begin<Geometry>::apply(geometry);
}
// MK:: need to add doc here
template <typename Geometry>
inline point_iterator<Geometry>
points_end(Geometry& geometry)
{
return dispatch::points_end<Geometry>::apply(geometry);
}
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP

View File

@@ -0,0 +1,203 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP
#define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP
#include <boost/geometry/iterators/dispatch/point_iterator_type.hpp>
#include <boost/geometry/iterators/dispatch/point_iterator.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/multi/core/tags.hpp>
#include <boost/geometry/iterators/flatten_iterator.hpp>
#include <boost/geometry/iterators/concatenate_iterator.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail_dispatch
{
template <typename Geometry>
struct point_iterator_value_type
{
typedef typename boost::mpl::if_c
<
!boost::is_const<Geometry>::type::value,
typename geometry::point_type<Geometry>::type,
typename geometry::point_type<Geometry>::type const
>::type type;
};
template
<
typename Geometry,
typename Tag = typename tag<Geometry>::type
>
struct point_iterator_inner_range_type
{
typedef typename boost::mpl::if_c
<
!boost::is_const<Geometry>::type::value,
typename boost::range_value<Geometry>::type,
typename boost::range_value<Geometry>::type const
>::type type;
};
template <typename Polygon>
struct point_iterator_inner_range_type<Polygon, polygon_tag>
{
typedef typename boost::mpl::if_c
<
!boost::is_const<Polygon>::type::value,
typename geometry::ring_type<Polygon>::type,
typename geometry::ring_type<Polygon>::type const
>::type type;
};
} // namespace detail_dispatch
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename Linestring>
struct point_iterator_type<Linestring, linestring_tag>
{
typedef typename boost::range_iterator<Linestring>::type type;
};
template <typename Ring>
struct point_iterator_type<Ring, ring_tag>
{
typedef typename boost::range_iterator<Ring>::type type;
};
template <typename Polygon>
class point_iterator_type<Polygon, polygon_tag>
{
private:
typedef typename detail_dispatch::point_iterator_inner_range_type
<
Polygon
>::type InnerRange;
public:
typedef concatenate_iterator
<
typename boost::range_iterator<InnerRange>::type,
flatten_iterator
<
typename boost::range_iterator
<
typename geometry::interior_type<Polygon>::type
>::type,
typename dispatch::point_iterator_type
<
InnerRange
>::type,
typename detail_dispatch::point_iterator_value_type
<
Polygon
>::type,
dispatch::points_begin<InnerRange>,
dispatch::points_end<InnerRange>
>,
typename detail_dispatch::point_iterator_value_type<Polygon>::type
> type;
};
template <typename MultiPoint>
struct point_iterator_type<MultiPoint, multi_point_tag>
{
typedef typename boost::range_iterator<MultiPoint>::type type;
};
template <typename MultiLinestring>
class point_iterator_type<MultiLinestring, multi_linestring_tag>
{
private:
typedef typename detail_dispatch::point_iterator_inner_range_type
<
MultiLinestring
>::type InnerRange;
public:
typedef flatten_iterator
<
typename boost::range_iterator<MultiLinestring>::type,
typename dispatch::point_iterator_type<InnerRange>::type,
typename detail_dispatch::point_iterator_value_type
<
MultiLinestring
>::type,
dispatch::points_begin<InnerRange>,
dispatch::points_end<InnerRange>
> type;
};
template <typename MultiPolygon>
class point_iterator_type<MultiPolygon, multi_polygon_tag>
{
private:
typedef typename detail_dispatch::point_iterator_inner_range_type
<
MultiPolygon
>::type InnerRange;
public:
typedef flatten_iterator
<
typename boost::range_iterator<MultiPolygon>::type,
typename dispatch::point_iterator_type<InnerRange>::type,
typename detail_dispatch::point_iterator_value_type
<
MultiPolygon
>::type,
dispatch::points_begin<InnerRange>,
dispatch::points_end<InnerRange>
> type;
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP

View File

@@ -22,14 +22,15 @@
//TEST
//#include <to_svg.hpp>
//#include <boost/geometry.hpp>
//#include <boost/geometry/multi/geometries/multi_linestring.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/multi/geometries/multi_linestring.hpp>
template <typename T>
void test_all()
{
typedef bg::model::point<T, 2, bg::cs::cartesian> pt;
typedef bg::model::linestring<pt> ls;
typedef bg::model::multi_linestring<ls> mls;
test_geometry<ls, ls>("LINESTRING(0 0,2 0)", "LINESTRING(0 0,2 0)", "tii", "txx");
test_geometry<ls, ls>("LINESTRING(0 0,2 0)", "LINESTRING(2 0,0 0)", "tix", "txi");
@@ -120,6 +121,14 @@ void test_all()
// to_svg<ls, ls>("LINESTRING(31 0,15 0,10 5,5 5,4 0,1 0,0 0,-1 1)", "LINESTRING(-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0)", "test33.svg");
// to_svg<ls, ls>("LINESTRING(31 0,15 0,10 5,5 5,4 0,1 0,0 0,-1 1)", "LINESTRING(30 0,3 0,2.5 1,2 0,1 0,0 0,-1 -1)", "test34.svg");
//}
test_geometry<mls, mls>("MULTILINESTRING((0 0,10 0,30 0))",
"MULTILINESTRING((0 10,5 0,20 0,20 0,30 0),(2 0,2 0),(3 0,3 0,3 0))",
expected("mii")("ccc")("ccc")("txx"));
test_geometry<ls, ls>("LINESTRING(2 2,5 -1,15 2,18 0,20 0)",
"LINESTRING(30 0,19 0,18 0,0 0)",
expected("iuu")("iuu")("tiu")("mxi"));
}
int test_main(int, char* [])

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
#
# Use, modification and distribution is subject to the Boost Software License,
# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,4 +17,7 @@ test-suite boost-geometry-iterators
:
[ run closing_iterator.cpp ]
[ run ever_circling_iterator.cpp ]
[ run point_iterator.cpp ]
[ run concatenate_iterator.cpp ]
[ run flatten_iterator.cpp ]
;

View File

@@ -0,0 +1,260 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_TEST_MODULE
#define BOOST_TEST_MODULE test_concatenate_iterator
#endif
#include <boost/test/included/unit_test.hpp>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <list>
#include <boost/assign/std/vector.hpp>
#include <boost/assign/std/list.hpp>
#include <boost/geometry/iterators/concatenate_iterator.hpp>
using namespace boost::assign;
template <typename Iterator>
std::ostream& print_container(std::ostream& os,
Iterator begin, Iterator end,
std::string const& header)
{
std::cout << header;
for (Iterator it = begin; it != end; ++it)
{
os << " " << *it;
}
return os;
}
template <typename T>
struct is_odd
{
inline bool operator()(T const& t) const
{
return t % 2 != 0;
}
};
struct test_concatenate_iterator
{
template <typename Container1, typename Container2>
static inline void apply(Container1& c1, Container2& c2,
std::string const& case_id)
{
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "case id: " << case_id << std::endl;
#endif
typedef typename Container1::const_iterator const_iterator1;
typedef typename Container2::const_iterator const_iterator2;
typedef typename Container1::iterator iterator1;
typedef typename Container2::iterator iterator2;
typedef boost::geometry::concatenate_iterator
<
const_iterator1, const_iterator2,
typename Container1::value_type const
> const_concat_iterator;
typedef boost::geometry::concatenate_iterator
<
iterator1, iterator2, typename Container1::value_type
> concat_iterator;
concat_iterator begin(c1.begin(), c1.end(), c2.begin());
concat_iterator end(c1.end(), c2.end());
const_concat_iterator const_begin(begin);
const_concat_iterator const_end(end);
const_begin = begin;
const_end = end;
std::size_t size(0);
for (const_concat_iterator it = const_begin; it != const_end; ++it)
{
++size;
}
BOOST_CHECK( c1.size() + c2.size() == size );
size = 0;
for (concat_iterator it = begin; it != end; ++it)
{
++size;
}
BOOST_CHECK( c1.size() + c2.size() == size );
#ifdef GEOMETRY_TEST_DEBUG
print_container(std::cout, c1.begin(), c1.end(), "first :")
<< std::endl;
print_container(std::cout, c2.begin(), c2.end(), "second :")
<< std::endl;
print_container(std::cout, begin, end, "combined:")
<< std::endl;
if ( begin != end )
{
std::cout << "min element: "
<< *std::min_element(begin, end)
<< std::endl;
std::cout << "max element: "
<< *std::max_element(const_begin, const_end)
<< std::endl;
}
#endif
{
const_iterator1 it1 = c1.begin();
const_iterator2 it2 = c2.begin();
for (const_concat_iterator it = const_begin; it != const_end; ++it)
{
if ( it1 != c1.end() )
{
BOOST_CHECK( *it == *it1 );
++it1;
}
else
{
BOOST_CHECK( *it == *it2 );
++it2;
}
}
}
typedef typename std::iterator_traits
<
concat_iterator
>::value_type value_type;
if ( c1.size() != 0 )
{
concat_iterator it_max = std::max_element(begin, end);
const_concat_iterator const_it_max =
std::max_element(const_begin, const_end);
BOOST_CHECK( it_max == const_it_max );
value_type old_value = *const_begin;
value_type new_value = *it_max + 1;
*begin = *it_max + 1;
BOOST_CHECK( *c1.begin() == new_value );
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl;
std::cout << "modified element of 1st container:" << std::endl;
print_container(std::cout, c1.begin(), c1.end(), "first :")
<< std::endl;
print_container(std::cout, begin, end, "combined:")
<< std::endl;
#endif
*begin = old_value;
BOOST_CHECK( *c1.begin() == old_value );
}
if ( c2.size() != 0 )
{
concat_iterator begin2 = begin;
std::size_t counter(0);
while ( counter != c1.size() )
{
++counter;
begin2++;
}
concat_iterator it_max = std::max_element(begin, end);
const_concat_iterator const_it_max =
std::max_element(const_begin, const_end);
BOOST_CHECK( it_max == const_it_max );
value_type old_value = *begin2;
value_type new_value = *it_max + 1;
*begin2 = *it_max + 1;
BOOST_CHECK( *c2.begin() == new_value );
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl;
std::cout << "modified element of 2nd container:" << std::endl;
print_container(std::cout, c2.begin(), c2.end(), "second :")
<< std::endl;
print_container(std::cout, begin, end, "combined:")
<< std::endl;
#endif
*begin2 = old_value;
BOOST_CHECK( *c2.begin() == old_value );
}
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl;
std::cout << "odd elements removed:" << std::endl;
print_container(std::cout, begin, end, "before:")
<< std::endl;
#endif
concat_iterator new_end =
std::remove_if(begin, end, is_odd<value_type>());
for (const_concat_iterator it = const_begin; it != new_end; ++it)
{
BOOST_CHECK( !is_odd<value_type>()(*it) );
}
#ifdef GEOMETRY_TEST_DEBUG
print_container(std::cout, begin, new_end, "after :")
<< std::endl;
#endif
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "====================" << std::endl << std::endl;
#endif
}
};
BOOST_AUTO_TEST_CASE( test_concatenate_iterator_all )
{
{
std::vector<int> v;
std::list<int> l;
test_concatenate_iterator::apply(v, l, "empty_both");
}
{
std::vector<int> v;
std::list<int> l;
l += 10,11,12,13,14,15,16,17,18,19,20;
test_concatenate_iterator::apply(v, l, "empty_first");
}
{
std::vector<int> v;
v += 0,1,2,3,4,5,6;
std::list<int> l;
test_concatenate_iterator::apply(v, l, "empty_second");
}
{
std::vector<int> v;
v += 0,1,2,3,4,5,6;
std::list<int> l;
l += 10,11,12,13,14,15,16,17,18,19,20;
test_concatenate_iterator::apply(l, v, "non_empty");
}
}

View File

@@ -0,0 +1,430 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_TEST_MODULE
#define BOOST_TEST_MODULE test_flatten_iterator
#endif
#include <boost/test/included/unit_test.hpp>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <list>
#include <boost/mpl/if.hpp>
#include <boost/assign/std/vector.hpp>
#include <boost/assign/std/list.hpp>
#include <boost/assign/std/set.hpp>
#include <boost/geometry/iterators/flatten_iterator.hpp>
using namespace boost::assign;
template <typename Iterator>
std::ostream& print_container(std::ostream& os,
Iterator begin, Iterator end,
std::string const& header)
{
std::cout << header;
for (Iterator it = begin; it != end; ++it)
{
os << " " << *it;
}
return os;
}
template <typename Iterator>
std::ostream& print_nested_container(std::ostream& os,
Iterator begin, Iterator end,
std::string const& header)
{
std::cout << header;
for (Iterator outer = begin; outer != end; ++outer)
{
os << " (";
for (BOOST_AUTO_TPL(inner, outer->begin());
inner != outer->end(); ++inner)
{
if ( inner != outer->begin() )
{
os << " ";
}
os << *inner;
}
os << ") ";
}
return os;
}
template <typename T>
struct is_odd
{
inline bool operator()(T const& t) const
{
return t % 2 != 0;
}
};
template <typename T>
struct is_even
{
inline bool operator()(T const& t) const
{
return !is_odd<T>()(t);
}
};
template <typename InnerContainer>
struct access_begin
{
typedef typename boost::mpl::if_
<
typename boost::is_const<InnerContainer>::type,
typename InnerContainer::const_iterator,
typename InnerContainer::iterator
>::type return_type;
static inline return_type apply(InnerContainer& inner)
{
return inner.begin();
}
};
template <typename InnerContainer>
struct access_end
{
typedef typename boost::mpl::if_
<
typename boost::is_const<InnerContainer>::type,
typename InnerContainer::const_iterator,
typename InnerContainer::iterator
>::type return_type;
static inline return_type apply(InnerContainer& inner)
{
return inner.end();
}
};
template <typename NestedContainer>
std::size_t number_of_elements(NestedContainer const& c)
{
std::size_t num_elements(0);
for (typename NestedContainer::const_iterator outer = c.begin();
outer != c.end(); ++outer)
{
num_elements += outer->size();
}
return num_elements;
}
struct test_flatten_iterator
{
template <typename NestedContainer>
static inline void apply(NestedContainer& c,
std::string const& case_id,
std::string const& container_id)
{
#ifdef GEOMETRY_TEST_DEBUG
std::stringstream sstream;
sstream << case_id << " " << "[" << container_id << "]";
std::cout << "case id: " << sstream.str() << std::endl;
#endif
typedef typename NestedContainer::const_iterator const_outer_iterator;
typedef typename NestedContainer::iterator outer_iterator;
typedef typename NestedContainer::value_type inner_container;
typedef typename inner_container::const_iterator const_inner_iterator;
typedef typename inner_container::iterator inner_iterator;
typedef boost::geometry::flatten_iterator
<
const_outer_iterator,
const_inner_iterator,
typename inner_container::value_type const,
access_begin<inner_container const>,
access_end<inner_container const>
> const_flatten_iterator;
typedef boost::geometry::flatten_iterator
<
outer_iterator,
inner_iterator,
typename inner_container::value_type,
access_begin<inner_container>,
access_end<inner_container>
> flatten_iterator;
flatten_iterator begin(c.begin(), c.end());
flatten_iterator end(c.end());
const_flatten_iterator const_begin(begin);
const_flatten_iterator const_end(end);
const_begin = begin;
const_end = end;
std::size_t size(0);
for (const_flatten_iterator it = const_begin; it != const_end; ++it)
{
++size;
}
BOOST_CHECK( number_of_elements(c) == size );
size = 0;
for (flatten_iterator it = begin; it != end; ++it)
{
++size;
}
BOOST_CHECK( number_of_elements(c) == size );
#ifdef GEOMETRY_TEST_DEBUG
print_nested_container(std::cout, c.begin(), c.end(), "nested :")
<< std::endl;
print_container(std::cout, begin, end, "flattened :")
<< std::endl;
if ( begin != end )
{
std::cout << "min element: "
<< *std::min_element(begin, end)
<< std::endl;
std::cout << "max element: "
<< *std::max_element(const_begin, const_end)
<< std::endl;
}
#endif
{
const_flatten_iterator it = begin;
const_outer_iterator outer_begin = c.begin();
const_outer_iterator outer_end = c.end();
for (const_outer_iterator outer = outer_begin;
outer != outer_end; ++outer)
{
const_inner_iterator inner_begin = outer->begin();
const_inner_iterator inner_end = outer->end();
for (const_inner_iterator inner = inner_begin;
inner != inner_end; ++inner, it++)
// it++, instead of ++it, on purpose here
{
BOOST_CHECK( *it == *inner );
}
}
}
typedef typename std::iterator_traits
<
flatten_iterator
>::value_type value_type;
if ( begin != end )
{
flatten_iterator it_max = std::max_element(begin, end);
const_flatten_iterator const_it_max =
std::max_element(const_begin, const_end);
BOOST_CHECK( it_max == const_it_max );
BOOST_CHECK( *it_max == *const_it_max );
value_type old_value = *const_begin;
value_type new_value = *it_max + 1;
*begin = *it_max + 1;
const_outer_iterator outer = c.begin();
while ( outer->begin() == outer->end() )
{
++outer;
}
const_inner_iterator inner = outer->begin();
BOOST_CHECK( *inner == new_value );
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl;
std::cout << "modified 1st element of 1st non-empty "
<< "inner container:" << std::endl;
print_nested_container(std::cout, c.begin(), c.end(), "nested :")
<< std::endl;
print_container(std::cout, begin, end, "flattened:")
<< std::endl;
#endif
*begin = old_value;
BOOST_CHECK( *inner == old_value );
}
if ( begin != end )
{
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl;
std::cout << "odd elements removed:" << std::endl;
print_nested_container(std::cout, c.begin(), c.end(),
"nested before:")
<< std::endl;
print_container(std::cout, begin, end,
"flattended before:")
<< std::endl;
#endif
typename std::iterator_traits<flatten_iterator>::difference_type
num_even = std::count_if(begin, end, is_even<int>());
flatten_iterator new_end =
std::remove_if(begin, end, is_odd<value_type>());
std::size_t new_size(0);
for (const_flatten_iterator it = const_begin; it != new_end; ++it)
{
++new_size;
BOOST_CHECK( !is_odd<value_type>()(*it) );
}
BOOST_CHECK( new_size == static_cast<std::size_t>(num_even) );
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl;
print_nested_container(std::cout, c.begin(), c.end(),
"nested after (all elements) :")
<< std::endl;
print_container(std::cout, begin, new_end, "flattened after :")
<< std::endl;
#endif
}
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "====================" << std::endl << std::endl;
#endif
}
};
// the actual test cases -- START
template <int CaseNumber>
struct test_case_per_container;
template<>
struct test_case_per_container<0>
{
template <typename NestedContainer>
static inline void apply(std::string const& case_id,
std::string const& container_id)
{
NestedContainer c;
test_flatten_iterator::apply(c, case_id, container_id);
}
};
template<>
struct test_case_per_container<1>
{
template <typename NestedContainer>
static inline void apply(std::string const& case_id,
std::string const& container_id)
{
NestedContainer c;
for (int i = 0; i < 5; ++i)
{
c += typename NestedContainer::value_type();
}
test_flatten_iterator::apply(c, case_id, container_id);
}
};
template<>
struct test_case_per_container<2>
{
template <typename NestedContainer>
static inline void apply(std::string const& case_id,
std::string const& container_id)
{
NestedContainer c;
typename NestedContainer::value_type ic[4];
ic[0] += 5,4,3,2,1;
ic[1] += 6,7,8;
ic[2] += 9;
ic[3] += 9,8,7,6,5;
c += ic[0],ic[1],ic[2],ic[3];
test_flatten_iterator::apply(c, case_id, container_id);
}
};
template<>
struct test_case_per_container<3>
{
template <typename NestedContainer>
static inline void apply(std::string const& case_id,
std::string const& container_id)
{
NestedContainer c;
typename NestedContainer::value_type ic[20];
ic[2] += 5,4,3,2,1;
ic[3] += 6,7,8;
ic[8] += 9;
ic[9] += 9,8,7,6,5;
ic[14] += 4,3,2,1;
for (std::size_t i = 0; i < 20; ++i)
{
c += ic[i];
}
test_flatten_iterator::apply(c, case_id, container_id);
}
};
// the actual test cases -- END
template <int CaseNumber>
inline void test_case_all_containers(std::string const& case_id)
{
typedef typename std::vector<std::vector<int> > VV;
typedef typename std::vector<std::list<int> > VL;
typedef typename std::list<std::vector<int> > LV;
typedef typename std::list<std::list<int> > LL;
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl;
#endif
test_case_per_container<CaseNumber>::template apply<VV>(case_id, "VV");
test_case_per_container<CaseNumber>::template apply<VL>(case_id, "VL");
test_case_per_container<CaseNumber>::template apply<LV>(case_id, "LV");
test_case_per_container<CaseNumber>::template apply<LL>(case_id, "LL");
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl;
std::cout << "********************************************************"
<< std::endl << std::endl;
#endif
}
BOOST_AUTO_TEST_CASE( test_flatten_iterator_all )
{
test_case_all_containers<0>("empty");
test_case_all_containers<1>("case1");
test_case_all_containers<2>("case2");
test_case_all_containers<3>("case3");
}

View File

@@ -0,0 +1,468 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#include <iostream>
#ifndef BOOST_TEST_MODULE
#define BOOST_TEST_MODULE test_point_iterator
#endif
#include <boost/test/included/unit_test.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
#include <boost/geometry/multi/geometries/multi_geometries.hpp>
#include <boost/geometry/multi/geometries/register/multi_point.hpp>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/io/wkt/read.hpp>
#include <boost/geometry/io/wkt/write.hpp>
#include <boost/geometry/io/dsv/write.hpp>
#include <boost/geometry/multi/io/dsv/write.hpp>
#include <boost/geometry/multi/io/wkt/write.hpp>
#include <boost/geometry/multi/io/wkt/read.hpp>
#include <boost/geometry/iterators/point_iterator.hpp>
namespace bg = ::boost::geometry;
namespace ba = ::boost::assign;
typedef bg::model::point<double, 2, bg::cs::cartesian> point_type;
typedef bg::model::point<double, 3, bg::cs::cartesian> point_type_3d;
typedef bg::model::linestring<point_type> linestring_type;
typedef bg::model::polygon<point_type, false, false> polygon_type; //ccw, open
// multi geometries
typedef bg::model::multi_point<point_type> multi_point_type;
typedef bg::model::multi_point<point_type_3d> multi_point_type_3d;
typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
typedef boost::tuple<double, double> tuple_point_type;
typedef boost::tuple<double, double, double> tuple_point_type_3d;
typedef std::vector<tuple_point_type> tuple_multi_point_type;
typedef std::vector<tuple_point_type_3d> tuple_multi_point_type_3d;
BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
BOOST_GEOMETRY_REGISTER_MULTI_POINT(tuple_multi_point_type)
BOOST_GEOMETRY_REGISTER_MULTI_POINT(tuple_multi_point_type_3d)
template <typename Geometry>
Geometry from_wkt(std::string const& wkt)
{
Geometry geometry;
boost::geometry::read_wkt(wkt, geometry);
return geometry;
}
struct equals
{
template <typename Iterator>
static inline std::size_t number_of_elements(Iterator begin,
Iterator end)
{
std::size_t num_elems(0);
for (Iterator it = begin; it != end; ++it)
{
++num_elems;
}
return num_elems;
}
template <typename Iterator1, typename Iterator2>
static inline bool apply(Iterator1 begin1, Iterator1 end1,
Iterator2 begin2, Iterator2 end2)
{
std::size_t num_points1 = number_of_elements(begin1, end1);
std::size_t num_points2 = number_of_elements(begin2, end2);
if ( num_points1 != num_points2 )
{
return false;
}
Iterator1 it1 = begin1;
Iterator2 it2 = begin2;
for (; it1 != end1; ++it1, ++it2)
{
if ( !bg::equals(*it1, *it2) )
{
return false;
}
}
return true;
}
};
struct test_assignment
{
template <typename Iterator, typename ConstIterator, typename Value>
static inline void apply(Iterator it, ConstIterator cit,
Value const& value1, Value const& value2)
{
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "== before assignment ==" << std::endl;
std::cout << "value1: " << bg::wkt(value1) << std::endl;
std::cout << "value2: " << bg::wkt(value2) << std::endl;
std::cout << "*it : " << bg::wkt(*it) << std::endl;
std::cout << "*cit : " << bg::wkt(*cit) << std::endl;
#endif
BOOST_CHECK( bg::equals(*it, value1) );
BOOST_CHECK( !bg::equals(*it, value2) );
BOOST_CHECK( bg::equals(*cit, value1) );
BOOST_CHECK( !bg::equals(*cit, value2) );
*it = value2;
BOOST_CHECK( bg::equals(*it, value2) );
BOOST_CHECK( !bg::equals(*it, value1) );
BOOST_CHECK( bg::equals(*cit, value2) );
BOOST_CHECK( !bg::equals(*cit, value1) );
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "== after 1st assignment ==" << std::endl;
std::cout << "value1: " << bg::wkt(value1) << std::endl;
std::cout << "value2: " << bg::wkt(value2) << std::endl;
std::cout << "*it : " << bg::wkt(*it) << std::endl;
std::cout << "*cit : " << bg::wkt(*cit) << std::endl;
#endif
*it = value1;
BOOST_CHECK( bg::equals(*it, value1) );
BOOST_CHECK( !bg::equals(*it, value2) );
BOOST_CHECK( bg::equals(*cit, value1) );
BOOST_CHECK( !bg::equals(*cit, value2) );
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "== after 2nd assignment ==" << std::endl;
std::cout << "value1: " << bg::wkt(value1) << std::endl;
std::cout << "value2: " << bg::wkt(value2) << std::endl;
std::cout << "*it : " << bg::wkt(*it) << std::endl;
std::cout << "*cit : " << bg::wkt(*cit) << std::endl;
std::cout << std::endl;
#endif
}
};
template <typename Geometry, typename PointRange>
struct test_point_iterator_of_geometry
{
template <typename G>
static inline void base_test(G& geometry,
PointRange const& point_range,
std::string const& header)
{
typedef bg::point_iterator<G> point_iterator;
typedef bg::point_iterator<G const> const_point_iterator;
point_iterator begin = bg::points_begin(geometry);
point_iterator end = bg::points_end(geometry);
BOOST_CHECK( equals::apply(begin, end,
bg::points_begin(point_range),
bg::points_end(point_range))
);
#ifdef GEOMETRY_TEST_DEBUG
std::cout << header << " geometry: " << bg::wkt(geometry) << std::endl;
std::cout << "point range: (";
for (point_iterator pit = begin; pit != end; ++pit)
{
std::cout << " " << bg::dsv(*pit);
}
std::cout << " )" << std::endl;
typedef bg::point_iterator<PointRange const> point_range_iterator;
point_range_iterator rng_begin = bg::points_begin(point_range);
point_range_iterator rng_end = bg::points_end(point_range);
std::cout << "expected point range: (";
for (point_range_iterator pit = rng_begin; pit != rng_end; ++pit)
{
std::cout << " " << bg::dsv(*pit);
}
std::cout << " )" << std::endl;
#endif
}
static inline void apply(Geometry geometry, PointRange const& point_range)
{
base_test<Geometry>(geometry, point_range, "non-const");
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl;
#endif
base_test<Geometry const>(geometry, point_range, "const");
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl;
#endif
// testing construction of const and non-const iterator
typedef bg::point_iterator<Geometry> point_iterator;
typedef bg::point_iterator<Geometry const> const_point_iterator;
point_iterator begin = bg::points_begin(geometry);
point_iterator end = bg::points_end(geometry);
const_point_iterator const_begin = bg::points_begin(geometry);
const_point_iterator const_end = bg::points_end(geometry);
// testing assignment of non-const to const iterator
const_begin = begin;
const_end = end;
// testing dereferencing/assignment
if ( begin != end )
{
typedef typename bg::point_type<Geometry>::type point;
point p = *begin;
point q = bg::make_zero<point>();
test_assignment::apply(begin, const_begin, p, q);
*begin = q;
test_assignment::apply(begin, const_begin, q, p);
*begin = p;
}
}
};
//======================================================================
//======================================================================
BOOST_AUTO_TEST_CASE( test_linestring_point_iterator )
{
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "*** LINESTRING ***" << std::endl;
#endif
typedef tuple_multi_point_type TMP;
typedef linestring_type L;
typedef test_point_iterator_of_geometry<L, TMP> tester;
tester::apply(from_wkt<L>("LINESTRING()"),
TMP()
);
tester::apply(from_wkt<L>("LINESTRING(3 3,4 4,5 5)"),
ba::tuple_list_of(3,3)(4,4)(5,5)
);
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl << std::endl;
#endif
}
//======================================================================
//======================================================================
BOOST_AUTO_TEST_CASE( test_polygon_point_iterator )
{
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "*** POLYGON ***" << std::endl;
#endif
typedef tuple_multi_point_type TMP;
typedef polygon_type P;
typedef test_point_iterator_of_geometry<P, TMP> tester;
tester::apply(from_wkt<P>("POLYGON()"),
TMP()
);
tester::apply(from_wkt<P>("POLYGON(())"),
TMP()
);
tester::apply(from_wkt<P>("POLYGON((1 1,9 1,9 9,1 9),(5 5,6 5,6 6,5 6))"),
ba::tuple_list_of(1,1)(9,1)(9,9)(1,9)(5,5)(6,5)(6,6)(5,6)
);
tester::apply(from_wkt<P>("POLYGON((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),())"),
ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)
);
tester::apply(from_wkt<P>("POLYGON((),(3 3,4 4,5 5),(),(),(6 6,7 7,8 8),(),(),(9 9),())"),
ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)
);
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl;
#endif
}
//======================================================================
//======================================================================
BOOST_AUTO_TEST_CASE( test_multipoint_point_iterator )
{
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "*** MULTIPOINT ***" << std::endl;
#endif
typedef tuple_multi_point_type TMP;
typedef multi_point_type MP;
typedef test_point_iterator_of_geometry<MP, TMP> tester;
tester::apply(from_wkt<MP>("MULTIPOINT()"),
TMP()
);
tester::apply(from_wkt<MP>("MULTIPOINT(3 3,4 4,5 5)"),
ba::tuple_list_of(3,3)(4,4)(5,5)
);
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl << std::endl;
#endif
}
//======================================================================
//======================================================================
BOOST_AUTO_TEST_CASE( test_multipoint_3d_point_iterator )
{
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "*** MULTIPOINT 3D ***" << std::endl;
#endif
typedef tuple_multi_point_type_3d TMP;
typedef multi_point_type_3d MP;
typedef test_point_iterator_of_geometry<MP, TMP> tester;
tester::apply(from_wkt<MP>("MULTIPOINT()"),
TMP()
);
tester::apply(from_wkt<MP>("MULTIPOINT(3 3 3,4 4 4,5 5 5)"),
ba::tuple_list_of(3,3,3)(4,4,4)(5,5,5)
);
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl << std::endl;
#endif
}
//======================================================================
//======================================================================
BOOST_AUTO_TEST_CASE( test_multilinestring_point_iterator )
{
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "*** MULTILINESTRING ***" << std::endl;
#endif
typedef tuple_multi_point_type TMP;
typedef multi_linestring_type ML;
typedef test_point_iterator_of_geometry<ML, TMP> tester;
tester::apply(from_wkt<ML>("MULTILINESTRING()"),
TMP()
);
tester::apply(from_wkt<ML>("MULTILINESTRING(())"),
TMP()
);
tester::apply(from_wkt<ML>("MULTILINESTRING((),(),())"),
TMP()
);
tester::apply(from_wkt<ML>("MULTILINESTRING((1 1,2 2,3 3),(3 3,4 4,5 5),(6 6))"),
ba::tuple_list_of(1,1)(2,2)(3,3)(3,3)(4,4)(5,5)(6,6)
);
tester::apply(from_wkt<ML>("MULTILINESTRING((),(),(1 1,2 2,3 3),(),(),(3 3,4 4,5 5),(),(6 6),(),(),())"),
ba::tuple_list_of(1,1)(2,2)(3,3)(3,3)(4,4)(5,5)(6,6)
);
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl;
#endif
}
//======================================================================
//======================================================================
BOOST_AUTO_TEST_CASE( test_multipolygon_point_iterator )
{
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "*** MULTIPOLYGON ***" << std::endl;
#endif
typedef tuple_multi_point_type TMP;
typedef multi_polygon_type MPL;
typedef test_point_iterator_of_geometry<MPL, TMP> tester;
tester::apply(from_wkt<MPL>("MULTIPOLYGON()"),
TMP()
);
tester::apply(from_wkt<MPL>("MULTIPOLYGON( () )"),
TMP()
);
tester::apply(from_wkt<MPL>("MULTIPOLYGON( (()) )"),
TMP()
);
tester::apply(from_wkt<MPL>("MULTIPOLYGON( ((),()) )"),
TMP()
);
tester::apply(from_wkt<MPL>("MULTIPOLYGON(((3 3,4 4,5 5),(6 6,7 7,8 8),(9 9)),((1 1,2 2,10 10),(11 11,12 12)))"),
ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\
(1,1)(2,2)(10,10)(11,11)(12,12)
);
tester::apply(from_wkt<MPL>("MULTIPOLYGON(((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),()),((),(1 1,2 2,10 10),(),(),(),(11 11,12 12),(),(),(13 13),()))"),
ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\
(1,1)(2,2)(10,10)(11,11)(12,12)(13,13)
);
tester::apply(from_wkt<MPL>("MULTIPOLYGON(((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),()),((),(1 1,2 2,10 10),(),(),(),(11 11,12 12),(),(),(13 13),()),((),(),()))"),
ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\
(1,1)(2,2)(10,10)(11,11)(12,12)(13,13)
);
#ifdef GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl;
#endif
}