mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-09 11:12:21 +00:00
[algorithms][is_valid] implement predicate class that determines
whether a polygon or multi-polygon turn is acceptable (code partially moved from algorithms/detail/is_valid/polygon.hpp)
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, 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_IS_ACCEPTABLE_TURN_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_IS_ACCEPTABLE_TURN_HPP
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace is_valid
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
order_selector Order = geometry::point_order<Geometry>::value,
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct acceptable_operation
|
||||
{};
|
||||
|
||||
template <typename Polygon>
|
||||
struct acceptable_operation<Polygon, counterclockwise, polygon_tag>
|
||||
{
|
||||
static const detail::overlay::operation_type value =
|
||||
detail::overlay::operation_union;
|
||||
};
|
||||
|
||||
template <typename Polygon>
|
||||
struct acceptable_operation<Polygon, clockwise, polygon_tag>
|
||||
{
|
||||
static const detail::overlay::operation_type value =
|
||||
detail::overlay::operation_intersection;
|
||||
};
|
||||
|
||||
template <typename MultiPolygon>
|
||||
struct acceptable_operation<MultiPolygon, counterclockwise, multi_polygon_tag>
|
||||
{
|
||||
static const detail::overlay::operation_type value =
|
||||
detail::overlay::operation_intersection;
|
||||
};
|
||||
|
||||
template <typename MultiPolygon>
|
||||
struct acceptable_operation<MultiPolygon, clockwise, multi_polygon_tag>
|
||||
{
|
||||
static const detail::overlay::operation_type value =
|
||||
detail::overlay::operation_union;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct is_acceptable_turn
|
||||
{};
|
||||
|
||||
template <typename Polygon>
|
||||
class is_acceptable_turn<Polygon, polygon_tag>
|
||||
{
|
||||
protected:
|
||||
template <typename Turn, typename Method, typename Operation>
|
||||
static inline bool check_turn(Turn const& turn,
|
||||
Method method,
|
||||
Operation operation)
|
||||
{
|
||||
return turn.method == method
|
||||
&& turn.operations[0].operation == operation
|
||||
&& turn.operations[1].operation == operation;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
template <typename Turn>
|
||||
static inline bool apply(Turn const& turn)
|
||||
{
|
||||
using namespace detail::overlay;
|
||||
|
||||
if ( turn.operations[0].seg_id.ring_index
|
||||
== turn.operations[0].other_id.ring_index )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
operation_type const op = acceptable_operation<Polygon>::value;
|
||||
|
||||
return check_turn(turn, method_touch_interior, op)
|
||||
|| check_turn(turn, method_touch, op)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename MultiPolygon>
|
||||
class is_acceptable_turn<MultiPolygon, multi_polygon_tag>
|
||||
: is_acceptable_turn<typename boost::range_value<MultiPolygon>::type>
|
||||
{
|
||||
private:
|
||||
typedef typename boost::range_value<MultiPolygon>::type polygon;
|
||||
typedef is_acceptable_turn<polygon> base;
|
||||
|
||||
public:
|
||||
template <typename Turn>
|
||||
static inline bool apply(Turn const& turn)
|
||||
{
|
||||
using namespace detail::overlay;
|
||||
|
||||
if ( turn.operations[0].seg_id.multi_index
|
||||
== turn.operations[0].other_id.multi_index )
|
||||
{
|
||||
return base::apply(turn);
|
||||
}
|
||||
|
||||
operation_type const op = acceptable_operation<MultiPolygon>::value;
|
||||
|
||||
return base::check_turn(turn, method_touch_interior, op)
|
||||
|| base::check_turn(turn, method_touch, op)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::is_valid
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_IS_ACCEPTABLE_TURN_HPP
|
||||
Reference in New Issue
Block a user