Added ever_circling_range_iterator (range version)
Small adaptions to get_turns [SVN r62180]
This commit is contained in:
parent
8e9dfdf3e6
commit
8b260caec8
1
Jamroot
1
Jamroot
@ -13,4 +13,5 @@ project
|
||||
<include>../..
|
||||
<toolset>gcc:<cxxflags>"-pedantic -Wall -Wstrict-aliasing -fstrict-aliasing -Wno-long-long"
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE # For Ublas
|
||||
<dependency>/boost//headers
|
||||
;
|
||||
|
@ -111,6 +111,12 @@ public :
|
||||
typename geometry::range_type<Geometry2>::type const
|
||||
>::type range2_iterator;
|
||||
|
||||
range1_iterator begin_range_1, end_range_1;
|
||||
get_full_section(geometry1, sec1, begin_range_1, end_range_1);
|
||||
|
||||
range2_iterator begin_range_2, end_range_2;
|
||||
get_full_section(geometry2, sec2, begin_range_2, end_range_2);
|
||||
|
||||
int const dir1 = sec1.directions[0];
|
||||
int const dir2 = sec2.directions[0];
|
||||
int index1 = sec1.begin_index;
|
||||
@ -122,13 +128,18 @@ public :
|
||||
&& sec1.ring_index == sec2.ring_index;
|
||||
|
||||
range1_iterator prev1, it1, end1;
|
||||
range1_iterator begin_range_1, end_range_1;
|
||||
|
||||
ever_circling_iterator<range1_iterator> next1
|
||||
= start_at_section(sec1, prev1, it1, end1, begin_range_1, end_range_1,
|
||||
get_start_point_iterator(sec1, prev1, it1, end1,
|
||||
index1, ndi1, geometry1, dir1, sec2.bounding_box);
|
||||
|
||||
// We need a circular iterator because it might run through the closing point.
|
||||
// One circle is actually enough but this one is just convenient.
|
||||
ever_circling_iterator<range1_iterator> next1(begin_range_1, end_range_1, it1, true);
|
||||
next1++;
|
||||
|
||||
// Walk through section and stop if we exceed the other box
|
||||
// section 2: [--------------]
|
||||
// section 1: |----|---|---|---|---|
|
||||
for (prev1 = it1++, next1++;
|
||||
it1 != end1 && ! exceeding<0>(dir1, *prev1, sec2.bounding_box);
|
||||
prev1 = it1++, index1++, next1++, ndi1++)
|
||||
@ -141,11 +152,11 @@ public :
|
||||
int ndi2 = sec2.non_duplicate_index;
|
||||
|
||||
range2_iterator prev2, it2, end2;
|
||||
range2_iterator begin_range_2, end_range_2;
|
||||
|
||||
ever_circling_iterator<range2_iterator> next2 =
|
||||
start_at_section(sec2, prev2, it2, end2, begin_range_2, end_range_2,
|
||||
get_start_point_iterator(sec2, prev2, it2, end2,
|
||||
index2, ndi2, geometry2, dir2, sec1.bounding_box);
|
||||
ever_circling_iterator<range2_iterator> next2(begin_range_2, end_range_2, it2, true);
|
||||
next2++;
|
||||
|
||||
for (prev2 = it2++, next2++;
|
||||
it2 != end2 && ! exceeding<0>(dir2, *prev2, sec1.bounding_box);
|
||||
@ -264,9 +275,8 @@ private :
|
||||
// skips to the begin-point, we loose the index or have to recalculate it)
|
||||
// So we mimic it here
|
||||
template <typename RangeIterator, typename Section, typename Geometry, typename Box>
|
||||
static inline ever_circling_iterator<RangeIterator> start_at_section(Section & section,
|
||||
static inline RangeIterator get_start_point_iterator(Section & section,
|
||||
RangeIterator& it, RangeIterator& prev, RangeIterator& end,
|
||||
RangeIterator& begin_range_it, RangeIterator& end_range_it,
|
||||
int& index, int& ndi,
|
||||
Geometry const& geometry,
|
||||
int dir, Box const& other_bounding_box)
|
||||
@ -281,12 +291,7 @@ private :
|
||||
{}
|
||||
// Go back one step because we want to start completely preceding
|
||||
it = prev;
|
||||
|
||||
get_full_section(geometry, section, begin_range_it, end_range_it);
|
||||
|
||||
ever_circling_iterator<RangeIterator> next(begin_range_it, end_range_it, it, true);
|
||||
next++;
|
||||
return next;
|
||||
return it;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#ifndef BOOST_GEOMETRY_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
|
||||
#define BOOST_GEOMETRY_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
@ -90,6 +91,69 @@ private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename Range>
|
||||
class ever_circling_range_iterator
|
||||
: public boost::iterator_adaptor
|
||||
<
|
||||
ever_circling_range_iterator<Range>,
|
||||
typename boost::range_iterator<Range>::type
|
||||
>
|
||||
{
|
||||
public :
|
||||
typedef typename boost::range_iterator<Range>::type iterator_type;
|
||||
|
||||
explicit inline ever_circling_range_iterator(Range& range,
|
||||
bool skip_first = false)
|
||||
: m_range(range)
|
||||
, m_skip_first(skip_first)
|
||||
{
|
||||
this->base_reference() = boost::begin(m_range);
|
||||
}
|
||||
|
||||
explicit inline ever_circling_range_iterator(Range& range, iterator_type start,
|
||||
bool skip_first = false)
|
||||
: m_range(range)
|
||||
, m_skip_first(skip_first)
|
||||
{
|
||||
this->base_reference() = start;
|
||||
}
|
||||
|
||||
/// Navigate to a certain position, should be in [start .. end], if at end
|
||||
/// it will circle again.
|
||||
inline void moveto(iterator_type it)
|
||||
{
|
||||
this->base_reference() = it;
|
||||
check_end();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
inline void increment(bool possibly_skip = true)
|
||||
{
|
||||
(this->base_reference())++;
|
||||
check_end(possibly_skip);
|
||||
}
|
||||
|
||||
inline void check_end(bool possibly_skip = true)
|
||||
{
|
||||
if (this->base_reference() == boost::end(m_range))
|
||||
{
|
||||
this->base_reference() = boost::begin(m_range);
|
||||
if (m_skip_first && possibly_skip)
|
||||
{
|
||||
increment(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Range& m_range;
|
||||
bool m_skip_first;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
|
||||
|
@ -22,7 +22,7 @@ void test_geometry(std::string const& wkt)
|
||||
{
|
||||
G geo;
|
||||
boost::geometry::read_wkt(wkt, geo);
|
||||
typedef typename boost::range_const_iterator<G>::type iterator_type;
|
||||
typedef typename boost::range_iterator<G const>::type iterator_type;
|
||||
|
||||
|
||||
// Run 3 times through the geometry
|
||||
@ -64,6 +64,16 @@ void test_geometry(std::string const& wkt)
|
||||
BOOST_CHECK_EQUAL(out.str(), "543215432154321");
|
||||
}
|
||||
|
||||
// Check the range_iterator-one
|
||||
{
|
||||
std::ostringstream out;
|
||||
boost::geometry::ever_circling_range_iterator<G> it(geo);
|
||||
for (int i = 0; i < n; ++i, ++it)
|
||||
{
|
||||
out << boost::geometry::get<0>(*it);
|
||||
}
|
||||
BOOST_CHECK_EQUAL(out.str(), "123451234512345");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
|
Loading…
Reference in New Issue
Block a user