annotate 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
rev   line source
Chris@16 1 // Boost.Geometry (aka GGL, Generic Geometry Library)
Chris@16 2
Chris@16 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
Chris@16 4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
Chris@16 5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
Chris@16 6
Chris@16 7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
Chris@16 8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
Chris@16 9
Chris@16 10 // Use, modification and distribution is subject to the Boost Software License,
Chris@16 11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 12 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 13
Chris@16 14 #ifndef BOOST_GEOMETRY_IO_DSV_WRITE_HPP
Chris@16 15 #define BOOST_GEOMETRY_IO_DSV_WRITE_HPP
Chris@16 16
Chris@16 17 #include <cstddef>
Chris@16 18 #include <ostream>
Chris@16 19 #include <string>
Chris@16 20
Chris@16 21 #include <boost/concept_check.hpp>
Chris@16 22 #include <boost/range.hpp>
Chris@16 23 #include <boost/typeof/typeof.hpp>
Chris@16 24
Chris@16 25 #include <boost/geometry/core/exterior_ring.hpp>
Chris@16 26 #include <boost/geometry/core/interior_rings.hpp>
Chris@16 27 #include <boost/geometry/core/ring_type.hpp>
Chris@16 28 #include <boost/geometry/core/tag_cast.hpp>
Chris@16 29
Chris@16 30 #include <boost/geometry/geometries/concepts/check.hpp>
Chris@16 31
Chris@16 32 namespace boost { namespace geometry
Chris@16 33 {
Chris@16 34
Chris@16 35 #ifndef DOXYGEN_NO_DETAIL
Chris@16 36 namespace detail { namespace dsv
Chris@16 37 {
Chris@16 38
Chris@16 39 struct dsv_settings
Chris@16 40 {
Chris@16 41 std::string coordinate_separator;
Chris@16 42 std::string point_open;
Chris@16 43 std::string point_close;
Chris@16 44 std::string point_separator;
Chris@16 45 std::string list_open;
Chris@16 46 std::string list_close;
Chris@16 47 std::string list_separator;
Chris@16 48
Chris@16 49 dsv_settings(std::string const& sep
Chris@16 50 , std::string const& open
Chris@16 51 , std::string const& close
Chris@16 52 , std::string const& psep
Chris@16 53 , std::string const& lopen
Chris@16 54 , std::string const& lclose
Chris@16 55 , std::string const& lsep
Chris@16 56 )
Chris@16 57 : coordinate_separator(sep)
Chris@16 58 , point_open(open)
Chris@16 59 , point_close(close)
Chris@16 60 , point_separator(psep)
Chris@16 61 , list_open(lopen)
Chris@16 62 , list_close(lclose)
Chris@16 63 , list_separator(lsep)
Chris@16 64 {}
Chris@16 65 };
Chris@16 66
Chris@16 67 /*!
Chris@16 68 \brief Stream coordinate of a point as \ref DSV
Chris@16 69 */
Chris@16 70 template <typename Point, std::size_t Dimension, std::size_t Count>
Chris@16 71 struct stream_coordinate
Chris@16 72 {
Chris@16 73 template <typename Char, typename Traits>
Chris@16 74 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 75 Point const& point,
Chris@16 76 dsv_settings const& settings)
Chris@16 77 {
Chris@16 78 os << (Dimension > 0 ? settings.coordinate_separator : "")
Chris@16 79 << get<Dimension>(point);
Chris@16 80
Chris@16 81 stream_coordinate
Chris@16 82 <
Chris@16 83 Point, Dimension + 1, Count
Chris@16 84 >::apply(os, point, settings);
Chris@16 85 }
Chris@16 86 };
Chris@16 87
Chris@16 88 template <typename Point, std::size_t Count>
Chris@16 89 struct stream_coordinate<Point, Count, Count>
Chris@16 90 {
Chris@16 91 template <typename Char, typename Traits>
Chris@16 92 static inline void apply(std::basic_ostream<Char, Traits>&,
Chris@16 93 Point const&,
Chris@16 94 dsv_settings const& )
Chris@16 95 {
Chris@16 96 }
Chris@16 97 };
Chris@16 98
Chris@16 99 /*!
Chris@16 100 \brief Stream indexed coordinate of a box/segment as \ref DSV
Chris@16 101 */
Chris@16 102 template
Chris@16 103 <
Chris@16 104 typename Geometry,
Chris@16 105 std::size_t Index,
Chris@16 106 std::size_t Dimension,
Chris@16 107 std::size_t Count
Chris@16 108 >
Chris@16 109 struct stream_indexed
Chris@16 110 {
Chris@16 111 template <typename Char, typename Traits>
Chris@16 112 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 113 Geometry const& geometry,
Chris@16 114 dsv_settings const& settings)
Chris@16 115 {
Chris@16 116 os << (Dimension > 0 ? settings.coordinate_separator : "")
Chris@16 117 << get<Index, Dimension>(geometry);
Chris@16 118 stream_indexed
Chris@16 119 <
Chris@16 120 Geometry, Index, Dimension + 1, Count
Chris@16 121 >::apply(os, geometry, settings);
Chris@16 122 }
Chris@16 123 };
Chris@16 124
Chris@16 125 template <typename Geometry, std::size_t Index, std::size_t Count>
Chris@16 126 struct stream_indexed<Geometry, Index, Count, Count>
Chris@16 127 {
Chris@16 128 template <typename Char, typename Traits>
Chris@16 129 static inline void apply(std::basic_ostream<Char, Traits>&, Geometry const&,
Chris@16 130 dsv_settings const& )
Chris@16 131 {
Chris@16 132 }
Chris@16 133 };
Chris@16 134
Chris@16 135 /*!
Chris@16 136 \brief Stream points as \ref DSV
Chris@16 137 */
Chris@16 138 template <typename Point>
Chris@16 139 struct dsv_point
Chris@16 140 {
Chris@16 141 template <typename Char, typename Traits>
Chris@16 142 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 143 Point const& p,
Chris@16 144 dsv_settings const& settings)
Chris@16 145 {
Chris@16 146 os << settings.point_open;
Chris@16 147 stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p, settings);
Chris@16 148 os << settings.point_close;
Chris@16 149 }
Chris@16 150 };
Chris@16 151
Chris@16 152 /*!
Chris@16 153 \brief Stream ranges as DSV
Chris@16 154 \note policy is used to stream prefix/postfix, enabling derived classes to override this
Chris@16 155 */
Chris@16 156 template <typename Range>
Chris@16 157 struct dsv_range
Chris@16 158 {
Chris@16 159 template <typename Char, typename Traits>
Chris@16 160 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 161 Range const& range,
Chris@16 162 dsv_settings const& settings)
Chris@16 163 {
Chris@16 164 typedef typename boost::range_iterator<Range const>::type iterator_type;
Chris@16 165
Chris@16 166 bool first = true;
Chris@16 167
Chris@16 168 os << settings.list_open;
Chris@16 169
Chris@16 170 for (iterator_type it = boost::begin(range);
Chris@16 171 it != boost::end(range);
Chris@16 172 ++it)
Chris@16 173 {
Chris@16 174 os << (first ? "" : settings.point_separator)
Chris@16 175 << settings.point_open;
Chris@16 176
Chris@16 177 stream_coordinate
Chris@16 178 <
Chris@16 179 point_type, 0, dimension<point_type>::type::value
Chris@16 180 >::apply(os, *it, settings);
Chris@16 181 os << settings.point_close;
Chris@16 182
Chris@16 183 first = false;
Chris@16 184 }
Chris@16 185
Chris@16 186 os << settings.list_close;
Chris@16 187 }
Chris@16 188
Chris@16 189 private:
Chris@16 190 typedef typename boost::range_value<Range>::type point_type;
Chris@16 191 };
Chris@16 192
Chris@16 193 /*!
Chris@16 194 \brief Stream sequence of points as DSV-part, e.g. (1 2),(3 4)
Chris@16 195 \note Used in polygon, all multi-geometries
Chris@16 196 */
Chris@16 197
Chris@16 198 template <typename Polygon>
Chris@16 199 struct dsv_poly
Chris@16 200 {
Chris@16 201 template <typename Char, typename Traits>
Chris@16 202 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 203 Polygon const& poly,
Chris@16 204 dsv_settings const& settings)
Chris@16 205 {
Chris@16 206 typedef typename ring_type<Polygon>::type ring;
Chris@16 207
Chris@16 208 os << settings.list_open;
Chris@16 209
Chris@16 210 dsv_range<ring>::apply(os, exterior_ring(poly), settings);
Chris@16 211
Chris@16 212 typename interior_return_type<Polygon const>::type rings
Chris@16 213 = interior_rings(poly);
Chris@16 214 for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
Chris@16 215 {
Chris@16 216 os << settings.list_separator;
Chris@16 217 dsv_range<ring>::apply(os, *it, settings);
Chris@16 218 }
Chris@16 219 os << settings.list_close;
Chris@16 220 }
Chris@16 221 };
Chris@16 222
Chris@16 223 template <typename Geometry, std::size_t Index>
Chris@16 224 struct dsv_per_index
Chris@16 225 {
Chris@16 226 typedef typename point_type<Geometry>::type point_type;
Chris@16 227
Chris@16 228 template <typename Char, typename Traits>
Chris@16 229 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 230 Geometry const& geometry,
Chris@16 231 dsv_settings const& settings)
Chris@16 232 {
Chris@16 233 os << settings.point_open;
Chris@16 234 stream_indexed
Chris@16 235 <
Chris@16 236 Geometry, Index, 0, dimension<Geometry>::type::value
Chris@16 237 >::apply(os, geometry, settings);
Chris@16 238 os << settings.point_close;
Chris@16 239 }
Chris@16 240 };
Chris@16 241
Chris@16 242 template <typename Geometry>
Chris@16 243 struct dsv_indexed
Chris@16 244 {
Chris@16 245 typedef typename point_type<Geometry>::type point_type;
Chris@16 246
Chris@16 247 template <typename Char, typename Traits>
Chris@16 248 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 249 Geometry const& geometry,
Chris@16 250 dsv_settings const& settings)
Chris@16 251 {
Chris@16 252 os << settings.list_open;
Chris@16 253 dsv_per_index<Geometry, 0>::apply(os, geometry, settings);
Chris@16 254 os << settings.point_separator;
Chris@16 255 dsv_per_index<Geometry, 1>::apply(os, geometry, settings);
Chris@16 256 os << settings.list_close;
Chris@16 257 }
Chris@16 258 };
Chris@16 259
Chris@16 260 }} // namespace detail::dsv
Chris@16 261 #endif // DOXYGEN_NO_DETAIL
Chris@16 262
Chris@16 263 #ifndef DOXYGEN_NO_DISPATCH
Chris@16 264 namespace dispatch
Chris@16 265 {
Chris@16 266
Chris@16 267 template <typename Tag, typename Geometry>
Chris@16 268 struct dsv {};
Chris@16 269
Chris@16 270 template <typename Point>
Chris@16 271 struct dsv<point_tag, Point>
Chris@16 272 : detail::dsv::dsv_point<Point>
Chris@16 273 {};
Chris@16 274
Chris@16 275 template <typename Linestring>
Chris@16 276 struct dsv<linestring_tag, Linestring>
Chris@16 277 : detail::dsv::dsv_range<Linestring>
Chris@16 278 {};
Chris@16 279
Chris@16 280 template <typename Box>
Chris@16 281 struct dsv<box_tag, Box>
Chris@16 282 : detail::dsv::dsv_indexed<Box>
Chris@16 283 {};
Chris@16 284
Chris@16 285 template <typename Segment>
Chris@16 286 struct dsv<segment_tag, Segment>
Chris@16 287 : detail::dsv::dsv_indexed<Segment>
Chris@16 288 {};
Chris@16 289
Chris@16 290 template <typename Ring>
Chris@16 291 struct dsv<ring_tag, Ring>
Chris@16 292 : detail::dsv::dsv_range<Ring>
Chris@16 293 {};
Chris@16 294
Chris@16 295 template <typename Polygon>
Chris@16 296 struct dsv<polygon_tag, Polygon>
Chris@16 297 : detail::dsv::dsv_poly<Polygon>
Chris@16 298 {};
Chris@16 299
Chris@16 300 } // namespace dispatch
Chris@16 301 #endif // DOXYGEN_NO_DISPATCH
Chris@16 302
Chris@16 303 #ifndef DOXYGEN_NO_DETAIL
Chris@16 304 namespace detail { namespace dsv
Chris@16 305 {
Chris@16 306
Chris@16 307 // FIXME: This class is not copyable/assignable but it is used as such --mloskot
Chris@16 308 template <typename Geometry>
Chris@16 309 class dsv_manipulator
Chris@16 310 {
Chris@16 311 public:
Chris@16 312
Chris@16 313 inline dsv_manipulator(Geometry const& g,
Chris@16 314 dsv_settings const& settings)
Chris@16 315 : m_geometry(g)
Chris@16 316 , m_settings(settings)
Chris@16 317 {}
Chris@16 318
Chris@16 319 template <typename Char, typename Traits>
Chris@16 320 inline friend std::basic_ostream<Char, Traits>& operator<<(
Chris@16 321 std::basic_ostream<Char, Traits>& os,
Chris@16 322 dsv_manipulator const& m)
Chris@16 323 {
Chris@16 324 dispatch::dsv
Chris@16 325 <
Chris@16 326 typename tag_cast
Chris@16 327 <
Chris@16 328 typename tag<Geometry>::type,
Chris@16 329 multi_tag
Chris@16 330 >::type,
Chris@16 331 Geometry
Chris@16 332 >::apply(os, m.m_geometry, m.m_settings);
Chris@16 333 os.flush();
Chris@16 334 return os;
Chris@16 335 }
Chris@16 336
Chris@16 337 private:
Chris@16 338 Geometry const& m_geometry;
Chris@16 339 dsv_settings m_settings;
Chris@16 340 };
Chris@16 341
Chris@16 342 }} // namespace detail::dsv
Chris@16 343 #endif // DOXYGEN_NO_DETAIL
Chris@16 344
Chris@16 345 /*!
Chris@16 346 \brief Main DSV-streaming function
Chris@16 347 \details DSV stands for Delimiter Separated Values. Geometries can be streamed
Chris@16 348 as DSV. There are defaults for all separators.
Chris@16 349 \note Useful for examples and testing purposes
Chris@16 350 \note With this function GeoJSON objects can be created, using the right
Chris@16 351 delimiters
Chris@16 352 \ingroup utility
Chris@16 353 */
Chris@16 354 template <typename Geometry>
Chris@16 355 inline detail::dsv::dsv_manipulator<Geometry> dsv(Geometry const& geometry
Chris@16 356 , std::string const& coordinate_separator = ", "
Chris@16 357 , std::string const& point_open = "("
Chris@16 358 , std::string const& point_close = ")"
Chris@16 359 , std::string const& point_separator = ", "
Chris@16 360 , std::string const& list_open = "("
Chris@16 361 , std::string const& list_close = ")"
Chris@16 362 , std::string const& list_separator = ", "
Chris@16 363 )
Chris@16 364 {
Chris@16 365 concept::check<Geometry const>();
Chris@16 366
Chris@16 367 return detail::dsv::dsv_manipulator<Geometry>(geometry,
Chris@16 368 detail::dsv::dsv_settings(coordinate_separator,
Chris@16 369 point_open, point_close, point_separator,
Chris@16 370 list_open, list_close, list_separator));
Chris@16 371 }
Chris@16 372
Chris@16 373 }} // namespace boost::geometry
Chris@16 374
Chris@16 375 #endif // BOOST_GEOMETRY_IO_DSV_WRITE_HPP