diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/is_valid/linear.hpp')
-rw-r--r-- | boost/geometry/algorithms/detail/is_valid/linear.hpp | 81 |
1 files changed, 60 insertions, 21 deletions
diff --git a/boost/geometry/algorithms/detail/is_valid/linear.hpp b/boost/geometry/algorithms/detail/is_valid/linear.hpp index 244df9b035..69243563ec 100644 --- a/boost/geometry/algorithms/detail/is_valid/linear.hpp +++ b/boost/geometry/algorithms/detail/is_valid/linear.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014, Oracle and/or its affiliates. +// Copyright (c) 2014-2015, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -21,6 +21,7 @@ #include <boost/geometry/util/range.hpp> #include <boost/geometry/algorithms/equals.hpp> +#include <boost/geometry/algorithms/validity_failure_type.hpp> #include <boost/geometry/algorithms/detail/check_iterator_range.hpp> #include <boost/geometry/algorithms/detail/is_valid/has_spikes.hpp> #include <boost/geometry/algorithms/detail/num_distinct_consecutive_points.hpp> @@ -36,11 +37,18 @@ namespace detail { namespace is_valid { -template <typename Linestring, bool AllowSpikes> +template <typename Linestring> struct is_valid_linestring { - static inline bool apply(Linestring const& linestring) + template <typename VisitPolicy> + static inline bool apply(Linestring const& linestring, + VisitPolicy& visitor) { + if (boost::size(linestring) < 2) + { + return visitor.template apply<failure_few_points>(); + } + std::size_t num_distinct = detail::num_distinct_consecutive_points < Linestring, @@ -49,14 +57,17 @@ struct is_valid_linestring not_equal_to<typename point_type<Linestring>::type> >::apply(linestring); - if ( num_distinct < 2u ) + if (num_distinct < 2u) { - return false; + return + visitor.template apply<failure_wrong_topological_dimension>(); } - return num_distinct == 2u - || AllowSpikes - || !has_spikes<Linestring, closed>::apply(linestring); + if (num_distinct == 2u) + { + return visitor.template apply<no_failure>(); + } + return ! has_spikes<Linestring, closed>::apply(linestring, visitor); } }; @@ -84,9 +95,11 @@ namespace dispatch // By default, spikes are disallowed // // Reference: OGC 06-103r4 (6.1.6.1) -template <typename Linestring, bool AllowSpikes> -struct is_valid<Linestring, linestring_tag, AllowSpikes> - : detail::is_valid::is_valid_linestring<Linestring, AllowSpikes> +template <typename Linestring, bool AllowEmptyMultiGeometries> +struct is_valid + < + Linestring, linestring_tag, AllowEmptyMultiGeometries + > : detail::is_valid::is_valid_linestring<Linestring> {}; @@ -96,21 +109,47 @@ struct is_valid<Linestring, linestring_tag, AllowSpikes> // are on the boundaries of both elements. // // Reference: OGC 06-103r4 (6.1.8.1; Fig. 9) -template <typename MultiLinestring, bool AllowSpikes> -struct is_valid<MultiLinestring, multi_linestring_tag, AllowSpikes> +template <typename MultiLinestring, bool AllowEmptyMultiGeometries> +class is_valid + < + MultiLinestring, multi_linestring_tag, AllowEmptyMultiGeometries + > { - static inline bool apply(MultiLinestring const& multilinestring) +private: + template <typename VisitPolicy> + struct per_linestring + { + per_linestring(VisitPolicy& policy) : m_policy(policy) {} + + template <typename Linestring> + inline bool apply(Linestring const& linestring) const + { + return detail::is_valid::is_valid_linestring + < + Linestring + >::apply(linestring, m_policy); + } + + VisitPolicy& m_policy; + }; + +public: + template <typename VisitPolicy> + static inline bool apply(MultiLinestring const& multilinestring, + VisitPolicy& visitor) { + if (AllowEmptyMultiGeometries && boost::empty(multilinestring)) + { + return visitor.template apply<no_failure>(); + } + return detail::check_iterator_range < - detail::is_valid::is_valid_linestring - < - typename boost::range_value<MultiLinestring>::type, - AllowSpikes - >, - false // do not allow empty multilinestring + per_linestring<VisitPolicy>, + false // do not check for empty multilinestring (done above) >::apply(boost::begin(multilinestring), - boost::end(multilinestring)); + boost::end(multilinestring), + per_linestring<VisitPolicy>(visitor)); } }; |