annotate DEPENDENCIES/generic/include/boost/geometry/io/wkt/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_WKT_WRITE_HPP
Chris@16 15 #define BOOST_GEOMETRY_IO_WKT_WRITE_HPP
Chris@16 16
Chris@16 17 #include <ostream>
Chris@16 18 #include <string>
Chris@16 19
Chris@16 20 #include <boost/array.hpp>
Chris@16 21 #include <boost/range.hpp>
Chris@16 22 #include <boost/typeof/typeof.hpp>
Chris@16 23
Chris@16 24 #include <boost/geometry/algorithms/assign.hpp>
Chris@16 25 #include <boost/geometry/algorithms/convert.hpp>
Chris@16 26 #include <boost/geometry/algorithms/not_implemented.hpp>
Chris@16 27 #include <boost/geometry/core/exterior_ring.hpp>
Chris@16 28 #include <boost/geometry/core/interior_rings.hpp>
Chris@16 29 #include <boost/geometry/core/ring_type.hpp>
Chris@16 30
Chris@16 31 #include <boost/geometry/geometries/concepts/check.hpp>
Chris@16 32 #include <boost/geometry/geometries/ring.hpp>
Chris@16 33
Chris@16 34 #include <boost/geometry/io/wkt/detail/prefix.hpp>
Chris@16 35
Chris@16 36 #include <boost/variant/apply_visitor.hpp>
Chris@16 37 #include <boost/variant/static_visitor.hpp>
Chris@16 38 #include <boost/variant/variant_fwd.hpp>
Chris@16 39
Chris@16 40 namespace boost { namespace geometry
Chris@16 41 {
Chris@16 42
Chris@16 43 // Silence warning C4512: 'boost::geometry::wkt_manipulator<Geometry>' : assignment operator could not be generated
Chris@16 44 #if defined(_MSC_VER)
Chris@16 45 #pragma warning(push)
Chris@16 46 #pragma warning(disable : 4512)
Chris@16 47 #endif
Chris@16 48
Chris@16 49 #ifndef DOXYGEN_NO_DETAIL
Chris@16 50 namespace detail { namespace wkt
Chris@16 51 {
Chris@16 52
Chris@16 53 template <typename P, int I, int Count>
Chris@16 54 struct stream_coordinate
Chris@16 55 {
Chris@16 56 template <typename Char, typename Traits>
Chris@16 57 static inline void apply(std::basic_ostream<Char, Traits>& os, P const& p)
Chris@16 58 {
Chris@16 59 os << (I > 0 ? " " : "") << get<I>(p);
Chris@16 60 stream_coordinate<P, I + 1, Count>::apply(os, p);
Chris@16 61 }
Chris@16 62 };
Chris@16 63
Chris@16 64 template <typename P, int Count>
Chris@16 65 struct stream_coordinate<P, Count, Count>
Chris@16 66 {
Chris@16 67 template <typename Char, typename Traits>
Chris@16 68 static inline void apply(std::basic_ostream<Char, Traits>&, P const&)
Chris@16 69 {}
Chris@16 70 };
Chris@16 71
Chris@16 72 struct prefix_linestring_par
Chris@16 73 {
Chris@16 74 static inline const char* apply() { return "LINESTRING("; }
Chris@16 75 };
Chris@16 76
Chris@16 77 struct prefix_ring_par_par
Chris@16 78 {
Chris@16 79 // Note, double parentheses are intentional, indicating WKT ring begin/end
Chris@16 80 static inline const char* apply() { return "POLYGON(("; }
Chris@16 81 };
Chris@16 82
Chris@16 83 struct opening_parenthesis
Chris@16 84 {
Chris@16 85 static inline const char* apply() { return "("; }
Chris@16 86 };
Chris@16 87
Chris@16 88 struct closing_parenthesis
Chris@16 89 {
Chris@16 90 static inline const char* apply() { return ")"; }
Chris@16 91 };
Chris@16 92
Chris@16 93 struct double_closing_parenthesis
Chris@16 94 {
Chris@16 95 static inline const char* apply() { return "))"; }
Chris@16 96 };
Chris@16 97
Chris@16 98 /*!
Chris@16 99 \brief Stream points as \ref WKT
Chris@16 100 */
Chris@16 101 template <typename Point, typename Policy>
Chris@16 102 struct wkt_point
Chris@16 103 {
Chris@16 104 template <typename Char, typename Traits>
Chris@16 105 static inline void apply(std::basic_ostream<Char, Traits>& os, Point const& p)
Chris@16 106 {
Chris@16 107 os << Policy::apply() << "(";
Chris@16 108 stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p);
Chris@16 109 os << ")";
Chris@16 110 }
Chris@16 111 };
Chris@16 112
Chris@16 113 /*!
Chris@16 114 \brief Stream ranges as WKT
Chris@16 115 \note policy is used to stream prefix/postfix, enabling derived classes to override this
Chris@16 116 */
Chris@16 117 template <typename Range, typename PrefixPolicy, typename SuffixPolicy>
Chris@16 118 struct wkt_range
Chris@16 119 {
Chris@16 120 template <typename Char, typename Traits>
Chris@16 121 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 122 Range const& range)
Chris@16 123 {
Chris@16 124 typedef typename boost::range_iterator<Range const>::type iterator_type;
Chris@16 125
Chris@16 126 bool first = true;
Chris@16 127
Chris@16 128 os << PrefixPolicy::apply();
Chris@16 129
Chris@16 130 // TODO: check EMPTY here
Chris@16 131
Chris@16 132 for (iterator_type it = boost::begin(range);
Chris@16 133 it != boost::end(range);
Chris@16 134 ++it)
Chris@16 135 {
Chris@16 136 os << (first ? "" : ",");
Chris@16 137 stream_coordinate
Chris@16 138 <
Chris@16 139 point_type, 0, dimension<point_type>::type::value
Chris@16 140 >::apply(os, *it);
Chris@16 141 first = false;
Chris@16 142 }
Chris@16 143
Chris@16 144 os << SuffixPolicy::apply();
Chris@16 145 }
Chris@16 146
Chris@16 147 private:
Chris@16 148 typedef typename boost::range_value<Range>::type point_type;
Chris@16 149 };
Chris@16 150
Chris@16 151 /*!
Chris@16 152 \brief Stream sequence of points as WKT-part, e.g. (1 2),(3 4)
Chris@16 153 \note Used in polygon, all multi-geometries
Chris@16 154 */
Chris@16 155 template <typename Range>
Chris@16 156 struct wkt_sequence
Chris@16 157 : wkt_range
Chris@16 158 <
Chris@16 159 Range,
Chris@16 160 opening_parenthesis,
Chris@16 161 closing_parenthesis
Chris@16 162 >
Chris@16 163 {};
Chris@16 164
Chris@16 165 template <typename Polygon, typename PrefixPolicy>
Chris@16 166 struct wkt_poly
Chris@16 167 {
Chris@16 168 template <typename Char, typename Traits>
Chris@16 169 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 170 Polygon const& poly)
Chris@16 171 {
Chris@16 172 typedef typename ring_type<Polygon const>::type ring;
Chris@16 173
Chris@16 174 os << PrefixPolicy::apply();
Chris@16 175 // TODO: check EMPTY here
Chris@16 176 os << "(";
Chris@16 177 wkt_sequence<ring>::apply(os, exterior_ring(poly));
Chris@16 178
Chris@16 179 typename interior_return_type<Polygon const>::type rings
Chris@16 180 = interior_rings(poly);
Chris@16 181 for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
Chris@16 182 {
Chris@16 183 os << ",";
Chris@16 184 wkt_sequence<ring>::apply(os, *it);
Chris@16 185 }
Chris@16 186 os << ")";
Chris@16 187 }
Chris@16 188 };
Chris@16 189
Chris@16 190 template <typename Box>
Chris@16 191 struct wkt_box
Chris@16 192 {
Chris@16 193 typedef typename point_type<Box>::type point_type;
Chris@16 194
Chris@16 195 template <typename Char, typename Traits>
Chris@16 196 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 197 Box const& box)
Chris@16 198 {
Chris@16 199 // Convert to ring, then stream
Chris@16 200 typedef model::ring<point_type> ring_type;
Chris@16 201 ring_type ring;
Chris@16 202 geometry::convert(box, ring);
Chris@16 203 os << "POLYGON(";
Chris@16 204 wkt_sequence<ring_type>::apply(os, ring);
Chris@16 205 os << ")";
Chris@16 206 }
Chris@16 207
Chris@16 208 private:
Chris@16 209
Chris@16 210 inline wkt_box()
Chris@16 211 {
Chris@16 212 // Only streaming of boxes with two dimensions is support, otherwise it is a polyhedron!
Chris@16 213 //assert_dimension<B, 2>();
Chris@16 214 }
Chris@16 215 };
Chris@16 216
Chris@16 217
Chris@16 218 template <typename Segment>
Chris@16 219 struct wkt_segment
Chris@16 220 {
Chris@16 221 typedef typename point_type<Segment>::type point_type;
Chris@16 222
Chris@16 223 template <typename Char, typename Traits>
Chris@16 224 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 225 Segment const& segment)
Chris@16 226 {
Chris@16 227 // Convert to two points, then stream
Chris@16 228 typedef boost::array<point_type, 2> sequence;
Chris@16 229
Chris@16 230 sequence points;
Chris@16 231 geometry::detail::assign_point_from_index<0>(segment, points[0]);
Chris@16 232 geometry::detail::assign_point_from_index<1>(segment, points[1]);
Chris@16 233
Chris@16 234 // In Boost.Geometry a segment is represented
Chris@16 235 // in WKT-format like (for 2D): LINESTRING(x y,x y)
Chris@16 236 os << "LINESTRING";
Chris@16 237 wkt_sequence<sequence>::apply(os, points);
Chris@16 238 }
Chris@16 239
Chris@16 240 private:
Chris@16 241
Chris@16 242 inline wkt_segment()
Chris@16 243 {}
Chris@16 244 };
Chris@16 245
Chris@16 246 }} // namespace detail::wkt
Chris@16 247 #endif // DOXYGEN_NO_DETAIL
Chris@16 248
Chris@16 249 #ifndef DOXYGEN_NO_DISPATCH
Chris@16 250 namespace dispatch
Chris@16 251 {
Chris@16 252
Chris@16 253 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
Chris@16 254 struct wkt: not_implemented<Tag>
Chris@16 255 {};
Chris@16 256
Chris@16 257 template <typename Point>
Chris@16 258 struct wkt<Point, point_tag>
Chris@16 259 : detail::wkt::wkt_point
Chris@16 260 <
Chris@16 261 Point,
Chris@16 262 detail::wkt::prefix_point
Chris@16 263 >
Chris@16 264 {};
Chris@16 265
Chris@16 266 template <typename Linestring>
Chris@16 267 struct wkt<Linestring, linestring_tag>
Chris@16 268 : detail::wkt::wkt_range
Chris@16 269 <
Chris@16 270 Linestring,
Chris@16 271 detail::wkt::prefix_linestring_par,
Chris@16 272 detail::wkt::closing_parenthesis
Chris@16 273 >
Chris@16 274 {};
Chris@16 275
Chris@16 276 /*!
Chris@16 277 \brief Specialization to stream a box as WKT
Chris@16 278 \details A "box" does not exist in WKT.
Chris@16 279 It is therefore streamed as a polygon
Chris@16 280 */
Chris@16 281 template <typename Box>
Chris@16 282 struct wkt<Box, box_tag>
Chris@16 283 : detail::wkt::wkt_box<Box>
Chris@16 284 {};
Chris@16 285
Chris@16 286 template <typename Segment>
Chris@16 287 struct wkt<Segment, segment_tag>
Chris@16 288 : detail::wkt::wkt_segment<Segment>
Chris@16 289 {};
Chris@16 290
Chris@16 291 /*!
Chris@16 292 \brief Specialization to stream a ring as WKT
Chris@16 293 \details A ring or "linear_ring" does not exist in WKT.
Chris@16 294 A ring is equivalent to a polygon without inner rings
Chris@16 295 It is therefore streamed as a polygon
Chris@16 296 */
Chris@16 297 template <typename Ring>
Chris@16 298 struct wkt<Ring, ring_tag>
Chris@16 299 : detail::wkt::wkt_range
Chris@16 300 <
Chris@16 301 Ring,
Chris@16 302 detail::wkt::prefix_ring_par_par,
Chris@16 303 detail::wkt::double_closing_parenthesis
Chris@16 304 >
Chris@16 305 {};
Chris@16 306
Chris@16 307 /*!
Chris@16 308 \brief Specialization to stream polygon as WKT
Chris@16 309 */
Chris@16 310 template <typename Polygon>
Chris@16 311 struct wkt<Polygon, polygon_tag>
Chris@16 312 : detail::wkt::wkt_poly
Chris@16 313 <
Chris@16 314 Polygon,
Chris@16 315 detail::wkt::prefix_polygon
Chris@16 316 >
Chris@16 317 {};
Chris@16 318
Chris@16 319
Chris@16 320 template <typename Geometry>
Chris@16 321 struct devarianted_wkt
Chris@16 322 {
Chris@16 323 template <typename OutputStream>
Chris@16 324 static inline void apply(OutputStream& os, Geometry const& geometry)
Chris@16 325 {
Chris@16 326 wkt<Geometry>::apply(os, geometry);
Chris@16 327 }
Chris@16 328 };
Chris@16 329
Chris@16 330 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
Chris@16 331 struct devarianted_wkt<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
Chris@16 332 {
Chris@16 333 template <typename OutputStream>
Chris@16 334 struct visitor: static_visitor<void>
Chris@16 335 {
Chris@16 336 OutputStream& m_os;
Chris@16 337
Chris@16 338 visitor(OutputStream& os)
Chris@16 339 : m_os(os)
Chris@16 340 {}
Chris@16 341
Chris@16 342 template <typename Geometry>
Chris@16 343 inline void operator()(Geometry const& geometry) const
Chris@16 344 {
Chris@16 345 devarianted_wkt<Geometry>::apply(m_os, geometry);
Chris@16 346 }
Chris@16 347 };
Chris@16 348
Chris@16 349 template <typename OutputStream>
Chris@16 350 static inline void apply(
Chris@16 351 OutputStream& os,
Chris@16 352 variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry
Chris@16 353 )
Chris@16 354 {
Chris@16 355 apply_visitor(visitor<OutputStream>(os), geometry);
Chris@16 356 }
Chris@16 357 };
Chris@16 358
Chris@16 359
Chris@16 360 } // namespace dispatch
Chris@16 361 #endif // DOXYGEN_NO_DISPATCH
Chris@16 362
Chris@16 363 /*!
Chris@16 364 \brief Generic geometry template manipulator class, takes corresponding output class from traits class
Chris@16 365 \ingroup wkt
Chris@16 366 \details Stream manipulator, streams geometry classes as \ref WKT streams
Chris@16 367 \par Example:
Chris@16 368 Small example showing how to use the wkt class
Chris@16 369 \dontinclude doxygen_1.cpp
Chris@16 370 \skip example_as_wkt_point
Chris@16 371 \line {
Chris@16 372 \until }
Chris@16 373 */
Chris@16 374 template <typename Geometry>
Chris@16 375 class wkt_manipulator
Chris@16 376 {
Chris@16 377 public:
Chris@16 378
Chris@16 379 inline wkt_manipulator(Geometry const& g)
Chris@16 380 : m_geometry(g)
Chris@16 381 {}
Chris@16 382
Chris@16 383 template <typename Char, typename Traits>
Chris@16 384 inline friend std::basic_ostream<Char, Traits>& operator<<(
Chris@16 385 std::basic_ostream<Char, Traits>& os,
Chris@16 386 wkt_manipulator const& m)
Chris@16 387 {
Chris@16 388 dispatch::devarianted_wkt<Geometry>::apply(os, m.m_geometry);
Chris@16 389 os.flush();
Chris@16 390 return os;
Chris@16 391 }
Chris@16 392
Chris@16 393 private:
Chris@16 394 Geometry const& m_geometry;
Chris@16 395 };
Chris@16 396
Chris@16 397 /*!
Chris@16 398 \brief Main WKT-streaming function
Chris@16 399 \ingroup wkt
Chris@16 400 \par Example:
Chris@16 401 Small example showing how to use the wkt helper function
Chris@16 402 \dontinclude doxygen_1.cpp
Chris@16 403 \skip example_as_wkt_vector
Chris@16 404 \line {
Chris@16 405 \until }
Chris@16 406 */
Chris@16 407 template <typename Geometry>
Chris@16 408 inline wkt_manipulator<Geometry> wkt(Geometry const& geometry)
Chris@16 409 {
Chris@16 410 concept::check<Geometry const>();
Chris@16 411
Chris@16 412 return wkt_manipulator<Geometry>(geometry);
Chris@16 413 }
Chris@16 414
Chris@16 415 #if defined(_MSC_VER)
Chris@16 416 #pragma warning(pop)
Chris@16 417 #endif
Chris@16 418
Chris@16 419 }} // namespace boost::geometry
Chris@16 420
Chris@16 421 #endif // BOOST_GEOMETRY_IO_WKT_WRITE_HPP