Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/geometry/io/dsv/write.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/geometry/io/dsv/write.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,375 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. + +// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library +// (geolib/GGL), copyright (c) 1995-2010 Geodan, 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_IO_DSV_WRITE_HPP +#define BOOST_GEOMETRY_IO_DSV_WRITE_HPP + +#include <cstddef> +#include <ostream> +#include <string> + +#include <boost/concept_check.hpp> +#include <boost/range.hpp> +#include <boost/typeof/typeof.hpp> + +#include <boost/geometry/core/exterior_ring.hpp> +#include <boost/geometry/core/interior_rings.hpp> +#include <boost/geometry/core/ring_type.hpp> +#include <boost/geometry/core/tag_cast.hpp> + +#include <boost/geometry/geometries/concepts/check.hpp> + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace dsv +{ + +struct dsv_settings +{ + std::string coordinate_separator; + std::string point_open; + std::string point_close; + std::string point_separator; + std::string list_open; + std::string list_close; + std::string list_separator; + + dsv_settings(std::string const& sep + , std::string const& open + , std::string const& close + , std::string const& psep + , std::string const& lopen + , std::string const& lclose + , std::string const& lsep + ) + : coordinate_separator(sep) + , point_open(open) + , point_close(close) + , point_separator(psep) + , list_open(lopen) + , list_close(lclose) + , list_separator(lsep) + {} +}; + +/*! +\brief Stream coordinate of a point as \ref DSV +*/ +template <typename Point, std::size_t Dimension, std::size_t Count> +struct stream_coordinate +{ + template <typename Char, typename Traits> + static inline void apply(std::basic_ostream<Char, Traits>& os, + Point const& point, + dsv_settings const& settings) + { + os << (Dimension > 0 ? settings.coordinate_separator : "") + << get<Dimension>(point); + + stream_coordinate + < + Point, Dimension + 1, Count + >::apply(os, point, settings); + } +}; + +template <typename Point, std::size_t Count> +struct stream_coordinate<Point, Count, Count> +{ + template <typename Char, typename Traits> + static inline void apply(std::basic_ostream<Char, Traits>&, + Point const&, + dsv_settings const& ) + { + } +}; + +/*! +\brief Stream indexed coordinate of a box/segment as \ref DSV +*/ +template +< + typename Geometry, + std::size_t Index, + std::size_t Dimension, + std::size_t Count +> +struct stream_indexed +{ + template <typename Char, typename Traits> + static inline void apply(std::basic_ostream<Char, Traits>& os, + Geometry const& geometry, + dsv_settings const& settings) + { + os << (Dimension > 0 ? settings.coordinate_separator : "") + << get<Index, Dimension>(geometry); + stream_indexed + < + Geometry, Index, Dimension + 1, Count + >::apply(os, geometry, settings); + } +}; + +template <typename Geometry, std::size_t Index, std::size_t Count> +struct stream_indexed<Geometry, Index, Count, Count> +{ + template <typename Char, typename Traits> + static inline void apply(std::basic_ostream<Char, Traits>&, Geometry const&, + dsv_settings const& ) + { + } +}; + +/*! +\brief Stream points as \ref DSV +*/ +template <typename Point> +struct dsv_point +{ + template <typename Char, typename Traits> + static inline void apply(std::basic_ostream<Char, Traits>& os, + Point const& p, + dsv_settings const& settings) + { + os << settings.point_open; + stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p, settings); + os << settings.point_close; + } +}; + +/*! +\brief Stream ranges as DSV +\note policy is used to stream prefix/postfix, enabling derived classes to override this +*/ +template <typename Range> +struct dsv_range +{ + template <typename Char, typename Traits> + static inline void apply(std::basic_ostream<Char, Traits>& os, + Range const& range, + dsv_settings const& settings) + { + typedef typename boost::range_iterator<Range const>::type iterator_type; + + bool first = true; + + os << settings.list_open; + + for (iterator_type it = boost::begin(range); + it != boost::end(range); + ++it) + { + os << (first ? "" : settings.point_separator) + << settings.point_open; + + stream_coordinate + < + point_type, 0, dimension<point_type>::type::value + >::apply(os, *it, settings); + os << settings.point_close; + + first = false; + } + + os << settings.list_close; + } + +private: + typedef typename boost::range_value<Range>::type point_type; +}; + +/*! +\brief Stream sequence of points as DSV-part, e.g. (1 2),(3 4) +\note Used in polygon, all multi-geometries +*/ + +template <typename Polygon> +struct dsv_poly +{ + template <typename Char, typename Traits> + static inline void apply(std::basic_ostream<Char, Traits>& os, + Polygon const& poly, + dsv_settings const& settings) + { + typedef typename ring_type<Polygon>::type ring; + + os << settings.list_open; + + dsv_range<ring>::apply(os, exterior_ring(poly), settings); + + typename interior_return_type<Polygon const>::type rings + = interior_rings(poly); + for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it) + { + os << settings.list_separator; + dsv_range<ring>::apply(os, *it, settings); + } + os << settings.list_close; + } +}; + +template <typename Geometry, std::size_t Index> +struct dsv_per_index +{ + typedef typename point_type<Geometry>::type point_type; + + template <typename Char, typename Traits> + static inline void apply(std::basic_ostream<Char, Traits>& os, + Geometry const& geometry, + dsv_settings const& settings) + { + os << settings.point_open; + stream_indexed + < + Geometry, Index, 0, dimension<Geometry>::type::value + >::apply(os, geometry, settings); + os << settings.point_close; + } +}; + +template <typename Geometry> +struct dsv_indexed +{ + typedef typename point_type<Geometry>::type point_type; + + template <typename Char, typename Traits> + static inline void apply(std::basic_ostream<Char, Traits>& os, + Geometry const& geometry, + dsv_settings const& settings) + { + os << settings.list_open; + dsv_per_index<Geometry, 0>::apply(os, geometry, settings); + os << settings.point_separator; + dsv_per_index<Geometry, 1>::apply(os, geometry, settings); + os << settings.list_close; + } +}; + +}} // namespace detail::dsv +#endif // DOXYGEN_NO_DETAIL + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + +template <typename Tag, typename Geometry> +struct dsv {}; + +template <typename Point> +struct dsv<point_tag, Point> + : detail::dsv::dsv_point<Point> +{}; + +template <typename Linestring> +struct dsv<linestring_tag, Linestring> + : detail::dsv::dsv_range<Linestring> +{}; + +template <typename Box> +struct dsv<box_tag, Box> + : detail::dsv::dsv_indexed<Box> +{}; + +template <typename Segment> +struct dsv<segment_tag, Segment> + : detail::dsv::dsv_indexed<Segment> +{}; + +template <typename Ring> +struct dsv<ring_tag, Ring> + : detail::dsv::dsv_range<Ring> +{}; + +template <typename Polygon> +struct dsv<polygon_tag, Polygon> + : detail::dsv::dsv_poly<Polygon> +{}; + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace dsv +{ + +// FIXME: This class is not copyable/assignable but it is used as such --mloskot +template <typename Geometry> +class dsv_manipulator +{ +public: + + inline dsv_manipulator(Geometry const& g, + dsv_settings const& settings) + : m_geometry(g) + , m_settings(settings) + {} + + template <typename Char, typename Traits> + inline friend std::basic_ostream<Char, Traits>& operator<<( + std::basic_ostream<Char, Traits>& os, + dsv_manipulator const& m) + { + dispatch::dsv + < + typename tag_cast + < + typename tag<Geometry>::type, + multi_tag + >::type, + Geometry + >::apply(os, m.m_geometry, m.m_settings); + os.flush(); + return os; + } + +private: + Geometry const& m_geometry; + dsv_settings m_settings; +}; + +}} // namespace detail::dsv +#endif // DOXYGEN_NO_DETAIL + +/*! +\brief Main DSV-streaming function +\details DSV stands for Delimiter Separated Values. Geometries can be streamed + as DSV. There are defaults for all separators. +\note Useful for examples and testing purposes +\note With this function GeoJSON objects can be created, using the right + delimiters +\ingroup utility +*/ +template <typename Geometry> +inline detail::dsv::dsv_manipulator<Geometry> dsv(Geometry const& geometry + , std::string const& coordinate_separator = ", " + , std::string const& point_open = "(" + , std::string const& point_close = ")" + , std::string const& point_separator = ", " + , std::string const& list_open = "(" + , std::string const& list_close = ")" + , std::string const& list_separator = ", " + ) +{ + concept::check<Geometry const>(); + + return detail::dsv::dsv_manipulator<Geometry>(geometry, + detail::dsv::dsv_settings(coordinate_separator, + point_open, point_close, point_separator, + list_open, list_close, list_separator)); +} + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_IO_DSV_WRITE_HPP