1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2014-2017, Oracle and/or its affiliates. 4 5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle 7 8 // Licensed under the Boost Software License version 1.0. 9 // http://www.boost.org/users/license.html 10 11 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_VALID_SELF_TURNS_HPP 12 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_VALID_SELF_TURNS_HPP 13 14 #include <vector> 15 16 #include <boost/core/ignore_unused.hpp> 17 #include <boost/range.hpp> 18 19 #include <boost/geometry/core/assert.hpp> 20 #include <boost/geometry/core/point_type.hpp> 21 22 #include <boost/geometry/policies/predicate_based_interrupt_policy.hpp> 23 #include <boost/geometry/policies/robustness/segment_ratio_type.hpp> 24 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp> 25 26 #include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp> 27 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp> 28 #include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp> 29 30 #include <boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp> 31 32 namespace boost { namespace geometry 33 { 34 35 36 #ifndef DOXYGEN_NO_DETAIL 37 namespace detail { namespace is_valid 38 { 39 40 41 template 42 < 43 typename Geometry, 44 typename IsAcceptableTurn = is_acceptable_turn<Geometry> 45 > 46 class has_valid_self_turns 47 { 48 private: 49 typedef typename point_type<Geometry>::type point_type; 50 51 typedef typename geometry::rescale_policy_type 52 < 53 point_type 54 >::type rescale_policy_type; 55 56 typedef detail::overlay::get_turn_info 57 < 58 detail::overlay::assign_null_policy 59 > turn_policy; 60 61 public: 62 typedef detail::overlay::turn_info 63 < 64 point_type, 65 typename geometry::segment_ratio_type 66 < 67 point_type, 68 rescale_policy_type 69 >::type 70 > turn_type; 71 72 // returns true if all turns are valid 73 template <typename Turns, typename VisitPolicy, typename Strategy> apply(Geometry const & geometry,Turns & turns,VisitPolicy & visitor,Strategy const & strategy)74 static inline bool apply(Geometry const& geometry, 75 Turns& turns, 76 VisitPolicy& visitor, 77 Strategy const& strategy) 78 { 79 boost::ignore_unused(visitor); 80 81 rescale_policy_type robust_policy 82 = geometry::get_rescale_policy<rescale_policy_type>(geometry); 83 84 detail::overlay::stateless_predicate_based_interrupt_policy 85 < 86 IsAcceptableTurn 87 > interrupt_policy; 88 89 detail::self_get_turn_points::self_turns<false, turn_policy>(geometry, 90 strategy, 91 robust_policy, 92 turns, 93 interrupt_policy); 94 95 if (interrupt_policy.has_intersections) 96 { 97 BOOST_GEOMETRY_ASSERT(! boost::empty(turns)); 98 return visitor.template apply<failure_self_intersections>(turns); 99 } 100 else 101 { 102 return visitor.template apply<no_failure>(); 103 } 104 } 105 106 // returns true if all turns are valid 107 template <typename VisitPolicy, typename Strategy> apply(Geometry const & geometry,VisitPolicy & visitor,Strategy const & strategy)108 static inline bool apply(Geometry const& geometry, VisitPolicy& visitor, Strategy const& strategy) 109 { 110 std::vector<turn_type> turns; 111 return apply(geometry, turns, visitor, strategy); 112 } 113 }; 114 115 116 }} // namespace detail::is_valid 117 #endif // DOXYGEN_NO_DETAIL 118 119 }} // namespace boost::geometry 120 121 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_HAS_VALID_SELF_TURNS_HPP 122