diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:33:54 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:36:09 +0900 |
commit | d9ec475d945d3035377a0d89ed42e382d8988891 (patch) | |
tree | 34aff2cee4b209906243ab5499d61f3edee2982f /boost/geometry/algorithms/detail/is_valid | |
parent | 71d216b90256936a9638f325af9bc69d720e75de (diff) | |
download | boost-d9ec475d945d3035377a0d89ed42e382d8988891.tar.gz boost-d9ec475d945d3035377a0d89ed42e382d8988891.tar.bz2 boost-d9ec475d945d3035377a0d89ed42e382d8988891.zip |
Imported Upstream version 1.60.0
Change-Id: Ie709530d6d5841088ceaba025cbe175a4ef43050
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/geometry/algorithms/detail/is_valid')
7 files changed, 213 insertions, 15 deletions
diff --git a/boost/geometry/algorithms/detail/is_valid/box.hpp b/boost/geometry/algorithms/detail/is_valid/box.hpp index e7a67252ba..863ce625fe 100644 --- a/boost/geometry/algorithms/detail/is_valid/box.hpp +++ b/boost/geometry/algorithms/detail/is_valid/box.hpp @@ -20,6 +20,7 @@ #include <boost/geometry/core/coordinate_dimension.hpp> #include <boost/geometry/algorithms/validity_failure_type.hpp> +#include <boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp> #include <boost/geometry/algorithms/dispatch/is_valid.hpp> @@ -66,6 +67,20 @@ struct has_valid_corners<Box, 0> } }; + +template <typename Box> +struct is_valid_box +{ + template <typename VisitPolicy> + static inline bool apply(Box const& box, VisitPolicy& visitor) + { + return + ! has_invalid_coordinate<Box>::apply(box, visitor) + && + has_valid_corners<Box, dimension<Box>::value>::apply(box, visitor); + } +}; + }} // namespace detail::is_valid #endif // DOXYGEN_NO_DETAIL @@ -85,7 +100,7 @@ namespace dispatch // Reference (for polygon validity): OGC 06-103r4 (6.1.11.1) template <typename Box> struct is_valid<Box, box_tag> - : detail::is_valid::has_valid_corners<Box, dimension<Box>::value> + : detail::is_valid::is_valid_box<Box> {}; diff --git a/boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp b/boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp new file mode 100644 index 0000000000..6e6823d62f --- /dev/null +++ b/boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp @@ -0,0 +1,151 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014-2015, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_INVALID_COORDINATE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_INVALID_COORDINATE_HPP + +#include <cstddef> + +#include <boost/type_traits/is_floating_point.hpp> + +#include <boost/geometry/core/coordinate_type.hpp> +#include <boost/geometry/core/point_type.hpp> + +#include <boost/geometry/util/has_non_finite_coordinate.hpp> + +#include <boost/geometry/iterators/point_iterator.hpp> +#include <boost/geometry/views/detail/indexed_point_view.hpp> +#include <boost/geometry/algorithms/detail/check_iterator_range.hpp> + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace is_valid +{ + +struct always_valid +{ + template <typename Geometry, typename VisitPolicy> + static inline bool apply(Geometry const&, VisitPolicy& visitor) + { + return ! visitor.template apply<no_failure>(); + } +}; + +struct point_has_invalid_coordinate +{ + template <typename Point, typename VisitPolicy> + static inline bool apply(Point const& point, VisitPolicy& visitor) + { + boost::ignore_unused(visitor); + + return + geometry::has_non_finite_coordinate(point) + ? + (! visitor.template apply<failure_invalid_coordinate>()) + : + (! visitor.template apply<no_failure>()); + } + + template <typename Point> + static inline bool apply(Point const& point) + { + return geometry::has_non_finite_coordinate(point); + } +}; + +struct indexed_has_invalid_coordinate +{ + template <typename Geometry, typename VisitPolicy> + static inline bool apply(Geometry const& geometry, VisitPolicy& visitor) + { + geometry::detail::indexed_point_view<Geometry const, 0> p0(geometry); + geometry::detail::indexed_point_view<Geometry const, 1> p1(geometry); + + return point_has_invalid_coordinate::apply(p0, visitor) + || point_has_invalid_coordinate::apply(p1, visitor); + } +}; + + +struct range_has_invalid_coordinate +{ + struct point_has_valid_coordinates + { + template <typename Point> + static inline bool apply(Point const& point) + { + return ! point_has_invalid_coordinate::apply(point); + } + }; + + template <typename Geometry, typename VisitPolicy> + static inline bool apply(Geometry const& geometry, VisitPolicy& visitor) + { + boost::ignore_unused(visitor); + + bool const has_valid_coordinates = detail::check_iterator_range + < + point_has_valid_coordinates, + true // do not consider an empty range as problematic + >::apply(geometry::points_begin(geometry), + geometry::points_end(geometry)); + + return has_valid_coordinates + ? + (! visitor.template apply<no_failure>()) + : + (! visitor.template apply<failure_invalid_coordinate>()); + } +}; + + +template +< + typename Geometry, + typename Tag = typename tag<Geometry>::type, + bool HasFloatingPointCoordinates = boost::is_floating_point + < + typename coordinate_type<Geometry>::type + >::value +> +struct has_invalid_coordinate + : range_has_invalid_coordinate +{}; + +template <typename Geometry, typename Tag> +struct has_invalid_coordinate<Geometry, Tag, false> + : always_valid +{}; + +template <typename Point> +struct has_invalid_coordinate<Point, point_tag, true> + : point_has_invalid_coordinate +{}; + +template <typename Segment> +struct has_invalid_coordinate<Segment, segment_tag, true> + : indexed_has_invalid_coordinate +{}; + +template <typename Box> +struct has_invalid_coordinate<Box, box_tag, true> + : indexed_has_invalid_coordinate +{}; + + +}} // namespace detail::is_valid +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_INVALID_COORDINATE_HPP diff --git a/boost/geometry/algorithms/detail/is_valid/linear.hpp b/boost/geometry/algorithms/detail/is_valid/linear.hpp index e30064faf0..a49e077237 100644 --- a/boost/geometry/algorithms/detail/is_valid/linear.hpp +++ b/boost/geometry/algorithms/detail/is_valid/linear.hpp @@ -25,6 +25,7 @@ #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_invalid_coordinate.hpp> #include <boost/geometry/algorithms/detail/is_valid/has_spikes.hpp> #include <boost/geometry/algorithms/detail/num_distinct_consecutive_points.hpp> @@ -46,6 +47,11 @@ struct is_valid_linestring static inline bool apply(Linestring const& linestring, VisitPolicy& visitor) { + if (has_invalid_coordinate<Linestring>::apply(linestring, visitor)) + { + return false; + } + if (boost::size(linestring) < 2) { return visitor.template apply<failure_few_points>(); diff --git a/boost/geometry/algorithms/detail/is_valid/pointlike.hpp b/boost/geometry/algorithms/detail/is_valid/pointlike.hpp index e51ab74643..51035f7a73 100644 --- a/boost/geometry/algorithms/detail/is_valid/pointlike.hpp +++ b/boost/geometry/algorithms/detail/is_valid/pointlike.hpp @@ -17,6 +17,7 @@ #include <boost/geometry/core/tags.hpp> #include <boost/geometry/algorithms/validity_failure_type.hpp> +#include <boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp> #include <boost/geometry/algorithms/dispatch/is_valid.hpp> #include <boost/geometry/util/condition.hpp> @@ -36,10 +37,13 @@ template <typename Point> struct is_valid<Point, point_tag> { template <typename VisitPolicy> - static inline bool apply(Point const&, VisitPolicy& visitor) + static inline bool apply(Point const& point, VisitPolicy& visitor) { boost::ignore_unused(visitor); - return visitor.template apply<no_failure>(); + return ! detail::is_valid::has_invalid_coordinate + < + Point + >::apply(point, visitor); } }; @@ -63,7 +67,10 @@ struct is_valid<MultiPoint, multi_point_tag, AllowEmptyMultiGeometries> { // we allow empty multi-geometries, so an empty multipoint // is considered valid - return visitor.template apply<no_failure>(); + return ! detail::is_valid::has_invalid_coordinate + < + MultiPoint + >::apply(multipoint, visitor); } else { diff --git a/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/boost/geometry/algorithms/detail/is_valid/polygon.hpp index 6e87273aa1..bbe8e8fc39 100644 --- a/boost/geometry/algorithms/detail/is_valid/polygon.hpp +++ b/boost/geometry/algorithms/detail/is_valid/polygon.hpp @@ -11,6 +11,9 @@ #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_POLYGON_HPP #include <cstddef> +#ifdef BOOST_GEOMETRY_TEST_DEBUG +#include <iostream> +#endif // BOOST_GEOMETRY_TEST_DEBUG #include <algorithm> #include <deque> @@ -327,7 +330,9 @@ protected: g.add_edge(v2, vip); } +#ifdef BOOST_GEOMETRY_TEST_DEBUG debug_print_complement_graph(std::cout, g); +#endif // BOOST_GEOMETRY_TEST_DEBUG if (g.has_cycles()) { diff --git a/boost/geometry/algorithms/detail/is_valid/ring.hpp b/boost/geometry/algorithms/detail/is_valid/ring.hpp index c35e843418..925c03a472 100644 --- a/boost/geometry/algorithms/detail/is_valid/ring.hpp +++ b/boost/geometry/algorithms/detail/is_valid/ring.hpp @@ -30,8 +30,9 @@ #include <boost/geometry/algorithms/intersects.hpp> #include <boost/geometry/algorithms/validity_failure_type.hpp> #include <boost/geometry/algorithms/detail/num_distinct_consecutive_points.hpp> -#include <boost/geometry/algorithms/detail/is_valid/has_spikes.hpp> #include <boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp> +#include <boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp> +#include <boost/geometry/algorithms/detail/is_valid/has_spikes.hpp> #include <boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp> #include <boost/geometry/strategies/area.hpp> @@ -153,17 +154,23 @@ struct is_valid_ring static inline bool apply(Ring const& ring, VisitPolicy& visitor) { // return invalid if any of the following condition holds: - // (a) the ring's size is below the minimal one - // (b) the ring consists of at most two distinct points - // (c) the ring is not topologically closed - // (d) the ring has spikes - // (e) the ring has duplicate points (if AllowDuplicates is false) - // (f) the boundary of the ring has self-intersections - // (g) the order of the points is inconsistent with the defined order + // (a) the ring's point coordinates are not invalid (e.g., NaN) + // (b) the ring's size is below the minimal one + // (c) the ring consists of at most two distinct points + // (d) the ring is not topologically closed + // (e) the ring has spikes + // (f) the ring has duplicate points (if AllowDuplicates is false) + // (g) the boundary of the ring has self-intersections + // (h) the order of the points is inconsistent with the defined order // // Note: no need to check if the area is zero. If this is the // case, then the ring must have at least two spikes, which is - // checked by condition (c). + // checked by condition (d). + + if (has_invalid_coordinate<Ring>::apply(ring, visitor)) + { + return false; + } closure_selector const closure = geometry::closure<Ring>::value; typedef typename closeable_view<Ring const, closure>::type view_type; diff --git a/boost/geometry/algorithms/detail/is_valid/segment.hpp b/boost/geometry/algorithms/detail/is_valid/segment.hpp index a93d2bfe9e..f92f73381f 100644 --- a/boost/geometry/algorithms/detail/is_valid/segment.hpp +++ b/boost/geometry/algorithms/detail/is_valid/segment.hpp @@ -19,7 +19,7 @@ #include <boost/geometry/algorithms/assign.hpp> #include <boost/geometry/algorithms/equals.hpp> #include <boost/geometry/algorithms/validity_failure_type.hpp> - +#include <boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp> #include <boost/geometry/algorithms/dispatch/is_valid.hpp> @@ -53,7 +53,14 @@ struct is_valid<Segment, segment_tag> detail::assign_point_from_index<0>(segment, p[0]); detail::assign_point_from_index<1>(segment, p[1]); - if(! geometry::equals(p[0], p[1])) + if (detail::is_valid::has_invalid_coordinate + < + Segment + >::apply(segment, visitor)) + { + return false; + } + else if (! geometry::equals(p[0], p[1])) { return visitor.template apply<no_failure>(); } |