mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-13 12:32:09 +00:00
[feature/point iterator] implementation of point iterator for most geometries (not yet for point, segment & box);
This commit is contained in:
47
include/boost/geometry/core/dispatch/point_iterator.hpp
Normal file
47
include/boost/geometry/core/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_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
|
||||
37
include/boost/geometry/core/dispatch/point_iterator_type.hpp
Normal file
37
include/boost/geometry/core/dispatch/point_iterator_type.hpp
Normal 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
|
||||
242
include/boost/geometry/core/point_iterator.hpp
Normal file
242
include/boost/geometry/core/point_iterator.hpp
Normal 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
|
||||
216
include/boost/geometry/core/point_iterator_type.hpp
Normal file
216
include/boost/geometry/core/point_iterator_type.hpp
Normal 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
|
||||
91
include/boost/geometry/util/concatenate_iterator.hpp
Normal file
91
include/boost/geometry/util/concatenate_iterator.hpp
Normal 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
|
||||
219
include/boost/geometry/util/flatten_iterator.hpp
Normal file
219
include/boost/geometry/util/flatten_iterator.hpp
Normal 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
|
||||
331
test/core/point_iterator.cpp
Normal file
331
test/core/point_iterator.cpp
Normal 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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user