From 5e946a1c1e0d4ae0a88b6d8b438f1307bdb163a5 Mon Sep 17 00:00:00 2001 From: Bruno Lalande Date: Sun, 22 Dec 2013 23:18:29 +0000 Subject: [PATCH 1/4] Added resolve_strategy stage for simplify. --- .../boost/geometry/algorithms/simplify.hpp | 61 ++++++++++++++----- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index 2bd097f13..fec379fc1 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -229,6 +230,49 @@ struct simplify_insert #endif // DOXYGEN_NO_DISPATCH +namespace resolve_strategy +{ + +struct simplify +{ + template + static inline void apply(Geometry const& geometry, + Geometry& out, + Distance const& max_distance, + Strategy const& strategy) + { + dispatch::simplify::apply(geometry, out, max_distance, strategy); + } + + template + static inline void apply(Geometry const& geometry, + Geometry& out, + Distance const& max_distance, + default_strategy) + { + typedef typename point_type::type point_type; + + typedef typename strategy::distance::services::default_strategy + < + segment_tag, point_type + >::type ds_strategy_type; + + typedef strategy::simplify::douglas_peucker + < + point_type, ds_strategy_type + > strategy_type; + + BOOST_CONCEPT_ASSERT( + (concept::SimplifyStrategy) + ); + + apply(geometry, out, max_distance, strategy_type()); + } +}; + +} // namespace resolve_strategy + + /*! \brief Simplify a geometry using a specified strategy \ingroup simplify @@ -252,13 +296,9 @@ inline void simplify(Geometry const& geometry, Geometry& out, { concept::check(); - BOOST_CONCEPT_ASSERT( - (concept::SimplifyStrategy::type>) - ); - geometry::clear(out); - dispatch::simplify::apply(geometry, out, max_distance, strategy); + resolve_strategy::simplify::apply(geometry, out, max_distance, strategy); } @@ -285,17 +325,8 @@ inline void simplify(Geometry const& geometry, Geometry& out, concept::check(); typedef typename point_type::type point_type; - typedef typename strategy::distance::services::default_strategy - < - segment_tag, point_type - >::type ds_strategy_type; - typedef strategy::simplify::douglas_peucker - < - point_type, ds_strategy_type - > strategy_type; - - simplify(geometry, out, max_distance, strategy_type()); + simplify(geometry, out, max_distance, default_strategy()); } From 2ddcf5dccf70d377995dfb287d03643db6691ba9 Mon Sep 17 00:00:00 2001 From: Bruno Lalande Date: Mon, 23 Dec 2013 12:19:25 +0000 Subject: [PATCH 2/4] Added resolve_strategy stage for simplify_insert. --- .../boost/geometry/algorithms/simplify.hpp | 59 ++++++++++++++----- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index fec379fc1..0dc2bd0c6 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -270,6 +270,49 @@ struct simplify } }; +struct simplify_insert +{ + template + < + typename Geometry, + typename OutputIterator, + typename Distance, + typename Strategy + > + static inline void apply(Geometry const& geometry, + OutputIterator& out, + Distance const& max_distance, + Strategy const& strategy) + { + dispatch::simplify_insert::apply(geometry, out, max_distance, strategy); + } + + template + static inline void apply(Geometry const& geometry, + OutputIterator& out, + Distance const& max_distance, + default_strategy) + { + typedef typename point_type::type point_type; + + typedef typename strategy::distance::services::default_strategy + < + segment_tag, point_type + >::type ds_strategy_type; + + typedef strategy::simplify::douglas_peucker + < + point_type, ds_strategy_type + > strategy_type; + + BOOST_CONCEPT_ASSERT( + (concept::SimplifyStrategy) + ); + + apply(geometry, out, max_distance, strategy_type()); + } +}; + } // namespace resolve_strategy @@ -377,23 +420,11 @@ template inline void simplify_insert(Geometry const& geometry, OutputIterator out, Distance const& max_distance) { - typedef typename point_type::type point_type; - // Concept: output point type = point type of input geometry concept::check(); - concept::check(); + concept::check::type>(); - typedef typename strategy::distance::services::default_strategy - < - segment_tag, point_type - >::type ds_strategy_type; - - typedef strategy::simplify::douglas_peucker - < - point_type, ds_strategy_type - > strategy_type; - - dispatch::simplify_insert::apply(geometry, out, max_distance, strategy_type()); + resolve_strategy::simplify_insert::apply(geometry, out, max_distance, default_strategy()); } }} // namespace detail::simplify From 4919e00e2d904b3512eaaeaaf83b14be3e84534c Mon Sep 17 00:00:00 2001 From: Bruno Lalande Date: Tue, 24 Dec 2013 22:15:15 +0000 Subject: [PATCH 3/4] Made simplify variant-aware --- .../boost/geometry/algorithms/simplify.hpp | 60 ++++++++++++++++++- test/algorithms/test_simplify.hpp | 57 +++++++++++------- 2 files changed, 95 insertions(+), 22 deletions(-) diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index 0dc2bd0c6..ad6463f01 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -37,6 +37,10 @@ #include #include +#include +#include +#include + namespace boost { namespace geometry { @@ -316,6 +320,60 @@ struct simplify_insert } // namespace resolve_strategy +namespace resolve_variant { + +template +struct simplify +{ + template + static inline void apply(Geometry const& geometry, + Geometry& out, + Distance const& max_distance, + Strategy const& strategy) + { + resolve_strategy::simplify::apply(geometry, out, max_distance, strategy); + } +}; + +template +struct simplify > +{ + template + struct visitor: boost::static_visitor + { + Distance const& m_max_distance; + Strategy const& m_strategy; + + visitor(Distance const& max_distance, Strategy const& strategy) + : m_max_distance(max_distance) + , m_strategy(strategy) + {} + + template + void operator()(Geometry const& geometry, Geometry& out) const + { + simplify::apply(geometry, out, m_max_distance, m_strategy); + } + }; + + template + static inline void + apply(boost::variant const& geometry, + boost::variant& out, + Distance const& max_distance, + Strategy const& strategy) + { + boost::apply_visitor( + visitor(max_distance, strategy), + geometry, + out + ); + } +}; + +} // namespace resolve_variant + + /*! \brief Simplify a geometry using a specified strategy \ingroup simplify @@ -341,7 +399,7 @@ inline void simplify(Geometry const& geometry, Geometry& out, geometry::clear(out); - resolve_strategy::simplify::apply(geometry, out, max_distance, strategy); + resolve_variant::simplify::apply(geometry, out, max_distance, strategy); } diff --git a/test/algorithms/test_simplify.hpp b/test/algorithms/test_simplify.hpp index 0eda9b3b4..b3c64ba56 100644 --- a/test/algorithms/test_simplify.hpp +++ b/test/algorithms/test_simplify.hpp @@ -17,8 +17,8 @@ #include #include #include - #include +#include template struct test_inserter @@ -46,24 +46,43 @@ struct test_inserter template -void test_geometry(std::string const& wkt, std::string const& expected, double distance) +void check_geometry(Geometry const& geometry, + std::string const& expected, + double distance) { - Geometry geometry, simplified; - - // Generate polygon using only integer coordinates and obvious results - // Polygon is a hexagon, having one extra point (2,1) on a line which should be filtered out. - bg::read_wkt(wkt, geometry); + Geometry simplified; bg::simplify(geometry, simplified, distance); - { - std::ostringstream out; - out << std::setprecision(12) << bg::wkt(simplified); + std::ostringstream out; + out << std::setprecision(12) << bg::wkt(simplified); + BOOST_CHECK_EQUAL(out.str(), expected); +} - BOOST_CHECK_MESSAGE(out.str() == expected, - "simplify: " << bg::wkt(geometry) - << " expected " << expected - << " got " << out.str()); - } +template +void check_geometry(Geometry const& geometry, + std::string const& expected, + double distance, + Strategy const& strategy) +{ + Geometry simplified; + bg::simplify(geometry, simplified, distance, strategy); + + std::ostringstream out; + out << std::setprecision(12) << bg::wkt(simplified); + BOOST_CHECK_EQUAL(out.str(), expected); +} + +template +void test_geometry(std::string const& wkt, std::string const& expected, double distance) +{ + // Generate polygon using only integer coordinates and obvious results + // Polygon is a hexagon, having one extra point (2,1) on a line which should be filtered out. + Geometry geometry; + bg::read_wkt(wkt, geometry); + boost::variant v(geometry); + + check_geometry(geometry, expected, distance); + check_geometry(v, expected, distance); // Check using user-specified strategy typedef typename bg::point_type::type point_type; @@ -76,13 +95,9 @@ void test_geometry(std::string const& wkt, std::string const& expected, double d > simplify_strategy_type; BOOST_CONCEPT_ASSERT( (bg::concept::SimplifyStrategy) ); - bg::simplify(geometry, simplified, distance, simplify_strategy_type()); - { - std::ostringstream out; - out << std::setprecision(12) << bg::wkt(simplified); - BOOST_CHECK_EQUAL(out.str(), expected); - } + check_geometry(geometry, expected, distance, simplify_strategy_type()); + check_geometry(v, expected, distance, simplify_strategy_type()); // Check inserter (if applicable) test_inserter From ea3cf83bf8314d722fbb3f67c655600de1e475cc Mon Sep 17 00:00:00 2001 From: Bruno Lalande Date: Tue, 24 Dec 2013 22:27:38 +0000 Subject: [PATCH 4/4] Fixed how resolve_strategy::simplify_insert is called from the public functions --- include/boost/geometry/algorithms/simplify.hpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index ad6463f01..1de639784 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -453,14 +453,11 @@ namespace detail { namespace simplify */ template inline void simplify_insert(Geometry const& geometry, OutputIterator out, - Distance const& max_distance, Strategy const& strategy) + Distance const& max_distance, Strategy const& strategy) { concept::check(); - BOOST_CONCEPT_ASSERT( - (concept::SimplifyStrategy::type>) - ); - dispatch::simplify_insert::apply(geometry, out, max_distance, strategy); + resolve_strategy::simplify_insert::apply(geometry, out, max_distance, strategy); } /*! @@ -476,13 +473,13 @@ inline void simplify_insert(Geometry const& geometry, OutputIterator out, */ template inline void simplify_insert(Geometry const& geometry, OutputIterator out, - Distance const& max_distance) + Distance const& max_distance) { // Concept: output point type = point type of input geometry concept::check(); concept::check::type>(); - resolve_strategy::simplify_insert::apply(geometry, out, max_distance, default_strategy()); + simplify_insert(geometry, out, max_distance, default_strategy()); } }} // namespace detail::simplify