|
Geometry : |
Subject: [ggl] box_range is not a valid range
From: zzsj (feverzsj)
Date: 2011-05-12 09:39:20
hi, Barend
> Besides this I also fixed/implemented the point_order on a box_view, if
> you specify Reverse it is counter clockwise, as expected. Closure might
> complete it (but requires another copy-policy and an adapted approach).
In the old solution, Closure could be simply achieved by setting the end index. For example:
template<typename Box, bool ClockWise = true, bool Closed = true>
class box2d_range
{
...
const_iterator begin() const { return const_iterator(m_points, 0); }
const_iterator end() const { return const_iterator(m_points, 4 + Closed); }
void init(Box const& box)
{
ggl::detail::assign_box_corners_oriented<!ClockWise>(box, m_points);
}
private :
point_type m_points[4];
}
This could be also possible for points_view.
>> Also, now that box_view is of ring type, why it cannot be an opened ring?
>> The view concept is a kinda confusing concept. It mixes the range and geometry concepts.
>> I think the view concept should follow the range concept.
>> As mentioned in "[ggl] transform linestring into a ring", I found two geometry wrappers very useful in many aspects. Here they are:
>
> OK, we will think / discuss about this.
Thanks. I've attached my ggl helpers. It includes the two wrappers(support box with box2d_range), and some useful functions.
regards, ZhouShuangJiang
-------------- next part --------------
#ifndef _GGL_HELPER_H_2011_4_15_15_34_12
#define _GGL_HELPER_H_2011_4_15_15_34_12
#include <boost/range.hpp>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/multi/multi.hpp>
#include <boost/geometry/views/box_view.hpp>
#include <boost/geometry/geometries/register/point.hpp>
namespace ggl = boost::geometry;
// test if a ring is oriented correctly with resepect
// to the presumed orientation
template<class Ring>
inline bool valid_orientation(Ring const& r)
{
return boost::geometry::area(r) > 0;
}
// test if a ring's actaul closure is same as its presumed closure;
template<class Ring>
inline bool valid_closure(Ring const& r)
{
if(boost::size(r) < 3)
return false; // ?
if(ggl::disjoint(*boost::begin(r), *(boost::end(r) - 1)))
return ggl::closure<Ring>::value == ggl::open;
return ggl::closure<Ring>::value == ggl::closed;
}
template<typename Box, bool ClockWise = true, bool Closed = true>
class box2d_range
{
public :
typedef typename ggl::point_type<Box>::type point_type;
struct box2d_iterator
: public boost::iterator_facade<
box2d_iterator,
point_type const, // read only
boost::random_access_traversal_tag
>
{
box2d_iterator(point_type const* p = 0, int i = 0)
: m_points(p), m_index(i) {}
typedef std::ptrdiff_t difference_type;
private:
friend class boost::iterator_core_access;
point_type const& dereference() const
{
assert(m_points);
if (m_index >= 0 && m_index <= 3)
{
return m_points[m_index];
}
// If it index is 4, or other, return first point
return m_points[0];
}
bool equal(box2d_iterator const& other) const
{
return other.m_index == m_index;
}
void increment()
{
m_index++;
}
void decrement()
{
m_index--;
}
void advance(difference_type n)
{
m_index += n;
}
difference_type distance_to(box2d_iterator const& other) const
{
return other.m_index - m_index;
}
int m_index;
point_type const* m_points;
};
typedef box2d_iterator const_iterator;
typedef box2d_iterator iterator; // must be defined
explicit box2d_range(Box const& box)
{
init(box);
}
const_iterator begin() const { return const_iterator(m_points, 0); }
const_iterator end() const { return const_iterator(m_points, 4 + Closed); }
// It may not be used non-const, so comment this:
//iterator begin() { return m_begin; }
//iterator end() { return m_end; }
void init(Box const& box)
{
ggl::detail::assign_box_corners_oriented<!ClockWise>(box, m_points);
}
private :
point_type m_points[4];
};
namespace detail{
template<class tag, class X, bool CloseOpenedRing, bool ClosedBox, bool ClockwiseBox>
struct linestring_wrapper_dispatch // default for range
{
typedef ggl::identity_view<X> base_type;
};
template<class X, bool CloseOpenedRing, bool ClosedBox, bool ClockwiseBox>
struct linestring_wrapper_dispatch<ggl::ring_tag, X, CloseOpenedRing, ClosedBox, ClockwiseBox>
{
typedef typename boost::mpl::if_c<CloseOpenedRing,
typename ggl::closeable_view<X, ggl::closure<X>::value>::type,
ggl::identity_view<X>
>::type base_type;
};
template<class X, bool CloseOpenedRing, bool ClosedBox, bool ClockwiseBox>
struct linestring_wrapper_dispatch<ggl::box_tag, X, CloseOpenedRing, ClosedBox, ClockwiseBox>
{
typedef box2d_range<X, ClosedBox, ClockwiseBox> base_type;
};
template<class tag, class X, bool ClockWise, bool Closed>
struct ring_wrapper_dispatch // default for range/linestring
{
typedef ggl::identity_view<X> base_type;
};
template<class X, bool ClockWise, bool Closed>
struct ring_wrapper_dispatch<ggl::box_tag, X, ClockWise, Closed>
{
typedef box2d_range<X, ClockWise, Closed> base_type;
};
} // namespace detail
// warp X as linestring
// X : ring, box, range/other geometry(since other geometry type could be already a range type)
// CloseOpenedRing : close presumed open ring if set to true, otherwise do nothing, ignored if X is box
// note: box is added for convenience, user can also use box2d_range to transform box into wanted range.
template<class X, bool CloseOpenedRing = true,
bool ClosedBox = true, bool ClockwiseBox = true>
struct linestring_wrapper
: public detail::linestring_wrapper_dispatch<
typename ggl::tag<X>::type, X, CloseOpenedRing, ClosedBox, ClockwiseBox>::base_type
{
typedef typename detail::linestring_wrapper_dispatch<
typename ggl::tag<X>::type, X, CloseOpenedRing, ClosedBox, ClockwiseBox>::base_type base_type;
explicit linestring_wrapper(X& x) : base_type(x) {}
};
// for defalut
template<class X>
inline linestring_wrapper<X> as_linestring(X& x)
{
return linestring_wrapper<X>(x);
}
template<class X>
inline linestring_wrapper<X const> as_linestring(X const& x)
{
return linestring_wrapper<X const>(x);
}
// for ring
template<bool CloseOpenedRing, class Ring>
inline linestring_wrapper<Ring, CloseOpenedRing> as_linestring(Ring& r)
{
return linestring_wrapper<Ring, CloseOpenedRing>(r);
}
template<bool CloseOpenedRing, class Ring>
inline linestring_wrapper<Ring const, CloseOpenedRing> as_linestring(Ring const& r)
{
return linestring_wrapper<Ring const, CloseOpenedRing>(r);
}
// for box
template<bool ClosedBox, bool ClockwiseBox, class Box>
inline linestring_wrapper<Box, false, ClosedBox, ClockwiseBox> as_linestring(Box& b)
{
return linestring_wrapper<Box, false, ClosedBox, ClockwiseBox>(b);
}
template<bool ClosedBox, bool ClockwiseBox, class Box>
inline linestring_wrapper<Box const, false, ClosedBox, ClockwiseBox> as_linestring(Box const& b)
{
return linestring_wrapper<Box const, false, ClosedBox, ClockwiseBox>(b);
}
// warp X as ring
// X : linestring, box, range/other geometry(since other geometry type could be already a range type)
template<class X, bool ClockWise = true, bool Closed = false> // note: presumed open on default
struct ring_wrapper
: public detail::ring_wrapper_dispatch<
typename ggl::tag<X>::type, X, ClockWise, Closed>::base_type
{
typedef typename detail::ring_wrapper_dispatch<
typename ggl::tag<X>::type, X, ClockWise, Closed>::base_type base_type;
ring_wrapper(X& x) : base_type(x) {}
};
template<class X>
inline ring_wrapper<X> as_ring(X& x)
{
return ring_wrapper<X>(x);
}
template<class X>
inline ring_wrapper<X const> as_ring(X const& x)
{
return ring_wrapper<X const>(x);
}
template<bool ClockWise, bool Closed, class X>
inline ring_wrapper<X, ClockWise, Closed> as_ring(X& x)
{
return ring_wrapper<X, ClockWise, Closed>(x);
}
template<bool ClockWise, bool Closed, class X>
inline ring_wrapper<X const, ClockWise, Closed> as_ring(X const& x)
{
return ring_wrapper<X const, ClockWise, Closed>(x);
}
namespace boost{ namespace geometry{ namespace traits{
// for linestring_wrapper
template<class X, bool CloseOpenedRing, bool ClosedBox, bool ClockwiseBox>
struct tag<linestring_wrapper<X, CloseOpenedRing, ClosedBox, ClockwiseBox> >
{
typedef linestring_tag type;
};
// for ring_wrapper
template<class X, bool ClockWise, bool Closed>
struct tag<ring_wrapper<X, ClockWise, Closed> >
{
typedef ring_tag type;
};
template<class X, bool Closed>
struct point_order<ring_wrapper<X, false, Closed> >
{
static const order_selector value = counterclockwise;
};
template<class X, bool Closed>
struct point_order<ring_wrapper<X, true, Closed> >
{
static const order_selector value = clockwise;
};
template<class X, bool PointOrder>
struct closure<ring_wrapper<X, PointOrder, true> >
{
static const closure_selector value = closed;
};
template<class X, bool PointOrder>
struct closure<ring_wrapper<X, PointOrder, false> >
{
static const closure_selector value = open;
};
} } } // namespace boost::geometry::traits
#endif /* _GGL_HELPER_H_2011_4_15_15_34_12 */
Geometry list run by mateusz at loskot.net