diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/overlay/self_turn_points.hpp')
-rw-r--r-- | boost/geometry/algorithms/detail/overlay/self_turn_points.hpp | 151 |
1 files changed, 97 insertions, 54 deletions
diff --git a/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp b/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp index 8540ef98a0..5e9d8efa8e 100644 --- a/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp +++ b/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp @@ -1,6 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2017. // Modifications copyright (c) 2017 Oracle and/or its affiliates. @@ -22,12 +23,14 @@ #include <boost/geometry/core/access.hpp> #include <boost/geometry/core/coordinate_dimension.hpp> +#include <boost/geometry/core/point_order.hpp> #include <boost/geometry/core/tags.hpp> #include <boost/geometry/geometries/concepts/check.hpp> #include <boost/geometry/algorithms/detail/disjoint/box_box.hpp> #include <boost/geometry/algorithms/detail/partition.hpp> +#include <boost/geometry/algorithms/detail/overlay/do_reverse.hpp> #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp> #include <boost/geometry/algorithms/detail/sections/section_box_policies.hpp> @@ -57,12 +60,9 @@ struct no_interrupt_policy }; - - -class self_ip_exception : public geometry::exception {}; - template < + bool Reverse, typename Geometry, typename Turns, typename TurnPolicy, @@ -77,17 +77,20 @@ struct self_section_visitor RobustPolicy const& m_rescale_policy; Turns& m_turns; InterruptPolicy& m_interrupt_policy; + std::size_t m_source_index; inline self_section_visitor(Geometry const& g, IntersectionStrategy const& is, RobustPolicy const& rp, Turns& turns, - InterruptPolicy& ip) + InterruptPolicy& ip, + std::size_t source_index) : m_geometry(g) , m_intersection_strategy(is) , m_rescale_policy(rp) , m_turns(turns) , m_interrupt_policy(ip) + , m_source_index(source_index) {} template <typename Section> @@ -97,26 +100,21 @@ struct self_section_visitor && ! sec1.duplicate && ! sec2.duplicate) { - detail::get_turns::get_turns_in_sections + // false if interrupted + return detail::get_turns::get_turns_in_sections < Geometry, Geometry, - false, false, + Reverse, Reverse, Section, Section, TurnPolicy - >::apply( - 0, m_geometry, sec1, - 0, m_geometry, sec2, - false, - m_intersection_strategy, - m_rescale_policy, - m_turns, m_interrupt_policy); - } - if (BOOST_GEOMETRY_CONDITION(m_interrupt_policy.has_intersections)) - { - // TODO: we should give partition an interrupt policy. - // Now we throw, and catch below, to stop the partition loop. - throw self_ip_exception(); + >::apply(m_source_index, m_geometry, sec1, + m_source_index, m_geometry, sec2, + false, + m_intersection_strategy, + m_rescale_policy, + m_turns, m_interrupt_policy); } + return true; } @@ -124,7 +122,7 @@ struct self_section_visitor -template<typename TurnPolicy> +template <bool Reverse, typename TurnPolicy> struct get_turns { template <typename Geometry, typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy> @@ -133,7 +131,8 @@ struct get_turns IntersectionStrategy const& intersection_strategy, RobustPolicy const& robust_policy, Turns& turns, - InterruptPolicy& interrupt_policy) + InterruptPolicy& interrupt_policy, + std::size_t source_index) { typedef model::box < @@ -149,29 +148,24 @@ struct get_turns typedef boost::mpl::vector_c<std::size_t, 0> dimensions; sections_type sec; - geometry::sectionalize<false, dimensions>(geometry, robust_policy, sec); + geometry::sectionalize<Reverse, dimensions>(geometry, robust_policy, sec, + intersection_strategy.get_envelope_strategy()); self_section_visitor < - Geometry, + Reverse, Geometry, Turns, TurnPolicy, IntersectionStrategy, RobustPolicy, InterruptPolicy - > visitor(geometry, intersection_strategy, robust_policy, turns, interrupt_policy); + > visitor(geometry, intersection_strategy, robust_policy, turns, interrupt_policy, source_index); - try - { - geometry::partition - < - box_type - >::apply(sec, visitor, - detail::section::get_section_box(), - detail::section::overlaps_section_box()); - } - catch(self_ip_exception const& ) - { - return false; - } + // false if interrupted + geometry::partition + < + box_type + >::apply(sec, visitor, + detail::section::get_section_box(), + detail::section::overlaps_section_box()); - return true; + return ! interrupt_policy.has_intersections; } }; @@ -186,6 +180,7 @@ namespace dispatch template < + bool Reverse, typename GeometryTag, typename Geometry, typename TurnPolicy @@ -197,26 +192,28 @@ struct self_get_turn_points template < + bool Reverse, typename Ring, typename TurnPolicy > struct self_get_turn_points < - ring_tag, Ring, + Reverse, ring_tag, Ring, TurnPolicy > - : detail::self_get_turn_points::get_turns<TurnPolicy> + : detail::self_get_turn_points::get_turns<Reverse, TurnPolicy> {}; template < + bool Reverse, typename Box, typename TurnPolicy > struct self_get_turn_points < - box_tag, Box, + Reverse, box_tag, Box, TurnPolicy > { @@ -226,7 +223,8 @@ struct self_get_turn_points Strategy const& , RobustPolicy const& , Turns& , - InterruptPolicy& ) + InterruptPolicy& , + std::size_t) { return true; } @@ -235,29 +233,31 @@ struct self_get_turn_points template < + bool Reverse, typename Polygon, typename TurnPolicy > struct self_get_turn_points < - polygon_tag, Polygon, + Reverse, polygon_tag, Polygon, TurnPolicy > - : detail::self_get_turn_points::get_turns<TurnPolicy> + : detail::self_get_turn_points::get_turns<Reverse, TurnPolicy> {}; template < + bool Reverse, typename MultiPolygon, typename TurnPolicy > struct self_get_turn_points < - multi_polygon_tag, MultiPolygon, + Reverse, multi_polygon_tag, MultiPolygon, TurnPolicy > - : detail::self_get_turn_points::get_turns<TurnPolicy> + : detail::self_get_turn_points::get_turns<Reverse, TurnPolicy> {}; @@ -265,6 +265,45 @@ struct self_get_turn_points #endif // DOXYGEN_NO_DISPATCH +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace self_get_turn_points +{ + +// Version where Reverse can be specified manually. TODO: +// can most probably be merged with self_get_turn_points::get_turn +template +< + bool Reverse, + typename AssignPolicy, + typename Geometry, + typename IntersectionStrategy, + typename RobustPolicy, + typename Turns, + typename InterruptPolicy +> +inline void self_turns(Geometry const& geometry, + IntersectionStrategy const& strategy, + RobustPolicy const& robust_policy, + Turns& turns, + InterruptPolicy& interrupt_policy, + std::size_t source_index = 0) +{ + concepts::check<Geometry const>(); + + typedef detail::overlay::get_turn_info<detail::overlay::assign_null_policy> turn_policy; + + dispatch::self_get_turn_points + < + Reverse, + typename tag<Geometry>::type, + Geometry, + turn_policy + >::apply(geometry, strategy, robust_policy, turns, interrupt_policy, source_index); +} + +}} // namespace detail::self_get_turn_points +#endif // DOXYGEN_NO_DETAIL + /*! \brief Calculate self intersections of a geometry \ingroup overlay @@ -290,18 +329,22 @@ template inline void self_turns(Geometry const& geometry, IntersectionStrategy const& strategy, RobustPolicy const& robust_policy, - Turns& turns, InterruptPolicy& interrupt_policy) + Turns& turns, + InterruptPolicy& interrupt_policy, + std::size_t source_index = 0) { concepts::check<Geometry const>(); - typedef detail::overlay::get_turn_info<detail::overlay::assign_null_policy> turn_policy; + static bool const reverse = detail::overlay::do_reverse + < + geometry::point_order<Geometry>::value + >::value; - dispatch::self_get_turn_points + detail::self_get_turn_points::self_turns < - typename tag<Geometry>::type, - Geometry, - turn_policy - >::apply(geometry, strategy, robust_policy, turns, interrupt_policy); + reverse, + AssignPolicy + >(geometry, strategy, robust_policy, turns, interrupt_policy, source_index); } |