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_ALGORITHMS_CONVERT_HPP
|
Chris@16
|
15 #define BOOST_GEOMETRY_ALGORITHMS_CONVERT_HPP
|
Chris@16
|
16
|
Chris@16
|
17
|
Chris@16
|
18 #include <cstddef>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/numeric/conversion/cast.hpp>
|
Chris@16
|
21 #include <boost/range.hpp>
|
Chris@16
|
22 #include <boost/type_traits/is_array.hpp>
|
Chris@16
|
23
|
Chris@16
|
24 #include <boost/geometry/arithmetic/arithmetic.hpp>
|
Chris@16
|
25 #include <boost/geometry/algorithms/not_implemented.hpp>
|
Chris@16
|
26 #include <boost/geometry/algorithms/append.hpp>
|
Chris@16
|
27 #include <boost/geometry/algorithms/clear.hpp>
|
Chris@16
|
28 #include <boost/geometry/algorithms/for_each.hpp>
|
Chris@16
|
29 #include <boost/geometry/algorithms/detail/assign_values.hpp>
|
Chris@16
|
30 #include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
|
Chris@16
|
31 #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
|
Chris@16
|
32 #include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
|
Chris@16
|
33 #include <boost/geometry/algorithms/detail/convert_indexed_to_indexed.hpp>
|
Chris@16
|
34
|
Chris@16
|
35 #include <boost/geometry/views/closeable_view.hpp>
|
Chris@16
|
36 #include <boost/geometry/views/reversible_view.hpp>
|
Chris@16
|
37
|
Chris@16
|
38 #include <boost/geometry/core/cs.hpp>
|
Chris@16
|
39 #include <boost/geometry/core/closure.hpp>
|
Chris@16
|
40 #include <boost/geometry/core/point_order.hpp>
|
Chris@16
|
41 #include <boost/geometry/geometries/concepts/check.hpp>
|
Chris@16
|
42
|
Chris@16
|
43 #include <boost/variant/static_visitor.hpp>
|
Chris@16
|
44 #include <boost/variant/apply_visitor.hpp>
|
Chris@16
|
45 #include <boost/variant/variant_fwd.hpp>
|
Chris@16
|
46
|
Chris@16
|
47
|
Chris@16
|
48 namespace boost { namespace geometry
|
Chris@16
|
49 {
|
Chris@16
|
50
|
Chris@16
|
51 // Silence warning C4127: conditional expression is constant
|
Chris@16
|
52 // Silence warning C4512: assignment operator could not be generated
|
Chris@16
|
53 #if defined(_MSC_VER)
|
Chris@16
|
54 #pragma warning(push)
|
Chris@16
|
55 #pragma warning(disable : 4127 4512)
|
Chris@16
|
56 #endif
|
Chris@16
|
57
|
Chris@16
|
58
|
Chris@16
|
59 #ifndef DOXYGEN_NO_DETAIL
|
Chris@16
|
60 namespace detail { namespace conversion
|
Chris@16
|
61 {
|
Chris@16
|
62
|
Chris@16
|
63 template
|
Chris@16
|
64 <
|
Chris@16
|
65 typename Point,
|
Chris@16
|
66 typename Box,
|
Chris@16
|
67 std::size_t Index,
|
Chris@16
|
68 std::size_t Dimension,
|
Chris@16
|
69 std::size_t DimensionCount
|
Chris@16
|
70 >
|
Chris@16
|
71 struct point_to_box
|
Chris@16
|
72 {
|
Chris@16
|
73 static inline void apply(Point const& point, Box& box)
|
Chris@16
|
74 {
|
Chris@16
|
75 typedef typename coordinate_type<Box>::type coordinate_type;
|
Chris@16
|
76
|
Chris@16
|
77 set<Index, Dimension>(box,
|
Chris@16
|
78 boost::numeric_cast<coordinate_type>(get<Dimension>(point)));
|
Chris@16
|
79 point_to_box
|
Chris@16
|
80 <
|
Chris@16
|
81 Point, Box,
|
Chris@16
|
82 Index, Dimension + 1, DimensionCount
|
Chris@16
|
83 >::apply(point, box);
|
Chris@16
|
84 }
|
Chris@16
|
85 };
|
Chris@16
|
86
|
Chris@16
|
87
|
Chris@16
|
88 template
|
Chris@16
|
89 <
|
Chris@16
|
90 typename Point,
|
Chris@16
|
91 typename Box,
|
Chris@16
|
92 std::size_t Index,
|
Chris@16
|
93 std::size_t DimensionCount
|
Chris@16
|
94 >
|
Chris@16
|
95 struct point_to_box<Point, Box, Index, DimensionCount, DimensionCount>
|
Chris@16
|
96 {
|
Chris@16
|
97 static inline void apply(Point const& , Box& )
|
Chris@16
|
98 {}
|
Chris@16
|
99 };
|
Chris@16
|
100
|
Chris@16
|
101 template <typename Box, typename Range, bool Close, bool Reverse>
|
Chris@16
|
102 struct box_to_range
|
Chris@16
|
103 {
|
Chris@16
|
104 static inline void apply(Box const& box, Range& range)
|
Chris@16
|
105 {
|
Chris@16
|
106 traits::resize<Range>::apply(range, Close ? 5 : 4);
|
Chris@16
|
107 assign_box_corners_oriented<Reverse>(box, range);
|
Chris@16
|
108 if (Close)
|
Chris@16
|
109 {
|
Chris@16
|
110 range[4] = range[0];
|
Chris@16
|
111 }
|
Chris@16
|
112 }
|
Chris@16
|
113 };
|
Chris@16
|
114
|
Chris@16
|
115 template <typename Segment, typename Range>
|
Chris@16
|
116 struct segment_to_range
|
Chris@16
|
117 {
|
Chris@16
|
118 static inline void apply(Segment const& segment, Range& range)
|
Chris@16
|
119 {
|
Chris@16
|
120 traits::resize<Range>::apply(range, 2);
|
Chris@16
|
121
|
Chris@16
|
122 typename boost::range_iterator<Range>::type it = boost::begin(range);
|
Chris@16
|
123
|
Chris@16
|
124 assign_point_from_index<0>(segment, *it);
|
Chris@16
|
125 ++it;
|
Chris@16
|
126 assign_point_from_index<1>(segment, *it);
|
Chris@16
|
127 }
|
Chris@16
|
128 };
|
Chris@16
|
129
|
Chris@16
|
130 template
|
Chris@16
|
131 <
|
Chris@16
|
132 typename Range1,
|
Chris@16
|
133 typename Range2,
|
Chris@16
|
134 bool Reverse = false
|
Chris@16
|
135 >
|
Chris@16
|
136 struct range_to_range
|
Chris@16
|
137 {
|
Chris@16
|
138 typedef typename reversible_view
|
Chris@16
|
139 <
|
Chris@16
|
140 Range1 const,
|
Chris@16
|
141 Reverse ? iterate_reverse : iterate_forward
|
Chris@16
|
142 >::type rview_type;
|
Chris@16
|
143 typedef typename closeable_view
|
Chris@16
|
144 <
|
Chris@16
|
145 rview_type const,
|
Chris@16
|
146 geometry::closure<Range1>::value
|
Chris@16
|
147 >::type view_type;
|
Chris@16
|
148
|
Chris@16
|
149 static inline void apply(Range1 const& source, Range2& destination)
|
Chris@16
|
150 {
|
Chris@16
|
151 geometry::clear(destination);
|
Chris@16
|
152
|
Chris@16
|
153 rview_type rview(source);
|
Chris@16
|
154
|
Chris@16
|
155 // We consider input always as closed, and skip last
|
Chris@16
|
156 // point for open output.
|
Chris@16
|
157 view_type view(rview);
|
Chris@16
|
158
|
Chris@16
|
159 int n = boost::size(view);
|
Chris@16
|
160 if (geometry::closure<Range2>::value == geometry::open)
|
Chris@16
|
161 {
|
Chris@16
|
162 n--;
|
Chris@16
|
163 }
|
Chris@16
|
164
|
Chris@16
|
165 int i = 0;
|
Chris@16
|
166 for (typename boost::range_iterator<view_type const>::type it
|
Chris@16
|
167 = boost::begin(view);
|
Chris@16
|
168 it != boost::end(view) && i < n;
|
Chris@16
|
169 ++it, ++i)
|
Chris@16
|
170 {
|
Chris@16
|
171 geometry::append(destination, *it);
|
Chris@16
|
172 }
|
Chris@16
|
173 }
|
Chris@16
|
174 };
|
Chris@16
|
175
|
Chris@16
|
176 template <typename Polygon1, typename Polygon2>
|
Chris@16
|
177 struct polygon_to_polygon
|
Chris@16
|
178 {
|
Chris@16
|
179 typedef range_to_range
|
Chris@16
|
180 <
|
Chris@16
|
181 typename geometry::ring_type<Polygon1>::type,
|
Chris@16
|
182 typename geometry::ring_type<Polygon2>::type,
|
Chris@16
|
183 geometry::point_order<Polygon1>::value
|
Chris@16
|
184 != geometry::point_order<Polygon2>::value
|
Chris@16
|
185 > per_ring;
|
Chris@16
|
186
|
Chris@16
|
187 static inline void apply(Polygon1 const& source, Polygon2& destination)
|
Chris@16
|
188 {
|
Chris@16
|
189 // Clearing managed per ring, and in the resizing of interior rings
|
Chris@16
|
190
|
Chris@16
|
191 per_ring::apply(geometry::exterior_ring(source),
|
Chris@16
|
192 geometry::exterior_ring(destination));
|
Chris@16
|
193
|
Chris@16
|
194 // Container should be resizeable
|
Chris@16
|
195 traits::resize
|
Chris@16
|
196 <
|
Chris@16
|
197 typename boost::remove_reference
|
Chris@16
|
198 <
|
Chris@16
|
199 typename traits::interior_mutable_type<Polygon2>::type
|
Chris@16
|
200 >::type
|
Chris@16
|
201 >::apply(interior_rings(destination), num_interior_rings(source));
|
Chris@16
|
202
|
Chris@16
|
203 typename interior_return_type<Polygon1 const>::type rings_source
|
Chris@16
|
204 = interior_rings(source);
|
Chris@16
|
205 typename interior_return_type<Polygon2>::type rings_dest
|
Chris@16
|
206 = interior_rings(destination);
|
Chris@16
|
207
|
Chris@16
|
208 BOOST_AUTO_TPL(it_source, boost::begin(rings_source));
|
Chris@16
|
209 BOOST_AUTO_TPL(it_dest, boost::begin(rings_dest));
|
Chris@16
|
210
|
Chris@16
|
211 for ( ; it_source != boost::end(rings_source); ++it_source, ++it_dest)
|
Chris@16
|
212 {
|
Chris@16
|
213 per_ring::apply(*it_source, *it_dest);
|
Chris@16
|
214 }
|
Chris@16
|
215 }
|
Chris@16
|
216 };
|
Chris@16
|
217
|
Chris@16
|
218
|
Chris@16
|
219 }} // namespace detail::conversion
|
Chris@16
|
220 #endif // DOXYGEN_NO_DETAIL
|
Chris@16
|
221
|
Chris@16
|
222
|
Chris@16
|
223 #ifndef DOXYGEN_NO_DISPATCH
|
Chris@16
|
224 namespace dispatch
|
Chris@16
|
225 {
|
Chris@16
|
226
|
Chris@16
|
227 template
|
Chris@16
|
228 <
|
Chris@16
|
229 typename Geometry1, typename Geometry2,
|
Chris@16
|
230 typename Tag1 = typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
|
Chris@16
|
231 typename Tag2 = typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type,
|
Chris@16
|
232 std::size_t DimensionCount = dimension<Geometry1>::type::value,
|
Chris@16
|
233 bool UseAssignment = boost::is_same<Geometry1, Geometry2>::value
|
Chris@16
|
234 && !boost::is_array<Geometry1>::value
|
Chris@16
|
235 >
|
Chris@16
|
236 struct convert: not_implemented<Tag1, Tag2, mpl::int_<DimensionCount> >
|
Chris@16
|
237 {};
|
Chris@16
|
238
|
Chris@16
|
239
|
Chris@16
|
240 template
|
Chris@16
|
241 <
|
Chris@16
|
242 typename Geometry1, typename Geometry2,
|
Chris@16
|
243 typename Tag,
|
Chris@16
|
244 std::size_t DimensionCount
|
Chris@16
|
245 >
|
Chris@16
|
246 struct convert<Geometry1, Geometry2, Tag, Tag, DimensionCount, true>
|
Chris@16
|
247 {
|
Chris@16
|
248 // Same geometry type -> copy whole geometry
|
Chris@16
|
249 static inline void apply(Geometry1 const& source, Geometry2& destination)
|
Chris@16
|
250 {
|
Chris@16
|
251 destination = source;
|
Chris@16
|
252 }
|
Chris@16
|
253 };
|
Chris@16
|
254
|
Chris@16
|
255
|
Chris@16
|
256 template
|
Chris@16
|
257 <
|
Chris@16
|
258 typename Geometry1, typename Geometry2,
|
Chris@16
|
259 std::size_t DimensionCount
|
Chris@16
|
260 >
|
Chris@16
|
261 struct convert<Geometry1, Geometry2, point_tag, point_tag, DimensionCount, false>
|
Chris@16
|
262 : detail::conversion::point_to_point<Geometry1, Geometry2, 0, DimensionCount>
|
Chris@16
|
263 {};
|
Chris@16
|
264
|
Chris@16
|
265
|
Chris@16
|
266 template
|
Chris@16
|
267 <
|
Chris@16
|
268 typename Box1, typename Box2,
|
Chris@16
|
269 std::size_t DimensionCount
|
Chris@16
|
270 >
|
Chris@16
|
271 struct convert<Box1, Box2, box_tag, box_tag, DimensionCount, false>
|
Chris@16
|
272 : detail::conversion::indexed_to_indexed<Box1, Box2, 0, DimensionCount>
|
Chris@16
|
273 {};
|
Chris@16
|
274
|
Chris@16
|
275
|
Chris@16
|
276 template
|
Chris@16
|
277 <
|
Chris@16
|
278 typename Segment1, typename Segment2,
|
Chris@16
|
279 std::size_t DimensionCount
|
Chris@16
|
280 >
|
Chris@16
|
281 struct convert<Segment1, Segment2, segment_tag, segment_tag, DimensionCount, false>
|
Chris@16
|
282 : detail::conversion::indexed_to_indexed<Segment1, Segment2, 0, DimensionCount>
|
Chris@16
|
283 {};
|
Chris@16
|
284
|
Chris@16
|
285
|
Chris@16
|
286 template <typename Segment, typename LineString, std::size_t DimensionCount>
|
Chris@16
|
287 struct convert<Segment, LineString, segment_tag, linestring_tag, DimensionCount, false>
|
Chris@16
|
288 : detail::conversion::segment_to_range<Segment, LineString>
|
Chris@16
|
289 {};
|
Chris@16
|
290
|
Chris@16
|
291
|
Chris@16
|
292 template <typename Ring1, typename Ring2, std::size_t DimensionCount>
|
Chris@16
|
293 struct convert<Ring1, Ring2, ring_tag, ring_tag, DimensionCount, false>
|
Chris@16
|
294 : detail::conversion::range_to_range
|
Chris@16
|
295 <
|
Chris@16
|
296 Ring1,
|
Chris@16
|
297 Ring2,
|
Chris@16
|
298 geometry::point_order<Ring1>::value
|
Chris@16
|
299 != geometry::point_order<Ring2>::value
|
Chris@16
|
300 >
|
Chris@16
|
301 {};
|
Chris@16
|
302
|
Chris@16
|
303 template <typename LineString1, typename LineString2, std::size_t DimensionCount>
|
Chris@16
|
304 struct convert<LineString1, LineString2, linestring_tag, linestring_tag, DimensionCount, false>
|
Chris@16
|
305 : detail::conversion::range_to_range<LineString1, LineString2>
|
Chris@16
|
306 {};
|
Chris@16
|
307
|
Chris@16
|
308 template <typename Polygon1, typename Polygon2, std::size_t DimensionCount>
|
Chris@16
|
309 struct convert<Polygon1, Polygon2, polygon_tag, polygon_tag, DimensionCount, false>
|
Chris@16
|
310 : detail::conversion::polygon_to_polygon<Polygon1, Polygon2>
|
Chris@16
|
311 {};
|
Chris@16
|
312
|
Chris@16
|
313 template <typename Box, typename Ring>
|
Chris@16
|
314 struct convert<Box, Ring, box_tag, ring_tag, 2, false>
|
Chris@16
|
315 : detail::conversion::box_to_range
|
Chris@16
|
316 <
|
Chris@16
|
317 Box,
|
Chris@16
|
318 Ring,
|
Chris@16
|
319 geometry::closure<Ring>::value == closed,
|
Chris@16
|
320 geometry::point_order<Ring>::value == counterclockwise
|
Chris@16
|
321 >
|
Chris@16
|
322 {};
|
Chris@16
|
323
|
Chris@16
|
324
|
Chris@16
|
325 template <typename Box, typename Polygon>
|
Chris@16
|
326 struct convert<Box, Polygon, box_tag, polygon_tag, 2, false>
|
Chris@16
|
327 {
|
Chris@16
|
328 static inline void apply(Box const& box, Polygon& polygon)
|
Chris@16
|
329 {
|
Chris@16
|
330 typedef typename ring_type<Polygon>::type ring_type;
|
Chris@16
|
331
|
Chris@16
|
332 convert
|
Chris@16
|
333 <
|
Chris@16
|
334 Box, ring_type,
|
Chris@16
|
335 box_tag, ring_tag,
|
Chris@16
|
336 2, false
|
Chris@16
|
337 >::apply(box, exterior_ring(polygon));
|
Chris@16
|
338 }
|
Chris@16
|
339 };
|
Chris@16
|
340
|
Chris@16
|
341
|
Chris@16
|
342 template <typename Point, typename Box, std::size_t DimensionCount>
|
Chris@16
|
343 struct convert<Point, Box, point_tag, box_tag, DimensionCount, false>
|
Chris@16
|
344 {
|
Chris@16
|
345 static inline void apply(Point const& point, Box& box)
|
Chris@16
|
346 {
|
Chris@16
|
347 detail::conversion::point_to_box
|
Chris@16
|
348 <
|
Chris@16
|
349 Point, Box, min_corner, 0, DimensionCount
|
Chris@16
|
350 >::apply(point, box);
|
Chris@16
|
351 detail::conversion::point_to_box
|
Chris@16
|
352 <
|
Chris@16
|
353 Point, Box, max_corner, 0, DimensionCount
|
Chris@16
|
354 >::apply(point, box);
|
Chris@16
|
355 }
|
Chris@16
|
356 };
|
Chris@16
|
357
|
Chris@16
|
358
|
Chris@16
|
359 template <typename Ring, typename Polygon, std::size_t DimensionCount>
|
Chris@16
|
360 struct convert<Ring, Polygon, ring_tag, polygon_tag, DimensionCount, false>
|
Chris@16
|
361 {
|
Chris@16
|
362 static inline void apply(Ring const& ring, Polygon& polygon)
|
Chris@16
|
363 {
|
Chris@16
|
364 typedef typename ring_type<Polygon>::type ring_type;
|
Chris@16
|
365 convert
|
Chris@16
|
366 <
|
Chris@16
|
367 Ring, ring_type,
|
Chris@16
|
368 ring_tag, ring_tag,
|
Chris@16
|
369 DimensionCount, false
|
Chris@16
|
370 >::apply(ring, exterior_ring(polygon));
|
Chris@16
|
371 }
|
Chris@16
|
372 };
|
Chris@16
|
373
|
Chris@16
|
374
|
Chris@16
|
375 template <typename Polygon, typename Ring, std::size_t DimensionCount>
|
Chris@16
|
376 struct convert<Polygon, Ring, polygon_tag, ring_tag, DimensionCount, false>
|
Chris@16
|
377 {
|
Chris@16
|
378 static inline void apply(Polygon const& polygon, Ring& ring)
|
Chris@16
|
379 {
|
Chris@16
|
380 typedef typename ring_type<Polygon>::type ring_type;
|
Chris@16
|
381
|
Chris@16
|
382 convert
|
Chris@16
|
383 <
|
Chris@16
|
384 ring_type, Ring,
|
Chris@16
|
385 ring_tag, ring_tag,
|
Chris@16
|
386 DimensionCount, false
|
Chris@16
|
387 >::apply(exterior_ring(polygon), ring);
|
Chris@16
|
388 }
|
Chris@16
|
389 };
|
Chris@16
|
390
|
Chris@16
|
391
|
Chris@16
|
392 template <typename Geometry1, typename Geometry2>
|
Chris@16
|
393 struct devarianted_convert
|
Chris@16
|
394 {
|
Chris@16
|
395 static inline void apply(Geometry1 const& geometry1, Geometry2& geometry2)
|
Chris@16
|
396 {
|
Chris@16
|
397 concept::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2>();
|
Chris@16
|
398 convert<Geometry1, Geometry2>::apply(geometry1, geometry2);
|
Chris@16
|
399 }
|
Chris@16
|
400 };
|
Chris@16
|
401
|
Chris@16
|
402 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
Chris@16
|
403 struct devarianted_convert<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
Chris@16
|
404 {
|
Chris@16
|
405 struct visitor: static_visitor<void>
|
Chris@16
|
406 {
|
Chris@16
|
407 Geometry2& m_geometry2;
|
Chris@16
|
408
|
Chris@16
|
409 visitor(Geometry2& geometry2)
|
Chris@16
|
410 : m_geometry2(geometry2)
|
Chris@16
|
411 {}
|
Chris@16
|
412
|
Chris@16
|
413 template <typename Geometry1>
|
Chris@16
|
414 inline void operator()(Geometry1 const& geometry1) const
|
Chris@16
|
415 {
|
Chris@16
|
416 devarianted_convert<Geometry1, Geometry2>::apply(geometry1, m_geometry2);
|
Chris@16
|
417 }
|
Chris@16
|
418 };
|
Chris@16
|
419
|
Chris@16
|
420 static inline void apply(
|
Chris@16
|
421 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
Chris@16
|
422 Geometry2& geometry2
|
Chris@16
|
423 )
|
Chris@16
|
424 {
|
Chris@16
|
425 apply_visitor(visitor(geometry2), geometry1);
|
Chris@16
|
426 }
|
Chris@16
|
427 };
|
Chris@16
|
428
|
Chris@16
|
429
|
Chris@16
|
430 } // namespace dispatch
|
Chris@16
|
431 #endif // DOXYGEN_NO_DISPATCH
|
Chris@16
|
432
|
Chris@16
|
433
|
Chris@16
|
434 /*!
|
Chris@16
|
435 \brief Converts one geometry to another geometry
|
Chris@16
|
436 \details The convert algorithm converts one geometry, e.g. a BOX, to another
|
Chris@16
|
437 geometry, e.g. a RING. This only works if it is possible and applicable.
|
Chris@16
|
438 If the point-order is different, or the closure is different between two
|
Chris@16
|
439 geometry types, it will be converted correctly by explicitly reversing the
|
Chris@16
|
440 points or closing or opening the polygon rings.
|
Chris@16
|
441 \ingroup convert
|
Chris@16
|
442 \tparam Geometry1 \tparam_geometry
|
Chris@16
|
443 \tparam Geometry2 \tparam_geometry
|
Chris@16
|
444 \param geometry1 \param_geometry (source)
|
Chris@16
|
445 \param geometry2 \param_geometry (target)
|
Chris@16
|
446
|
Chris@16
|
447 \qbk{[include reference/algorithms/convert.qbk]}
|
Chris@16
|
448 */
|
Chris@16
|
449 template <typename Geometry1, typename Geometry2>
|
Chris@16
|
450 inline void convert(Geometry1 const& geometry1, Geometry2& geometry2)
|
Chris@16
|
451 {
|
Chris@16
|
452 dispatch::devarianted_convert<Geometry1, Geometry2>::apply(geometry1, geometry2);
|
Chris@16
|
453 }
|
Chris@16
|
454
|
Chris@16
|
455 #if defined(_MSC_VER)
|
Chris@16
|
456 #pragma warning(pop)
|
Chris@16
|
457 #endif
|
Chris@16
|
458
|
Chris@16
|
459 }} // namespace boost::geometry
|
Chris@16
|
460
|
Chris@16
|
461 #endif // BOOST_GEOMETRY_ALGORITHMS_CONVERT_HPP
|