[ create a new paste ] login | about

Link: http://codepad.org/4a3TxTGN    [ raw code | fork ]

C++, pasted on Feb 19:
#include <iostream>

#include <boost/geometry.hpp>
#include <boost/range.hpp>

#include <boost/iterator/iterator_facade.hpp>

#include "objdefs.hpp"

namespace boost {

    namespace geometry {

        namespace traits {

            // Adapt points to Boost.Geometry
            
            template<> struct tag<QPoint>
            { typedef point_tag type; };

            template<> struct coordinate_type<QPoint>
            { typedef double type; };

            template<> struct coordinate_system<QPoint>
            { typedef cs::cartesian type; };

            template<> struct dimension<QPoint> : boost::mpl::int_<2> {};

            template<>
            struct access<QPoint, 0>
            {
                static double get(QPoint const& p)
                {
                    return p.x;
                }

                static void set(QPoint& p, double const& value)
                {
                    p.x = value;
                }
            };

            template<>
            struct access<QPoint, 1>
            {
                static double get(QPoint const& p)
                {
                    return p.y;
                }

                static void set(QPoint& p, double const& value)
                {
                    p.y = value;
                }
            };


            // POINTER version - still necessary for QLineString*

            template<> struct tag<QPoint*>
            { typedef point_tag type; };

            template<> struct coordinate_type<QPoint*>
            { typedef double type; };

            template<> struct coordinate_system<QPoint*>
            { typedef cs::cartesian type; };

            template<> struct dimension<QPoint*> : boost::mpl::int_<2> {};

            template<>
            struct access<QPoint*, 0>
            {
                static double get(QPoint* const& p)
                {
                    return p->x;
                }

                static void set(QPoint*& p, double const& value)
                {
                    p->x = value;
                }
            };

            template<>
            struct access<QPoint*, 1>
            {
                static double get(QPoint* const& p)
                {
                    return p->y;
                }

                static void set(QPoint*& p, double const& value)
                {
                    p->y = value;
                }
            };

        }

        
        
    }

} // namespace boost::geometry::traits

namespace boost
{

	//
	// Specialize metafunctions. We must include the range.hpp header.
	// We must open the 'boost' namespace.
	//

	template<>
	struct range_iterator< QLineString* >
	{
		typedef std::vector<QPoint*>::iterator type;
	};

	template<>
	struct range_const_iterator< QLineString* >
	{
		//
		// Remark: this is defined similar to 'range_iterator'
		//         because the 'Pair' type does not distinguish
		//         between an iterator and a const_iterator.
		//
		typedef std::vector<QPoint*>::const_iterator type;
	};

	template<>
	struct range_size< QLineString* >
	{

		typedef std::size_t type;
	};

} // namespace boost

	//
	// The required functions. These should be defined in
	// the same namespace as 'Pair', in this case
	// in namespace 'Foo'.
	//


	inline std::vector<QPoint*>::iterator range_begin( QLineString* x )
	{
		return x->points.begin();
	}


	inline std::vector<QPoint*>::const_iterator range_begin( const QLineString* x )
	{
		return x->points.begin();
	}


	inline std::vector<QPoint*>::iterator range_end( QLineString* x )
	{
		return x->points.end();
	}


	inline std::vector<QPoint*>::const_iterator range_end( const QLineString* x )
	{
		return x->points.end();
	}

	inline std::vector<QPoint*>::size_type
	range_size( const QLineString* x )
	{
		return x->points.size();
	}

//BOOST_GEOMETRY_REGISTER_LINESTRING(QLineString);
namespace boost {
    namespace geometry {
        namespace traits {
            template
            <>
            struct tag<QLineString*>
            {
                typedef linestring_tag type;
            };
        }
    }
}

// Ring adaption

    /* Custom iterator type that flattens a 2D array into a 1D array */
    template <class I, // Line iterator type
              class R  // Point reference type
             >
    class RingIteratorImpl : public boost::iterator_facade<
            RingIteratorImpl<I,R>, R, boost::forward_traversal_tag, R>
    {
    public:
        RingIteratorImpl() : lineStringIter_(0), pointIndex_(0) {}

        explicit RingIteratorImpl(I lineStringIter)
        :   lineStringIter_(lineStringIter), pointIndex_(0) {}

    private:
        friend class boost::iterator_core_access;

        void increment()
        {
            ++pointIndex_;
            if (pointIndex_ >= (*lineStringIter_)->points.size())
            {
                ++lineStringIter_;
                pointIndex_ = 0;
            }
        }

        bool equal(const RingIteratorImpl& other) const
        {
            return (lineStringIter_ == other.lineStringIter_) &&
                   (pointIndex_ == other.pointIndex_);
        }

        R dereference() const {return *(*lineStringIter_)->points[pointIndex_];}

        I lineStringIter_;
        size_t pointIndex_;
    };

    typedef RingIteratorImpl<std::vector<QLineString*>::iterator, QPoint> RingIterator;
    typedef RingIteratorImpl<std::vector<QLineString*>::const_iterator, const QPoint>
            ConstRingIterator;

    namespace boost
    {
        // Specialize metafunctions. We must include the range.hpp header.
        // We must open the 'boost' namespace.

        template <>
        struct range_mutable_iterator<QRing> { typedef RingIterator type; };

    	template<>
        struct range_const_iterator<QRing> { typedef ConstRingIterator type; };

    } // namespace 'boost'


    // The required Range functions. These should be defined in the same namespace
    // as Ring.

    inline RingIterator range_begin(QRing& r)
        {return RingIterator(r.lines.begin());}

    inline ConstRingIterator range_begin(const QRing& r)
        {return ConstRingIterator(r.lines.begin());}

    inline RingIterator range_end(QRing& r)
        {return RingIterator(r.lines.end());}

    inline ConstRingIterator range_end(const QRing& r)
        {return ConstRingIterator(r.lines.end());}

namespace boost {
namespace geometry {
namespace traits {

template <>
struct tag<QRing>
{
    typedef ring_tag type;
};

/*
template
<
    typename Point,
    bool Closed,
    template<typename, typename> class Container,
    template<typename> class Allocator
>
struct point_order<QRing>
{
    static const order_selector value = counterclockwise;
};


template
<
    typename Point,
    bool Closed,
    template<typename, typename> class Container,
    template<typename> class Allocator
>
struct point_order<QRing>
{
    static const order_selector value = clockwise;
};

template
<
    typename Point,
    bool PointOrder,
    template<typename, typename> class Container,
    template<typename> class Allocator
>
struct closure<QRing>
{
    static const closure_selector value = closed;
};

template
<
    typename Point,
    bool PointOrder,
    template<typename, typename> class Container,
    template<typename> class Allocator
>
struct closure<QRing>
{
    static const closure_selector value = open;
};
*/
} // namespace traits
} // namespace geometry
} // namespace boost

int main()
{

    QPoint* pP1 = new QPoint(1,2);
    QPoint* pP2 = new QPoint(2,3);
    QPoint* pP3 = new QPoint(3,4);

    QPoint* pP4 =  new QPoint(5,6);
    QPoint* pP5 =  new QPoint(7,8);
    QPoint* pP6 =  new QPoint(9,10);

    QLineString* pls = new QLineString();
    pls->cw = true;
    pls->points.push_back(pP1);
    pls->points.push_back(pP2);
    pls->points.push_back(pP3);

    std::cout << boost::geometry::wkt(pls) << std::endl;


    QLineString* pls2 = new QLineString();
    pls2->cw = true;
    pls2->points.push_back(pP4);
    pls2->points.push_back(pP5);
    pls2->points.push_back(pP6);

    std::cout << boost::geometry::wkt(pls2) << std::endl;

    QRing r1 = QRing();

    r1.lines.push_back(pls);
    r1.lines.push_back(pls2);

    RingIterator ri = range_begin(r1);
    ri++;
    ri++;
    QPoint& p = *ri;
    p.x = 50;
    std::cout << boost::geometry::wkt(p) << std::endl;
    
    std::cout << boost::geometry::wkt(r1) << std::endl;

    QPoint const& pc = *ri;
    std::cout << boost::geometry::wkt(pc) << std::endl;
    
    return 0;
}


Create a new paste based on this one


Comments: