From 7abe47876b19831c399696ee197be4806f355d92 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Wed, 26 Mar 2014 10:22:31 +0200 Subject: [PATCH] [feature/point iterator] implementation of point iterator for most geometries (not yet for point, segment & box); --- .../geometry/core/dispatch/point_iterator.hpp | 47 +++ .../core/dispatch/point_iterator_type.hpp | 37 ++ .../boost/geometry/core/point_iterator.hpp | 242 +++++++++++++ .../geometry/core/point_iterator_type.hpp | 216 ++++++++++++ .../geometry/util/concatenate_iterator.hpp | 91 +++++ .../boost/geometry/util/flatten_iterator.hpp | 219 ++++++++++++ test/core/point_iterator.cpp | 331 ++++++++++++++++++ 7 files changed, 1183 insertions(+) create mode 100644 include/boost/geometry/core/dispatch/point_iterator.hpp create mode 100644 include/boost/geometry/core/dispatch/point_iterator_type.hpp create mode 100644 include/boost/geometry/core/point_iterator.hpp create mode 100644 include/boost/geometry/core/point_iterator_type.hpp create mode 100644 include/boost/geometry/util/concatenate_iterator.hpp create mode 100644 include/boost/geometry/util/flatten_iterator.hpp create mode 100644 test/core/point_iterator.cpp diff --git a/include/boost/geometry/core/dispatch/point_iterator.hpp b/include/boost/geometry/core/dispatch/point_iterator.hpp new file mode 100644 index 000000000..9d89ae737 --- /dev/null +++ b/include/boost/geometry/core/dispatch/point_iterator.hpp @@ -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 +#include + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + + +// dispatch for points_begin +template ::type> +struct points_begin + : not_implemented +{}; + + + +// dispatch for points_end +template ::type> +struct points_end + : not_implemented +{}; + + + +} // namespace core_dispatch +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_HPP diff --git a/include/boost/geometry/core/dispatch/point_iterator_type.hpp b/include/boost/geometry/core/dispatch/point_iterator_type.hpp new file mode 100644 index 000000000..abf91dd9a --- /dev/null +++ b/include/boost/geometry/core/dispatch/point_iterator_type.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_CORE_DISPATCH_POINT_ITERATOR_TYPE_HPP +#define BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_TYPE_HPP + +#include +#include + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + +template ::type> +struct point_iterator_type + : not_implemented +{}; + + + +} // namespace core_dispatch +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_TYPE_HPP diff --git a/include/boost/geometry/core/point_iterator.hpp b/include/boost/geometry/core/point_iterator.hpp new file mode 100644 index 000000000..7339977c1 --- /dev/null +++ b/include/boost/geometry/core/point_iterator.hpp @@ -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 +#include + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + + +// specializations for points_begin + + +// linestring +template +struct points_begin +{ + static inline typename point_iterator_type::type + apply(Linestring& linestring) + { + return boost::begin(linestring); + } +}; + + +// ring +template +struct points_begin +{ + static inline typename point_iterator_type::type + apply(Ring& ring) + { + return boost::begin(ring); + } +}; + + +// polygon +template +struct points_begin +{ + typedef typename point_iterator_type::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 +struct points_begin +{ + static inline typename point_iterator_type::type + apply(MultiPoint& multipoint) + { + return boost::begin(multipoint); + } +}; + + +// multi-linestring +template +struct points_begin +{ + static inline typename point_iterator_type::type + apply(MultiLinestring& multilinestring) + { + return typename point_iterator_type + < + MultiLinestring + >::type(boost::begin(multilinestring), boost::end(multilinestring)); + } +}; + + +// multi-polygon +template +struct points_begin +{ + static inline typename point_iterator_type::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 +struct points_end +{ + static inline typename point_iterator_type::type + apply(Linestring& linestring) + { + return boost::end(linestring); + } +}; + + +// ring +template +struct points_end +{ + static inline typename point_iterator_type::type + apply(Ring& ring) + { + return boost::end(ring); + } +}; + + +// polygon +template +struct points_end +{ + typedef typename point_iterator_type::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 +struct points_end +{ + static inline typename point_iterator_type::type + apply(MultiPoint& multipoint) + { + return boost::end(multipoint); + } +}; + + +// multi-linestring +template +struct points_end +{ + static inline typename point_iterator_type::type + apply(MultiLinestring& multilinestring) + { + return typename point_iterator_type + < + MultiLinestring + >::type(boost::end(multilinestring)); + } +}; + + +// multi-polygon +template +struct points_end +{ + static inline typename point_iterator_type::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 point_iterator_type::type +points_begin(Geometry& geometry) +{ + return core_dispatch::points_begin::apply(geometry); +} + + +// MK:: need to add doc here +template +typename point_iterator_type::type +points_end(Geometry& geometry) +{ + return core_dispatch::points_end::apply(geometry); +} + + + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_CORE_POINT_ITERATOR_HPP diff --git a/include/boost/geometry/core/point_iterator_type.hpp b/include/boost/geometry/core/point_iterator_type.hpp new file mode 100644 index 000000000..51e409d66 --- /dev/null +++ b/include/boost/geometry/core/point_iterator_type.hpp @@ -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 +#include + +#include +#include +#include +#include +#include +#include + + +namespace boost { namespace geometry +{ + + + +#ifndef DOXYGEN_NO_DETAIL +namespace core_detail +{ + + +template +struct point_iterator_value_type +{ + typedef typename boost::mpl::if_c + < + !boost::is_const::type::value, + typename geometry::point_type::type, + typename geometry::point_type::type const + >::type type; +}; + + + + +template +< + typename Geometry, + typename Tag = typename tag::type +> +struct point_iterator_inner_range_type +{ + typedef typename boost::mpl::if_c + < + !boost::is_const::type::value, + typename boost::range_value::type, + typename boost::range_value::type const + >::type type; +}; + + +template +struct point_iterator_inner_range_type +{ + typedef typename boost::mpl::if_c + < + !boost::is_const::type::value, + typename geometry::ring_type::type, + typename geometry::ring_type::type const + >::type type; +}; + + + +} // namespace core_detail +#endif // DOXYGEN_NO_DETAIL + + + + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + + +// linestring +template +struct point_iterator_type +{ + typedef typename boost::range_iterator::type type; +}; + + +// ring +template +struct point_iterator_type +{ + typedef typename boost::range_iterator::type type; +}; + + +// polygon +template +class point_iterator_type +{ +private: + typedef typename core_detail::point_iterator_inner_range_type + < + Polygon + >::type InnerRange; + +public: + typedef util::concatenate_iterator + < + typename boost::range_iterator::type, + util::flatten_iterator + < + typename boost::range_iterator + < + typename geometry::interior_type::type + >::type, + typename core_dispatch::point_iterator_type + < + InnerRange + >::type, + typename core_detail::point_iterator_value_type + < + Polygon + >::type, + core_dispatch::points_begin, + core_dispatch::points_end + >, + typename core_detail::point_iterator_value_type::type + > type; +}; + + +// multi-point +template +struct point_iterator_type +{ + typedef typename boost::range_iterator::type type; +}; + + +// multi-linestring +template +class point_iterator_type +{ +private: + typedef typename core_detail::point_iterator_inner_range_type + < + MultiLinestring + >::type InnerRange; + +public: + typedef util::flatten_iterator + < + typename boost::range_iterator::type, + typename core_dispatch::point_iterator_type::type, + typename core_detail::point_iterator_value_type + < + MultiLinestring + >::type, + core_dispatch::points_begin, + core_dispatch::points_end + > type; +}; + + +// multi-polygon +template +class point_iterator_type +{ +private: + typedef typename core_detail::point_iterator_inner_range_type + < + MultiPolygon + >::type InnerRange; + +public: + typedef util::flatten_iterator + < + typename boost::range_iterator::type, + typename core_dispatch::point_iterator_type::type, + typename core_detail::point_iterator_value_type::type, + core_dispatch::points_begin, + core_dispatch::points_end + > type; +}; + + + + + +} // namespace core_dispatch +#endif // DOXYGEN_NO_DISPATCH + + + +// MK::need to add doc here +template +struct point_iterator_type +{ + typedef typename core_dispatch::point_iterator_type::type type; +}; + + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_CORE_POINT_ITERATOR_TYPE_HPP diff --git a/include/boost/geometry/util/concatenate_iterator.hpp b/include/boost/geometry/util/concatenate_iterator.hpp new file mode 100644 index 000000000..7071cf87b --- /dev/null +++ b/include/boost/geometry/util/concatenate_iterator.hpp @@ -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 + + +namespace boost { namespace geometry +{ + + +namespace util +{ + + +template +struct concatenate_iterator + : public boost::iterator_facade + < + concatenate_iterator, + 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 diff --git a/include/boost/geometry/util/flatten_iterator.hpp b/include/boost/geometry/util/flatten_iterator.hpp new file mode 100644 index 000000000..9b44370bc --- /dev/null +++ b/include/boost/geometry/util/flatten_iterator.hpp @@ -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 +#include +#include + + +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 diff --git a/test/core/point_iterator.cpp b/test/core/point_iterator.cpp new file mode 100644 index 000000000..a88a79b7d --- /dev/null +++ b/test/core/point_iterator.cpp @@ -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 + +#ifndef BOOST_TEST_MODULE +#define BOOST_TEST_MODULE test_point_iterator +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../algorithms/from_wkt.hpp" + +#include + + +namespace bg = ::boost::geometry; + +typedef bg::model::point point_type; +typedef bg::model::linestring linestring_type; +typedef bg::model::polygon polygon_type; //ccw, open + +// multi geometries +typedef bg::model::multi_point multi_point_type; +typedef bg::model::multi_linestring multi_linestring_type; +typedef bg::model::multi_polygon multi_polygon_type; + +struct equals +{ + template + 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 + 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 +struct test_point_iterator_of_geometry +{ + template + 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, point_range, "non-const"); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl; +#endif + + base_test(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 tester; + + tester::apply(from_wkt("LINESTRING()"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("LINESTRING(3 3,4 4,5 5)"), + from_wkt("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 tester; + + tester::apply(from_wkt

("POLYGON()"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt

("POLYGON(())"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt

("POLYGON((3 3,4 4,5 5),(),(),(),\ + (6 6,7 7,8 8),(),(),(9 9),())"), + from_wkt("MULTIPOINT(3 3,4 4,5 5,6 6,7 7,8 8,9 9)") + ); + + tester::apply(from_wkt

("POLYGON((),(3 3,4 4,5 5),(),(),\ + (6 6,7 7,8 8),(),(),(9 9),())"), + from_wkt("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 tester; + + tester::apply(from_wkt("MULTIPOINT()"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTIPOINT(3 3,4 4,5 5)"), + from_wkt("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 tester; + + tester::apply(from_wkt("MULTILINESTRING()"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTILINESTRING(())"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTILINESTRING((),(),())"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTILINESTRING((),(),(0 0,1 1,2 2),(),(),\ + (3 3,4 4,5 5),(),(6 6),(),(),())"), + from_wkt("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 tester; + + tester::apply(from_wkt("MULTIPOLYGON()"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTIPOLYGON( () )"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTIPOLYGON( (()) )"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTIPOLYGON( ((),()) )"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("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("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("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("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 +} +