[feature/point iterator] implementation of point iterator for most geometries (not yet for point, segment & box);

This commit is contained in:
Menelaos Karavelas
2014-03-26 10:22:31 +02:00
parent 830a073c0d
commit 7abe47876b
7 changed files with 1183 additions and 0 deletions

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_CORE_DISPATCH_POINT_ITERATOR_HPP
#define BOOST_GEOMETRY_CORE_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 core_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_CORE_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_CORE_DISPATCH_POINT_ITERATOR_TYPE_HPP
#define BOOST_GEOMETRY_CORE_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 core_dispatch
{
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct point_iterator_type
: not_implemented<Geometry>
{};
} // namespace core_dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_TYPE_HPP

View File

@@ -0,0 +1,242 @@
// 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_CORE_POINT_ITERATOR_HPP
#define BOOST_GEOMETRY_CORE_POINT_ITERATOR_HPP
#include <boost/geometry/core/dispatch/point_iterator.hpp>
#include <boost/geometry/core/point_iterator_type.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace core_dispatch
{
// specializations for points_begin
// linestring
template <typename Linestring>
struct points_begin<Linestring, linestring_tag>
{
static inline typename point_iterator_type<Linestring>::type
apply(Linestring& linestring)
{
return boost::begin(linestring);
}
};
// ring
template <typename Ring>
struct points_begin<Ring, ring_tag>
{
static inline typename point_iterator_type<Ring>::type
apply(Ring& ring)
{
return boost::begin(ring);
}
};
// polygon
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))
)
);
}
};
// multi-point
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);
}
};
// multi-linestring
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));
}
};
// multi-polygon
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 core_dispatch
#endif // DOXYGEN_NO_DISPATCH
#ifndef DOXYGEN_NO_DISPATCH
namespace core_dispatch
{
// specializations for points_end
// linestring
template <typename Linestring>
struct points_end<Linestring, linestring_tag>
{
static inline typename point_iterator_type<Linestring>::type
apply(Linestring& linestring)
{
return boost::end(linestring);
}
};
// ring
template <typename Ring>
struct points_end<Ring, ring_tag>
{
static inline typename point_iterator_type<Ring>::type
apply(Ring& ring)
{
return boost::end(ring);
}
};
// polygon
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)) )
);
}
};
// multi-point
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);
}
};
// multi-linestring
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));
}
};
// multi-polygon
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 core_dispatch
#endif // DOXYGEN_NO_DISPATCH
// MK:: need to add doc here
template <typename Geometry>
typename point_iterator_type<Geometry>::type
points_begin(Geometry& geometry)
{
return core_dispatch::points_begin<Geometry>::apply(geometry);
}
// MK:: need to add doc here
template <typename Geometry>
typename point_iterator_type<Geometry>::type
points_end(Geometry& geometry)
{
return core_dispatch::points_end<Geometry>::apply(geometry);
}
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_CORE_POINT_ITERATOR_HPP

View File

@@ -0,0 +1,216 @@
// 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_CORE_POINT_ITERATOR_TYPE_HPP
#define BOOST_GEOMETRY_CORE_POINT_ITERATOR_TYPE_HPP
#include <boost/geometry/core/dispatch/point_iterator_type.hpp>
#include <boost/geometry/core/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/util/flatten_iterator.hpp>
#include <boost/geometry/util/concatenate_iterator.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace core_detail
{
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 core_detail
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace core_dispatch
{
// linestring
template <typename Linestring>
struct point_iterator_type<Linestring, linestring_tag>
{
typedef typename boost::range_iterator<Linestring>::type type;
};
// ring
template <typename Ring>
struct point_iterator_type<Ring, ring_tag>
{
typedef typename boost::range_iterator<Ring>::type type;
};
// polygon
template <typename Polygon>
class point_iterator_type<Polygon, polygon_tag>
{
private:
typedef typename core_detail::point_iterator_inner_range_type
<
Polygon
>::type InnerRange;
public:
typedef util::concatenate_iterator
<
typename boost::range_iterator<InnerRange>::type,
util::flatten_iterator
<
typename boost::range_iterator
<
typename geometry::interior_type<Polygon>::type
>::type,
typename core_dispatch::point_iterator_type
<
InnerRange
>::type,
typename core_detail::point_iterator_value_type
<
Polygon
>::type,
core_dispatch::points_begin<InnerRange>,
core_dispatch::points_end<InnerRange>
>,
typename core_detail::point_iterator_value_type<Polygon>::type
> type;
};
// multi-point
template <typename MultiPoint>
struct point_iterator_type<MultiPoint, multi_point_tag>
{
typedef typename boost::range_iterator<MultiPoint>::type type;
};
// multi-linestring
template <typename MultiLinestring>
class point_iterator_type<MultiLinestring, multi_linestring_tag>
{
private:
typedef typename core_detail::point_iterator_inner_range_type
<
MultiLinestring
>::type InnerRange;
public:
typedef util::flatten_iterator
<
typename boost::range_iterator<MultiLinestring>::type,
typename core_dispatch::point_iterator_type<InnerRange>::type,
typename core_detail::point_iterator_value_type
<
MultiLinestring
>::type,
core_dispatch::points_begin<InnerRange>,
core_dispatch::points_end<InnerRange>
> type;
};
// multi-polygon
template <typename MultiPolygon>
class point_iterator_type<MultiPolygon, multi_polygon_tag>
{
private:
typedef typename core_detail::point_iterator_inner_range_type
<
MultiPolygon
>::type InnerRange;
public:
typedef util::flatten_iterator
<
typename boost::range_iterator<MultiPolygon>::type,
typename core_dispatch::point_iterator_type<InnerRange>::type,
typename core_detail::point_iterator_value_type<MultiPolygon>::type,
core_dispatch::points_begin<InnerRange>,
core_dispatch::points_end<InnerRange>
> type;
};
} // namespace core_dispatch
#endif // DOXYGEN_NO_DISPATCH
// MK::need to add doc here
template <typename Geometry>
struct point_iterator_type
{
typedef typename core_dispatch::point_iterator_type<Geometry>::type type;
};
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_CORE_POINT_ITERATOR_TYPE_HPP

View File

@@ -0,0 +1,91 @@
// 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_UTIL_POINT_CONCATENATE_ITERATOR_HPP
#define BOOST_GEOMETRY_UTIL_POINT_CONCATENATE_ITERATOR_HPP
#include <boost/iterator/iterator_facade.hpp>
namespace boost { namespace geometry
{
namespace util
{
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;
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)
{}
private:
friend class boost::iterator_core_access;
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 util
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_UTIL_CONCATENATE_ITERATOR_HPP

View File

@@ -0,0 +1,219 @@
// 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_UTIL_FLATTEN_ITERATOR_HPP
#define BOOST_GEOMETRY_UTIL_FLATTEN_ITERATOR_HPP
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/iterator/iterator_facade.hpp>
namespace boost { namespace geometry
{
namespace util
{
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)
{
if ( m_outer_it != m_outer_end )
{
m_inner_it = AccessInnerBegin::apply(*m_outer_it);
// m_inner_it = AccessInnerBegin(*m_outer_it);
}
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
>
explicit flatten_iterator(flatten_iterator
<
OtherOuterIterator,
OtherInnerIterator,
OtherValue,
AccessInnerBegin,
AccessInnerEnd
> const& other,
typename boost::enable_if
<
boost::is_convertible
<
OtherOuterIterator*, OuterIterator*
>, 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
>
flatten_iterator operator=(flatten_iterator
<
OtherOuterIterator,
OtherInnerIterator,
OtherValue,
AccessInnerBegin,
AccessInnerEnd
> 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 OuterIterator1,
typename InnerIterator1,
typename Value1,
typename AccessInnerBegin1,
typename AccessInnerEnd1
>
friend class flatten_iterator;
static inline bool empty(OuterIterator outer_it)
{
return
AccessInnerBegin::apply(*outer_it) == AccessInnerEnd::apply(*outer_it);
// AccessInnerBegin(*outer_it) == AccessInnerEnd(*outer_it);
}
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);
// m_inner_it = AccessInnerBegin(*m_outer_it);
}
}
Value& dereference() const
{
BOOST_ASSERT( m_outer_it != m_outer_end );
BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
// BOOST_ASSERT( m_inner_it != AccessInnerEnd(*m_outer_it) );
return *m_inner_it;
}
template
<
typename OtherOuterIterator,
typename OtherInnerIterator,
typename OtherValue
>
bool equal(flatten_iterator
<
OtherOuterIterator,
OtherInnerIterator,
OtherValue,
AccessInnerBegin,
AccessInnerEnd
> 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;
}
void increment()
{
BOOST_ASSERT( m_outer_it != m_outer_end );
BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
// BOOST_ASSERT( m_inner_it != AccessInnerEnd(*m_outer_it) );
++m_inner_it;
if ( m_inner_it == AccessInnerEnd::apply(*m_outer_it) )
//if ( m_inner_it == AccessInnerEnd(*m_outer_it) )
{
++m_outer_it;
advance_through_empty();
}
}
};
} // namespace util
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_UTIL_FLATTEN_INTERATOR_HPP

View File

@@ -0,0 +1,331 @@
// 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/geometry/geometries/geometries.hpp>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/multi/geometries/multi_geometries.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 "../algorithms/from_wkt.hpp"
#include <boost/geometry/core/point_iterator.hpp>
namespace bg = ::boost::geometry;
typedef bg::model::point<double, 2, bg::cs::cartesian> point_type;
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_linestring<linestring_type> multi_linestring_type;
typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
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;
}
};
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 typename bg::point_iterator_type
<
G
>::type point_iterator_type;
point_iterator_type begin = bg::points_begin(geometry);
point_iterator_type end = bg::points_end(geometry);
BOOST_CHECK( equals::apply(begin, end,
boost::begin(point_range),
boost::end(point_range))
);
#ifdef GEOMETRY_TEST_DEBUG
std::cout << header << " geometry: " << bg::wkt(geometry) << std::endl;
std::cout << "point range: (";
for (point_iterator_type pit = begin; pit != end; ++pit)
{
std::cout << " " << bg::dsv(*pit);
}
std::cout << " )" << std::endl;
std::cout << "expected point range: " << bg::wkt(point_range)
<< 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
}
};
//======================================================================
//======================================================================
BOOST_AUTO_TEST_CASE( test_linestring_point_iterator )
{
#ifdef GEOMETRY_TEST_DEBUG
std::cout << "*** LINESTRING ***" << std::endl;
#endif
typedef multi_point_type MP;
typedef linestring_type L;
typedef test_point_iterator_of_geometry<L, MP> tester;
tester::apply(from_wkt<L>("LINESTRING()"),
from_wkt<MP>("MULTIPOINT()")
);
tester::apply(from_wkt<L>("LINESTRING(3 3,4 4,5 5)"),
from_wkt<MP>("MULTIPOINT(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 multi_point_type MP;
typedef polygon_type P;
typedef test_point_iterator_of_geometry<P, MP> tester;
tester::apply(from_wkt<P>("POLYGON()"),
from_wkt<MP>("MULTIPOINT()")
);
tester::apply(from_wkt<P>("POLYGON(())"),
from_wkt<MP>("MULTIPOINT()")
);
tester::apply(from_wkt<P>("POLYGON((3 3,4 4,5 5),(),(),(),\
(6 6,7 7,8 8),(),(),(9 9),())"),
from_wkt<MP>("MULTIPOINT(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),())"),
from_wkt<MP>("MULTIPOINT(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 multi_point_type MP;
typedef test_point_iterator_of_geometry<MP, MP> tester;
tester::apply(from_wkt<MP>("MULTIPOINT()"),
from_wkt<MP>("MULTIPOINT()")
);
tester::apply(from_wkt<MP>("MULTIPOINT(3 3,4 4,5 5)"),
from_wkt<MP>("MULTIPOINT(3 3,4 4,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 multi_point_type MP;
typedef linestring_type L;
typedef multi_linestring_type ML;
typedef test_point_iterator_of_geometry<ML, MP> tester;
tester::apply(from_wkt<ML>("MULTILINESTRING()"),
from_wkt<MP>("MULTIPOINT()")
);
tester::apply(from_wkt<ML>("MULTILINESTRING(())"),
from_wkt<MP>("MULTIPOINT()")
);
tester::apply(from_wkt<ML>("MULTILINESTRING((),(),())"),
from_wkt<MP>("MULTIPOINT()")
);
tester::apply(from_wkt<ML>("MULTILINESTRING((),(),(0 0,1 1,2 2),(),(),\
(3 3,4 4,5 5),(),(6 6),(),(),())"),
from_wkt<MP>("MULTIPOINT(0 0,1 1,2 2,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 multi_point_type MP;
typedef multi_polygon_type MPL;
typedef test_point_iterator_of_geometry<MPL, MP> tester;
tester::apply(from_wkt<MPL>("MULTIPOLYGON()"),
from_wkt<MP>("MULTIPOINT()")
);
tester::apply(from_wkt<MPL>("MULTIPOLYGON( () )"),
from_wkt<MP>("MULTIPOINT()")
);
tester::apply(from_wkt<MPL>("MULTIPOLYGON( (()) )"),
from_wkt<MP>("MULTIPOINT()")
);
tester::apply(from_wkt<MPL>("MULTIPOLYGON( ((),()) )"),
from_wkt<MP>("MULTIPOINT()")
);
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),())\
)"),
from_wkt<MP>("MULTIPOINT(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),())\
\
((),(),()),\
)"),
from_wkt<MP>("MULTIPOINT(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
}