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