Fixed convex_hull for empty geometries by throwing exception

[SVN r76488]
This commit is contained in:
Barend Gehrels 2012-01-14 14:44:21 +00:00
parent 229222a373
commit 72518c78f7
6 changed files with 75 additions and 1 deletions

View File

@ -27,12 +27,41 @@
#include <boost/geometry/views/detail/range_type.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/algorithms/detail/as_range.hpp>
namespace boost { namespace geometry
{
#if ! defined(BOOST_GEOMETRY_CONVEX_HULL_NO_THROW)
/*!
\brief Convex Hull Exception
\ingroup convex_hull
\details The convex_hull_exception is thrown if the free convex hull function is called with
geometries for which the hull cannot be calculated. For example: a linestring
without points, a polygon without points, an empty multi-geometry.
\qbk{
[heading See also]
\* [link geometry.reference.algorithms.convex_hull the convex_hull function]
}
*/
class convex_hull_exception : public geometry::exception
{
public:
inline convex_hull_exception() {}
virtual char const* what() const throw()
{
return "Boost.Geometry Convex Hull calculation exception";
}
};
#endif
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace convex_hull
{
@ -143,6 +172,13 @@ inline void convex_hull(Geometry const& geometry,
BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy<Strategy>) );
if (geometry::num_points(geometry) == 0)
{
#if ! defined(BOOST_GEOMETRY_CONVEX_HULL_NO_THROW)
throw convex_hull_exception();
#endif
return;
}
dispatch::convex_hull
<

View File

@ -47,6 +47,7 @@
#include <boost/geometry/multi/algorithms/unique.hpp>
#include <boost/geometry/multi/algorithms/within.hpp>
#include <boost/geometry/multi/algorithms/detail/for_each_range.hpp>
#include <boost/geometry/multi/algorithms/detail/modify_with_predicate.hpp>
#include <boost/geometry/multi/algorithms/detail/multi_sum.hpp>

View File

@ -67,12 +67,17 @@ struct get_extremes
StrategyLess less;
StrategyGreater greater;
get_extremes()
inline get_extremes()
: first(true)
{}
inline void apply(InputRange const& range)
{
if (boost::size(range) == 0)
{
return;
}
// First iterate through this range
// (this two-stage approach avoids many point copies,
// because iterators are kept in memory. Because iterators are

View File

@ -45,8 +45,13 @@ void test_all()
12, 8, 5.245);
// Waits for next cycle test_geometry<bg::model::box<P> >("box(0 0,2 2)", 5, 5, 4);
test_convex_hull_exception<bg::model::linestring<P> >();
test_convex_hull_exception<bg::model::polygon<P> >();
test_convex_hull_exception<bg::model::ring<P> >();
}
int test_main(int, char* [])
{
//test_all<bg::model::d2::point_xy<int> >();

View File

@ -108,5 +108,26 @@ void test_geometry(std::string const& wkt,
test_geometry_order<Geometry, false>(wkt, size_original, size_hull, expected_area);
}
template <typename Geometry>
void test_convex_hull_exception()
{
Geometry geometry;
try
{
bg::model::polygon
<
typename bg::point_type<Geometry>::type
> hull;
bg::convex_hull(geometry, hull);
}
catch(bg::convex_hull_exception const& )
{
return;
}
BOOST_CHECK_MESSAGE(false, "A convex_hull_exception should have been thrown" );
}
#endif

View File

@ -48,8 +48,14 @@ void test_all()
typedef bg::model::multi_linestring<bg::model::linestring<P> > ml;
typedef bg::model::multi_polygon<bg::model::polygon<P> > mpoly;
test_geometry<mp>("multipoint((1.1 1.1), (2.5 2.1), (3.1 3.1), (4.9 1.1), (3.1 1.9))", 5, 4, 3.8);
// Ticket 6021:
test_geometry<mp>("multipoint((0 53), (0 103), (1 53))", 3, 4, 25);
test_geometry<ml>("multilinestring((2 4, 3 4, 3 5), (4 3,4 4,5 4))", 6, 5, 3.0);
test_geometry<mpoly>("multipolygon(((1 4,1 6,2 5,3 5,4 6,4 4,1 4)), ((4 2,4 3,6 3,6 2,4 2)))", 12, 7, 14.0);
test_convex_hull_exception<mp>();
test_convex_hull_exception<ml>();
test_convex_hull_exception<mpoly>();
}