geometry_iterator code documentation.
This commit is contained in:
parent
4720303507
commit
6f6b161c7c
2 changed files with 69 additions and 7 deletions
|
@ -33,6 +33,20 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
/*
|
||||
* @brief Iterator class used to iterate over geometry vertexes.
|
||||
* Since mapnik::geometry provides access to the components of
|
||||
* a vertex only through variables passed by reference,
|
||||
* geometry_iterator retrieves these components (command, x coord,
|
||||
* and y coord) and makes them available inside tuples.
|
||||
*
|
||||
* This iterator exposes the behavior of a forward iterator and
|
||||
* subclasses boost::iterator_adaptor, which already implements
|
||||
* several iterator operations, such as dereferencing.
|
||||
*
|
||||
* @tparam Value the type of sequence element dereferenced.
|
||||
* @tparam Container the sequence over which it iterates.
|
||||
*/
|
||||
template <typename Value, typename Container=geometry_type>
|
||||
class geometry_iterator
|
||||
: public boost::iterator_adaptor<geometry_iterator<Value, Container>,
|
||||
|
@ -44,14 +58,32 @@ public:
|
|||
typedef Value value_type;
|
||||
typedef Container container_type;
|
||||
|
||||
/*!
|
||||
* @brief Constructor that initializes the reference to the current element to null.
|
||||
* This constructor is suitable to mark the end of the iterator (analogous to
|
||||
* calling end_iterator() in an STL container).
|
||||
*
|
||||
* @param geometry the geometry that handles the vector of vertexes.
|
||||
*/
|
||||
geometry_iterator(Container const& geometry)
|
||||
: geometry_iterator::iterator_adaptor_(0),
|
||||
geometry_(geometry),
|
||||
first_value_(new Value(0,0,0,0,0))
|
||||
{}
|
||||
|
||||
explicit geometry_iterator(Value* p, Container const& geometry)
|
||||
: geometry_iterator::iterator_adaptor_(p),
|
||||
/*!
|
||||
* This constructor receives the first element of the sequence as a pointer.
|
||||
* Since the container type will likely be a mapnik::geometry, this
|
||||
* first element would need to be obtained in a similar way as the increment
|
||||
* method below. For this reason, most of the time this constructor will
|
||||
* be called with a null pointer. The body of the constructor makes a call
|
||||
* to increment() in order to obtain this first element from the container.
|
||||
*
|
||||
* @param p pointer to the first element of the sequence.
|
||||
* @param geometry the geometry that handles the vector of vertexes.
|
||||
*/
|
||||
explicit geometry_iterator(Value* first_element, Container const& geometry)
|
||||
: geometry_iterator::iterator_adaptor_(first_element),
|
||||
geometry_(geometry),
|
||||
first_value_(new Value(0,0,0,0,0))
|
||||
{
|
||||
|
@ -60,6 +92,10 @@ public:
|
|||
|
||||
struct enabler {};
|
||||
|
||||
/*!
|
||||
* @brief Constructor that enables operation between const and non-const iterators.
|
||||
* @sa http://www.boost.org/doc/libs/1_45_0/libs/iterator/doc/iterator_facade.html#interoperability
|
||||
*/
|
||||
template <typename OtherValue>
|
||||
geometry_iterator(geometry_iterator<OtherValue> const& other,
|
||||
typename boost::enable_if<boost::is_convertible<OtherValue*, Value*>,
|
||||
|
@ -67,29 +103,55 @@ public:
|
|||
: geometry_iterator::iterator_adaptor_(other.base()) {}
|
||||
|
||||
private:
|
||||
|
||||
// grant access to iterator_adaptor to handle iteration properly.
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
/*!
|
||||
* @brief Advance the iterator.
|
||||
*/
|
||||
void increment()
|
||||
{
|
||||
// variables used to extract vertex components.
|
||||
geometry_type::value_type x;
|
||||
geometry_type::value_type y;
|
||||
|
||||
// extract next vertex components.
|
||||
unsigned cmd = geometry_.vertex(&x, &y);
|
||||
|
||||
if(cmd == SEG_END)
|
||||
{
|
||||
// if the end of the sequence is reached, set the reference
|
||||
// to the current element to null, so it matches the value
|
||||
// that marks the end of the sequence as defined in the
|
||||
// "end_iterator" constructor.
|
||||
this->base_reference() = 0;
|
||||
}
|
||||
else if(this->base_reference() == 0)
|
||||
{
|
||||
// the first element of the container is stored in the
|
||||
// member variable 'first_value_' and later assigned
|
||||
// to the reference that boost::iterator_adaptor stores
|
||||
// to track the current element.
|
||||
//
|
||||
// 'first_value_' is used as intermediate storage
|
||||
// because the compiler prohibits the assignment of the
|
||||
// address of a temporary object (&Value(...)).
|
||||
*first_value_ = Value(cmd, x, y, x, y);
|
||||
this->base_reference() = first_value_.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
// point the reference to the current element to the next.
|
||||
*(this->base_reference()) = Value(cmd, x, y, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Test whether the current element is equal to 'other'.
|
||||
* @tparam OtherValue the value type of the other iterator (it may be const or non-const).
|
||||
* @param other iterator to compare to current element.
|
||||
*/
|
||||
template <typename OtherValue>
|
||||
bool equal(geometry_iterator<OtherValue, Container> const& other) const
|
||||
{
|
||||
|
@ -100,6 +162,11 @@ private:
|
|||
boost::shared_ptr<Value> first_value_;
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief Specialization of geometry_iterator, as needed by mapnik::svg::svg_path_data_grammar.
|
||||
* The Value type is a boost::tuple that holds 5 elements, the command and the x and y coordinate.
|
||||
* Each coordinate is stored twice to match the needs the grammar.
|
||||
*/
|
||||
typedef geometry_iterator<boost::tuple<unsigned, geometry_type::value_type, geometry_type::value_type, geometry_type::value_type, geometry_type::value_type>, geometry_type> geometry_iterator_type;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,18 +102,15 @@ namespace boost { namespace spirit { namespace traits {
|
|||
template <>
|
||||
struct container_iterator<mapnik::geometry_type const>
|
||||
{
|
||||
//typedef mapnik::geometry_type::iterator type;
|
||||
typedef mapnik::geometry_iterator_type type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct begin_container<mapnik::geometry_type const>
|
||||
{
|
||||
//static mapnik::geometry_type::iterator
|
||||
static mapnik::geometry_iterator_type
|
||||
call(mapnik::geometry_type const& g)
|
||||
{
|
||||
//return g.begin();
|
||||
return mapnik::geometry_iterator_type(0, g);
|
||||
}
|
||||
};
|
||||
|
@ -121,11 +118,9 @@ namespace boost { namespace spirit { namespace traits {
|
|||
template <>
|
||||
struct end_container<mapnik::geometry_type const>
|
||||
{
|
||||
//static mapnik::geometry_type::iterator
|
||||
static mapnik::geometry_iterator_type
|
||||
call(mapnik::geometry_type const& g)
|
||||
{
|
||||
//return g.end();
|
||||
return mapnik::geometry_iterator_type(g);
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue