annotate DEPENDENCIES/generic/include/boost/geometry/algorithms/simplify.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_ALGORITHMS_SIMPLIFY_HPP
Chris@16 15 #define BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
Chris@16 16
Chris@16 17
Chris@16 18 #include <cstddef>
Chris@16 19
Chris@16 20 #include <boost/range.hpp>
Chris@16 21 #include <boost/typeof/typeof.hpp>
Chris@16 22
Chris@16 23 #include <boost/geometry/core/cs.hpp>
Chris@16 24 #include <boost/geometry/core/closure.hpp>
Chris@16 25 #include <boost/geometry/core/ring_type.hpp>
Chris@16 26 #include <boost/geometry/core/exterior_ring.hpp>
Chris@16 27 #include <boost/geometry/core/interior_rings.hpp>
Chris@16 28 #include <boost/geometry/core/mutable_range.hpp>
Chris@16 29
Chris@16 30 #include <boost/geometry/geometries/concepts/check.hpp>
Chris@16 31 #include <boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp>
Chris@16 32 #include <boost/geometry/strategies/concepts/simplify_concept.hpp>
Chris@16 33
Chris@16 34 #include <boost/geometry/algorithms/clear.hpp>
Chris@16 35 #include <boost/geometry/algorithms/convert.hpp>
Chris@16 36 #include <boost/geometry/algorithms/not_implemented.hpp>
Chris@16 37 #include <boost/geometry/algorithms/num_interior_rings.hpp>
Chris@16 38
Chris@16 39
Chris@16 40 namespace boost { namespace geometry
Chris@16 41 {
Chris@16 42
Chris@16 43 #ifndef DOXYGEN_NO_DETAIL
Chris@16 44 namespace detail { namespace simplify
Chris@16 45 {
Chris@16 46
Chris@16 47 struct simplify_range_insert
Chris@16 48 {
Chris@16 49 template<typename Range, typename Strategy, typename OutputIterator, typename Distance>
Chris@16 50 static inline void apply(Range const& range, OutputIterator out,
Chris@16 51 Distance const& max_distance, Strategy const& strategy)
Chris@16 52 {
Chris@16 53 if (boost::size(range) <= 2 || max_distance < 0)
Chris@16 54 {
Chris@16 55 std::copy(boost::begin(range), boost::end(range), out);
Chris@16 56 }
Chris@16 57 else
Chris@16 58 {
Chris@16 59 strategy.apply(range, out, max_distance);
Chris@16 60 }
Chris@16 61 }
Chris@16 62 };
Chris@16 63
Chris@16 64
Chris@16 65 struct simplify_copy
Chris@16 66 {
Chris@16 67 template <typename Range, typename Strategy, typename Distance>
Chris@16 68 static inline void apply(Range const& range, Range& out,
Chris@16 69 Distance const& , Strategy const& )
Chris@16 70 {
Chris@16 71 std::copy
Chris@16 72 (
Chris@16 73 boost::begin(range), boost::end(range), std::back_inserter(out)
Chris@16 74 );
Chris@16 75 }
Chris@16 76 };
Chris@16 77
Chris@16 78
Chris@16 79 template<std::size_t Minimum>
Chris@16 80 struct simplify_range
Chris@16 81 {
Chris@16 82 template <typename Range, typename Strategy, typename Distance>
Chris@16 83 static inline void apply(Range const& range, Range& out,
Chris@16 84 Distance const& max_distance, Strategy const& strategy)
Chris@16 85 {
Chris@16 86 // Call do_container for a linestring / ring
Chris@16 87
Chris@16 88 /* For a RING:
Chris@16 89 The first/last point (the closing point of the ring) should maybe
Chris@16 90 be excluded because it lies on a line with second/one but last.
Chris@16 91 Here it is never excluded.
Chris@16 92
Chris@16 93 Note also that, especially if max_distance is too large,
Chris@16 94 the output ring might be self intersecting while the input ring is
Chris@16 95 not, although chances are low in normal polygons
Chris@16 96
Chris@16 97 Finally the inputring might have 3 (open) or 4 (closed) points (=correct),
Chris@16 98 the output < 3 or 4(=wrong)
Chris@16 99 */
Chris@16 100
Chris@16 101 if (boost::size(range) <= int(Minimum) || max_distance < 0.0)
Chris@16 102 {
Chris@16 103 simplify_copy::apply(range, out, max_distance, strategy);
Chris@16 104 }
Chris@16 105 else
Chris@16 106 {
Chris@16 107 simplify_range_insert::apply
Chris@16 108 (
Chris@16 109 range, std::back_inserter(out), max_distance, strategy
Chris@16 110 );
Chris@16 111 }
Chris@16 112 }
Chris@16 113 };
Chris@16 114
Chris@16 115 struct simplify_polygon
Chris@16 116 {
Chris@16 117 template <typename Polygon, typename Strategy, typename Distance>
Chris@16 118 static inline void apply(Polygon const& poly_in, Polygon& poly_out,
Chris@16 119 Distance const& max_distance, Strategy const& strategy)
Chris@16 120 {
Chris@16 121 typedef typename ring_type<Polygon>::type ring_type;
Chris@16 122
Chris@16 123 int const Minimum = core_detail::closure::minimum_ring_size
Chris@16 124 <
Chris@16 125 geometry::closure<Polygon>::value
Chris@16 126 >::value;
Chris@16 127
Chris@16 128 // Note that if there are inner rings, and distance is too large,
Chris@16 129 // they might intersect with the outer ring in the output,
Chris@16 130 // while it didn't in the input.
Chris@16 131 simplify_range<Minimum>::apply(exterior_ring(poly_in),
Chris@16 132 exterior_ring(poly_out),
Chris@16 133 max_distance, strategy);
Chris@16 134
Chris@16 135 traits::resize
Chris@16 136 <
Chris@16 137 typename boost::remove_reference
Chris@16 138 <
Chris@16 139 typename traits::interior_mutable_type<Polygon>::type
Chris@16 140 >::type
Chris@16 141 >::apply(interior_rings(poly_out), num_interior_rings(poly_in));
Chris@16 142
Chris@16 143 typename interior_return_type<Polygon const>::type rings_in
Chris@16 144 = interior_rings(poly_in);
Chris@16 145 typename interior_return_type<Polygon>::type rings_out
Chris@16 146 = interior_rings(poly_out);
Chris@16 147 BOOST_AUTO_TPL(it_out, boost::begin(rings_out));
Chris@16 148 for (BOOST_AUTO_TPL(it_in, boost::begin(rings_in));
Chris@16 149 it_in != boost::end(rings_in);
Chris@16 150 ++it_in, ++it_out)
Chris@16 151 {
Chris@16 152 simplify_range<Minimum>::apply(*it_in, *it_out, max_distance, strategy);
Chris@16 153 }
Chris@16 154 }
Chris@16 155 };
Chris@16 156
Chris@16 157
Chris@16 158 }} // namespace detail::simplify
Chris@16 159 #endif // DOXYGEN_NO_DETAIL
Chris@16 160
Chris@16 161
Chris@16 162 #ifndef DOXYGEN_NO_DISPATCH
Chris@16 163 namespace dispatch
Chris@16 164 {
Chris@16 165
Chris@16 166 template
Chris@16 167 <
Chris@16 168 typename Geometry,
Chris@16 169 typename Tag = typename tag<Geometry>::type
Chris@16 170 >
Chris@16 171 struct simplify: not_implemented<Tag>
Chris@16 172 {};
Chris@16 173
Chris@16 174 template <typename Point>
Chris@16 175 struct simplify<Point, point_tag>
Chris@16 176 {
Chris@16 177 template <typename Distance, typename Strategy>
Chris@16 178 static inline void apply(Point const& point, Point& out,
Chris@16 179 Distance const& , Strategy const& )
Chris@16 180 {
Chris@16 181 geometry::convert(point, out);
Chris@16 182 }
Chris@16 183 };
Chris@16 184
Chris@16 185
Chris@16 186 template <typename Linestring>
Chris@16 187 struct simplify<Linestring, linestring_tag>
Chris@16 188 : detail::simplify::simplify_range<2>
Chris@16 189 {};
Chris@16 190
Chris@16 191 template <typename Ring>
Chris@16 192 struct simplify<Ring, ring_tag>
Chris@16 193 : detail::simplify::simplify_range
Chris@16 194 <
Chris@16 195 core_detail::closure::minimum_ring_size
Chris@16 196 <
Chris@16 197 geometry::closure<Ring>::value
Chris@16 198 >::value
Chris@16 199 >
Chris@16 200 {};
Chris@16 201
Chris@16 202 template <typename Polygon>
Chris@16 203 struct simplify<Polygon, polygon_tag>
Chris@16 204 : detail::simplify::simplify_polygon
Chris@16 205 {};
Chris@16 206
Chris@16 207
Chris@16 208 template
Chris@16 209 <
Chris@16 210 typename Geometry,
Chris@16 211 typename Tag = typename tag<Geometry>::type
Chris@16 212 >
Chris@16 213 struct simplify_insert: not_implemented<Tag>
Chris@16 214 {};
Chris@16 215
Chris@16 216
Chris@16 217 template <typename Linestring>
Chris@16 218 struct simplify_insert<Linestring, linestring_tag>
Chris@16 219 : detail::simplify::simplify_range_insert
Chris@16 220 {};
Chris@16 221
Chris@16 222 template <typename Ring>
Chris@16 223 struct simplify_insert<Ring, ring_tag>
Chris@16 224 : detail::simplify::simplify_range_insert
Chris@16 225 {};
Chris@16 226
Chris@16 227
Chris@16 228 } // namespace dispatch
Chris@16 229 #endif // DOXYGEN_NO_DISPATCH
Chris@16 230
Chris@16 231
Chris@16 232 /*!
Chris@16 233 \brief Simplify a geometry using a specified strategy
Chris@16 234 \ingroup simplify
Chris@16 235 \tparam Geometry \tparam_geometry
Chris@16 236 \tparam Distance A numerical distance measure
Chris@16 237 \tparam Strategy A type fulfilling a SimplifyStrategy concept
Chris@16 238 \param strategy A strategy to calculate simplification
Chris@16 239 \param geometry input geometry, to be simplified
Chris@16 240 \param out output geometry, simplified version of the input geometry
Chris@16 241 \param max_distance distance (in units of input coordinates) of a vertex
Chris@16 242 to other segments to be removed
Chris@16 243 \param strategy simplify strategy to be used for simplification, might
Chris@16 244 include point-distance strategy
Chris@16 245
Chris@16 246 \image html svg_simplify_country.png "The image below presents the simplified country"
Chris@16 247 \qbk{distinguish,with strategy}
Chris@16 248 */
Chris@16 249 template<typename Geometry, typename Distance, typename Strategy>
Chris@16 250 inline void simplify(Geometry const& geometry, Geometry& out,
Chris@16 251 Distance const& max_distance, Strategy const& strategy)
Chris@16 252 {
Chris@16 253 concept::check<Geometry>();
Chris@16 254
Chris@16 255 BOOST_CONCEPT_ASSERT(
Chris@16 256 (concept::SimplifyStrategy<Strategy, typename point_type<Geometry>::type>)
Chris@16 257 );
Chris@16 258
Chris@16 259 geometry::clear(out);
Chris@16 260
Chris@16 261 dispatch::simplify<Geometry>::apply(geometry, out, max_distance, strategy);
Chris@16 262 }
Chris@16 263
Chris@16 264
Chris@16 265
Chris@16 266
Chris@16 267 /*!
Chris@16 268 \brief Simplify a geometry
Chris@16 269 \ingroup simplify
Chris@16 270 \tparam Geometry \tparam_geometry
Chris@16 271 \tparam Distance \tparam_numeric
Chris@16 272 \note This version of simplify simplifies a geometry using the default
Chris@16 273 strategy (Douglas Peucker),
Chris@16 274 \param geometry input geometry, to be simplified
Chris@16 275 \param out output geometry, simplified version of the input geometry
Chris@16 276 \param max_distance distance (in units of input coordinates) of a vertex
Chris@16 277 to other segments to be removed
Chris@16 278
Chris@16 279 \qbk{[include reference/algorithms/simplify.qbk]}
Chris@16 280 */
Chris@16 281 template<typename Geometry, typename Distance>
Chris@16 282 inline void simplify(Geometry const& geometry, Geometry& out,
Chris@16 283 Distance const& max_distance)
Chris@16 284 {
Chris@16 285 concept::check<Geometry>();
Chris@16 286
Chris@16 287 typedef typename point_type<Geometry>::type point_type;
Chris@16 288 typedef typename strategy::distance::services::default_strategy
Chris@16 289 <
Chris@16 290 segment_tag, point_type
Chris@16 291 >::type ds_strategy_type;
Chris@16 292
Chris@16 293 typedef strategy::simplify::douglas_peucker
Chris@16 294 <
Chris@16 295 point_type, ds_strategy_type
Chris@16 296 > strategy_type;
Chris@16 297
Chris@16 298 simplify(geometry, out, max_distance, strategy_type());
Chris@16 299 }
Chris@16 300
Chris@16 301
Chris@16 302 #ifndef DOXYGEN_NO_DETAIL
Chris@16 303 namespace detail { namespace simplify
Chris@16 304 {
Chris@16 305
Chris@16 306
Chris@16 307 /*!
Chris@16 308 \brief Simplify a geometry, using an output iterator
Chris@16 309 and a specified strategy
Chris@16 310 \ingroup simplify
Chris@16 311 \tparam Geometry \tparam_geometry
Chris@16 312 \param geometry input geometry, to be simplified
Chris@16 313 \param out output iterator, outputs all simplified points
Chris@16 314 \param max_distance distance (in units of input coordinates) of a vertex
Chris@16 315 to other segments to be removed
Chris@16 316 \param strategy simplify strategy to be used for simplification,
Chris@16 317 might include point-distance strategy
Chris@16 318
Chris@16 319 \qbk{distinguish,with strategy}
Chris@16 320 \qbk{[include reference/algorithms/simplify.qbk]}
Chris@16 321 */
Chris@16 322 template<typename Geometry, typename OutputIterator, typename Distance, typename Strategy>
Chris@16 323 inline void simplify_insert(Geometry const& geometry, OutputIterator out,
Chris@16 324 Distance const& max_distance, Strategy const& strategy)
Chris@16 325 {
Chris@16 326 concept::check<Geometry const>();
Chris@16 327 BOOST_CONCEPT_ASSERT(
Chris@16 328 (concept::SimplifyStrategy<Strategy, typename point_type<Geometry>::type>)
Chris@16 329 );
Chris@16 330
Chris@16 331 dispatch::simplify_insert<Geometry>::apply(geometry, out, max_distance, strategy);
Chris@16 332 }
Chris@16 333
Chris@16 334 /*!
Chris@16 335 \brief Simplify a geometry, using an output iterator
Chris@16 336 \ingroup simplify
Chris@16 337 \tparam Geometry \tparam_geometry
Chris@16 338 \param geometry input geometry, to be simplified
Chris@16 339 \param out output iterator, outputs all simplified points
Chris@16 340 \param max_distance distance (in units of input coordinates) of a vertex
Chris@16 341 to other segments to be removed
Chris@16 342
Chris@16 343 \qbk{[include reference/algorithms/simplify_insert.qbk]}
Chris@16 344 */
Chris@16 345 template<typename Geometry, typename OutputIterator, typename Distance>
Chris@16 346 inline void simplify_insert(Geometry const& geometry, OutputIterator out,
Chris@16 347 Distance const& max_distance)
Chris@16 348 {
Chris@16 349 typedef typename point_type<Geometry>::type point_type;
Chris@16 350
Chris@16 351 // Concept: output point type = point type of input geometry
Chris@16 352 concept::check<Geometry const>();
Chris@16 353 concept::check<point_type>();
Chris@16 354
Chris@16 355 typedef typename strategy::distance::services::default_strategy
Chris@16 356 <
Chris@16 357 segment_tag, point_type
Chris@16 358 >::type ds_strategy_type;
Chris@16 359
Chris@16 360 typedef strategy::simplify::douglas_peucker
Chris@16 361 <
Chris@16 362 point_type, ds_strategy_type
Chris@16 363 > strategy_type;
Chris@16 364
Chris@16 365 dispatch::simplify_insert<Geometry>::apply(geometry, out, max_distance, strategy_type());
Chris@16 366 }
Chris@16 367
Chris@16 368 }} // namespace detail::simplify
Chris@16 369 #endif // DOXYGEN_NO_DETAIL
Chris@16 370
Chris@16 371
Chris@16 372
Chris@16 373 }} // namespace boost::geometry
Chris@16 374
Chris@16 375 #endif // BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP