mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-12 12:12:10 +00:00
Merge branch 'rescale_to_integer' of github.com:boostorg/geometry into rescale_to_integer
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
109
include/boost/geometry/iterators/concatenate_iterator.hpp
Normal file
109
include/boost/geometry/iterators/concatenate_iterator.hpp
Normal 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
|
||||
47
include/boost/geometry/iterators/dispatch/point_iterator.hpp
Normal file
47
include/boost/geometry/iterators/dispatch/point_iterator.hpp
Normal 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
|
||||
@@ -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
|
||||
208
include/boost/geometry/iterators/flatten_iterator.hpp
Normal file
208
include/boost/geometry/iterators/flatten_iterator.hpp
Normal 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
|
||||
278
include/boost/geometry/iterators/point_iterator.hpp
Normal file
278
include/boost/geometry/iterators/point_iterator.hpp
Normal 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
|
||||
203
include/boost/geometry/iterators/point_iterator_type.hpp
Normal file
203
include/boost/geometry/iterators/point_iterator_type.hpp
Normal 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
|
||||
@@ -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* [])
|
||||
|
||||
@@ -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 ]
|
||||
;
|
||||
|
||||
260
test/iterators/concatenate_iterator.cpp
Normal file
260
test/iterators/concatenate_iterator.cpp
Normal 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");
|
||||
}
|
||||
}
|
||||
430
test/iterators/flatten_iterator.cpp
Normal file
430
test/iterators/flatten_iterator.cpp
Normal 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");
|
||||
}
|
||||
468
test/iterators/point_iterator.cpp
Normal file
468
test/iterators/point_iterator.cpp
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user