summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/overlay/self_turn_points.hpp')
-rw-r--r--boost/geometry/algorithms/detail/overlay/self_turn_points.hpp151
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);
}