summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/overlay/handle_self_turns.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/overlay/handle_self_turns.hpp')
-rw-r--r--boost/geometry/algorithms/detail/overlay/handle_self_turns.hpp143
1 files changed, 143 insertions, 0 deletions
diff --git a/boost/geometry/algorithms/detail/overlay/handle_self_turns.hpp b/boost/geometry/algorithms/detail/overlay/handle_self_turns.hpp
new file mode 100644
index 0000000000..39c55db759
--- /dev/null
+++ b/boost/geometry/algorithms/detail/overlay/handle_self_turns.hpp
@@ -0,0 +1,143 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2017 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_SELF_TURNS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_SELF_TURNS_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/is_self_turn.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+struct discard_turns
+{
+ template <typename Turns, typename Geometry0, typename Geometry1>
+ static inline
+ void apply(Turns& , Geometry0 const& , Geometry1 const& )
+ {}
+};
+
+template <overlay_type OverlayType, operation_type OperationType>
+struct discard_closed_turns : discard_turns {};
+
+// It is only implemented for operation_union, not in buffer
+template <>
+struct discard_closed_turns<overlay_union, operation_union>
+{
+
+ template <typename Turns, typename Geometry0, typename Geometry1>
+ static inline
+ void apply(Turns& turns,
+ Geometry0 const& geometry0, Geometry1 const& geometry1)
+ {
+ typedef typename boost::range_value<Turns>::type turn_type;
+
+ for (typename boost::range_iterator<Turns>::type
+ it = boost::begin(turns);
+ it != boost::end(turns);
+ ++it)
+ {
+ turn_type& turn = *it;
+
+ if (turn.cluster_id >= 0
+ || turn.discarded
+ || ! is_self_turn<overlay_union>(turn))
+ {
+ continue;
+ }
+
+ bool const within =
+ turn.operations[0].seg_id.source_index == 0
+ ? geometry::within(turn.point, geometry1)
+ : geometry::within(turn.point, geometry0);
+
+ if (within)
+ {
+ // It is in the interior of the other geometry
+ turn.discarded = true;
+ }
+ }
+ }
+};
+
+struct discard_self_intersection_turns
+{
+ template <typename Turns, typename Geometry0, typename Geometry1>
+ static inline
+ void apply(Turns& turns,
+ Geometry0 const& geometry0, Geometry1 const& geometry1)
+ {
+ typedef typename boost::range_value<Turns>::type turn_type;
+
+ for (typename boost::range_iterator<Turns>::type
+ it = boost::begin(turns);
+ it != boost::end(turns);
+ ++it)
+ {
+ turn_type& turn = *it;
+
+ if (turn.cluster_id >= 0
+ || turn.discarded
+ || ! is_self_turn<overlay_intersection>(turn))
+ {
+ continue;
+ }
+
+ segment_identifier const& id0 = turn.operations[0].seg_id;
+ segment_identifier const& id1 = turn.operations[1].seg_id;
+ if (id0.multi_index != id1.multi_index
+ || (id0.ring_index == -1 && id1.ring_index == -1)
+ || (id0.ring_index >= 0 && id1.ring_index >= 0))
+ {
+ // Not an ii ring (int/ext) on same ring
+ continue;
+ }
+
+ // It is a non co-located ii self-turn
+ // Check if it is within the other geometry
+ // If not, it can be ignored
+
+ bool const within =
+ turn.operations[0].seg_id.source_index == 0
+ ? geometry::within(turn.point, geometry1)
+ : geometry::within(turn.point, geometry0);
+
+ if (! within)
+ {
+ // It is not within another geometry, discard the turn
+ turn.discarded = true;
+ }
+ }
+ }
+};
+
+template <overlay_type OverlayType, operation_type OperationType>
+struct discard_open_turns : discard_turns {};
+
+// Handler it for intersection
+template <>
+struct discard_open_turns<overlay_intersection, operation_intersection>
+ : discard_self_intersection_turns {};
+
+// For difference, it should be done in a different way (TODO)
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_SELF_TURNS_HPP