Merge branch 'develop' into feature/buffer

This commit is contained in:
Barend Gehrels
2014-10-01 10:26:21 +02:00
25 changed files with 1793 additions and 310 deletions

View File

@@ -220,10 +220,13 @@ public:
Strategy const& strategy,
bool check_intersection = true)
{
point_iterator<Geometry1 const> first1 = points_begin(geometry1);
point_iterator<Geometry1 const> beyond1 = points_end(geometry1);
point_iterator<Geometry2 const> first2 = points_begin(geometry2);
point_iterator<Geometry2 const> beyond2 = points_end(geometry2);
typedef geometry::point_iterator<Geometry1 const> const_point_iterator1;
typedef geometry::point_iterator<Geometry2 const> const_point_iterator2;
const_point_iterator1 first1 = points_begin(geometry1);
const_point_iterator1 beyond1 = points_end(geometry1);
const_point_iterator2 first2 = points_begin(geometry2);
const_point_iterator2 beyond2 = points_end(geometry2);
if ( geometry::has_one_element(first1, beyond1) )
{

View File

@@ -68,12 +68,12 @@ struct segment_identifier
#if defined(BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER)
friend std::ostream& operator<<(std::ostream &os, segment_identifier const& seg_id)
{
std::cout
os
<< "s:" << seg_id.source_index
<< ", v:" << seg_id.segment_index // ~vertex
<< ", v:" << seg_id.segment_index // v:vertex because s is used for source
;
if (seg_id.ring_index >= 0) std::cout << ", r:" << seg_id.ring_index;
if (seg_id.multi_index >= 0) std::cout << ", m:" << seg_id.multi_index;
if (seg_id.ring_index >= 0) os << ", r:" << seg_id.ring_index;
if (seg_id.multi_index >= 0) os << ", m:" << seg_id.multi_index;
return os;
}
#endif

View File

@@ -14,8 +14,10 @@
#include <iostream>
#include <string>
#include <boost/geometry/io/wkt/write.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/geometry/io/wkt/write.hpp>
#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
#endif // BOOST_GEOMETRY_DEBUG_TURNS

View File

@@ -1,10 +1,15 @@
// 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.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -24,6 +29,7 @@
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/point_type.hpp>
@@ -36,6 +42,9 @@
#include <boost/geometry/util/add_const_if_c.hpp>
#include <boost/geometry/views/closeable_view.hpp>
namespace boost { namespace geometry
{
@@ -91,17 +100,25 @@ struct fe_range_per_segment
template <typename Range, typename Functor>
static inline void apply(Range& range, Functor& f)
{
typedef typename closeable_view
<
Range, closure<Range>::value
>::type view_type;
typedef typename add_const_if_c
<
is_const<Range>::value,
typename point_type<Range>::type
>::type point_type;
typedef typename boost::range_iterator<Range>::type
typedef typename boost::range_iterator<view_type>::type
iterator_type;
iterator_type it = boost::begin(range);
view_type view(range);
iterator_type it = boost::begin(view);
iterator_type previous = it++;
while(it != boost::end(range))
while(it != boost::end(view))
{
model::referring_segment<point_type> s(*previous, *it);
f(s);

View File

@@ -89,7 +89,7 @@ inline void assert_dimension()
BOOST_STATIC_ASSERT((
boost::mpl::equal_to
<
geometry::dimension<Geometry>,
boost::mpl::int_<geometry::dimension<Geometry>::value>,
boost::mpl::int_<Dimensions>
>::type::value
));
@@ -102,13 +102,13 @@ inline void assert_dimension()
template <typename Geometry, int Dimensions>
inline void assert_dimension_less_equal()
{
BOOST_STATIC_ASSERT(( dimension<Geometry>::type::value <= Dimensions ));
BOOST_STATIC_ASSERT(( static_cast<int>(dimension<Geometry>::type::value) <= Dimensions ));
}
template <typename Geometry, int Dimensions>
inline void assert_dimension_greater_equal()
{
BOOST_STATIC_ASSERT(( dimension<Geometry>::type::value >= Dimensions ));
BOOST_STATIC_ASSERT(( static_cast<int>(dimension<Geometry>::type::value) >= Dimensions ));
}
/*!
@@ -118,7 +118,7 @@ inline void assert_dimension_greater_equal()
template <typename G1, typename G2>
inline void assert_dimension_equal()
{
BOOST_STATIC_ASSERT(( dimension<G1>::type::value == dimension<G2>::type::value ));
BOOST_STATIC_ASSERT(( static_cast<size_t>(dimension<G1>::type::value) == static_cast<size_t>(dimension<G2>::type::value) ));
}
}} // namespace boost::geometry

View File

@@ -0,0 +1,143 @@
// 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_GEOMETRIES_POINTING_SEGMENT_HPP
#define BOOST_GEOMETRY_GEOMETRIES_POINTING_SEGMENT_HPP
#include <cstddef>
#include <boost/assert.hpp>
#include <boost/concept/assert.hpp>
#include <boost/core/addressof.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
namespace boost { namespace geometry
{
namespace model
{
// const or non-const segment type that is meant to be
// * default constructible
// * copy constructible
// * assignable
// referring_segment does not fit these requirements, hence the
// pointing_segment class
//
// this class is used by the segment_iterator as its value type
template <typename ConstOrNonConstPoint>
class pointing_segment
{
BOOST_CONCEPT_ASSERT( (
typename boost::mpl::if_
<
boost::is_const<ConstOrNonConstPoint>,
concept::Point<ConstOrNonConstPoint>,
concept::ConstPoint<ConstOrNonConstPoint>
>
) );
typedef ConstOrNonConstPoint point_type;
public:
point_type* first;
point_type* second;
inline pointing_segment()
: first(NULL)
, second(NULL)
{}
inline pointing_segment(point_type const& p1, point_type const& p2)
: first(boost::addressof(p1))
, second(boost::addressof(p2))
{}
};
} // namespace model
// Traits specializations for segment above
#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
namespace traits
{
template <typename Point>
struct tag<model::pointing_segment<Point> >
{
typedef segment_tag type;
};
template <typename Point>
struct point_type<model::pointing_segment<Point> >
{
typedef Point type;
};
template <typename Point, std::size_t Dimension>
struct indexed_access<model::pointing_segment<Point>, 0, Dimension>
{
typedef model::pointing_segment<Point> segment_type;
typedef typename geometry::coordinate_type
<
segment_type
>::type coordinate_type;
static inline coordinate_type get(segment_type const& s)
{
BOOST_ASSERT( s.first != NULL );
return geometry::get<Dimension>(*s.first);
}
static inline void set(segment_type& s, coordinate_type const& value)
{
BOOST_ASSERT( s.first != NULL );
geometry::set<Dimension>(*s.first, value);
}
};
template <typename Point, std::size_t Dimension>
struct indexed_access<model::pointing_segment<Point>, 1, Dimension>
{
typedef model::pointing_segment<Point> segment_type;
typedef typename geometry::coordinate_type
<
segment_type
>::type coordinate_type;
static inline coordinate_type get(segment_type const& s)
{
BOOST_ASSERT( s.second != NULL );
return geometry::get<Dimension>(*s.second);
}
static inline void set(segment_type& s, coordinate_type const& value)
{
BOOST_ASSERT( s.second != NULL );
geometry::set<Dimension>(*s.second, value);
}
};
} // namespace traits
#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_GEOMETRIES_POINTING_SEGMENT_HPP

View File

@@ -19,7 +19,9 @@ template <typename Box, size_t Dimension>
struct is_valid_box
{
BOOST_MPL_ASSERT_MSG(
(0 < Dimension && Dimension <= dimension<Box>::value),
(0 < dimension<Box>::value &&
0 < Dimension &&
Dimension <= static_cast<size_t>(dimension<Box>::value)),
INVALID_DIMENSION_PARAMETER,
(is_valid_box));

View File

@@ -23,13 +23,20 @@ namespace boost { namespace geometry
template <typename Iterator1, typename Iterator2, typename Value>
template
<
typename Iterator1,
typename Iterator2,
typename Value,
typename Reference = Value&
>
class concatenate_iterator
: public boost::iterator_facade
<
concatenate_iterator<Iterator1, Iterator2, Value>,
concatenate_iterator<Iterator1, Iterator2, Value, Reference>,
Value,
boost::bidirectional_traversal_tag
boost::bidirectional_traversal_tag,
Reference
>
{
private:
@@ -54,9 +61,20 @@ public:
: m_it1(end1), m_end1(end1), m_begin2(begin2), m_it2(end2)
{}
template <typename OtherIt1, typename OtherIt2, typename OtherValue>
concatenate_iterator
(concatenate_iterator<OtherIt1, OtherIt2, OtherValue> const& other)
template
<
typename OtherIt1,
typename OtherIt2,
typename OtherValue,
typename OtherReference
>
concatenate_iterator(concatenate_iterator
<
OtherIt1,
OtherIt2,
OtherValue,
OtherReference
> const& other)
: m_it1(other.m_it1)
, m_end1(other.m_end1)
, m_begin2(other.m_begin2)
@@ -71,9 +89,20 @@ public:
(types<OtherIt1, OtherIt2>));
}
template <typename OtherIt1, typename OtherIt2, typename OtherValue>
concatenate_iterator
operator=(concatenate_iterator<OtherIt1, OtherIt2, OtherValue> const& other)
template
<
typename OtherIt1,
typename OtherIt2,
typename OtherValue,
typename OtherReference
>
concatenate_iterator operator=(concatenate_iterator
<
OtherIt1,
OtherIt2,
OtherValue,
OtherReference
> const& other)
{
static const bool are_conv
= boost::is_convertible<OtherIt1, Iterator1>::value
@@ -93,10 +122,10 @@ public:
private:
friend class boost::iterator_core_access;
template <typename It1, typename It2, typename V>
template <typename It1, typename It2, typename V, typename R>
friend class concatenate_iterator;
inline Value& dereference() const
inline Reference dereference() const
{
if ( m_it1 == m_end1 )
{
@@ -105,12 +134,19 @@ private:
return *m_it1;
}
template <typename OtherIt1, typename OtherIt2, typename OtherValue>
template
<
typename OtherIt1,
typename OtherIt2,
typename OtherValue,
typename OtherReference
>
inline bool equal(concatenate_iterator
<
OtherIt1,
OtherIt2,
OtherValue
OtherValue,
OtherReference
> const& other) const
{
return m_it1 == other.m_it1 && m_it2 == other.m_it2;

View File

@@ -0,0 +1,66 @@
// 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_DETAIL_POINT_ITERATOR_INNER_RANGE_TYPE_HPP
#define BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_INNER_RANGE_TYPE_HPP
#include <boost/range.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/if.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace point_iterator
{
template
<
typename Geometry,
typename Tag = typename tag<Geometry>::type
>
struct 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 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::point_iterator
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_INNER_RANGE_TYPE_HPP

View File

@@ -0,0 +1,136 @@
// 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_DETAIL_POINT_ITERATOR_ITERATOR_TYPE_HPP
#define BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_ITERATOR_TYPE_HPP
#include <boost/range.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/iterators/flatten_iterator.hpp>
#include <boost/geometry/iterators/concatenate_iterator.hpp>
#include <boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp>
#include <boost/geometry/iterators/detail/point_iterator/value_type.hpp>
#include <boost/geometry/iterators/dispatch/point_iterator.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace point_iterator
{
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct iterator_type
: not_implemented<Geometry>
{};
template <typename Linestring>
struct iterator_type<Linestring, linestring_tag>
{
typedef typename boost::range_iterator<Linestring>::type type;
};
template <typename Ring>
struct iterator_type<Ring, ring_tag>
{
typedef typename boost::range_iterator<Ring>::type type;
};
template <typename Polygon>
class iterator_type<Polygon, polygon_tag>
{
private:
typedef typename inner_range_type<Polygon>::type inner_range;
public:
typedef concatenate_iterator
<
typename boost::range_iterator<inner_range>::type,
flatten_iterator
<
typename boost::range_iterator
<
typename geometry::interior_type<Polygon>::type
>::type,
typename iterator_type<inner_range>::type,
typename value_type<Polygon>::type,
dispatch::points_begin<inner_range>,
dispatch::points_end<inner_range>
>,
typename value_type<Polygon>::type
> type;
};
template <typename MultiPoint>
struct iterator_type<MultiPoint, multi_point_tag>
{
typedef typename boost::range_iterator<MultiPoint>::type type;
};
template <typename MultiLinestring>
class iterator_type<MultiLinestring, multi_linestring_tag>
{
private:
typedef typename inner_range_type<MultiLinestring>::type inner_range;
public:
typedef flatten_iterator
<
typename boost::range_iterator<MultiLinestring>::type,
typename iterator_type<inner_range>::type,
typename value_type<MultiLinestring>::type,
dispatch::points_begin<inner_range>,
dispatch::points_end<inner_range>
> type;
};
template <typename MultiPolygon>
class iterator_type<MultiPolygon, multi_polygon_tag>
{
private:
typedef typename inner_range_type<MultiPolygon>::type inner_range;
public:
typedef flatten_iterator
<
typename boost::range_iterator<MultiPolygon>::type,
typename iterator_type<inner_range>::type,
typename value_type<MultiPolygon>::type,
dispatch::points_begin<inner_range>,
dispatch::points_end<inner_range>
> type;
};
}} // namespace detail::point_iterator
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_ITERATOR_TYPE_HPP

View File

@@ -0,0 +1,47 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_VALUE_TYPE_HPP
#define BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_VALUE_TYPE_HPP
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/if.hpp>
#include <boost/geometry/core/point_type.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace point_iterator
{
template <typename Geometry>
struct 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;
};
}} // namespace detail::point_iterator
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_DETAIL_POINT_ITERATOR_VALUE_TYPE_HPP

View File

@@ -0,0 +1,153 @@
// 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_DETAIL_SEGMENT_ITERATOR_ITERATOR_TYPE_HPP
#define BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_ITERATOR_TYPE_HPP
#include <boost/range.hpp>
#include <boost/geometry/core/interior_type.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/iterators/concatenate_iterator.hpp>
#include <boost/geometry/iterators/flatten_iterator.hpp>
#include <boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp>
#include <boost/geometry/iterators/detail/segment_iterator/range_segment_iterator.hpp>
#include <boost/geometry/iterators/detail/segment_iterator/value_type.hpp>
#include <boost/geometry/iterators/dispatch/segment_iterator.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace segment_iterator
{
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct iterator_type
: not_implemented<Geometry>
{};
template <typename Linestring>
struct iterator_type<Linestring, linestring_tag>
{
typedef range_segment_iterator
<
Linestring, typename value_type<Linestring>::type
> type;
};
template <typename Ring>
struct iterator_type<Ring, ring_tag>
{
typedef range_segment_iterator
<
Ring, typename value_type<Ring>::type
> type;
};
template <typename Polygon>
class iterator_type<Polygon, polygon_tag>
{
private:
typedef typename detail::point_iterator::inner_range_type
<
Polygon
>::type inner_range;
public:
typedef concatenate_iterator
<
range_segment_iterator
<
inner_range,
typename value_type<Polygon>::type
>,
flatten_iterator
<
typename boost::range_iterator
<
typename geometry::interior_type<Polygon>::type
>::type,
typename iterator_type<inner_range>::type,
typename value_type<Polygon>::type,
dispatch::segments_begin<inner_range>,
dispatch::segments_end<inner_range>,
typename value_type<Polygon>::type
>,
typename value_type<Polygon>::type,
typename value_type<Polygon>::type
> type;
};
template <typename MultiLinestring>
class iterator_type<MultiLinestring, multi_linestring_tag>
{
private:
typedef typename detail::point_iterator::inner_range_type
<
MultiLinestring
>::type inner_range;
public:
typedef flatten_iterator
<
typename boost::range_iterator<MultiLinestring>::type,
typename iterator_type<inner_range>::type,
typename value_type<MultiLinestring>::type,
dispatch::segments_begin<inner_range>,
dispatch::segments_end<inner_range>,
typename value_type<MultiLinestring>::type
> type;
};
template <typename MultiPolygon>
class iterator_type<MultiPolygon, multi_polygon_tag>
{
private:
typedef typename detail::point_iterator::inner_range_type
<
MultiPolygon
>::type inner_range;
public:
typedef flatten_iterator
<
typename boost::range_iterator<MultiPolygon>::type,
typename iterator_type<inner_range>::type,
typename value_type<MultiPolygon>::type,
dispatch::segments_begin<inner_range>,
dispatch::segments_end<inner_range>,
typename value_type<MultiPolygon>::type
> type;
};
}} // namespace detail::segment_iterator
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_ITERATOR_TYPE_HPP

View File

@@ -0,0 +1,223 @@
// 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_DETAIL_SEGMENT_ITERATOR_RANGE_SEGMENT_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_RANGE_SEGMENT_ITERATOR_HPP
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/iterators/closing_iterator.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace segment_iterator
{
template <typename Range, closure_selector Closure = closure<Range>::value>
struct range_iterator_type
{
typedef typename boost::range_iterator<Range>::type type;
};
template <typename Range>
struct range_iterator_type<Range, open>
{
typedef closing_iterator<Range> type;
};
template <typename Range, closure_selector Closure = closure<Range>::value>
struct range_iterator_begin
{
static inline typename range_iterator_type<Range, Closure>::type
apply(Range& range)
{
return boost::begin(range);
}
};
template <typename Range>
struct range_iterator_begin<Range, open>
{
static inline typename range_iterator_type<Range, open>::type
apply(Range& range)
{
return closing_iterator<Range>(range);
}
};
template <typename Range, closure_selector Closure = closure<Range>::value>
struct range_iterator_end
{
static inline typename range_iterator_type<Range, Closure>::type
apply(Range& range)
{
return boost::end(range);
}
};
template <typename Range>
struct range_iterator_end<Range, open>
{
static inline typename range_iterator_type<Range, open>::type
apply(Range& range)
{
return closing_iterator<Range>(range, true);
}
};
template <typename Range, typename Value, typename Reference = Value>
class range_segment_iterator
: public boost::iterator_facade
<
range_segment_iterator<Range, Value, Reference>,
Value,
boost::bidirectional_traversal_tag,
Reference
>
{
public:
typedef typename range_iterator_type<Range>::type iterator_type;
// default constructor
range_segment_iterator()
: m_it()
{}
// for begin
range_segment_iterator(Range& r)
: m_it(range_iterator_begin<Range>::apply(r))
{}
// for end
range_segment_iterator(Range& r, bool)
: m_it(--range_iterator_end<Range>::apply(r))
{}
template
<
typename OtherRange,
typename OtherValue,
typename OtherReference
>
range_segment_iterator(range_segment_iterator
<
OtherRange,
OtherValue,
OtherReference
> const& other)
: m_it(other.m_it)
{
typedef typename range_segment_iterator
<
OtherRange, OtherValue, OtherReference
>::iterator_type other_iterator_type;
static const bool are_conv
= boost::is_convertible<other_iterator_type, iterator_type>::value;
BOOST_MPL_ASSERT_MSG((are_conv), NOT_CONVERTIBLE, (types<OtherRange>));
}
template
<
typename OtherRange,
typename OtherValue,
typename OtherReference
>
range_segment_iterator operator=(range_segment_iterator
<
OtherRange,
OtherValue,
OtherReference
> const& other)
{
typedef typename range_segment_iterator
<
OtherRange, OtherValue, OtherReference
>::iterator_type other_iterator_type;
static const bool are_conv
= boost::is_convertible<other_iterator_type, iterator_type>::value;
BOOST_MPL_ASSERT_MSG((are_conv), NOT_CONVERTIBLE, (types<OtherRange>));
m_it = other.m_it;
return *this;
}
private:
friend class boost::iterator_core_access;
template <typename Rng, typename V, typename R>
friend class range_segment_iterator;
inline Reference dereference() const
{
iterator_type next(m_it);
++next;
return Reference(*m_it, *next);
}
template
<
typename OtherRange,
typename OtherValue,
typename OtherReference
>
inline bool equal(range_segment_iterator
<
OtherRange,
OtherValue,
OtherReference
> const& other) const
{
return m_it == other.m_it;
}
inline void increment()
{
++m_it;
}
inline void decrement()
{
--m_it;
}
private:
iterator_type m_it;
};
}} // namespace detail::segment_iterator
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_RANGE_SEGMENT_ITERATOR_HPP

View File

@@ -0,0 +1,43 @@
// 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_DETAIL_SEGMENT_ITERATOR_VALUE_TYPE_HPP
#define BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_VALUE_TYPE_HPP
#include <boost/geometry/iterators/detail/point_iterator/value_type.hpp>
#include <boost/geometry/geometries/pointing_segment.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace segment_iterator
{
template <typename Geometry>
struct value_type
{
typedef typename detail::point_iterator::value_type
<
Geometry
>::type point_iterator_value_type;
typedef geometry::model::pointing_segment
<
point_iterator_value_type
> type;
};
}} // namespace detail::segment_iterator
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_VALUE_TYPE_HPP

View File

@@ -7,8 +7,8 @@
// 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
#ifndef BOOST_GEOMETRY_ITERATORS_DISPATCH_SEGMENT_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_DISPATCH_SEGMENT_ITERATOR_HPP
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
@@ -21,8 +21,18 @@ namespace boost { namespace geometry
namespace dispatch
{
// dispatch for segments_begin
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct point_iterator_type
struct segments_begin
: not_implemented<Geometry>
{};
// dispatch for segments_end
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct segments_end
: not_implemented<Geometry>
{};
@@ -34,4 +44,4 @@ struct point_iterator_type
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP
#endif // BOOST_GEOMETRY_ITERATORS_DISPATCH_SEGMENT_ITERATOR_HPP

View File

@@ -29,7 +29,8 @@ template
typename InnerIterator,
typename Value,
typename AccessInnerBegin,
typename AccessInnerEnd
typename AccessInnerEnd,
typename Reference = Value&
>
class flatten_iterator
: public boost::iterator_facade
@@ -40,9 +41,12 @@ class flatten_iterator
InnerIterator,
Value,
AccessInnerBegin,
AccessInnerEnd>,
AccessInnerEnd,
Reference
>,
Value,
boost::bidirectional_traversal_tag
boost::bidirectional_traversal_tag,
Reference
>
{
private:
@@ -72,7 +76,8 @@ public:
<
typename OtherOuterIterator, typename OtherInnerIterator,
typename OtherValue,
typename OtherAccessInnerBegin, typename OtherAccessInnerEnd
typename OtherAccessInnerBegin, typename OtherAccessInnerEnd,
typename OtherReference
>
flatten_iterator(flatten_iterator
<
@@ -80,7 +85,8 @@ public:
OtherInnerIterator,
OtherValue,
OtherAccessInnerBegin,
OtherAccessInnerEnd
OtherAccessInnerEnd,
OtherReference
> const& other)
: m_outer_it(other.m_outer_it),
m_outer_end(other.m_outer_end),
@@ -107,7 +113,8 @@ public:
typename OtherInnerIterator,
typename OtherValue,
typename OtherAccessInnerBegin,
typename OtherAccessInnerEnd
typename OtherAccessInnerEnd,
typename OtherReference
>
flatten_iterator operator=(flatten_iterator
<
@@ -115,7 +122,8 @@ public:
OtherInnerIterator,
OtherValue,
OtherAccessInnerBegin,
OtherAccessInnerEnd
OtherAccessInnerEnd,
OtherReference
> const& other)
{
static const bool are_conv
@@ -147,7 +155,8 @@ private:
typename Inner,
typename V,
typename InnerBegin,
typename InnerEnd
typename InnerEnd,
typename R
>
friend class flatten_iterator;
@@ -170,7 +179,7 @@ private:
}
}
inline Value& dereference() const
inline Reference dereference() const
{
BOOST_ASSERT( m_outer_it != m_outer_end );
BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) );
@@ -184,7 +193,8 @@ private:
typename OtherInnerIterator,
typename OtherValue,
typename OtherAccessInnerBegin,
typename OtherAccessInnerEnd
typename OtherAccessInnerEnd,
typename OtherReference
>
inline bool equal(flatten_iterator
<
@@ -192,7 +202,8 @@ private:
OtherInnerIterator,
OtherValue,
OtherAccessInnerBegin,
OtherAccessInnerEnd
OtherAccessInnerEnd,
OtherReference
> const& other) const
{
if ( m_outer_it != other.m_outer_it )

View File

@@ -20,7 +20,7 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/iterators/dispatch/point_iterator.hpp>
#include <boost/geometry/iterators/point_iterator_type.hpp>
#include <boost/geometry/iterators/detail/point_iterator/iterator_type.hpp>
namespace boost { namespace geometry
@@ -38,7 +38,10 @@ namespace dispatch
template <typename Linestring>
struct points_begin<Linestring, linestring_tag>
{
static inline typename point_iterator_type<Linestring>::type
static inline typename detail::point_iterator::iterator_type
<
Linestring
>::type
apply(Linestring& linestring)
{
return boost::begin(linestring);
@@ -49,7 +52,7 @@ struct points_begin<Linestring, linestring_tag>
template <typename Ring>
struct points_begin<Ring, ring_tag>
{
static inline typename point_iterator_type<Ring>::type
static inline typename detail::point_iterator::iterator_type<Ring>::type
apply(Ring& ring)
{
return boost::begin(ring);
@@ -60,7 +63,10 @@ struct points_begin<Ring, ring_tag>
template <typename Polygon>
struct points_begin<Polygon, polygon_tag>
{
typedef typename point_iterator_type<Polygon>::type return_type;
typedef typename detail::point_iterator::iterator_type
<
Polygon
>::type return_type;
static inline return_type apply(Polygon& polygon)
{
@@ -83,7 +89,10 @@ struct points_begin<Polygon, polygon_tag>
template <typename MultiPoint>
struct points_begin<MultiPoint, multi_point_tag>
{
static inline typename point_iterator_type<MultiPoint>::type
static inline typename detail::point_iterator::iterator_type
<
MultiPoint
>::type
apply(MultiPoint& multipoint)
{
return boost::begin(multipoint);
@@ -94,13 +103,15 @@ struct points_begin<MultiPoint, multi_point_tag>
template <typename MultiLinestring>
struct points_begin<MultiLinestring, multi_linestring_tag>
{
static inline typename point_iterator_type<MultiLinestring>::type
apply(MultiLinestring& multilinestring)
typedef typename detail::point_iterator::iterator_type
<
MultiLinestring
>::type return_type;
static inline return_type apply(MultiLinestring& multilinestring)
{
return typename point_iterator_type
<
MultiLinestring
>::type(boost::begin(multilinestring), boost::end(multilinestring));
return return_type(boost::begin(multilinestring),
boost::end(multilinestring));
}
};
@@ -108,13 +119,15 @@ struct points_begin<MultiLinestring, multi_linestring_tag>
template <typename MultiPolygon>
struct points_begin<MultiPolygon, multi_polygon_tag>
{
static inline typename point_iterator_type<MultiPolygon>::type
apply(MultiPolygon& multipolygon)
typedef typename detail::point_iterator::iterator_type
<
MultiPolygon
>::type return_type;
static inline return_type apply(MultiPolygon& multipolygon)
{
return typename point_iterator_type
<
MultiPolygon
>::type(boost::begin(multipolygon), boost::end(multipolygon));
return return_type(boost::begin(multipolygon),
boost::end(multipolygon));
}
};
@@ -136,7 +149,10 @@ namespace dispatch
template <typename Linestring>
struct points_end<Linestring, linestring_tag>
{
static inline typename point_iterator_type<Linestring>::type
static inline typename detail::point_iterator::iterator_type
<
Linestring
>::type
apply(Linestring& linestring)
{
return boost::end(linestring);
@@ -147,7 +163,7 @@ struct points_end<Linestring, linestring_tag>
template <typename Ring>
struct points_end<Ring, ring_tag>
{
static inline typename point_iterator_type<Ring>::type
static inline typename detail::point_iterator::iterator_type<Ring>::type
apply(Ring& ring)
{
return boost::end(ring);
@@ -158,7 +174,10 @@ struct points_end<Ring, ring_tag>
template <typename Polygon>
struct points_end<Polygon, polygon_tag>
{
typedef typename point_iterator_type<Polygon>::type return_type;
typedef typename detail::point_iterator::iterator_type
<
Polygon
>::type return_type;
static inline return_type apply(Polygon& polygon)
{
@@ -178,7 +197,10 @@ struct points_end<Polygon, polygon_tag>
template <typename MultiPoint>
struct points_end<MultiPoint, multi_point_tag>
{
static inline typename point_iterator_type<MultiPoint>::type
static inline typename detail::point_iterator::iterator_type
<
MultiPoint
>::type
apply(MultiPoint& multipoint)
{
return boost::end(multipoint);
@@ -189,13 +211,14 @@ struct points_end<MultiPoint, multi_point_tag>
template <typename MultiLinestring>
struct points_end<MultiLinestring, multi_linestring_tag>
{
static inline typename point_iterator_type<MultiLinestring>::type
apply(MultiLinestring& multilinestring)
typedef typename detail::point_iterator::iterator_type
<
MultiLinestring
>::type return_type;
static inline return_type apply(MultiLinestring& multilinestring)
{
return typename point_iterator_type
<
MultiLinestring
>::type(boost::end(multilinestring));
return return_type(boost::end(multilinestring));
}
};
@@ -203,13 +226,14 @@ struct points_end<MultiLinestring, multi_linestring_tag>
template <typename MultiPolygon>
struct points_end<MultiPolygon, multi_polygon_tag>
{
static inline typename point_iterator_type<MultiPolygon>::type
apply(MultiPolygon& multipolygon)
typedef typename detail::point_iterator::iterator_type
<
MultiPolygon
>::type return_type;
static inline return_type apply(MultiPolygon& multipolygon)
{
return typename point_iterator_type
<
MultiPolygon
>::type(boost::end(multipolygon));
return return_type(boost::end(multipolygon));
}
};
@@ -221,17 +245,17 @@ struct points_end<MultiPolygon, multi_polygon_tag>
// MK:: need to add doc here
template <typename Geometry>
class point_iterator
: public dispatch::point_iterator_type<Geometry>::type
: public detail::point_iterator::iterator_type<Geometry>::type
{
private:
typedef typename dispatch::point_iterator_type<Geometry>::type base;
typedef typename detail::point_iterator::iterator_type<Geometry>::type base;
base* base_ptr()
inline base* base_ptr()
{
return this;
}
base const* base_ptr() const
inline base const* base_ptr() const
{
return this;
}
@@ -240,19 +264,25 @@ private:
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) {}
inline point_iterator(base const& base_it) : base(base_it) {}
public:
point_iterator() {}
inline point_iterator() {}
template <typename OtherGeometry>
point_iterator(point_iterator<OtherGeometry> const& other)
inline point_iterator(point_iterator<OtherGeometry> const& other)
: base(*other.base_ptr())
{
static const bool is_conv
= boost::is_convertible<
typename dispatch::point_iterator_type<OtherGeometry>::type,
typename dispatch::point_iterator_type<Geometry>::type
typename detail::point_iterator::iterator_type
<
OtherGeometry
>::type,
typename detail::point_iterator::iterator_type
<
Geometry
>::type
>::value;
BOOST_MPL_ASSERT_MSG((is_conv),

View File

@@ -1,207 +0,0 @@
// 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/type_traits/is_const.hpp>
#include <boost/mpl/if.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/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 inner_range;
public:
typedef concatenate_iterator
<
typename boost::range_iterator<inner_range>::type,
flatten_iterator
<
typename boost::range_iterator
<
typename geometry::interior_type<Polygon>::type
>::type,
typename dispatch::point_iterator_type
<
inner_range
>::type,
typename detail_dispatch::point_iterator_value_type
<
Polygon
>::type,
dispatch::points_begin<inner_range>,
dispatch::points_end<inner_range>
>,
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 inner_range;
public:
typedef flatten_iterator
<
typename boost::range_iterator<MultiLinestring>::type,
typename dispatch::point_iterator_type<inner_range>::type,
typename detail_dispatch::point_iterator_value_type
<
MultiLinestring
>::type,
dispatch::points_begin<inner_range>,
dispatch::points_end<inner_range>
> type;
};
template <typename MultiPolygon>
class point_iterator_type<MultiPolygon, multi_polygon_tag>
{
private:
typedef typename detail_dispatch::point_iterator_inner_range_type
<
MultiPolygon
>::type inner_range;
public:
typedef flatten_iterator
<
typename boost::range_iterator<MultiPolygon>::type,
typename dispatch::point_iterator_type<inner_range>::type,
typename detail_dispatch::point_iterator_value_type
<
MultiPolygon
>::type,
dispatch::points_begin<inner_range>,
dispatch::points_end<inner_range>
> type;
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP

View File

@@ -29,12 +29,12 @@ class point_reverse_iterator
private:
typedef std::reverse_iterator<point_iterator<Geometry> > base;
base* base_ptr()
inline base* base_ptr()
{
return this;
}
base const* base_ptr() const
inline base const* base_ptr() const
{
return this;
}
@@ -46,12 +46,13 @@ private:
template <typename G>
friend inline point_reverse_iterator<G> points_rend(G&);
point_reverse_iterator(base const& base_it) : base(base_it) {}
inline point_reverse_iterator(base const& base_it) : base(base_it) {}
public:
point_reverse_iterator() {}
inline point_reverse_iterator() {}
template <typename OtherGeometry>
inline
point_reverse_iterator(point_reverse_iterator<OtherGeometry> const& other)
: base(*other.base_ptr())
{

View File

@@ -0,0 +1,317 @@
// 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_SEGMENT_ITERATOR_HPP
#define BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp>
#include <boost/geometry/iterators/detail/segment_iterator/iterator_type.hpp>
#include <boost/geometry/iterators/dispatch/segment_iterator.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// specializations for segments_begin
template <typename Linestring>
struct segments_begin<Linestring, linestring_tag>
{
typedef typename detail::segment_iterator::iterator_type
<
Linestring
>::type return_type;
static inline return_type apply(Linestring& linestring)
{
return return_type(linestring);
}
};
template <typename Ring>
struct segments_begin<Ring, ring_tag>
{
typedef typename detail::segment_iterator::iterator_type
<
Ring
>::type return_type;
static inline return_type apply(Ring& ring)
{
return return_type(ring);
}
};
template <typename Polygon>
struct segments_begin<Polygon, polygon_tag>
{
typedef typename detail::point_iterator::inner_range_type
<
Polygon
>::type inner_range;
typedef typename detail::segment_iterator::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
(segments_begin
<
inner_range
>::apply(geometry::exterior_ring(polygon)),
segments_end
<
inner_range
>::apply(geometry::exterior_ring(polygon)),
flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
boost::end(geometry::interior_rings(polygon))
),
flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
boost::end(geometry::interior_rings(polygon))
)
);
}
};
template <typename MultiLinestring>
struct segments_begin<MultiLinestring, multi_linestring_tag>
{
typedef typename detail::segment_iterator::iterator_type
<
MultiLinestring
>::type return_type;
static inline return_type apply(MultiLinestring& multilinestring)
{
return return_type(boost::begin(multilinestring),
boost::end(multilinestring));
}
};
template <typename MultiPolygon>
struct segments_begin<MultiPolygon, multi_polygon_tag>
{
typedef typename detail::segment_iterator::iterator_type
<
MultiPolygon
>::type return_type;
static inline return_type apply(MultiPolygon& multipolygon)
{
return return_type(boost::begin(multipolygon),
boost::end(multipolygon));
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// specializations for segments_end
template <typename Linestring>
struct segments_end<Linestring, linestring_tag>
{
typedef typename detail::segment_iterator::iterator_type
<
Linestring
>::type return_type;
static inline return_type apply(Linestring& linestring)
{
return return_type(linestring, true);
}
};
template <typename Ring>
struct segments_end<Ring, ring_tag>
{
typedef typename detail::segment_iterator::iterator_type
<
Ring
>::type return_type;
static inline return_type apply(Ring& ring)
{
return return_type(ring, true);
}
};
template <typename Polygon>
struct segments_end<Polygon, polygon_tag>
{
typedef typename detail::point_iterator::inner_range_type
<
Polygon
>::type inner_range;
typedef typename detail::segment_iterator::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
(segments_end
<
inner_range
>::apply(geometry::exterior_ring(polygon)),
flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
boost::end(geometry::interior_rings(polygon))
),
flatten_iterator( boost::end(geometry::interior_rings(polygon)) )
);
}
};
template <typename MultiLinestring>
struct segments_end<MultiLinestring, multi_linestring_tag>
{
typedef typename detail::segment_iterator::iterator_type
<
MultiLinestring
>::type return_type;
static inline return_type apply(MultiLinestring& multilinestring)
{
return return_type(boost::end(multilinestring));
}
};
template <typename MultiPolygon>
struct segments_end<MultiPolygon, multi_polygon_tag>
{
typedef typename detail::segment_iterator::iterator_type
<
MultiPolygon
>::type return_type;
static inline return_type apply(MultiPolygon& multipolygon)
{
return return_type(boost::end(multipolygon));
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
// MK:: need to add doc here
template <typename Geometry>
class segment_iterator
: public detail::segment_iterator::iterator_type<Geometry>::type
{
private:
typedef typename detail::segment_iterator::iterator_type
<
Geometry
>::type base;
inline base const* base_ptr() const
{
return this;
}
template <typename OtherGeometry> friend class segment_iterator;
template <typename G>
friend inline segment_iterator<G const> segments_begin(G const&);
template <typename G>
friend inline segment_iterator<G const> segments_end(G const&);
inline segment_iterator(base const& base_it) : base(base_it) {}
public:
inline segment_iterator() {}
template <typename OtherGeometry>
inline segment_iterator(segment_iterator<OtherGeometry> const& other)
: base(*other.base_ptr())
{
static const bool is_conv
= boost::is_convertible<
typename detail::segment_iterator::iterator_type
<
OtherGeometry
>::type,
typename detail::segment_iterator::iterator_type<Geometry>::type
>::value;
BOOST_MPL_ASSERT_MSG((is_conv),
NOT_CONVERTIBLE,
(segment_iterator<OtherGeometry>));
}
};
// MK:: need to add doc here
template <typename Geometry>
inline segment_iterator<Geometry const>
segments_begin(Geometry const& geometry)
{
return dispatch::segments_begin<Geometry const>::apply(geometry);
}
// MK:: need to add doc here
template <typename Geometry>
inline segment_iterator<Geometry const>
segments_end(Geometry const& geometry)
{
return dispatch::segments_end<Geometry const>::apply(geometry);
}
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP

View File

@@ -211,7 +211,10 @@ public :
#if defined(BOOST_GEOMETRY_DEFINE_STREAM_OPERATOR_SEGMENT_RATIO)
friend std::ostream& operator<<(std::ostream &os, segment_ratio const& ratio)
{
os << ratio.m_numerator << "/" << ratio.m_denominator;
os << ratio.m_numerator << "/" << ratio.m_denominator
<< " (" << (static_cast<double>(ratio.m_numerator)
/ static_cast<double>(ratio.m_denominator))
<< ")";
return os;
}
#endif

View File

@@ -26,6 +26,7 @@ typedef bg::model::segment<int_point_type> int_segment_type;
typedef bg::model::linestring<point_type> linestring_type;
typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
typedef bg::model::polygon<point_type, false> polygon_type;
typedef bg::model::polygon<point_type, false, false> open_polygon_type;
typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
typedef bg::model::ring<point_type, false> ring_type;
typedef bg::model::box<point_type> box_type;
@@ -80,6 +81,10 @@ void test_distance_linestring_polygon(Strategy const& strategy)
"polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
10, 100, strategy, true);
tester::apply("linestring(-5 1,-2 1)",
"polygon((0 0,10 0,10 10,0 10,0 0))",
2, 4, strategy, true);
tester::apply("linestring(-1 20,1 20,1 5)",
"polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
0, 0, strategy, true);
@@ -91,6 +96,25 @@ void test_distance_linestring_polygon(Strategy const& strategy)
//===========================================================================
template <typename Strategy>
void test_distance_linestring_open_polygon(Strategy const& strategy)
{
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << std::endl;
std::cout << "linestring/open polygon distance tests" << std::endl;
#endif
typedef test_distance_of_geometries
<
linestring_type, open_polygon_type
> tester;
tester::apply("linestring(-5 1,-2 1)",
"polygon((0 0,10 0,10 10,0 10))",
2, 4, strategy, true);
}
//===========================================================================
template <typename Strategy>
void test_distance_multilinestring_polygon(Strategy const& strategy)
{
@@ -843,6 +867,7 @@ BOOST_AUTO_TEST_CASE( test_all_segment_polygon )
BOOST_AUTO_TEST_CASE( test_all_linestring_polygon )
{
test_distance_linestring_polygon(point_segment_strategy());
test_distance_linestring_open_polygon(point_segment_strategy());
}
BOOST_AUTO_TEST_CASE( test_all_multilinestring_polygon )

View File

@@ -16,8 +16,9 @@
test-suite boost-geometry-iterators
:
[ run closing_iterator.cpp ]
[ run ever_circling_iterator.cpp ]
[ run point_iterator.cpp ]
[ run concatenate_iterator.cpp ]
[ run ever_circling_iterator.cpp ]
[ run flatten_iterator.cpp ]
[ run point_iterator.cpp ]
[ run segment_iterator.cpp ]
;

View File

@@ -23,6 +23,8 @@
#include <boost/assign/list_of.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/multi/core/point_type.hpp>
@@ -37,12 +39,8 @@
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/io/wkt/read.hpp>
#include <boost/geometry/io/wkt/write.hpp>
#include <boost/geometry/io/wkt/wkt.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>
#include <boost/geometry/iterators/point_reverse_iterator.hpp>
@@ -210,7 +208,9 @@ struct test_point_iterator_of_geometry
point_iterator begin = bg::points_begin(geometry);
point_iterator end = bg::points_end(geometry);
BOOST_CHECK( std::distance(begin, end) == bg::num_points(geometry) );
BOOST_CHECK( std::size_t(std::distance(begin, end))
==
bg::num_points(geometry) );
BOOST_CHECK( equals::apply(begin, end,
bg::points_begin(point_range),

View File

@@ -0,0 +1,421 @@
// 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_segment_iterator
#endif
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <boost/test/included/unit_test.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
#include <boost/geometry/geometries/register/linestring.hpp>
#include <boost/geometry/geometries/register/multi_linestring.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/geometry/io/dsv/write.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/algorithms/num_segments.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/iterators/segment_iterator.hpp>
namespace ba = ::boost::assign;
namespace bg = ::boost::geometry;
namespace bgm = bg::model;
typedef bgm::point<double, 2, bg::cs::cartesian> point_type;
typedef bgm::linestring<point_type> linestring_type;
typedef bgm::ring<point_type, true, true> ring_cw_closed_type;
typedef bgm::ring<point_type, true, false> ring_cw_open_type;
typedef bgm::polygon<point_type, true, true> polygon_cw_closed_type;
typedef bgm::polygon<point_type, true, false> polygon_cw_open_type;
// multi-geometries
typedef bgm::multi_linestring<linestring_type> multi_linestring_type;
typedef bgm::multi_polygon<polygon_cw_closed_type> multi_polygon_cw_closed_type;
typedef bgm::multi_polygon<polygon_cw_open_type> multi_polygon_cw_open_type;
// tuple-based geometries
typedef boost::tuple<double, double> tuple_point_type;
typedef std::vector<tuple_point_type> tuple_linestring_type;
typedef std::vector<tuple_linestring_type> tuple_multi_linestring_type;
BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
BOOST_GEOMETRY_REGISTER_LINESTRING(tuple_linestring_type)
BOOST_GEOMETRY_REGISTER_MULTI_LINESTRING(tuple_multi_linestring_type)
template <typename Geometry>
inline Geometry from_wkt(std::string const& wkt)
{
Geometry geometry;
boost::geometry::read_wkt(wkt, geometry);
return geometry;
}
template <typename Iterator>
inline std::ostream& print_geometry_range(std::ostream& os,
Iterator first,
Iterator beyond,
std::string const& header)
{
os << header << "(";
for (Iterator it = first; it != beyond; ++it)
{
os << " " << bg::dsv(*it);
}
os << " )";
return os;
}
struct equals
{
template <typename Iterator>
static inline std::size_t number_of_elements(Iterator begin,
Iterator end)
{
std::size_t size = std::distance(begin, end);
std::size_t num_elems(0);
for (Iterator it = begin; it != end; ++it)
{
++num_elems;
}
BOOST_CHECK( size == num_elems );
num_elems = 0;
for (Iterator it = end; it != begin; --it)
{
++num_elems;
}
BOOST_CHECK( size == 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 SegmentRange>
struct test_segment_iterator_of_geometry
{
template <typename G>
static inline void base_test(G const& geometry,
SegmentRange const& segment_range,
std::string const& header)
{
typedef bg::segment_iterator<G const> segment_iterator;
segment_iterator begin = bg::segments_begin(geometry);
segment_iterator end = bg::segments_end(geometry);
BOOST_CHECK( std::size_t(std::distance(begin, end))
==
bg::num_segments(geometry) );
BOOST_CHECK( equals::apply(begin, end,
bg::segments_begin(segment_range),
bg::segments_end(segment_range))
);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::string closure
= (
(bg::closure<Geometry>::value == bg::closed)
? "closed"
: "open"
);
std::cout << header << " geometry (WKT): "
<< bg::wkt(geometry) << std::endl;
std::cout << header << " geometry (DSV): "
<< bg::dsv(geometry) << std::endl;
std::cout << "geometry's closure: " << closure << std::endl;
print_geometry_range(std::cout, begin, end, "segment range: ");
std::cout << std::endl;
print_geometry_range(std::cout,
bg::segments_begin(segment_range),
bg::segments_end(segment_range),
"expected segment range: ");
std::cout << std::endl;
#endif
// testing dereferencing
typedef typename std::iterator_traits
<
segment_iterator
>::value_type value_type;
value_type first_segment = *bg::segments_begin(geometry);
boost::ignore_unused(first_segment);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << "first segment in geometry: "
<< bg::wkt(first_segment)
<< std::endl;
std::cout << std::endl << std::endl;
#endif
// test copying all segments to a vector
std::vector<value_type> segments;
std::copy(bg::segments_begin(geometry),
bg::segments_end(geometry),
std::back_inserter(segments));
BOOST_CHECK( std::size_t( std::distance(bg::segments_begin(geometry),
bg::segments_end(geometry)) )
==
segments.size() );
}
static inline void apply(Geometry geometry,
SegmentRange const& segment_range)
{
base_test<Geometry>(geometry, segment_range, "const");
}
};
//======================================================================
//======================================================================
template <typename ClosedGeometry, typename ExpectedResult>
struct dual_tester
{
template <typename OpenGeometry>
static inline void apply(OpenGeometry const& open_g,
ExpectedResult expected)
{
typedef test_segment_iterator_of_geometry
<
OpenGeometry, ExpectedResult
> otester;
typedef test_segment_iterator_of_geometry
<
ClosedGeometry, ExpectedResult
> ctester;
otester::apply(open_g, expected);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl;
#endif
ClosedGeometry closed_g;
bg::convert(open_g, closed_g);
ctester::apply(closed_g, expected);
}
};
//======================================================================
//======================================================================
BOOST_AUTO_TEST_CASE( test_linestring_segment_iterator )
{
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << "*** LINESTRING ***" << std::endl;
#endif
typedef tuple_multi_linestring_type TML;
typedef linestring_type G;
typedef test_segment_iterator_of_geometry<G, TML> tester;
tester::apply(from_wkt<G>("LINESTRING(0 0,1 1,2 2,3 3,4 4)"),
ba::list_of<tuple_linestring_type>
( ba::tuple_list_of(0,0)(1,1) )
( ba::tuple_list_of(1,1)(2,2) )
( ba::tuple_list_of(2,2)(3,3) )
( ba::tuple_list_of(3,3)(4,4) )
);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl << std::endl;
#endif
}
//======================================================================
//======================================================================
BOOST_AUTO_TEST_CASE( test_ring_segment_iterator )
{
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << "*** RING ***" << std::endl;
#endif
typedef tuple_multi_linestring_type TML;
typedef ring_cw_open_type OG;
typedef ring_cw_closed_type CG;
typedef dual_tester<CG, TML> tester;
tester::apply(from_wkt<OG>("POLYGON((0 0,0 10,10 10,10 0))"),
ba::list_of<tuple_linestring_type>
( ba::tuple_list_of(0,0)(0,10) )
( ba::tuple_list_of(0,10)(10,10) )
( ba::tuple_list_of(10,10)(10,0) )
( ba::tuple_list_of(10,0)(0,0) )
);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl << std::endl;
#endif
}
//======================================================================
//======================================================================
BOOST_AUTO_TEST_CASE( test_polygon_segment_iterator )
{
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << "*** POLYGON ***" << std::endl;
#endif
typedef tuple_multi_linestring_type TML;
typedef polygon_cw_open_type OG;
typedef polygon_cw_closed_type CG;
typedef dual_tester<CG, TML> tester;
tester::apply(from_wkt<OG>("POLYGON((0 0,0 10,10 10,10 0),(1 1,9 1,9 9,1 9))"),
ba::list_of<tuple_linestring_type>
( ba::tuple_list_of(0,0)(0,10) )
( ba::tuple_list_of(0,10)(10,10) )
( ba::tuple_list_of(10,10)(10,0) )
( ba::tuple_list_of(10,0)(0,0) )
( ba::tuple_list_of(1,1)(9,1) )
( ba::tuple_list_of(9,1)(9,9) )
( ba::tuple_list_of(9,9)(1,9) )
( ba::tuple_list_of(1,9)(1,1) )
);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl << std::endl;
#endif
}
//======================================================================
//======================================================================
BOOST_AUTO_TEST_CASE( test_multi_linestring_segment_iterator )
{
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << "*** MULTILINESTRING ***" << std::endl;
#endif
typedef tuple_multi_linestring_type TML;
typedef multi_linestring_type G;
typedef test_segment_iterator_of_geometry<G, TML> tester;
tester::apply(from_wkt<G>("MULTILINESTRING((0 0,1 1,2 2,3 3,4 4),(5 5,6 6,7 7,8 8),(9 9,10 10))"),
ba::list_of<tuple_linestring_type>
( ba::tuple_list_of(0,0)(1,1) )
( ba::tuple_list_of(1,1)(2,2) )
( ba::tuple_list_of(2,2)(3,3) )
( ba::tuple_list_of(3,3)(4,4) )
( ba::tuple_list_of(5,5)(6,6) )
( ba::tuple_list_of(6,6)(7,7) )
( ba::tuple_list_of(7,7)(8,8) )
( ba::tuple_list_of(9,9)(10,10) )
);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl << std::endl;
#endif
}
//======================================================================
//======================================================================
BOOST_AUTO_TEST_CASE( test_multi_polygon_segment_iterator )
{
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << "*** MULTIPOLYGON ***" << std::endl;
#endif
typedef tuple_multi_linestring_type TML;
typedef multi_polygon_cw_open_type OG;
typedef multi_polygon_cw_closed_type CG;
typedef dual_tester<CG, TML> tester;
tester::apply(from_wkt<OG>("MULTIPOLYGON(((0 0,0 10,10 10,10 0),(1 1,9 1,9 9,1 9)),((20 0,20 10,30 10,30 0),(21 1,29 1,29 9,21 9)))"),
ba::list_of<tuple_linestring_type>
( ba::tuple_list_of(0,0)(0,10) )
( ba::tuple_list_of(0,10)(10,10) )
( ba::tuple_list_of(10,10)(10,0) )
( ba::tuple_list_of(10,0)(0,0) )
( ba::tuple_list_of(1,1)(9,1) )
( ba::tuple_list_of(9,1)(9,9) )
( ba::tuple_list_of(9,9)(1,9) )
( ba::tuple_list_of(1,9)(1,1) )
( ba::tuple_list_of(20,0)(20,10) )
( ba::tuple_list_of(20,10)(30,10) )
( ba::tuple_list_of(30,10)(30,0) )
( ba::tuple_list_of(30,0)(20,0) )
( ba::tuple_list_of(21,1)(29,1) )
( ba::tuple_list_of(29,1)(29,9) )
( ba::tuple_list_of(29,9)(21,9) )
( ba::tuple_list_of(21,9)(21,1) )
);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl << std::endl;
#endif
}