summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/is_valid
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:33:54 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:36:09 +0900
commitd9ec475d945d3035377a0d89ed42e382d8988891 (patch)
tree34aff2cee4b209906243ab5499d61f3edee2982f /boost/geometry/algorithms/detail/is_valid
parent71d216b90256936a9638f325af9bc69d720e75de (diff)
downloadboost-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')
-rw-r--r--boost/geometry/algorithms/detail/is_valid/box.hpp17
-rw-r--r--boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp151
-rw-r--r--boost/geometry/algorithms/detail/is_valid/linear.hpp6
-rw-r--r--boost/geometry/algorithms/detail/is_valid/pointlike.hpp13
-rw-r--r--boost/geometry/algorithms/detail/is_valid/polygon.hpp5
-rw-r--r--boost/geometry/algorithms/detail/is_valid/ring.hpp25
-rw-r--r--boost/geometry/algorithms/detail/is_valid/segment.hpp11
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>();
}