Added empty_input_exception and applied for distance, length, area, perimeter

Removed exception for convex_hull because that can be handled (for now) by leaving output empty. To be decided what is the definitive (additional, optional) behaviour.

[SVN r76514]
This commit is contained in:
Barend Gehrels
2012-01-15 13:23:08 +00:00
parent 5a8e6dcf8a
commit 05ab4d557a
20 changed files with 233 additions and 59 deletions

View File

@@ -19,7 +19,6 @@
#include <boost/range/functions.hpp>
#include <boost/range/metafunctions.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -30,6 +29,7 @@
#include <boost/geometry/algorithms/detail/calculate_null.hpp>
#include <boost/geometry/algorithms/detail/calculate_sum.hpp>
#include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
#include <boost/geometry/strategies/area.hpp>
#include <boost/geometry/strategies/default_area_result.hpp>
@@ -241,6 +241,8 @@ inline typename default_area_result<Geometry>::type area(Geometry const& geometr
point_type
>::type strategy_type;
detail::throw_on_empty_input(geometry);
return dispatch::area
<
Geometry
@@ -277,6 +279,8 @@ inline typename Strategy::return_type area(
{
concept::check<Geometry const>();
detail::throw_on_empty_input(geometry);
return dispatch::area
<
Geometry,

View File

@@ -35,33 +35,6 @@
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
@@ -204,9 +177,7 @@ inline void convex_hull(Geometry const& geometry,
if (geometry::num_points(geometry) == 0)
{
#if ! defined(BOOST_GEOMETRY_CONVEX_HULL_NO_THROW)
throw convex_hull_exception();
#endif
// Leave output empty
return;
}

View File

@@ -0,0 +1,43 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// 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)
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_THROW_ON_EMPTY_INPUT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_THROW_ON_EMPTY_INPUT_HPP
#include <boost/geometry/core/exception.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <typename Geometry>
inline void throw_on_empty_input(Geometry const& geometry)
{
#if ! defined(BOOST_GEOMETRY_EMPTY_INPUT_NO_THROW)
if (geometry::num_points(geometry) == 0)
{
throw empty_input_exception();
}
#endif
}
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_THROW_ON_EMPTY_INPUT_HPP

View File

@@ -25,6 +25,7 @@
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
@@ -549,6 +550,9 @@ inline typename strategy::distance::services::return_type<Strategy>::type distan
{
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
detail::throw_on_empty_input(geometry1);
detail::throw_on_empty_input(geometry2);
return dispatch::distance
<

View File

@@ -28,6 +28,7 @@
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/detail/calculate_null.hpp>
#include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/default_length_result.hpp>
@@ -151,6 +152,8 @@ inline typename default_length_result<Geometry>::type length(
{
concept::check<Geometry const>();
detail::throw_on_empty_input(geometry);
typedef typename strategy::distance::services::default_strategy
<
point_tag, typename point_type<Geometry>::type
@@ -185,6 +188,8 @@ inline typename default_length_result<Geometry>::type length(
{
concept::check<Geometry const>();
detail::throw_on_empty_input(geometry);
return dispatch::length
<
typename tag<Geometry>::type,

View File

@@ -22,6 +22,7 @@
#include <boost/geometry/algorithms/length.hpp>
#include <boost/geometry/algorithms/detail/calculate_null.hpp>
#include <boost/geometry/algorithms/detail/calculate_sum.hpp>
#include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
namespace boost { namespace geometry
@@ -97,6 +98,8 @@ inline typename default_length_result<Geometry>::type perimeter(
point_tag, point_type
>::type strategy_type;
detail::throw_on_empty_input(geometry);
return dispatch::perimeter
<
typename tag<Geometry>::type,
@@ -125,6 +128,8 @@ inline typename default_length_result<Geometry>::type perimeter(
{
concept::check<Geometry const>();
detail::throw_on_empty_input(geometry);
return dispatch::perimeter
<
typename tag<Geometry>::type,

View File

@@ -29,6 +29,32 @@ class exception : public std::exception
{};
/*!
\brief Empty Input Exception
\ingroup core
\details The empty_input_exception is thrown if free functions, e.g. distance,
are called with empty geometries, e.g. a linestring
without points, a polygon without points, an empty multi-geometry.
\qbk{
[heading See also]
\* [link geometry.reference.algorithms.area the area function]
\* [link geometry.reference.algorithms.distance the distance function]
\* [link geometry.reference.algorithms.length the length function]
}
*/
class empty_input_exception : public geometry::exception
{
public:
inline empty_input_exception() {}
virtual char const* what() const throw()
{
return "Boost.Geometry Empty-Input exception";
}
};
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_CORE_EXCEPTION_HPP

View File

@@ -23,6 +23,7 @@
#include <boost/geometry/multi/core/point_type.hpp>
#include <boost/geometry/algorithms/distance.hpp>
#include <boost/geometry/multi/algorithms/num_points.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
@@ -49,12 +50,12 @@ struct distance_single_to_multi
MultiGeometry const& multi,
Strategy const& strategy)
{
return_type mindist = return_type();
bool first = true;
return_type mindist;
for(typename range_iterator<MultiGeometry const>::type it = boost::begin(multi);
it != boost::end(multi);
++it)
++it, first = false)
{
return_type dist = dispatch::distance
<
@@ -67,7 +68,6 @@ struct distance_single_to_multi
{
mindist = dist;
}
first = false;
}
return mindist;
@@ -88,12 +88,12 @@ struct distance_multi_to_multi
static inline return_type apply(Multi1 const& multi1,
Multi2 const& multi2, Strategy const& strategy)
{
return_type mindist = return_type();
bool first = true;
return_type mindist;
for(typename range_iterator<Multi1 const>::type it = boost::begin(multi1);
it != boost::end(multi1);
++it)
++it, first = false)
{
return_type dist = distance_single_to_multi
<
@@ -105,7 +105,6 @@ struct distance_multi_to_multi
{
mindist = dist;
}
first = false;
}
return mindist;