diff options
Diffstat (limited to 'boost/geometry/geometries/adapted/boost_polygon')
7 files changed, 1106 insertions, 0 deletions
diff --git a/boost/geometry/geometries/adapted/boost_polygon/box.hpp b/boost/geometry/geometries/adapted/boost_polygon/box.hpp new file mode 100644 index 0000000000..87c3b60650 --- /dev/null +++ b/boost/geometry/geometries/adapted/boost_polygon/box.hpp @@ -0,0 +1,141 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_BOX_HPP +#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_BOX_HPP + +// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry +// boost::polygon::rectangle_data -> boost::geometry::box + + +#include <boost/polygon/polygon.hpp> + +#include <boost/geometry/core/access.hpp> +#include <boost/geometry/core/cs.hpp> +#include <boost/geometry/core/coordinate_dimension.hpp> +#include <boost/geometry/core/coordinate_type.hpp> +#include <boost/geometry/core/tags.hpp> + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS +namespace traits +{ + + +template <typename CoordinateType> +struct tag<boost::polygon::rectangle_data<CoordinateType> > +{ + typedef box_tag type; +}; + + +template <typename CoordinateType> +struct point_type<boost::polygon::rectangle_data<CoordinateType> > +{ + // Not sure what to do here. Boost.Polygon's rectangle does NOT define its + // point_type (but uses it...) + typedef boost::polygon::point_data<CoordinateType> type; +}; + + +template <typename CoordinateType> +struct indexed_access +< + boost::polygon::rectangle_data<CoordinateType>, + min_corner, 0 +> +{ + typedef boost::polygon::rectangle_data<CoordinateType> box_type; + + static inline CoordinateType get(box_type const& b) + { + return boost::polygon::xl(b); + } + + static inline void set(box_type& b, CoordinateType const& value) + { + boost::polygon::xl(b, value); + } +}; + + +template <typename CoordinateType> +struct indexed_access +< + boost::polygon::rectangle_data<CoordinateType>, + min_corner, 1 +> +{ + typedef boost::polygon::rectangle_data<CoordinateType> box_type; + + static inline CoordinateType get(box_type const& b) + { + return boost::polygon::yl(b); + } + + static inline void set(box_type& b, CoordinateType const& value) + { + boost::polygon::yl(b, value); + } +}; + + +template <typename CoordinateType> +struct indexed_access +< + boost::polygon::rectangle_data<CoordinateType>, + max_corner, 0 +> +{ + typedef boost::polygon::rectangle_data<CoordinateType> box_type; + + static inline CoordinateType get(box_type const& b) + { + return boost::polygon::xh(b); + } + + static inline void set(box_type& b, CoordinateType const& value) + { + boost::polygon::xh(b, value); + } +}; + + +template <typename CoordinateType> +struct indexed_access +< + boost::polygon::rectangle_data<CoordinateType>, + max_corner, 1 +> +{ + typedef boost::polygon::rectangle_data<CoordinateType> box_type; + + static inline CoordinateType get(box_type const& b) + { + return boost::polygon::yh(b); + } + + static inline void set(box_type& b, CoordinateType const& value) + { + boost::polygon::yh(b, value); + } +}; + + +} // namespace traits +#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_BOX_HPP diff --git a/boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp b/boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp new file mode 100644 index 0000000000..c9c1bc7b61 --- /dev/null +++ b/boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp @@ -0,0 +1,84 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLE_ITERATOR_HPP +#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLE_ITERATOR_HPP + +// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry +// boost::polygon::polygon_with_holes_data -> boost::geometry::polygon +// hole_iterator -> returning ring_proxy's instead of normal polygon_data + +#include <boost/polygon/polygon.hpp> + +#include <boost/iterator.hpp> +#include <boost/iterator/iterator_facade.hpp> + + +namespace boost { namespace geometry +{ + +namespace adapt { namespace bp +{ + + +template <typename Polygon, typename RingProxy> +class hole_iterator + : public ::boost::iterator_facade + < + hole_iterator<Polygon, RingProxy>, + RingProxy, // value type + boost::forward_traversal_tag, + RingProxy // reference type + > +{ +public : + typedef typename boost::polygon::polygon_with_holes_traits + < + Polygon + >::iterator_holes_type ith_type; + + explicit inline hole_iterator(Polygon& polygon, ith_type const it) + : m_polygon(polygon) + , m_base(it) + { + } + + typedef std::ptrdiff_t difference_type; + +private: + friend class boost::iterator_core_access; + + inline RingProxy dereference() const + { + return RingProxy(m_polygon, this->m_base); + } + + inline void increment() { ++m_base; } + inline void decrement() { --m_base; } + inline void advance(difference_type n) + { + for (int i = 0; i < n; i++) + { + ++m_base; + } + } + + inline bool equal(hole_iterator<Polygon, RingProxy> const& other) const + { + return this->m_base == other.m_base; + } + + Polygon& m_polygon; + ith_type m_base; +}; + + +}}}} + +#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLE_ITERATOR_HPP + diff --git a/boost/geometry/geometries/adapted/boost_polygon/holes_proxy.hpp b/boost/geometry/geometries/adapted/boost_polygon/holes_proxy.hpp new file mode 100644 index 0000000000..c2a6a44dba --- /dev/null +++ b/boost/geometry/geometries/adapted/boost_polygon/holes_proxy.hpp @@ -0,0 +1,204 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLES_PROXY_HPP +#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLES_PROXY_HPP + +// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry +// boost::polygon::polygon_with_holes_data -> boost::geometry::polygon +// pair{begin_holes, begin_holes} -> interior_proxy + +#include <boost/polygon/polygon.hpp> + +#include <boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp> +#include <boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp> + + +namespace boost { namespace geometry +{ + +namespace adapt { namespace bp +{ + + +// Polygon should implement the boost::polygon::polygon_with_holes_concept +// Specify constness in the template parameter if necessary +template<typename Polygon> +struct holes_proxy +{ + typedef ring_proxy + < + typename boost::mpl::if_ + < + typename boost::is_const<Polygon>, + Polygon const, + Polygon + >::type + > proxy_type; + typedef hole_iterator<Polygon, proxy_type> iterator_type; + + // The next line does not work probably because coordinate_type is part of the + // polygon_traits, but not of the polygon_with_holes_traits + // typedef typename boost::polygon::polygon_traits<Polygon>::coordinate_type coordinate_type; + + // So we use: + typedef typename Polygon::coordinate_type coordinate_type; + + inline holes_proxy(Polygon& p) + : polygon(p) + {} + + inline void clear() + { + Polygon empty; + // Clear the holes + polygon.set_holes + ( + boost::polygon::begin_holes(empty), + boost::polygon::end_holes(empty) + ); + } + + inline void resize(std::size_t new_size) + { + std::vector<boost::polygon::polygon_data<coordinate_type> > temporary_copy + ( + boost::polygon::begin_holes(polygon), + boost::polygon::end_holes(polygon) + ); + temporary_copy.resize(new_size); + polygon.set_holes(temporary_copy.begin(), temporary_copy.end()); + } + + template <typename Ring> + inline void push_back(Ring const& ring) + { + std::vector<boost::polygon::polygon_data<coordinate_type> > temporary_copy + ( + boost::polygon::begin_holes(polygon), + boost::polygon::end_holes(polygon) + ); + boost::polygon::polygon_data<coordinate_type> added; + boost::polygon::set_points(added, ring.begin(), ring.end()); + temporary_copy.push_back(added); + polygon.set_holes(temporary_copy.begin(), temporary_copy.end()); + } + + + Polygon& polygon; +}; + + +// Support holes_proxy for Boost.Range ADP + +// Const versions +template<typename Polygon> +inline typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type + range_begin(boost::geometry::adapt::bp::holes_proxy<Polygon const> const& proxy) +{ + typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type + begin(proxy.polygon, boost::polygon::begin_holes(proxy.polygon)); + return begin; +} + +template<typename Polygon> +inline typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type + range_end(boost::geometry::adapt::bp::holes_proxy<Polygon const> const& proxy) +{ + typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type + end(proxy.polygon, boost::polygon::end_holes(proxy.polygon)); + return end; +} + +// Mutable versions +template<typename Polygon> +inline typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type + range_begin(boost::geometry::adapt::bp::holes_proxy<Polygon>& proxy) +{ + typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type + begin(proxy.polygon, boost::polygon::begin_holes(proxy.polygon)); + return begin; +} + +template<typename Polygon> +inline typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type + range_end(boost::geometry::adapt::bp::holes_proxy<Polygon>& proxy) +{ + typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type + end(proxy.polygon, boost::polygon::end_holes(proxy.polygon)); + return end; +} + + +}} + +namespace traits +{ + +template <typename Polygon> +struct rvalue_type<adapt::bp::holes_proxy<Polygon> > +{ + typedef adapt::bp::holes_proxy<Polygon> type; +}; + + +template <typename Polygon> +struct clear<adapt::bp::holes_proxy<Polygon> > +{ + static inline void apply(adapt::bp::holes_proxy<Polygon> proxy) + { + proxy.clear(); + } +}; + +template <typename Polygon> +struct resize<adapt::bp::holes_proxy<Polygon> > +{ + static inline void apply(adapt::bp::holes_proxy<Polygon> proxy, std::size_t new_size) + { + proxy.resize(new_size); + } +}; + +template <typename Polygon> +struct push_back<adapt::bp::holes_proxy<Polygon> > +{ + template <typename Ring> + static inline void apply(adapt::bp::holes_proxy<Polygon> proxy, Ring const& ring) + { + proxy.push_back(ring); + } +}; + + + +} // namespace traits + + +}} + + +// Specialize holes_proxy for Boost.Range +namespace boost +{ + template<typename Polygon> + struct range_mutable_iterator<geometry::adapt::bp::holes_proxy<Polygon> > + { + typedef typename geometry::adapt::bp::holes_proxy<Polygon>::iterator_type type; + }; + + template<typename Polygon> + struct range_const_iterator<geometry::adapt::bp::holes_proxy<Polygon> > + { + typedef typename geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type type; + }; + +} // namespace boost + + +#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLES_PROXY_HPP diff --git a/boost/geometry/geometries/adapted/boost_polygon/point.hpp b/boost/geometry/geometries/adapted/boost_polygon/point.hpp new file mode 100644 index 0000000000..2aabb5663c --- /dev/null +++ b/boost/geometry/geometries/adapted/boost_polygon/point.hpp @@ -0,0 +1,102 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_POINT_HPP +#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_POINT_HPP + +// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry +// boost::polygon::point_data -> boost::geometry::point + + +#include <boost/polygon/polygon.hpp> + +#include <boost/geometry/core/access.hpp> +#include <boost/geometry/core/cs.hpp> +#include <boost/geometry/core/coordinate_dimension.hpp> +#include <boost/geometry/core/coordinate_type.hpp> +#include <boost/geometry/core/tags.hpp> + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS +namespace traits +{ + + +template <typename CoordinateType> +struct tag<boost::polygon::point_data<CoordinateType> > +{ + typedef point_tag type; +}; + + +template <typename CoordinateType> +struct coordinate_type<boost::polygon::point_data<CoordinateType> > +{ + typedef CoordinateType type; +}; + + +template <typename CoordinateType> +struct coordinate_system<boost::polygon::point_data<CoordinateType> > +{ + typedef cs::cartesian type; +}; + + +template <typename CoordinateType> +struct dimension<boost::polygon::point_data<CoordinateType> > + : boost::mpl::int_<2> +{}; + + +template <typename CoordinateType> +struct access<boost::polygon::point_data<CoordinateType>, 0> +{ + typedef boost::polygon::point_data<CoordinateType> point_type; + + static inline CoordinateType get(point_type const& p) + { + return p.x(); + } + + static inline void set(point_type& p, CoordinateType const& value) + { + p.x(value); + } +}; + + +template <typename CoordinateType> +struct access<boost::polygon::point_data<CoordinateType>, 1> +{ + typedef boost::polygon::point_data<CoordinateType> point_type; + + static inline CoordinateType get(point_type const& p) + { + return p.y(); + } + + static inline void set(point_type& p, CoordinateType const& value) + { + p.y(value); + } +}; + + +} // namespace traits +#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_POINT_HPP diff --git a/boost/geometry/geometries/adapted/boost_polygon/polygon.hpp b/boost/geometry/geometries/adapted/boost_polygon/polygon.hpp new file mode 100644 index 0000000000..5703601e05 --- /dev/null +++ b/boost/geometry/geometries/adapted/boost_polygon/polygon.hpp @@ -0,0 +1,111 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_POLYGON_HPP +#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_POLYGON_HPP + +// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry +// boost::polygon::polygon_with_holes_data -> boost::geometry::polygon + +#include <boost/polygon/polygon.hpp> + +#include <boost/geometry/core/tags.hpp> +#include <boost/geometry/core/ring_type.hpp> +#include <boost/geometry/core/exterior_ring.hpp> +#include <boost/geometry/core/interior_rings.hpp> + +#include <boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp> +#include <boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp> +#include <boost/geometry/geometries/adapted/boost_polygon/holes_proxy.hpp> + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS +namespace traits +{ + +template <typename CoordinateType> +struct tag<boost::polygon::polygon_with_holes_data<CoordinateType> > +{ + typedef polygon_tag type; +}; + +template <typename CoordinateType> +struct ring_const_type<boost::polygon::polygon_with_holes_data<CoordinateType> > +{ + typedef adapt::bp::ring_proxy<boost::polygon::polygon_with_holes_data<CoordinateType> const> type; +}; + +template <typename CoordinateType> +struct ring_mutable_type<boost::polygon::polygon_with_holes_data<CoordinateType> > +{ + typedef adapt::bp::ring_proxy<boost::polygon::polygon_with_holes_data<CoordinateType> > type; +}; + +template <typename CoordinateType> +struct interior_const_type<boost::polygon::polygon_with_holes_data<CoordinateType> > +{ + typedef adapt::bp::holes_proxy<boost::polygon::polygon_with_holes_data<CoordinateType> const> type; +}; + +template <typename CoordinateType> +struct interior_mutable_type<boost::polygon::polygon_with_holes_data<CoordinateType> > +{ + typedef adapt::bp::holes_proxy<boost::polygon::polygon_with_holes_data<CoordinateType> > type; +}; + + +template <typename CoordinateType> +struct exterior_ring<boost::polygon::polygon_with_holes_data<CoordinateType> > +{ + typedef boost::polygon::polygon_with_holes_data<CoordinateType> polygon_type; + typedef adapt::bp::ring_proxy<polygon_type> proxy; + typedef adapt::bp::ring_proxy<polygon_type const> const_proxy; + + static inline proxy get(polygon_type& p) + { + return proxy(p); + } + + static inline const_proxy get(polygon_type const& p) + { + return const_proxy(p); + } +}; + +template <typename CoordinateType> +struct interior_rings<boost::polygon::polygon_with_holes_data<CoordinateType> > +{ + typedef boost::polygon::polygon_with_holes_data<CoordinateType> polygon_type; + typedef adapt::bp::holes_proxy<polygon_type> proxy; + typedef adapt::bp::holes_proxy<polygon_type const> const_proxy; + + static inline proxy get(polygon_type& p) + { + return proxy(p); + } + + static inline const_proxy get(polygon_type const& p) + { + return const_proxy(p); + } +}; + + + +} // namespace traits +#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_POLYGON_HPP + diff --git a/boost/geometry/geometries/adapted/boost_polygon/ring.hpp b/boost/geometry/geometries/adapted/boost_polygon/ring.hpp new file mode 100644 index 0000000000..93b21fee94 --- /dev/null +++ b/boost/geometry/geometries/adapted/boost_polygon/ring.hpp @@ -0,0 +1,163 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_HPP +#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_HPP + +// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry +// boost::polygon::polygon_data -> boost::geometry::ring + +#include <cstddef> +#include <boost/polygon/polygon.hpp> + +#include <boost/geometry/core/access.hpp> +#include <boost/geometry/core/cs.hpp> +#include <boost/geometry/core/coordinate_dimension.hpp> +#include <boost/geometry/core/coordinate_type.hpp> +#include <boost/geometry/core/mutable_range.hpp> +#include <boost/geometry/core/tags.hpp> + + +#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS + +namespace boost { namespace geometry +{ + +namespace traits +{ + +template <typename CoordinateType> +struct tag<boost::polygon::polygon_data<CoordinateType> > +{ + typedef ring_tag type; +}; + +template <typename CoordinateType> +struct clear<boost::polygon::polygon_data<CoordinateType> > +{ + static inline void apply(boost::polygon::polygon_data<CoordinateType>& data) + { + // There is no "clear" function but we can assign + // a newly (and therefore empty) constructed polygon + boost::polygon::assign(data, boost::polygon::polygon_data<CoordinateType>()); + } +}; + +template <typename CoordinateType> +struct push_back<boost::polygon::polygon_data<CoordinateType> > +{ + typedef boost::polygon::point_data<CoordinateType> point_type; + + static inline void apply(boost::polygon::polygon_data<CoordinateType>& data, + point_type const& point) + { + // Boost.Polygon's polygons are not appendable. So create a temporary vector, + // add a record and set it to the original. Of course: this is not efficient. + // But there seems no other way (without using a wrapper) + std::vector<point_type> temporary_vector + ( + boost::polygon::begin_points(data), + boost::polygon::end_points(data) + ); + temporary_vector.push_back(point); + data.set(temporary_vector.begin(), temporary_vector.end()); + } +}; + + + + +} // namespace traits + +}} // namespace boost::geometry + + +// Adapt Boost.Polygon's polygon_data to Boost.Range +// This just translates to +// polygon_data.begin() and polygon_data.end() +namespace boost +{ + template<typename CoordinateType> + struct range_mutable_iterator<boost::polygon::polygon_data<CoordinateType> > + { + typedef typename boost::polygon::polygon_traits + < + boost::polygon::polygon_data<CoordinateType> + >::iterator_type type; + }; + + template<typename CoordinateType> + struct range_const_iterator<boost::polygon::polygon_data<CoordinateType> > + { + typedef typename boost::polygon::polygon_traits + < + boost::polygon::polygon_data<CoordinateType> + >::iterator_type type; + }; + + template<typename CoordinateType> + struct range_size<boost::polygon::polygon_data<CoordinateType> > + { + typedef std::size_t type; + }; + +} // namespace boost + + +// Support Boost.Polygon's polygon_data for Boost.Range ADP +namespace boost { namespace polygon +{ + +template<typename CoordinateType> +inline typename polygon_traits + < + polygon_data<CoordinateType> + >::iterator_type range_begin(polygon_data<CoordinateType>& polygon) +{ + return polygon.begin(); +} + +template<typename CoordinateType> +inline typename polygon_traits + < + polygon_data<CoordinateType> + >::iterator_type range_begin(polygon_data<CoordinateType> const& polygon) +{ + return polygon.begin(); +} + +template<typename CoordinateType> +inline typename polygon_traits + < + polygon_data<CoordinateType> + >::iterator_type range_end(polygon_data<CoordinateType>& polygon) +{ + return polygon.end(); +} + +template<typename CoordinateType> +inline typename polygon_traits + < + polygon_data<CoordinateType> + >::iterator_type range_end(polygon_data<CoordinateType> const& polygon) +{ + return polygon.end(); +} + +template<typename CoordinateType> +inline std::size_t range_calculate_size(polygon_data<CoordinateType> const& polygon) +{ + return polygon.size(); +} + +}} + +#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS + + +#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_HPP diff --git a/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp b/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp new file mode 100644 index 0000000000..825ef8061f --- /dev/null +++ b/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp @@ -0,0 +1,301 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP +#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP + +// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry +// boost::polygon::polygon_with_holes_data -> boost::geometry::polygon +// pair{begin_points, end_points} -> ring_proxy + +#include <boost/polygon/polygon.hpp> +#include <boost/range.hpp> + + + +namespace boost { namespace geometry +{ + +namespace adapt { namespace bp +{ + +namespace detail +{ + +template <bool Mutable> +struct modify +{}; + +template <> +struct modify<true> +{ + template <typename Ring, typename Point> + static inline void push_back(Ring& ring, Point const& point) + { + // Boost.Polygon's polygons are not appendable. So create a temporary vector, + // add a record and set it to the original. Of course: this is not efficient. + // But there seems no other way (without using a wrapper) + std::vector<Point> temporary_vector + ( + boost::polygon::begin_points(ring), + boost::polygon::end_points(ring) + ); + temporary_vector.push_back(point); + boost::polygon::set_points(ring, temporary_vector.begin(), temporary_vector.end()); + } + +}; + +template <> +struct modify<false> +{ + template <typename Ring, typename Point> + static inline void push_back(Ring& ring, Point const& point) + { + } + +}; + + +} + + +// Polygon should implement the boost::polygon::polygon_with_holes_concept +// Specify constness in the template parameter if necessary +template<typename Polygon> +class ring_proxy +{ +public : + typedef typename boost::polygon::polygon_traits + < + typename boost::remove_const<Polygon>::type + >::iterator_type iterator_type; + + typedef typename boost::polygon::polygon_with_holes_traits + < + typename boost::remove_const<Polygon>::type + >::iterator_holes_type hole_iterator_type; + + static const bool is_mutable = !boost::is_const<Polygon>::type::value; + + inline ring_proxy(Polygon& p) + : m_polygon_pointer(&p) + , m_do_hole(false) + {} + + // Constructor used from hole_iterator + inline ring_proxy(Polygon& p, hole_iterator_type hole_it) + : m_polygon_pointer(&p) + , m_do_hole(true) + , m_hole_it(hole_it) + {} + + // Default constructor, for mutable polygons / appending (interior) rings + inline ring_proxy() + : m_polygon_pointer(&m_polygon_for_default_constructor) + , m_do_hole(false) + {} + + + iterator_type begin() const + { + return m_do_hole + ? boost::polygon::begin_points(*m_hole_it) + : boost::polygon::begin_points(*m_polygon_pointer) + ; + } + + iterator_type begin() + { + return m_do_hole + ? boost::polygon::begin_points(*m_hole_it) + : boost::polygon::begin_points(*m_polygon_pointer) + ; + } + + iterator_type end() const + { + return m_do_hole + ? boost::polygon::end_points(*m_hole_it) + : boost::polygon::end_points(*m_polygon_pointer) + ; + } + + iterator_type end() + { + return m_do_hole + ? boost::polygon::end_points(*m_hole_it) + : boost::polygon::end_points(*m_polygon_pointer) + ; + } + + // Mutable + void clear() + { + Polygon p; + if (m_do_hole) + { + // Does NOT work see comment above + } + else + { + boost::polygon::set_points(*m_polygon_pointer, + boost::polygon::begin_points(p), + boost::polygon::end_points(p)); + } + } + + void resize(std::size_t new_size) + { + if (m_do_hole) + { + // Does NOT work see comment above + } + else + { + // TODO: implement this by resizing the container + } + } + + + + template <typename Point> + void push_back(Point const& point) + { + if (m_do_hole) + { + //detail::modify<is_mutable>::push_back(*m_hole_it, point); + //std::cout << "HOLE: " << typeid(*m_hole_it).name() << std::endl; + //std::cout << "HOLE: " << typeid(m_hole_it).name() << std::endl; + //std::cout << "HOLE: " << typeid(hole_iterator_type).name() << std::endl; + + // Note, ths does NOT work because hole_iterator_type is defined + // as a const_iterator by Boost.Polygon + + } + else + { + detail::modify<is_mutable>::push_back(*m_polygon_pointer, point); + } + } + +private : + Polygon* m_polygon_pointer; + bool m_do_hole; + hole_iterator_type m_hole_it; + + Polygon m_polygon_for_default_constructor; +}; + + + + +// Support geometry::adapt::bp::ring_proxy for Boost.Range ADP +template<typename Polygon> +inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type + range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon>& proxy) +{ + return proxy.begin(); +} + +template<typename Polygon> +inline typename boost::geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type + range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon const> const& proxy) +{ + return proxy.begin(); +} + +template<typename Polygon> +inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type + range_end(boost::geometry::adapt::bp::ring_proxy<Polygon>& proxy) +{ + return proxy.end(); +} + +template<typename Polygon> +inline typename boost::geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type + range_end(boost::geometry::adapt::bp::ring_proxy<Polygon const> const& proxy) +{ + return proxy.end(); +} + + + + +}} // namespace adapt::bp + + +namespace traits +{ + +template <typename Polygon> +struct tag<adapt::bp::ring_proxy<Polygon> > +{ + typedef ring_tag type; +}; + + +template <typename Polygon> +struct rvalue_type<adapt::bp::ring_proxy<Polygon> > +{ + typedef adapt::bp::ring_proxy<Polygon> type; +}; + +template <typename Polygon> +struct clear<adapt::bp::ring_proxy<Polygon> > +{ + static inline void apply(adapt::bp::ring_proxy<Polygon> proxy) + { + proxy.clear(); + } +}; + + +template <typename Polygon> +struct resize<adapt::bp::ring_proxy<Polygon> > +{ + static inline void apply(adapt::bp::ring_proxy<Polygon> proxy, std::size_t new_size) + { + proxy.resize(new_size); + } +}; + +template <typename Polygon> +struct push_back<adapt::bp::ring_proxy<Polygon> > +{ + static inline void apply(adapt::bp::ring_proxy<Polygon> proxy, + typename boost::polygon::polygon_traits<Polygon>::point_type const& point) + { + proxy.push_back(point); + } +}; + + +} // namespace traits + +}} // namespace boost::geometry + +// Specialize ring_proxy for Boost.Range +namespace boost +{ + template<typename Polygon> + struct range_mutable_iterator<geometry::adapt::bp::ring_proxy<Polygon> > + { + typedef typename geometry::adapt::bp::ring_proxy<Polygon>::iterator_type type; + }; + + template<typename Polygon> + struct range_const_iterator<geometry::adapt::bp::ring_proxy<Polygon> > + { + typedef typename geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type type; + }; + +} // namespace boost + + +#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP |