diff options
Diffstat (limited to 'boost/geometry/algorithms/remove_spikes.hpp')
-rw-r--r-- | boost/geometry/algorithms/remove_spikes.hpp | 112 |
1 files changed, 75 insertions, 37 deletions
diff --git a/boost/geometry/algorithms/remove_spikes.hpp b/boost/geometry/algorithms/remove_spikes.hpp index caa7fed9be..196b20c6a4 100644 --- a/boost/geometry/algorithms/remove_spikes.hpp +++ b/boost/geometry/algorithms/remove_spikes.hpp @@ -5,6 +5,11 @@ // Copyright (c) 2009-2013 Mateusz Loskot, London, UK. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -34,6 +39,8 @@ #include <boost/geometry/algorithms/detail/interior_iterator.hpp> #include <boost/geometry/algorithms/clear.hpp> +#include <boost/geometry/strategies/default_strategy.hpp> + #include <boost/geometry/util/condition.hpp> @@ -59,20 +66,13 @@ namespace detail { namespace remove_spikes { -template <typename Range> struct range_remove_spikes { - typedef typename strategy::side::services::default_strategy - < - typename cs_tag<Range>::type - >::type side_strategy; - - typedef typename coordinate_type<Range>::type coordinate_type; - typedef typename point_type<Range>::type point_type; - - - static inline void apply(Range& range) + template <typename Range, typename SideStrategy> + static inline void apply(Range& range, SideStrategy const& strategy) { + typedef typename point_type<Range>::type point_type; + std::size_t n = boost::size(range); std::size_t const min_num_points = core_detail::closure::minimum_ring_size < @@ -91,7 +91,10 @@ struct range_remove_spikes cleaned.push_back(*it); while(cleaned.size() >= 3 - && detail::point_is_spike_or_equal(cleaned.back(), *(cleaned.end() - 3), *(cleaned.end() - 2))) + && detail::point_is_spike_or_equal(cleaned.back(), + *(cleaned.end() - 3), + *(cleaned.end() - 2), + strategy)) { // Remove pen-ultimate point causing the spike (or which was equal) cleaned.erase(cleaned.end() - 2); @@ -110,13 +113,21 @@ struct range_remove_spikes found = false; // Check for spike in first point int const penultimate = 2; - while(cleaned.size() >= 3 && detail::point_is_spike_or_equal(cleaned.front(), *(cleaned.end() - penultimate), cleaned.back())) + while(cleaned.size() >= 3 + && detail::point_is_spike_or_equal(cleaned.front(), + *(cleaned.end() - penultimate), + cleaned.back(), + strategy)) { cleaned.pop_back(); found = true; } // Check for spike in second point - while(cleaned.size() >= 3 && detail::point_is_spike_or_equal(*(cleaned.begin() + 1), cleaned.back(), cleaned.front())) + while(cleaned.size() >= 3 + && detail::point_is_spike_or_equal(*(cleaned.begin() + 1), + cleaned.back(), + cleaned.front(), + strategy)) { cleaned.pop_front(); found = true; @@ -144,15 +155,13 @@ struct range_remove_spikes }; -template <typename Polygon> struct polygon_remove_spikes { - static inline void apply(Polygon& polygon) + template <typename Polygon, typename SideStrategy> + static inline void apply(Polygon& polygon, SideStrategy const& strategy) { - typedef typename geometry::ring_type<Polygon>::type ring_type; - - typedef range_remove_spikes<ring_type> per_range; - per_range::apply(exterior_ring(polygon)); + typedef range_remove_spikes per_range; + per_range::apply(exterior_ring(polygon), strategy); typename interior_return_type<Polygon>::type rings = interior_rings(polygon); @@ -160,23 +169,24 @@ struct polygon_remove_spikes for (typename detail::interior_iterator<Polygon>::type it = boost::begin(rings); it != boost::end(rings); ++it) { - per_range::apply(*it); + per_range::apply(*it, strategy); } } }; -template <typename MultiGeometry, typename SingleVersion> +template <typename SingleVersion> struct multi_remove_spikes { - static inline void apply(MultiGeometry& multi) + template <typename MultiGeometry, typename SideStrategy> + static inline void apply(MultiGeometry& multi, SideStrategy const& strategy) { for (typename boost::range_iterator<MultiGeometry>::type it = boost::begin(multi); it != boost::end(multi); ++it) { - SingleVersion::apply(*it); + SingleVersion::apply(*it, strategy); } } }; @@ -199,21 +209,22 @@ template > struct remove_spikes { - static inline void apply(Geometry&) + template <typename SideStrategy> + static inline void apply(Geometry&, SideStrategy const&) {} }; template <typename Ring> struct remove_spikes<Ring, ring_tag> - : detail::remove_spikes::range_remove_spikes<Ring> + : detail::remove_spikes::range_remove_spikes {}; template <typename Polygon> struct remove_spikes<Polygon, polygon_tag> - : detail::remove_spikes::polygon_remove_spikes<Polygon> + : detail::remove_spikes::polygon_remove_spikes {}; @@ -221,11 +232,7 @@ template <typename MultiPolygon> struct remove_spikes<MultiPolygon, multi_polygon_tag> : detail::remove_spikes::multi_remove_spikes < - MultiPolygon, detail::remove_spikes::polygon_remove_spikes - < - typename boost::range_value<MultiPolygon>::type - > > {}; @@ -239,28 +246,46 @@ namespace resolve_variant { template <typename Geometry> struct remove_spikes { - static void apply(Geometry& geometry) + template <typename Strategy> + static void apply(Geometry& geometry, Strategy const& strategy) { concepts::check<Geometry>(); - dispatch::remove_spikes<Geometry>::apply(geometry); + dispatch::remove_spikes<Geometry>::apply(geometry, strategy); + } + + static void apply(Geometry& geometry, geometry::default_strategy const&) + { + typedef typename strategy::side::services::default_strategy + < + typename cs_tag<Geometry>::type + >::type side_strategy; + + apply(geometry, side_strategy()); } }; template <BOOST_VARIANT_ENUM_PARAMS(typename T)> struct remove_spikes<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > { + template <typename Strategy> struct visitor: boost::static_visitor<void> { + Strategy const& m_strategy; + + visitor(Strategy const& strategy) : m_strategy(strategy) {} + template <typename Geometry> void operator()(Geometry& geometry) const { - remove_spikes<Geometry>::apply(geometry); + remove_spikes<Geometry>::apply(geometry, m_strategy); } }; - static inline void apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry) + template <typename Strategy> + static inline void apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry, + Strategy const& strategy) { - boost::apply_visitor(visitor(), geometry); + boost::apply_visitor(visitor<Strategy>(strategy), geometry); } }; @@ -275,7 +300,20 @@ struct remove_spikes<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > template <typename Geometry> inline void remove_spikes(Geometry& geometry) { - resolve_variant::remove_spikes<Geometry>::apply(geometry); + resolve_variant::remove_spikes<Geometry>::apply(geometry, geometry::default_strategy()); +} + +/*! + \ingroup remove_spikes + \tparam Geometry geometry type + \tparam Strategy side strategy type + \param geometry the geometry to make remove_spikes + \param strategy the side strategy used by the algorithm +*/ +template <typename Geometry, typename Strategy> +inline void remove_spikes(Geometry& geometry, Strategy const& strategy) +{ + resolve_variant::remove_spikes<Geometry>::apply(geometry, strategy); } |