Chris@16
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@16
|
2
|
Chris@101
|
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@101
|
4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
Chris@101
|
5 // Copyright (c) 2009-2015 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_SIMPLIFY_HPP
|
Chris@16
|
15 #define BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
|
Chris@16
|
16
|
Chris@16
|
17 #include <cstddef>
|
Chris@16
|
18
|
Chris@101
|
19 #include <boost/core/ignore_unused.hpp>
|
Chris@16
|
20 #include <boost/range.hpp>
|
Chris@101
|
21
|
Chris@101
|
22 #include <boost/variant/apply_visitor.hpp>
|
Chris@101
|
23 #include <boost/variant/static_visitor.hpp>
|
Chris@101
|
24 #include <boost/variant/variant_fwd.hpp>
|
Chris@16
|
25
|
Chris@16
|
26 #include <boost/geometry/core/cs.hpp>
|
Chris@16
|
27 #include <boost/geometry/core/closure.hpp>
|
Chris@16
|
28 #include <boost/geometry/core/exterior_ring.hpp>
|
Chris@16
|
29 #include <boost/geometry/core/interior_rings.hpp>
|
Chris@16
|
30 #include <boost/geometry/core/mutable_range.hpp>
|
Chris@101
|
31 #include <boost/geometry/core/tags.hpp>
|
Chris@16
|
32
|
Chris@16
|
33 #include <boost/geometry/geometries/concepts/check.hpp>
|
Chris@16
|
34 #include <boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp>
|
Chris@16
|
35 #include <boost/geometry/strategies/concepts/simplify_concept.hpp>
|
Chris@101
|
36 #include <boost/geometry/strategies/default_strategy.hpp>
|
Chris@101
|
37 #include <boost/geometry/strategies/distance.hpp>
|
Chris@16
|
38
|
Chris@16
|
39 #include <boost/geometry/algorithms/clear.hpp>
|
Chris@16
|
40 #include <boost/geometry/algorithms/convert.hpp>
|
Chris@16
|
41 #include <boost/geometry/algorithms/not_implemented.hpp>
|
Chris@16
|
42
|
Chris@101
|
43 #include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
|
Chris@16
|
44
|
Chris@16
|
45 namespace boost { namespace geometry
|
Chris@16
|
46 {
|
Chris@16
|
47
|
Chris@16
|
48 #ifndef DOXYGEN_NO_DETAIL
|
Chris@16
|
49 namespace detail { namespace simplify
|
Chris@16
|
50 {
|
Chris@16
|
51
|
Chris@16
|
52 struct simplify_range_insert
|
Chris@16
|
53 {
|
Chris@16
|
54 template<typename Range, typename Strategy, typename OutputIterator, typename Distance>
|
Chris@16
|
55 static inline void apply(Range const& range, OutputIterator out,
|
Chris@16
|
56 Distance const& max_distance, Strategy const& strategy)
|
Chris@16
|
57 {
|
Chris@101
|
58 boost::ignore_unused(strategy);
|
Chris@101
|
59
|
Chris@16
|
60 if (boost::size(range) <= 2 || max_distance < 0)
|
Chris@16
|
61 {
|
Chris@16
|
62 std::copy(boost::begin(range), boost::end(range), out);
|
Chris@16
|
63 }
|
Chris@16
|
64 else
|
Chris@16
|
65 {
|
Chris@16
|
66 strategy.apply(range, out, max_distance);
|
Chris@16
|
67 }
|
Chris@16
|
68 }
|
Chris@16
|
69 };
|
Chris@16
|
70
|
Chris@16
|
71
|
Chris@16
|
72 struct simplify_copy
|
Chris@16
|
73 {
|
Chris@16
|
74 template <typename Range, typename Strategy, typename Distance>
|
Chris@16
|
75 static inline void apply(Range const& range, Range& out,
|
Chris@16
|
76 Distance const& , Strategy const& )
|
Chris@16
|
77 {
|
Chris@16
|
78 std::copy
|
Chris@16
|
79 (
|
Chris@16
|
80 boost::begin(range), boost::end(range), std::back_inserter(out)
|
Chris@16
|
81 );
|
Chris@16
|
82 }
|
Chris@16
|
83 };
|
Chris@16
|
84
|
Chris@16
|
85
|
Chris@16
|
86 template<std::size_t Minimum>
|
Chris@16
|
87 struct simplify_range
|
Chris@16
|
88 {
|
Chris@16
|
89 template <typename Range, typename Strategy, typename Distance>
|
Chris@16
|
90 static inline void apply(Range const& range, Range& out,
|
Chris@16
|
91 Distance const& max_distance, Strategy const& strategy)
|
Chris@16
|
92 {
|
Chris@16
|
93 // Call do_container for a linestring / ring
|
Chris@16
|
94
|
Chris@16
|
95 /* For a RING:
|
Chris@16
|
96 The first/last point (the closing point of the ring) should maybe
|
Chris@16
|
97 be excluded because it lies on a line with second/one but last.
|
Chris@16
|
98 Here it is never excluded.
|
Chris@16
|
99
|
Chris@16
|
100 Note also that, especially if max_distance is too large,
|
Chris@16
|
101 the output ring might be self intersecting while the input ring is
|
Chris@16
|
102 not, although chances are low in normal polygons
|
Chris@16
|
103
|
Chris@16
|
104 Finally the inputring might have 3 (open) or 4 (closed) points (=correct),
|
Chris@16
|
105 the output < 3 or 4(=wrong)
|
Chris@16
|
106 */
|
Chris@16
|
107
|
Chris@16
|
108 if (boost::size(range) <= int(Minimum) || max_distance < 0.0)
|
Chris@16
|
109 {
|
Chris@16
|
110 simplify_copy::apply(range, out, max_distance, strategy);
|
Chris@16
|
111 }
|
Chris@16
|
112 else
|
Chris@16
|
113 {
|
Chris@16
|
114 simplify_range_insert::apply
|
Chris@16
|
115 (
|
Chris@16
|
116 range, std::back_inserter(out), max_distance, strategy
|
Chris@16
|
117 );
|
Chris@16
|
118 }
|
Chris@16
|
119 }
|
Chris@16
|
120 };
|
Chris@16
|
121
|
Chris@16
|
122 struct simplify_polygon
|
Chris@16
|
123 {
|
Chris@101
|
124 private:
|
Chris@101
|
125
|
Chris@101
|
126 template
|
Chris@101
|
127 <
|
Chris@101
|
128 std::size_t Minimum,
|
Chris@101
|
129 typename IteratorIn,
|
Chris@101
|
130 typename IteratorOut,
|
Chris@101
|
131 typename Distance,
|
Chris@101
|
132 typename Strategy
|
Chris@101
|
133 >
|
Chris@101
|
134 static inline void iterate(IteratorIn begin, IteratorIn end,
|
Chris@101
|
135 IteratorOut it_out,
|
Chris@101
|
136 Distance const& max_distance, Strategy const& strategy)
|
Chris@101
|
137 {
|
Chris@101
|
138 for (IteratorIn it_in = begin; it_in != end; ++it_in, ++it_out)
|
Chris@101
|
139 {
|
Chris@101
|
140 simplify_range<Minimum>::apply(*it_in, *it_out, max_distance, strategy);
|
Chris@101
|
141 }
|
Chris@101
|
142 }
|
Chris@101
|
143
|
Chris@101
|
144 template
|
Chris@101
|
145 <
|
Chris@101
|
146 std::size_t Minimum,
|
Chris@101
|
147 typename InteriorRingsIn,
|
Chris@101
|
148 typename InteriorRingsOut,
|
Chris@101
|
149 typename Distance,
|
Chris@101
|
150 typename Strategy
|
Chris@101
|
151 >
|
Chris@101
|
152 static inline void apply_interior_rings(
|
Chris@101
|
153 InteriorRingsIn const& interior_rings_in,
|
Chris@101
|
154 InteriorRingsOut& interior_rings_out,
|
Chris@101
|
155 Distance const& max_distance, Strategy const& strategy)
|
Chris@101
|
156 {
|
Chris@101
|
157 traits::resize<InteriorRingsOut>::apply(interior_rings_out,
|
Chris@101
|
158 boost::size(interior_rings_in));
|
Chris@101
|
159
|
Chris@101
|
160 iterate<Minimum>(
|
Chris@101
|
161 boost::begin(interior_rings_in), boost::end(interior_rings_in),
|
Chris@101
|
162 boost::begin(interior_rings_out),
|
Chris@101
|
163 max_distance, strategy);
|
Chris@101
|
164 }
|
Chris@101
|
165
|
Chris@101
|
166 public:
|
Chris@16
|
167 template <typename Polygon, typename Strategy, typename Distance>
|
Chris@16
|
168 static inline void apply(Polygon const& poly_in, Polygon& poly_out,
|
Chris@16
|
169 Distance const& max_distance, Strategy const& strategy)
|
Chris@16
|
170 {
|
Chris@101
|
171 std::size_t const minimum = core_detail::closure::minimum_ring_size
|
Chris@16
|
172 <
|
Chris@16
|
173 geometry::closure<Polygon>::value
|
Chris@16
|
174 >::value;
|
Chris@16
|
175
|
Chris@16
|
176 // Note that if there are inner rings, and distance is too large,
|
Chris@16
|
177 // they might intersect with the outer ring in the output,
|
Chris@16
|
178 // while it didn't in the input.
|
Chris@101
|
179 simplify_range<minimum>::apply(exterior_ring(poly_in),
|
Chris@16
|
180 exterior_ring(poly_out),
|
Chris@16
|
181 max_distance, strategy);
|
Chris@16
|
182
|
Chris@101
|
183 apply_interior_rings<minimum>(interior_rings(poly_in),
|
Chris@101
|
184 interior_rings(poly_out),
|
Chris@101
|
185 max_distance, strategy);
|
Chris@101
|
186 }
|
Chris@101
|
187 };
|
Chris@16
|
188
|
Chris@101
|
189
|
Chris@101
|
190 template<typename Policy>
|
Chris@101
|
191 struct simplify_multi
|
Chris@101
|
192 {
|
Chris@101
|
193 template <typename MultiGeometry, typename Strategy, typename Distance>
|
Chris@101
|
194 static inline void apply(MultiGeometry const& multi, MultiGeometry& out,
|
Chris@101
|
195 Distance const& max_distance, Strategy const& strategy)
|
Chris@101
|
196 {
|
Chris@101
|
197 traits::resize<MultiGeometry>::apply(out, boost::size(multi));
|
Chris@101
|
198
|
Chris@101
|
199 typename boost::range_iterator<MultiGeometry>::type it_out
|
Chris@101
|
200 = boost::begin(out);
|
Chris@101
|
201 for (typename boost::range_iterator<MultiGeometry const>::type
|
Chris@101
|
202 it_in = boost::begin(multi);
|
Chris@101
|
203 it_in != boost::end(multi);
|
Chris@101
|
204 ++it_in, ++it_out)
|
Chris@16
|
205 {
|
Chris@101
|
206 Policy::apply(*it_in, *it_out, max_distance, strategy);
|
Chris@16
|
207 }
|
Chris@16
|
208 }
|
Chris@16
|
209 };
|
Chris@16
|
210
|
Chris@16
|
211
|
Chris@16
|
212 }} // namespace detail::simplify
|
Chris@16
|
213 #endif // DOXYGEN_NO_DETAIL
|
Chris@16
|
214
|
Chris@16
|
215
|
Chris@16
|
216 #ifndef DOXYGEN_NO_DISPATCH
|
Chris@16
|
217 namespace dispatch
|
Chris@16
|
218 {
|
Chris@16
|
219
|
Chris@16
|
220 template
|
Chris@16
|
221 <
|
Chris@16
|
222 typename Geometry,
|
Chris@16
|
223 typename Tag = typename tag<Geometry>::type
|
Chris@16
|
224 >
|
Chris@16
|
225 struct simplify: not_implemented<Tag>
|
Chris@16
|
226 {};
|
Chris@16
|
227
|
Chris@16
|
228 template <typename Point>
|
Chris@16
|
229 struct simplify<Point, point_tag>
|
Chris@16
|
230 {
|
Chris@16
|
231 template <typename Distance, typename Strategy>
|
Chris@16
|
232 static inline void apply(Point const& point, Point& out,
|
Chris@16
|
233 Distance const& , Strategy const& )
|
Chris@16
|
234 {
|
Chris@16
|
235 geometry::convert(point, out);
|
Chris@16
|
236 }
|
Chris@16
|
237 };
|
Chris@16
|
238
|
Chris@16
|
239
|
Chris@16
|
240 template <typename Linestring>
|
Chris@16
|
241 struct simplify<Linestring, linestring_tag>
|
Chris@16
|
242 : detail::simplify::simplify_range<2>
|
Chris@16
|
243 {};
|
Chris@16
|
244
|
Chris@16
|
245 template <typename Ring>
|
Chris@16
|
246 struct simplify<Ring, ring_tag>
|
Chris@16
|
247 : detail::simplify::simplify_range
|
Chris@16
|
248 <
|
Chris@16
|
249 core_detail::closure::minimum_ring_size
|
Chris@16
|
250 <
|
Chris@16
|
251 geometry::closure<Ring>::value
|
Chris@16
|
252 >::value
|
Chris@16
|
253 >
|
Chris@16
|
254 {};
|
Chris@16
|
255
|
Chris@16
|
256 template <typename Polygon>
|
Chris@16
|
257 struct simplify<Polygon, polygon_tag>
|
Chris@16
|
258 : detail::simplify::simplify_polygon
|
Chris@16
|
259 {};
|
Chris@16
|
260
|
Chris@16
|
261
|
Chris@16
|
262 template
|
Chris@16
|
263 <
|
Chris@16
|
264 typename Geometry,
|
Chris@16
|
265 typename Tag = typename tag<Geometry>::type
|
Chris@16
|
266 >
|
Chris@16
|
267 struct simplify_insert: not_implemented<Tag>
|
Chris@16
|
268 {};
|
Chris@16
|
269
|
Chris@16
|
270
|
Chris@16
|
271 template <typename Linestring>
|
Chris@16
|
272 struct simplify_insert<Linestring, linestring_tag>
|
Chris@16
|
273 : detail::simplify::simplify_range_insert
|
Chris@16
|
274 {};
|
Chris@16
|
275
|
Chris@16
|
276 template <typename Ring>
|
Chris@16
|
277 struct simplify_insert<Ring, ring_tag>
|
Chris@16
|
278 : detail::simplify::simplify_range_insert
|
Chris@16
|
279 {};
|
Chris@16
|
280
|
Chris@101
|
281 template <typename MultiPoint>
|
Chris@101
|
282 struct simplify<MultiPoint, multi_point_tag>
|
Chris@101
|
283 : detail::simplify::simplify_copy
|
Chris@101
|
284 {};
|
Chris@101
|
285
|
Chris@101
|
286
|
Chris@101
|
287 template <typename MultiLinestring>
|
Chris@101
|
288 struct simplify<MultiLinestring, multi_linestring_tag>
|
Chris@101
|
289 : detail::simplify::simplify_multi<detail::simplify::simplify_range<2> >
|
Chris@101
|
290 {};
|
Chris@101
|
291
|
Chris@101
|
292
|
Chris@101
|
293 template <typename MultiPolygon>
|
Chris@101
|
294 struct simplify<MultiPolygon, multi_polygon_tag>
|
Chris@101
|
295 : detail::simplify::simplify_multi<detail::simplify::simplify_polygon>
|
Chris@101
|
296 {};
|
Chris@101
|
297
|
Chris@16
|
298
|
Chris@16
|
299 } // namespace dispatch
|
Chris@16
|
300 #endif // DOXYGEN_NO_DISPATCH
|
Chris@16
|
301
|
Chris@16
|
302
|
Chris@101
|
303 namespace resolve_strategy
|
Chris@101
|
304 {
|
Chris@101
|
305
|
Chris@101
|
306 struct simplify
|
Chris@101
|
307 {
|
Chris@101
|
308 template <typename Geometry, typename Distance, typename Strategy>
|
Chris@101
|
309 static inline void apply(Geometry const& geometry,
|
Chris@101
|
310 Geometry& out,
|
Chris@101
|
311 Distance const& max_distance,
|
Chris@101
|
312 Strategy const& strategy)
|
Chris@101
|
313 {
|
Chris@101
|
314 dispatch::simplify<Geometry>::apply(geometry, out, max_distance, strategy);
|
Chris@101
|
315 }
|
Chris@101
|
316
|
Chris@101
|
317 template <typename Geometry, typename Distance>
|
Chris@101
|
318 static inline void apply(Geometry const& geometry,
|
Chris@101
|
319 Geometry& out,
|
Chris@101
|
320 Distance const& max_distance,
|
Chris@101
|
321 default_strategy)
|
Chris@101
|
322 {
|
Chris@101
|
323 typedef typename point_type<Geometry>::type point_type;
|
Chris@101
|
324
|
Chris@101
|
325 typedef typename strategy::distance::services::default_strategy
|
Chris@101
|
326 <
|
Chris@101
|
327 point_tag, segment_tag, point_type
|
Chris@101
|
328 >::type ds_strategy_type;
|
Chris@101
|
329
|
Chris@101
|
330 typedef strategy::simplify::douglas_peucker
|
Chris@101
|
331 <
|
Chris@101
|
332 point_type, ds_strategy_type
|
Chris@101
|
333 > strategy_type;
|
Chris@101
|
334
|
Chris@101
|
335 BOOST_CONCEPT_ASSERT(
|
Chris@101
|
336 (concept::SimplifyStrategy<strategy_type, point_type>)
|
Chris@101
|
337 );
|
Chris@101
|
338
|
Chris@101
|
339 apply(geometry, out, max_distance, strategy_type());
|
Chris@101
|
340 }
|
Chris@101
|
341 };
|
Chris@101
|
342
|
Chris@101
|
343 struct simplify_insert
|
Chris@101
|
344 {
|
Chris@101
|
345 template
|
Chris@101
|
346 <
|
Chris@101
|
347 typename Geometry,
|
Chris@101
|
348 typename OutputIterator,
|
Chris@101
|
349 typename Distance,
|
Chris@101
|
350 typename Strategy
|
Chris@101
|
351 >
|
Chris@101
|
352 static inline void apply(Geometry const& geometry,
|
Chris@101
|
353 OutputIterator& out,
|
Chris@101
|
354 Distance const& max_distance,
|
Chris@101
|
355 Strategy const& strategy)
|
Chris@101
|
356 {
|
Chris@101
|
357 dispatch::simplify_insert<Geometry>::apply(geometry, out, max_distance, strategy);
|
Chris@101
|
358 }
|
Chris@101
|
359
|
Chris@101
|
360 template <typename Geometry, typename OutputIterator, typename Distance>
|
Chris@101
|
361 static inline void apply(Geometry const& geometry,
|
Chris@101
|
362 OutputIterator& out,
|
Chris@101
|
363 Distance const& max_distance,
|
Chris@101
|
364 default_strategy)
|
Chris@101
|
365 {
|
Chris@101
|
366 typedef typename point_type<Geometry>::type point_type;
|
Chris@101
|
367
|
Chris@101
|
368 typedef typename strategy::distance::services::default_strategy
|
Chris@101
|
369 <
|
Chris@101
|
370 point_tag, segment_tag, point_type
|
Chris@101
|
371 >::type ds_strategy_type;
|
Chris@101
|
372
|
Chris@101
|
373 typedef strategy::simplify::douglas_peucker
|
Chris@101
|
374 <
|
Chris@101
|
375 point_type, ds_strategy_type
|
Chris@101
|
376 > strategy_type;
|
Chris@101
|
377
|
Chris@101
|
378 BOOST_CONCEPT_ASSERT(
|
Chris@101
|
379 (concept::SimplifyStrategy<strategy_type, point_type>)
|
Chris@101
|
380 );
|
Chris@101
|
381
|
Chris@101
|
382 apply(geometry, out, max_distance, strategy_type());
|
Chris@101
|
383 }
|
Chris@101
|
384 };
|
Chris@101
|
385
|
Chris@101
|
386 } // namespace resolve_strategy
|
Chris@101
|
387
|
Chris@101
|
388
|
Chris@101
|
389 namespace resolve_variant {
|
Chris@101
|
390
|
Chris@101
|
391 template <typename Geometry>
|
Chris@101
|
392 struct simplify
|
Chris@101
|
393 {
|
Chris@101
|
394 template <typename Distance, typename Strategy>
|
Chris@101
|
395 static inline void apply(Geometry const& geometry,
|
Chris@101
|
396 Geometry& out,
|
Chris@101
|
397 Distance const& max_distance,
|
Chris@101
|
398 Strategy const& strategy)
|
Chris@101
|
399 {
|
Chris@101
|
400 resolve_strategy::simplify::apply(geometry, out, max_distance, strategy);
|
Chris@101
|
401 }
|
Chris@101
|
402 };
|
Chris@101
|
403
|
Chris@101
|
404 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
Chris@101
|
405 struct simplify<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
Chris@101
|
406 {
|
Chris@101
|
407 template <typename Distance, typename Strategy>
|
Chris@101
|
408 struct visitor: boost::static_visitor<void>
|
Chris@101
|
409 {
|
Chris@101
|
410 Distance const& m_max_distance;
|
Chris@101
|
411 Strategy const& m_strategy;
|
Chris@101
|
412
|
Chris@101
|
413 visitor(Distance const& max_distance, Strategy const& strategy)
|
Chris@101
|
414 : m_max_distance(max_distance)
|
Chris@101
|
415 , m_strategy(strategy)
|
Chris@101
|
416 {}
|
Chris@101
|
417
|
Chris@101
|
418 template <typename Geometry>
|
Chris@101
|
419 void operator()(Geometry const& geometry, Geometry& out) const
|
Chris@101
|
420 {
|
Chris@101
|
421 simplify<Geometry>::apply(geometry, out, m_max_distance, m_strategy);
|
Chris@101
|
422 }
|
Chris@101
|
423 };
|
Chris@101
|
424
|
Chris@101
|
425 template <typename Distance, typename Strategy>
|
Chris@101
|
426 static inline void
|
Chris@101
|
427 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
|
Chris@101
|
428 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& out,
|
Chris@101
|
429 Distance const& max_distance,
|
Chris@101
|
430 Strategy const& strategy)
|
Chris@101
|
431 {
|
Chris@101
|
432 boost::apply_visitor(
|
Chris@101
|
433 visitor<Distance, Strategy>(max_distance, strategy),
|
Chris@101
|
434 geometry,
|
Chris@101
|
435 out
|
Chris@101
|
436 );
|
Chris@101
|
437 }
|
Chris@101
|
438 };
|
Chris@101
|
439
|
Chris@101
|
440 } // namespace resolve_variant
|
Chris@101
|
441
|
Chris@101
|
442
|
Chris@16
|
443 /*!
|
Chris@16
|
444 \brief Simplify a geometry using a specified strategy
|
Chris@16
|
445 \ingroup simplify
|
Chris@16
|
446 \tparam Geometry \tparam_geometry
|
Chris@16
|
447 \tparam Distance A numerical distance measure
|
Chris@16
|
448 \tparam Strategy A type fulfilling a SimplifyStrategy concept
|
Chris@16
|
449 \param strategy A strategy to calculate simplification
|
Chris@16
|
450 \param geometry input geometry, to be simplified
|
Chris@16
|
451 \param out output geometry, simplified version of the input geometry
|
Chris@16
|
452 \param max_distance distance (in units of input coordinates) of a vertex
|
Chris@16
|
453 to other segments to be removed
|
Chris@16
|
454 \param strategy simplify strategy to be used for simplification, might
|
Chris@16
|
455 include point-distance strategy
|
Chris@16
|
456
|
Chris@16
|
457 \image html svg_simplify_country.png "The image below presents the simplified country"
|
Chris@16
|
458 \qbk{distinguish,with strategy}
|
Chris@16
|
459 */
|
Chris@16
|
460 template<typename Geometry, typename Distance, typename Strategy>
|
Chris@16
|
461 inline void simplify(Geometry const& geometry, Geometry& out,
|
Chris@16
|
462 Distance const& max_distance, Strategy const& strategy)
|
Chris@16
|
463 {
|
Chris@16
|
464 concept::check<Geometry>();
|
Chris@16
|
465
|
Chris@16
|
466 geometry::clear(out);
|
Chris@16
|
467
|
Chris@101
|
468 resolve_variant::simplify<Geometry>::apply(geometry, out, max_distance, strategy);
|
Chris@16
|
469 }
|
Chris@16
|
470
|
Chris@16
|
471
|
Chris@16
|
472
|
Chris@16
|
473
|
Chris@16
|
474 /*!
|
Chris@16
|
475 \brief Simplify a geometry
|
Chris@16
|
476 \ingroup simplify
|
Chris@16
|
477 \tparam Geometry \tparam_geometry
|
Chris@16
|
478 \tparam Distance \tparam_numeric
|
Chris@16
|
479 \note This version of simplify simplifies a geometry using the default
|
Chris@16
|
480 strategy (Douglas Peucker),
|
Chris@16
|
481 \param geometry input geometry, to be simplified
|
Chris@16
|
482 \param out output geometry, simplified version of the input geometry
|
Chris@16
|
483 \param max_distance distance (in units of input coordinates) of a vertex
|
Chris@16
|
484 to other segments to be removed
|
Chris@16
|
485
|
Chris@16
|
486 \qbk{[include reference/algorithms/simplify.qbk]}
|
Chris@16
|
487 */
|
Chris@16
|
488 template<typename Geometry, typename Distance>
|
Chris@16
|
489 inline void simplify(Geometry const& geometry, Geometry& out,
|
Chris@16
|
490 Distance const& max_distance)
|
Chris@16
|
491 {
|
Chris@16
|
492 concept::check<Geometry>();
|
Chris@16
|
493
|
Chris@101
|
494 simplify(geometry, out, max_distance, default_strategy());
|
Chris@16
|
495 }
|
Chris@16
|
496
|
Chris@16
|
497
|
Chris@16
|
498 #ifndef DOXYGEN_NO_DETAIL
|
Chris@16
|
499 namespace detail { namespace simplify
|
Chris@16
|
500 {
|
Chris@16
|
501
|
Chris@16
|
502
|
Chris@16
|
503 /*!
|
Chris@16
|
504 \brief Simplify a geometry, using an output iterator
|
Chris@16
|
505 and a specified strategy
|
Chris@16
|
506 \ingroup simplify
|
Chris@16
|
507 \tparam Geometry \tparam_geometry
|
Chris@16
|
508 \param geometry input geometry, to be simplified
|
Chris@16
|
509 \param out output iterator, outputs all simplified points
|
Chris@16
|
510 \param max_distance distance (in units of input coordinates) of a vertex
|
Chris@16
|
511 to other segments to be removed
|
Chris@16
|
512 \param strategy simplify strategy to be used for simplification,
|
Chris@16
|
513 might include point-distance strategy
|
Chris@16
|
514
|
Chris@16
|
515 \qbk{distinguish,with strategy}
|
Chris@16
|
516 \qbk{[include reference/algorithms/simplify.qbk]}
|
Chris@16
|
517 */
|
Chris@16
|
518 template<typename Geometry, typename OutputIterator, typename Distance, typename Strategy>
|
Chris@16
|
519 inline void simplify_insert(Geometry const& geometry, OutputIterator out,
|
Chris@101
|
520 Distance const& max_distance, Strategy const& strategy)
|
Chris@16
|
521 {
|
Chris@16
|
522 concept::check<Geometry const>();
|
Chris@16
|
523
|
Chris@101
|
524 resolve_strategy::simplify_insert::apply(geometry, out, max_distance, strategy);
|
Chris@16
|
525 }
|
Chris@16
|
526
|
Chris@16
|
527 /*!
|
Chris@16
|
528 \brief Simplify a geometry, using an output iterator
|
Chris@16
|
529 \ingroup simplify
|
Chris@16
|
530 \tparam Geometry \tparam_geometry
|
Chris@16
|
531 \param geometry input geometry, to be simplified
|
Chris@16
|
532 \param out output iterator, outputs all simplified points
|
Chris@16
|
533 \param max_distance distance (in units of input coordinates) of a vertex
|
Chris@16
|
534 to other segments to be removed
|
Chris@16
|
535
|
Chris@16
|
536 \qbk{[include reference/algorithms/simplify_insert.qbk]}
|
Chris@16
|
537 */
|
Chris@16
|
538 template<typename Geometry, typename OutputIterator, typename Distance>
|
Chris@16
|
539 inline void simplify_insert(Geometry const& geometry, OutputIterator out,
|
Chris@101
|
540 Distance const& max_distance)
|
Chris@16
|
541 {
|
Chris@16
|
542 // Concept: output point type = point type of input geometry
|
Chris@16
|
543 concept::check<Geometry const>();
|
Chris@101
|
544 concept::check<typename point_type<Geometry>::type>();
|
Chris@16
|
545
|
Chris@101
|
546 simplify_insert(geometry, out, max_distance, default_strategy());
|
Chris@16
|
547 }
|
Chris@16
|
548
|
Chris@16
|
549 }} // namespace detail::simplify
|
Chris@16
|
550 #endif // DOXYGEN_NO_DETAIL
|
Chris@16
|
551
|
Chris@16
|
552
|
Chris@16
|
553
|
Chris@16
|
554 }} // namespace boost::geometry
|
Chris@16
|
555
|
Chris@16
|
556 #endif // BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
|