update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, 2018, Oracle and/or its affiliates.
// Copyright (c) 2014-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -32,7 +33,7 @@ namespace detail { namespace is_valid
{
template <typename TurnPoint>
template <typename TurnPoint, typename Strategy>
class complement_graph_vertex
{
public:
@@ -55,7 +56,7 @@ public:
{
return geometry::less
<
TurnPoint
TurnPoint, -1, Strategy
>()(*m_turn_point, *other.m_turn_point);
}
if ( m_turn_point == NULL && other.m_turn_point == NULL )
@@ -77,11 +78,11 @@ private:
template <typename TurnPoint>
template <typename TurnPoint, typename Strategy>
class complement_graph
{
private:
typedef complement_graph_vertex<TurnPoint> vertex;
typedef complement_graph_vertex<TurnPoint, Strategy> vertex;
typedef std::set<vertex> vertex_container;
public:
@@ -224,9 +225,10 @@ public:
}
#ifdef BOOST_GEOMETRY_TEST_DEBUG
template <typename OStream, typename TP>
template <typename OutputStream>
friend inline
void debug_print_complement_graph(OStream&, complement_graph<TP> const&);
void debug_print_complement_graph(OutputStream&,
complement_graph<TurnPoint, Strategy> const&);
#endif // BOOST_GEOMETRY_TEST_DEBUG
private:

View File

@@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, 2018, Oracle and/or its affiliates.
// Copyright (c) 2014-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -25,12 +26,12 @@ namespace detail { namespace is_valid
#ifdef BOOST_GEOMETRY_TEST_DEBUG
template <typename OutputStream, typename TurnPoint>
template <typename OutputStream, typename TurnPoint, typename Strategy>
inline void
debug_print_complement_graph(OutputStream& os,
complement_graph<TurnPoint> const& graph)
complement_graph<TurnPoint, Strategy> const& graph)
{
typedef typename complement_graph<TurnPoint>::vertex_handle vertex_handle;
typedef typename complement_graph<TurnPoint, Strategy>::vertex_handle vertex_handle;
os << "num rings: " << graph.m_num_rings << std::endl;
os << "vertex ids: {";
@@ -39,7 +40,7 @@ debug_print_complement_graph(OutputStream& os,
{
os << " " << it->id();
}
os << " }" << std::endl;
os << " }" << std::endl;
for (vertex_handle it = graph.m_vertices.begin();
it != graph.m_vertices.end(); ++it)
@@ -47,20 +48,20 @@ debug_print_complement_graph(OutputStream& os,
os << "neighbors of " << it->id() << ": {";
for (typename complement_graph
<
TurnPoint
TurnPoint, Strategy
>::neighbor_container::const_iterator
nit = graph.m_neighbors[it->id()].begin();
nit != graph.m_neighbors[it->id()].end(); ++nit)
{
os << " " << (*nit)->id();
}
os << "}" << std::endl;
os << "}" << std::endl;
}
}
#else
template <typename OutputStream, typename TurnPoint>
template <typename OutputStream, typename TurnPoint, typename Strategy>
inline void debug_print_complement_graph(OutputStream&,
complement_graph<TurnPoint> const&)
complement_graph<TurnPoint, Strategy> const&)
{
}
#endif

View File

@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Copyright (c) 2014-2021, 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
@@ -11,7 +12,9 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_DUPLICATES_HPP
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/size.hpp>
#include <boost/geometry/core/closure.hpp>
@@ -30,33 +33,33 @@ namespace boost { namespace geometry
namespace detail { namespace is_valid
{
template <typename Range, closure_selector Closure>
template <typename Range>
struct has_duplicates
{
template <typename VisitPolicy>
static inline bool apply(Range const& range, VisitPolicy& visitor)
template <typename VisitPolicy, typename Strategy>
static inline bool apply(Range const& range, VisitPolicy& visitor,
Strategy const& )
{
boost::ignore_unused(visitor);
typedef typename closeable_view<Range const, Closure>::type view_type;
typedef typename boost::range_const_iterator
<
view_type const
>::type const_iterator;
view_type view(range);
detail::closed_view<Range const> const view(range);
if ( boost::size(view) < 2 )
{
return ! visitor.template apply<no_failure>();
}
geometry::equal_to<typename boost::range_value<Range>::type> equal;
geometry::equal_to
<
typename boost::range_value<Range>::type,
-1,
typename Strategy::cs_tag
> equal;
const_iterator it = boost::const_begin(view);
const_iterator next = it;
++next;
for (; next != boost::const_end(view); ++it, ++next)
auto it = boost::begin(view);
auto const end = boost::end(view);
auto next = it;
for (++next; next != end; ++it, ++next)
{
if ( equal(*it, *next) )
{

View File

@@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Copyright (c) 2014-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -12,10 +13,8 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_INVALID_COORDINATE_HPP
#include <cstddef>
#include <type_traits>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
@@ -29,7 +28,7 @@
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace is_valid
{
@@ -81,26 +80,19 @@ struct indexed_has_invalid_coordinate
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));
auto const points_end = geometry::points_end(geometry);
bool const has_valid_coordinates = std::none_of
(
geometry::points_begin(geometry), points_end,
[]( auto const& point ){
return point_has_invalid_coordinate::apply(point);
}
);
return has_valid_coordinates
?
@@ -115,7 +107,7 @@ template
<
typename Geometry,
typename Tag = typename tag<Geometry>::type,
bool HasFloatingPointCoordinates = boost::is_floating_point
bool HasFloatingPointCoordinates = std::is_floating_point
<
typename coordinate_type<Geometry>::type
>::value

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Copyright (c) 2014-2021, 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
@@ -14,25 +14,29 @@
#include <algorithm>
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/rbegin.hpp>
#include <boost/range/rend.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/io/dsv/write.hpp>
#include <boost/geometry/policies/is_valid/default_policy.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/util/type_traits.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp>
#include <boost/geometry/io/dsv/write.hpp>
namespace boost { namespace geometry
{
@@ -42,123 +46,98 @@ namespace boost { namespace geometry
namespace detail { namespace is_valid
{
template <typename Point>
struct equal_to
{
Point const& m_point;
equal_to(Point const& point)
: m_point(point)
{}
template <typename OtherPoint>
inline bool operator()(OtherPoint const& other) const
{
return geometry::equals(m_point, other);
}
};
template <typename Point>
struct not_equal_to
{
Point const& m_point;
not_equal_to(Point const& point)
: m_point(point)
{}
template <typename OtherPoint>
inline bool operator()(OtherPoint const& other) const
{
return ! geometry::equals(other, m_point);
}
};
template <typename Range, closure_selector Closure>
template <typename Range>
struct has_spikes
{
template <typename Iterator>
template <typename Iterator, typename Strategy>
static inline Iterator find_different_from_first(Iterator first,
Iterator last)
Iterator last,
Strategy const& strategy)
{
typedef not_equal_to<typename point_type<Range>::type> not_equal;
BOOST_GEOMETRY_ASSERT(first != last);
Iterator second = first;
++second;
return std::find_if(second, last, not_equal(*first));
if (first == last)
{
return last;
}
auto const& front = *first;
++first;
return std::find_if(first, last, [&](auto const& pt) {
return ! equals::equals_point_point(pt, front, strategy);
});
}
template <typename VisitPolicy, typename SideStrategy>
static inline bool apply(Range const& range, VisitPolicy& visitor,
SideStrategy const& strategy)
template <typename View, typename VisitPolicy, typename Strategy>
static inline bool apply_at_closure(View const& view, VisitPolicy& visitor,
Strategy const& strategy,
bool is_linear)
{
boost::ignore_unused(visitor);
typedef typename closeable_view<Range const, Closure>::type view_type;
typedef typename boost::range_iterator<view_type const>::type iterator;
auto cur = boost::begin(view);
auto prev = find_different_from_first(boost::rbegin(view),
boost::rend(view),
strategy);
bool const is_linear
= boost::is_same<typename tag<Range>::type, linestring_tag>::value;
auto next = find_different_from_first(cur, boost::end(view), strategy);
if (detail::is_spike_or_equal(*next, *cur, *prev, strategy.side()))
{
return ! visitor.template apply<failure_spikes>(is_linear, *cur);
}
else
{
return ! visitor.template apply<no_failure>();
}
}
view_type const view(range);
iterator prev = boost::begin(view);
template <typename VisitPolicy, typename Strategy>
static inline bool apply(Range const& range, VisitPolicy& visitor,
Strategy const& strategy)
{
boost::ignore_unused(visitor);
iterator cur = find_different_from_first(prev, boost::end(view));
if (cur == boost::end(view))
bool const is_linestring = util::is_linestring<Range>::value;
detail::closed_view<Range const> const view(range);
auto prev = boost::begin(view);
auto const end = boost::end(view);
auto cur = find_different_from_first(prev, boost::end(view), strategy);
if (cur == end)
{
// the range has only one distinct point, so it
// cannot have a spike
return ! visitor.template apply<no_failure>();
}
iterator next = find_different_from_first(cur, boost::end(view));
if (next == boost::end(view))
auto next = find_different_from_first(cur, boost::end(view), strategy);
if (next == end)
{
// the range has only two distinct points, so it
// cannot have a spike
return ! visitor.template apply<no_failure>();
}
while (next != boost::end(view))
while (next != end)
{
// Verify spike. TODO: this is a reverse order from expected
// in is_spike_or_equal, but this order calls the side
// strategy in the way to correctly detect the spikes,
// also in geographic cases going over the pole
if (detail::is_spike_or_equal(*next, *cur, *prev, strategy))
if (detail::is_spike_or_equal(*next, *cur, *prev, strategy.side()))
{
return
! visitor.template apply<failure_spikes>(is_linear, *cur);
return ! visitor.template apply<failure_spikes>(is_linestring, *cur);
}
prev = cur;
cur = next;
next = find_different_from_first(cur, boost::end(view));
next = find_different_from_first(cur, boost::end(view), strategy);
}
if (geometry::equals(range::front(view), range::back(view)))
if (equals::equals_point_point(range::front(view), range::back(view),
strategy))
{
iterator cur = boost::begin(view);
typename boost::range_reverse_iterator
<
view_type const
>::type prev = find_different_from_first(boost::rbegin(view),
boost::rend(view));
iterator next = find_different_from_first(cur, boost::end(view));
if (detail::is_spike_or_equal(*next, *cur, *prev, strategy))
{
return
! visitor.template apply<failure_spikes>(is_linear, *cur);
}
else
{
return ! visitor.template apply<no_failure>();
}
return apply_at_closure(view, visitor, strategy, is_linestring);
}
return ! visitor.template apply<no_failure>();

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Copyright (c) 2014-2021, 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
@@ -14,7 +14,7 @@
#include <vector>
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/range/empty.hpp>
#include <boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
@@ -41,7 +41,7 @@ namespace detail { namespace is_valid
template
<
typename Geometry,
typename IsAcceptableTurn = is_acceptable_turn<Geometry>
typename CSTag // TODO: remove
>
class has_valid_self_turns
{
@@ -50,19 +50,15 @@ private:
typedef typename geometry::rescale_policy_type
<
point_type
point_type,
CSTag
>::type rescale_policy_type;
typedef detail::overlay::get_turn_info
<
detail::overlay::assign_null_policy
> turn_policy;
public:
typedef detail::overlay::turn_info
<
point_type,
typename geometry::segment_ratio_type
typename segment_ratio_type
<
point_type,
rescale_policy_type
@@ -79,18 +75,19 @@ public:
boost::ignore_unused(visitor);
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry);
= geometry::get_rescale_policy<rescale_policy_type>(geometry, strategy);
detail::overlay::stateless_predicate_based_interrupt_policy
<
IsAcceptableTurn
is_acceptable_turn<Geometry>
> interrupt_policy;
detail::self_get_turn_points::self_turns<false, turn_policy>(geometry,
strategy,
robust_policy,
turns,
interrupt_policy);
// Calculate self-turns, skipping adjacent segments
detail::self_get_turn_points::self_turns
<
false, detail::overlay::assign_null_policy
>(geometry, strategy, robust_policy, turns, interrupt_policy,
0, true);
if (interrupt_policy.has_intersections)
{

View File

@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, Oracle and/or its affiliates.
// Copyright (c) 2014-2021, 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
@@ -18,4 +19,8 @@
#include <boost/geometry/algorithms/detail/is_valid/segment.hpp>
#include <boost/geometry/algorithms/detail/is_valid/box.hpp>
#include <boost/geometry/strategies/relate/cartesian.hpp>
#include <boost/geometry/strategies/relate/geographic.hpp>
#include <boost/geometry/strategies/relate/spherical.hpp>
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_IMPLEMENTATION_HPP

View File

@@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Copyright (c) 2014-2021, 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
@@ -14,29 +14,34 @@
#include <sstream>
#include <string>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/detail/visit.hpp>
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/visit.hpp>
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/policies/is_valid/default_policy.hpp>
#include <boost/geometry/policies/is_valid/failing_reason_policy.hpp>
#include <boost/geometry/policies/is_valid/failure_type_policy.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/relate/services.hpp>
namespace boost { namespace geometry
{
namespace resolve_strategy
{
template
<
typename Strategy,
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
>
struct is_valid
{
template <typename Geometry, typename VisitPolicy, typename Strategy>
template <typename Geometry, typename VisitPolicy>
static inline bool apply(Geometry const& geometry,
VisitPolicy& visitor,
Strategy const& strategy)
@@ -44,27 +49,50 @@ struct is_valid
return dispatch::is_valid<Geometry>::apply(geometry, visitor, strategy);
}
};
template <typename Strategy>
struct is_valid<Strategy, false>
{
template <typename Geometry, typename VisitPolicy>
static inline bool apply(Geometry const& geometry,
VisitPolicy& visitor,
Strategy const& strategy)
{
using strategies::relate::services::strategy_converter;
return dispatch::is_valid
<
Geometry
>::apply(geometry, visitor,
strategy_converter<Strategy>::get(strategy));
}
};
template <>
struct is_valid<default_strategy, false>
{
template <typename Geometry, typename VisitPolicy>
static inline bool apply(Geometry const& geometry,
VisitPolicy& visitor,
default_strategy)
{
// NOTE: Currently the strategy is only used for Areal geometries
typedef typename strategy::intersection::services::default_strategy
typedef typename strategies::relate::services::default_strategy
<
typename cs_tag<Geometry>::type
Geometry, Geometry
>::type strategy_type;
return dispatch::is_valid<Geometry>::apply(geometry, visitor, strategy_type());
return dispatch::is_valid<Geometry>::apply(geometry, visitor,
strategy_type());
}
};
} // namespace resolve_strategy
namespace resolve_variant
namespace resolve_dynamic
{
template <typename Geometry>
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct is_valid
{
template <typename VisitPolicy, typename Strategy>
@@ -74,43 +102,49 @@ struct is_valid
{
concepts::check<Geometry const>();
return resolve_strategy::is_valid::apply(geometry, visitor, strategy);
return resolve_strategy::is_valid
<
Strategy
>::apply(geometry, visitor, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct is_valid<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
template <typename Geometry>
struct is_valid<Geometry, dynamic_geometry_tag>
{
template <typename VisitPolicy, typename Strategy>
struct visitor : boost::static_visitor<bool>
static inline bool apply(Geometry const& geometry,
VisitPolicy& policy_visitor,
Strategy const& strategy)
{
visitor(VisitPolicy& policy, Strategy const& strategy)
: m_policy(policy)
, m_strategy(strategy)
{}
template <typename Geometry>
bool operator()(Geometry const& geometry) const
bool result = true;
traits::visit<Geometry>::apply([&](auto const& g)
{
return is_valid<Geometry>::apply(geometry, m_policy, m_strategy);
}
VisitPolicy& m_policy;
Strategy const& m_strategy;
};
template <typename VisitPolicy, typename Strategy>
static inline bool
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
VisitPolicy& policy_visitor,
Strategy const& strategy)
{
return boost::apply_visitor(visitor<VisitPolicy, Strategy>(policy_visitor, strategy),
geometry);
result = is_valid<util::remove_cref_t<decltype(g)>>::apply(g, policy_visitor, strategy);
}, geometry);
return result;
}
};
} // namespace resolve_variant
template <typename Geometry>
struct is_valid<Geometry, geometry_collection_tag>
{
template <typename VisitPolicy, typename Strategy>
static inline bool apply(Geometry const& geometry,
VisitPolicy& policy_visitor,
Strategy const& strategy)
{
bool result = true;
detail::visit_breadth_first([&](auto const& g)
{
result = is_valid<util::remove_cref_t<decltype(g)>>::apply(g, policy_visitor, strategy);
return result;
}, geometry);
return result;
}
};
} // namespace resolve_dynamic
// Undocumented for now
@@ -119,7 +153,7 @@ inline bool is_valid(Geometry const& geometry,
VisitPolicy& visitor,
Strategy const& strategy)
{
return resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy);
return resolve_dynamic::is_valid<Geometry>::apply(geometry, visitor, strategy);
}
@@ -143,7 +177,7 @@ template <typename Geometry, typename Strategy>
inline bool is_valid(Geometry const& geometry, Strategy const& strategy)
{
is_valid_default_policy<> visitor;
return resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy);
return resolve_dynamic::is_valid<Geometry>::apply(geometry, visitor, strategy);
}
/*!
@@ -188,7 +222,7 @@ template <typename Geometry, typename Strategy>
inline bool is_valid(Geometry const& geometry, validity_failure_type& failure, Strategy const& strategy)
{
failure_type_policy<> visitor;
bool result = resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy);
bool result = resolve_dynamic::is_valid<Geometry>::apply(geometry, visitor, strategy);
failure = visitor.failure();
return result;
}
@@ -239,7 +273,7 @@ inline bool is_valid(Geometry const& geometry, std::string& message, Strategy co
{
std::ostringstream stream;
failing_reason_policy<> visitor(stream);
bool result = resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy);
bool result = resolve_dynamic::is_valid<Geometry>::apply(geometry, visitor, strategy);
message = stream.str();
return result;
}

View File

@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Copyright (c) 2014-2020, 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
@@ -10,7 +11,7 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_IS_ACCEPTABLE_TURN_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_IS_ACCEPTABLE_TURN_HPP
#include <boost/range.hpp>
#include <boost/range/value_type.hpp>
#include <boost/geometry/core/point_order.hpp>
#include <boost/geometry/core/tag.hpp>
@@ -150,7 +151,7 @@ public:
|| turn.method == method_touch_interior)
&& turn.touch_only;
}
};
};
}} // namespace detail::is_valid

View File

@@ -1,7 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2014-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -13,24 +15,25 @@
#include <cstddef>
#include <boost/range.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/empty.hpp>
#include <boost/range/end.hpp>
#include <boost/range/size.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_invalid_coordinate.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_spikes.hpp>
#include <boost/geometry/algorithms/detail/num_distinct_consecutive_points.hpp>
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/constexpr.hpp>
namespace boost { namespace geometry
{
@@ -48,6 +51,8 @@ struct is_valid_linestring
VisitPolicy& visitor,
Strategy const& strategy)
{
// TODO: Consider checking coordinates based on coordinate system
// Right now they are only checked for infinity in all systems.
if (has_invalid_coordinate<Linestring>::apply(linestring, visitor))
{
return false;
@@ -60,11 +65,8 @@ struct is_valid_linestring
std::size_t num_distinct = detail::num_distinct_consecutive_points
<
Linestring,
3u,
true,
not_equal_to<typename point_type<Linestring>::type>
>::apply(linestring);
Linestring, 3u, true
>::apply(linestring, strategy);
if (num_distinct < 2u)
{
@@ -77,11 +79,12 @@ struct is_valid_linestring
return visitor.template apply<no_failure>();
}
return ! has_spikes
<
Linestring, closed
>::apply(linestring, visitor,
strategy.get_side_strategy());
// TODO: This algorithm iterates over the linestring until a spike is
// found and only then the decision about the validity is made. This
// is done regardless of VisitPolicy.
// An obvious improvement is to avoid calling the algorithm at all if
// spikes are allowed which is the default.
return ! has_spikes<Linestring>::apply(linestring, visitor, strategy);
}
};
@@ -103,7 +106,7 @@ namespace dispatch
// A curve is simple if it does not pass through the same point twice,
// with the possible exception of its two endpoints
//
// There is an option here as to whether spikes are allowed for linestrings;
// There is an option here as to whether spikes are allowed for linestrings;
// here we pass this as an additional template parameter: allow_spikes
// If allow_spikes is set to true, spikes are allowed, false otherwise.
// By default, spikes are disallowed
@@ -129,7 +132,6 @@ class is_valid
MultiLinestring, multi_linestring_tag, AllowEmptyMultiGeometries
>
{
private:
template <typename VisitPolicy, typename Strategy>
struct per_linestring
{
@@ -139,7 +141,7 @@ private:
{}
template <typename Linestring>
inline bool apply(Linestring const& linestring) const
inline bool operator()(Linestring const& linestring) const
{
return detail::is_valid::is_valid_linestring
<
@@ -157,21 +159,19 @@ public:
VisitPolicy& visitor,
Strategy const& strategy)
{
if (BOOST_GEOMETRY_CONDITION(
AllowEmptyMultiGeometries && boost::empty(multilinestring)))
if BOOST_GEOMETRY_CONSTEXPR (AllowEmptyMultiGeometries)
{
return visitor.template apply<no_failure>();
if (boost::empty(multilinestring))
{
return visitor.template apply<no_failure>();
}
}
typedef per_linestring<VisitPolicy, Strategy> per_ls;
using per_ls = per_linestring<VisitPolicy, Strategy>;
return detail::check_iterator_range
<
per_ls,
false // do not check for empty multilinestring (done above)
>::apply(boost::begin(multilinestring),
boost::end(multilinestring),
per_ls(visitor, strategy));
return std::all_of(boost::begin(multilinestring),
boost::end(multilinestring),
per_ls(visitor, strategy));
}
};

View File

@@ -1,7 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2014-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -16,14 +18,17 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/size.hpp>
#include <boost/range/value_type.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/geometries/box.hpp>
@@ -31,7 +36,6 @@
#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp>
@@ -115,11 +119,6 @@ private:
}
}
// prepare strategies
typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
envelope_strategy_type const envelope_strategy
= strategy.get_envelope_strategy();
// call partition to check if polygons are disjoint from each other
typename base::template item_visitor_type<Strategy> item_visitor(strategy);
@@ -127,8 +126,8 @@ private:
<
geometry::model::box<typename point_type<MultiPolygon>::type>
>::apply(polygon_iterators, item_visitor,
typename base::template expand_box<envelope_strategy_type>(envelope_strategy),
typename base::template overlaps_box<envelope_strategy_type>(envelope_strategy));
typename base::template expand_box<Strategy>(strategy),
typename base::template overlaps_box<Strategy>(strategy));
if (item_visitor.items_overlap)
{
@@ -259,55 +258,56 @@ private:
template <typename VisitPolicy, typename Strategy>
struct per_polygon
struct is_invalid_polygon
{
per_polygon(VisitPolicy& policy, Strategy const& strategy)
is_invalid_polygon(VisitPolicy& policy, Strategy const& strategy)
: m_policy(policy)
, m_strategy(strategy)
{}
template <typename Polygon>
inline bool apply(Polygon const& polygon) const
inline bool operator()(Polygon const& polygon) const
{
return base::apply(polygon, m_policy, m_strategy);
return ! base::apply(polygon, m_policy, m_strategy);
}
VisitPolicy& m_policy;
Strategy const& m_strategy;
};
public:
template <typename VisitPolicy, typename Strategy>
static inline bool apply(MultiPolygon const& multipolygon,
VisitPolicy& visitor,
Strategy const& strategy)
{
typedef debug_validity_phase<MultiPolygon> debug_phase;
using debug_phase = debug_validity_phase<MultiPolygon>;
if (BOOST_GEOMETRY_CONDITION(
AllowEmptyMultiGeometries && boost::empty(multipolygon)))
if BOOST_GEOMETRY_CONSTEXPR (AllowEmptyMultiGeometries)
{
return visitor.template apply<no_failure>();
if (boost::empty(multipolygon))
{
return visitor.template apply<no_failure>();
}
}
// check validity of all polygons ring
debug_phase::apply(1);
if (! detail::check_iterator_range
<
per_polygon<VisitPolicy, Strategy>,
false // do not check for empty multipolygon (done above)
>::apply(boost::begin(multipolygon),
boost::end(multipolygon),
per_polygon<VisitPolicy, Strategy>(visitor, strategy)))
if (std::any_of(boost::begin(multipolygon), boost::end(multipolygon),
is_invalid_polygon<VisitPolicy, Strategy>(visitor, strategy)))
{
return false;
}
// compute turns and check if all are acceptable
debug_phase::apply(2);
typedef has_valid_self_turns<MultiPolygon> has_valid_turns;
using has_valid_turns = has_valid_self_turns
<
MultiPolygon,
typename Strategy::cs_tag
>;
std::deque<typename has_valid_turns::turn_type> turns;
bool has_invalid_turns =

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Copyright (c) 2014-2020, 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
@@ -12,7 +12,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_POINTLIKE_HPP
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/range/empty.hpp>
#include <boost/geometry/core/tags.hpp>

View File

@@ -1,9 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2014-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -25,7 +25,8 @@
#include <vector>
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
@@ -33,8 +34,9 @@
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/util/sequence.hpp>
#include <boost/geometry/geometries/box.hpp>
@@ -48,7 +50,6 @@
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/is_valid/complement_graph.hpp>
@@ -63,6 +64,12 @@
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
// TEMP
#include <boost/geometry/strategies/envelope/cartesian.hpp>
#include <boost/geometry/strategies/envelope/geographic.hpp>
#include <boost/geometry/strategies/envelope/spherical.hpp>
namespace boost { namespace geometry
{
@@ -76,20 +83,19 @@ template <typename Polygon, bool CheckRingValidityOnly = false>
class is_valid_polygon
{
protected:
typedef debug_validity_phase<Polygon> debug_phase;
template <typename VisitPolicy, typename Strategy>
struct per_ring
struct is_invalid_ring
{
per_ring(VisitPolicy& policy, Strategy const& strategy)
is_invalid_ring(VisitPolicy& policy, Strategy const& strategy)
: m_policy(policy)
, m_strategy(strategy)
{}
template <typename Ring>
inline bool apply(Ring const& ring) const
inline bool operator()(Ring const& ring) const
{
return detail::is_valid::is_valid_ring
return ! detail::is_valid::is_valid_ring
<
Ring, false, true
>::apply(ring, m_policy, m_strategy);
@@ -104,14 +110,9 @@ protected:
VisitPolicy& visitor,
Strategy const& strategy)
{
return
detail::check_iterator_range
<
per_ring<VisitPolicy, Strategy>,
true // allow for empty interior ring range
>::apply(boost::begin(interior_rings),
boost::end(interior_rings),
per_ring<VisitPolicy, Strategy>(visitor, strategy));
return std::none_of(boost::begin(interior_rings),
boost::end(interior_rings),
is_invalid_ring<VisitPolicy, Strategy>(visitor, strategy));
}
struct has_valid_rings
@@ -121,6 +122,7 @@ protected:
VisitPolicy& visitor,
Strategy const& strategy)
{
typedef debug_validity_phase<Polygon> debug_phase;
typedef typename ring_type<Polygon>::type ring_type;
// check validity of exterior ring
@@ -177,42 +179,50 @@ protected:
};
// structs for partition -- start
template <typename EnvelopeStrategy>
template <typename Strategy>
struct expand_box
{
explicit expand_box(EnvelopeStrategy const& strategy) : m_strategy(strategy) {}
explicit expand_box(Strategy const& strategy)
: m_strategy(strategy)
{}
template <typename Box, typename Iterator>
inline void apply(Box& total, partition_item<Iterator, Box> const& item) const
{
geometry::expand(total, item.get_envelope(m_strategy));
geometry::expand(total,
item.get_envelope(m_strategy),
m_strategy);
}
EnvelopeStrategy const& m_strategy;
Strategy const& m_strategy;
};
template <typename EnvelopeStrategy>
template <typename Strategy>
struct overlaps_box
{
explicit overlaps_box(EnvelopeStrategy const& strategy) : m_strategy(strategy) {}
explicit overlaps_box(Strategy const& strategy)
: m_strategy(strategy)
{}
template <typename Box, typename Iterator>
inline bool apply(Box const& box, partition_item<Iterator, Box> const& item) const
{
return ! geometry::disjoint(item.get_envelope(m_strategy), box);
return ! geometry::disjoint(item.get_envelope(m_strategy),
box,
m_strategy);
}
EnvelopeStrategy const& m_strategy;
Strategy const& m_strategy;
};
template <typename WithinStrategy>
template <typename Strategy>
struct item_visitor_type
{
bool items_overlap;
WithinStrategy const& m_strategy;
Strategy const& m_strategy;
explicit item_visitor_type(WithinStrategy const& strategy)
explicit item_visitor_type(Strategy const& strategy)
: items_overlap(false)
, m_strategy(strategy)
{}
@@ -221,7 +231,7 @@ protected:
inline bool apply(partition_item<Iterator, Box> const& item1,
partition_item<Iterator, Box> const& item2)
{
typedef boost::mpl::vector
typedef util::type_sequence
<
geometry::de9im::static_mask<'T'>,
geometry::de9im::static_mask<'*', 'T'>,
@@ -275,14 +285,6 @@ protected:
}
}
// prepare strategy
typedef typename std::iterator_traits<RingIterator>::value_type inter_ring_type;
typename Strategy::template point_in_geometry_strategy
<
inter_ring_type, ExteriorRing
>::type const in_exterior_strategy
= strategy.template get_point_in_geometry_strategy<inter_ring_type, ExteriorRing>();
signed_size_type ring_index = 0;
for (RingIterator it = rings_first; it != rings_beyond;
++it, ++ring_index)
@@ -290,7 +292,7 @@ protected:
// do not examine interior rings that have turns with the
// exterior ring
if (ring_indices.find(ring_index) == ring_indices.end()
&& ! geometry::covered_by(range::front(*it), exterior_ring, in_exterior_strategy))
&& ! geometry::covered_by(range::front(*it), exterior_ring, strategy))
{
return visitor.template apply<failure_interior_rings_outside>();
}
@@ -318,11 +320,6 @@ protected:
}
}
// prepare strategies
typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
envelope_strategy_type const envelope_strategy
= strategy.get_envelope_strategy();
// call partition to check if interior rings are disjoint from
// each other
item_visitor_type<Strategy> item_visitor(strategy);
@@ -331,8 +328,8 @@ protected:
<
box_type
>::apply(ring_iterators, item_visitor,
expand_box<envelope_strategy_type>(envelope_strategy),
overlaps_box<envelope_strategy_type>(envelope_strategy));
expand_box<Strategy>(strategy),
overlaps_box<Strategy>(strategy));
if (item_visitor.items_overlap)
{
@@ -369,7 +366,7 @@ protected:
}
struct has_holes_inside
{
{
template <typename TurnIterator, typename VisitPolicy, typename Strategy>
static inline bool apply(Polygon const& polygon,
TurnIterator first,
@@ -404,7 +401,11 @@ protected:
<
TurnIterator
>::value_type turn_type;
typedef complement_graph<typename turn_type::point_type> graph;
typedef complement_graph
<
typename turn_type::point_type,
Strategy
> graph;
graph g(geometry::num_interior_rings(polygon) + 1);
for (TurnIterator tit = first; tit != beyond; ++tit)
@@ -445,15 +446,16 @@ public:
return false;
}
if (BOOST_GEOMETRY_CONDITION(CheckRingValidityOnly))
if BOOST_GEOMETRY_CONSTEXPR (CheckRingValidityOnly)
{
return true;
}
// compute turns and check if all are acceptable
typedef debug_validity_phase<Polygon> debug_phase;
debug_phase::apply(3);
typedef has_valid_self_turns<Polygon> has_valid_turns;
typedef has_valid_self_turns<Polygon, typename Strategy::cs_tag> has_valid_turns;
std::deque<typename has_valid_turns::turn_type> turns;
bool has_invalid_turns

View File

@@ -2,7 +2,7 @@
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Copyright (c) 2014-2021, 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
@@ -25,13 +25,12 @@
#include <boost/geometry/util/order_as_direction.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/num_distinct_consecutive_points.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp>
@@ -39,7 +38,11 @@
#include <boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp>
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
#include <boost/geometry/strategies/area.hpp>
// TEMP - with UmberllaStrategy this will be not needed
#include <boost/geometry/strategy/area.hpp>
#include <boost/geometry/strategies/area/services.hpp>
// TODO: use point_order instead of area
#ifdef BOOST_GEOMETRY_TEST_DEBUG
#include <boost/geometry/io/dsv/write.hpp>
@@ -55,11 +58,11 @@ namespace detail { namespace is_valid
// struct to check whether a ring is topologically closed
template <typename Ring, closure_selector Closure /* open */>
template <typename Ring, closure_selector Closure = geometry::closure<Ring>::value>
struct is_topologically_closed
{
template <typename VisitPolicy>
static inline bool apply(Ring const&, VisitPolicy& visitor)
template <typename VisitPolicy, typename Strategy>
static inline bool apply(Ring const&, VisitPolicy& visitor, Strategy const&)
{
boost::ignore_unused(visitor);
@@ -70,12 +73,13 @@ struct is_topologically_closed
template <typename Ring>
struct is_topologically_closed<Ring, closed>
{
template <typename VisitPolicy>
static inline bool apply(Ring const& ring, VisitPolicy& visitor)
template <typename VisitPolicy, typename Strategy>
static inline bool apply(Ring const& ring, VisitPolicy& visitor, Strategy const& strategy)
{
boost::ignore_unused(visitor);
if (geometry::equals(range::front(ring), range::back(ring)))
using geometry::detail::equals::equals_point_point;
if (equals_point_point(range::front(ring), range::back(ring), strategy))
{
return visitor.template apply<no_failure>();
}
@@ -87,21 +91,7 @@ struct is_topologically_closed<Ring, closed>
};
template <typename ResultType, bool IsInteriorRing /* false */>
struct ring_area_predicate
{
typedef std::greater<ResultType> type;
};
template <typename ResultType>
struct ring_area_predicate<ResultType, true>
{
typedef std::less<ResultType> type;
};
// TODO: use calculate_point_order here
template <typename Ring, bool IsInteriorRing>
struct is_properly_oriented
{
@@ -111,28 +101,11 @@ struct is_properly_oriented
{
boost::ignore_unused(visitor);
typedef detail::area::ring_area
<
order_as_direction<geometry::point_order<Ring>::value>::value,
geometry::closure<Ring>::value
> ring_area_type;
typedef typename Strategy::template area_strategy
<
Ring
>::type::template result_type<Ring>::type area_result_type;
typename ring_area_predicate
<
area_result_type, IsInteriorRing
>::type predicate;
// Check area
area_result_type const zero = 0;
area_result_type const area
= ring_area_type::apply(ring,
strategy.template get_area_strategy<Ring>());
if (predicate(area, zero))
auto const area = detail::area::ring_area::apply(ring, strategy);
decltype(area) const zero = 0;
if (IsInteriorRing ? (area < zero) : (area > zero))
{
return visitor.template apply<no_failure>();
}
@@ -176,21 +149,17 @@ struct is_valid_ring
return false;
}
closure_selector const closure = geometry::closure<Ring>::value;
typedef typename closeable_view<Ring const, closure>::type view_type;
if (boost::size(ring)
< core_detail::closure::minimum_ring_size<closure>::value)
if (boost::size(ring) < detail::minimum_ring_size<Ring>::value)
{
return visitor.template apply<failure_few_points>();
}
view_type const view(ring);
detail::closed_view<Ring const> const view(ring);
if (detail::num_distinct_consecutive_points
<
view_type, 4u, true,
not_equal_to<typename point_type<Ring>::type>
>::apply(view)
decltype(view), 4u, true
>::apply(view, strategy)
< 4u)
{
return
@@ -198,11 +167,11 @@ struct is_valid_ring
}
return
is_topologically_closed<Ring, closure>::apply(ring, visitor)
&& ! has_duplicates<Ring, closure>::apply(ring, visitor)
&& ! has_spikes<Ring, closure>::apply(ring, visitor, strategy.get_side_strategy())
is_topologically_closed<Ring>::apply(ring, visitor, strategy)
&& ! has_duplicates<Ring>::apply(ring, visitor, strategy)
&& ! has_spikes<Ring>::apply(ring, visitor, strategy)
&& (! CheckSelfIntersections
|| has_valid_self_turns<Ring>::apply(ring, visitor, strategy))
|| has_valid_self_turns<Ring, typename Strategy::cs_tag>::apply(ring, visitor, strategy))
&& is_properly_oriented<Ring, IsInteriorRing>::apply(ring, visitor, strategy);
}
};

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Copyright (c) 2014-2019, 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
@@ -17,8 +17,8 @@
#include <boost/geometry/core/tags.hpp>
#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/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp>
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
@@ -45,7 +45,7 @@ template <typename Segment>
struct is_valid<Segment, segment_tag>
{
template <typename VisitPolicy, typename Strategy>
static inline bool apply(Segment const& segment, VisitPolicy& visitor, Strategy const&)
static inline bool apply(Segment const& segment, VisitPolicy& visitor, Strategy const& strategy)
{
boost::ignore_unused(visitor);
@@ -60,7 +60,7 @@ struct is_valid<Segment, segment_tag>
{
return false;
}
else if (! geometry::equals(p[0], p[1]))
else if (! detail::equals::equals_point_point(p[0], p[1], strategy))
{
return visitor.template apply<no_failure>();
}