From 5aa6d2a69e9474c99651ba0307394e8d0149c29a Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Sat, 28 Nov 2015 09:10:50 +0200 Subject: [PATCH 1/2] [algorithms][centroid] the centroid algorithm should not be able to compute the centroid of a multipolygon (which is actually invalid) that contains one or more polygons that have empty exterior ring and non-empty interior rings; in such cases an exception should be thrown; this commit fixes the behavior of the centroid algorithm in the direction described above; --- include/boost/geometry/algorithms/centroid.hpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/algorithms/centroid.hpp b/include/boost/geometry/algorithms/centroid.hpp index 8ef017a3f1..b0f46e3775 100644 --- a/include/boost/geometry/algorithms/centroid.hpp +++ b/include/boost/geometry/algorithms/centroid.hpp @@ -283,9 +283,26 @@ struct centroid_polygon_state typename Strategy::state_type& state) { typedef typename ring_type::type ring_type; - typedef centroid_range_state::value> per_ring; + typedef centroid_range_state + < + geometry::closure::value + > per_ring; + + typename ring_return_type + < + Polygon const + >::type e_ring = exterior_ring(poly); + + if (boost::empty(e_ring) && ! geometry::is_empty(poly)) + { +#if ! defined(BOOST_GEOMETRY_CENTROID_NO_THROW) + throw centroid_exception(); +#else + return; +#endif + } - per_ring::apply(exterior_ring(poly), transformer, strategy, state); + per_ring::apply(e_ring, transformer, strategy, state); typename interior_return_type::type rings = interior_rings(poly); From 7e3edb242f80ebfb88986272b4c36da51f2a61a9 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Sat, 28 Nov 2015 09:13:24 +0200 Subject: [PATCH 2/2] [test][algorithms][centroid] add test case consisting of a multi-polygon that contains a polygon with empty exterior ring and non-empty interior ring; such a multi-polygon is expected to trigger an exception; --- test/algorithms/centroid_multi.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/algorithms/centroid_multi.cpp b/test/algorithms/centroid_multi.cpp index 5f250116e2..93c5129ce8 100644 --- a/test/algorithms/centroid_multi.cpp +++ b/test/algorithms/centroid_multi.cpp @@ -133,6 +133,10 @@ void test_exceptions() test_centroid_exception("MULTILINESTRING()"); test_centroid_exception("MULTILINESTRING(())"); test_centroid_exception("MULTILINESTRING((), ())"); + + // Multi-polygon containing polygon with empty exterior ring + test_centroid_exception + ("MULTIPOLYGON(((4 1,4 3,8 3,8 1,4 1)),((),(0 0,1 0,1 1,0 1,0 0)))"); } template