1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2017 Barend Gehrels, Amsterdam, the Netherlands. 4 5 // Use, modification and distribution is subject to the Boost Software License, 6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 9 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_SELF_TURNS_HPP 10 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_SELF_TURNS_HPP 11 12 #include <boost/range.hpp> 13 14 #include <boost/geometry/algorithms/detail/overlay/is_self_turn.hpp> 15 #include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp> 16 #include <boost/geometry/algorithms/within.hpp> 17 18 namespace boost { namespace geometry 19 { 20 21 #ifndef DOXYGEN_NO_DETAIL 22 namespace detail { namespace overlay 23 { 24 25 struct discard_turns 26 { 27 template <typename Turns, typename Geometry0, typename Geometry1> 28 static inline applyboost::geometry::detail::overlay::discard_turns29 void apply(Turns& , Geometry0 const& , Geometry1 const& ) 30 {} 31 }; 32 33 template <overlay_type OverlayType, operation_type OperationType> 34 struct discard_closed_turns : discard_turns {}; 35 36 // It is only implemented for operation_union, not in buffer 37 template <> 38 struct discard_closed_turns<overlay_union, operation_union> 39 { 40 41 template <typename Turns, typename Geometry0, typename Geometry1> 42 static inline applyboost::geometry::detail::overlay::discard_closed_turns43 void apply(Turns& turns, 44 Geometry0 const& geometry0, Geometry1 const& geometry1) 45 { 46 typedef typename boost::range_value<Turns>::type turn_type; 47 48 for (typename boost::range_iterator<Turns>::type 49 it = boost::begin(turns); 50 it != boost::end(turns); 51 ++it) 52 { 53 turn_type& turn = *it; 54 55 if (turn.cluster_id >= 0 56 || turn.discarded 57 || ! is_self_turn<overlay_union>(turn)) 58 { 59 continue; 60 } 61 62 bool const within = 63 turn.operations[0].seg_id.source_index == 0 64 ? geometry::within(turn.point, geometry1) 65 : geometry::within(turn.point, geometry0); 66 67 if (within) 68 { 69 // It is in the interior of the other geometry 70 turn.discarded = true; 71 } 72 } 73 } 74 }; 75 76 struct discard_self_intersection_turns 77 { 78 template <typename Turns, typename Geometry0, typename Geometry1> 79 static inline applyboost::geometry::detail::overlay::discard_self_intersection_turns80 void apply(Turns& turns, 81 Geometry0 const& geometry0, Geometry1 const& geometry1) 82 { 83 typedef typename boost::range_value<Turns>::type turn_type; 84 85 for (typename boost::range_iterator<Turns>::type 86 it = boost::begin(turns); 87 it != boost::end(turns); 88 ++it) 89 { 90 turn_type& turn = *it; 91 92 if (turn.cluster_id >= 0 93 || turn.discarded 94 || ! is_self_turn<overlay_intersection>(turn)) 95 { 96 continue; 97 } 98 99 segment_identifier const& id0 = turn.operations[0].seg_id; 100 segment_identifier const& id1 = turn.operations[1].seg_id; 101 if (id0.multi_index != id1.multi_index 102 || (id0.ring_index == -1 && id1.ring_index == -1) 103 || (id0.ring_index >= 0 && id1.ring_index >= 0)) 104 { 105 // Not an ii ring (int/ext) on same ring 106 continue; 107 } 108 109 // It is a non co-located ii self-turn 110 // Check if it is within the other geometry 111 // If not, it can be ignored 112 113 bool const within = 114 turn.operations[0].seg_id.source_index == 0 115 ? geometry::within(turn.point, geometry1) 116 : geometry::within(turn.point, geometry0); 117 118 if (! within) 119 { 120 // It is not within another geometry, discard the turn 121 turn.discarded = true; 122 } 123 } 124 } 125 }; 126 127 template <overlay_type OverlayType, operation_type OperationType> 128 struct discard_open_turns : discard_turns {}; 129 130 // Handler it for intersection 131 template <> 132 struct discard_open_turns<overlay_intersection, operation_intersection> 133 : discard_self_intersection_turns {}; 134 135 // For difference, it should be done in a different way (TODO) 136 137 }} // namespace detail::overlay 138 #endif //DOXYGEN_NO_DETAIL 139 140 141 }} // namespace boost::geometry 142 143 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_SELF_TURNS_HPP 144