1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
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)
9 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
10 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
15 #include <boost/mpl/vector_c.hpp>
16 #include <boost/range.hpp>
18 #include <boost/geometry/core/access.hpp>
19 #include <boost/geometry/core/coordinate_dimension.hpp>
20 #include <boost/geometry/core/tags.hpp>
22 #include <boost/geometry/geometries/concepts/check.hpp>
24 #include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
25 #include <boost/geometry/algorithms/detail/partition.hpp>
26 #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
27 #include <boost/geometry/algorithms/detail/sections/section_box_policies.hpp>
29 #include <boost/geometry/geometries/box.hpp>
31 #include <boost/geometry/util/condition.hpp>
34 namespace boost { namespace geometry
37 #ifndef DOXYGEN_NO_DETAIL
38 namespace detail { namespace self_get_turn_points
41 struct no_interrupt_policy
43 static bool const enabled = false;
44 static bool const has_intersections = false;
47 template <typename Range>
48 static inline bool apply(Range const&)
57 class self_ip_exception : public geometry::exception {};
64 typename RobustPolicy,
65 typename InterruptPolicy
67 struct self_section_visitor
69 Geometry const& m_geometry;
70 RobustPolicy const& m_rescale_policy;
72 InterruptPolicy& m_interrupt_policy;
74 inline self_section_visitor(Geometry const& g,
75 RobustPolicy const& rp,
76 Turns& turns, InterruptPolicy& ip)
78 , m_rescale_policy(rp)
80 , m_interrupt_policy(ip)
83 template <typename Section>
84 inline bool apply(Section const& sec1, Section const& sec2)
86 if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box)
90 detail::get_turns::get_turns_in_sections
101 m_turns, m_interrupt_policy);
103 if (BOOST_GEOMETRY_CONDITION(m_interrupt_policy.has_intersections))
105 // TODO: we should give partition an interrupt policy.
106 // Now we throw, and catch below, to stop the partition loop.
107 throw self_ip_exception();
116 template<typename TurnPolicy>
119 template <typename Geometry, typename RobustPolicy, typename Turns, typename InterruptPolicy>
120 static inline bool apply(
121 Geometry const& geometry,
122 RobustPolicy const& robust_policy,
124 InterruptPolicy& interrupt_policy)
128 typename geometry::robust_point_type
130 typename geometry::point_type<Geometry>::type,
135 typedef geometry::sections<box_type, 1> sections_type;
137 typedef boost::mpl::vector_c<std::size_t, 0> dimensions;
140 geometry::sectionalize<false, dimensions>(geometry, robust_policy, sec);
145 Turns, TurnPolicy, RobustPolicy, InterruptPolicy
146 > visitor(geometry, robust_policy, turns, interrupt_policy);
153 detail::section::get_section_box,
154 detail::section::overlaps_section_box
155 >::apply(sec, visitor);
157 catch(self_ip_exception const& )
167 }} // namespace detail::self_get_turn_points
168 #endif // DOXYGEN_NO_DETAIL
171 #ifndef DOXYGEN_NO_DISPATCH
177 typename GeometryTag,
181 struct self_get_turn_points
191 struct self_get_turn_points
196 : detail::self_get_turn_points::get_turns<TurnPolicy>
205 struct self_get_turn_points
211 template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
212 static inline bool apply(
214 RobustPolicy const& ,
228 struct self_get_turn_points
230 polygon_tag, Polygon,
233 : detail::self_get_turn_points::get_turns<TurnPolicy>
239 typename MultiPolygon,
242 struct self_get_turn_points
244 multi_polygon_tag, MultiPolygon,
247 : detail::self_get_turn_points::get_turns<TurnPolicy>
251 } // namespace dispatch
252 #endif // DOXYGEN_NO_DISPATCH
256 \brief Calculate self intersections of a geometry
258 \tparam Geometry geometry type
259 \tparam Turns type of intersection container
260 (e.g. vector of "intersection/turn point"'s)
261 \param geometry geometry
262 \param robust_policy policy to handle robustness issues
263 \param turns container which will contain intersection points
264 \param interrupt_policy policy determining if process is stopped
265 when intersection is found
269 typename AssignPolicy,
271 typename RobustPolicy,
273 typename InterruptPolicy
275 inline void self_turns(Geometry const& geometry,
276 RobustPolicy const& robust_policy,
277 Turns& turns, InterruptPolicy& interrupt_policy)
279 concepts::check<Geometry const>();
281 typedef detail::overlay::get_turn_info<detail::overlay::assign_null_policy> turn_policy;
283 dispatch::self_get_turn_points
285 typename tag<Geometry>::type,
288 >::apply(geometry, robust_policy, turns, interrupt_policy);
293 }} // namespace boost::geometry
295 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP