123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- // 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
- // 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 Ring>
- struct is_acceptable_turn<Ring, ring_tag>
- {
- template <typename Turn>
- static inline bool apply(Turn const&)
- {
- return false;
- }
- };
- 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[1].seg_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[1].seg_id.multi_index )
- {
- return base::apply(turn);
- }
- operation_type const op = acceptable_operation<MultiPolygon>::value;
- if ( base::check_turn(turn, method_touch_interior, op)
- || base::check_turn(turn, method_touch, op))
- {
- return true;
- }
- // Turn is acceptable only in case of a touch(interior) and both lines
- // (polygons) do not cross
- return (turn.method == method_touch
- || turn.method == method_touch_interior)
- && turn.touch_only;
- }
- };
- }} // namespace detail::is_valid
- #endif // DOXYGEN_NO_DETAIL
- }} // namespace boost::geometry
- #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_IS_ACCEPTABLE_TURN_HPP
|