summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/overlay/get_turns.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/overlay/get_turns.hpp')
-rw-r--r--boost/geometry/algorithms/detail/overlay/get_turns.hpp422
1 files changed, 295 insertions, 127 deletions
diff --git a/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/boost/geometry/algorithms/detail/overlay/get_turns.hpp
index 26629043cb..a96538c43a 100644
--- a/boost/geometry/algorithms/detail/overlay/get_turns.hpp
+++ b/boost/geometry/algorithms/detail/overlay/get_turns.hpp
@@ -1,11 +1,17 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
// 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)
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
@@ -14,19 +20,17 @@
#include <map>
#include <boost/array.hpp>
+#include <boost/concept_check.hpp>
#include <boost/mpl/if.hpp>
#include <boost/range.hpp>
-#include <boost/typeof/typeof.hpp>
-
-#include <boost/tuple/tuple.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
-#include <boost/geometry/core/reverse_dispatch.hpp>
-
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/reverse_dispatch.hpp>
#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
@@ -44,17 +48,22 @@
#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/strategies/intersection_result.hpp>
-#include <boost/geometry/algorithms/detail/disjoint.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
+#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
+
+#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
-#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
+#include <boost/geometry/algorithms/detail/recalculate.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp>
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
-
#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
+#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
#include <boost/geometry/algorithms/expand.hpp>
-#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
# include <sstream>
@@ -65,6 +74,12 @@
namespace boost { namespace geometry
{
+// Silence warning C4127: conditional expression is constant
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4127)
+#endif
+
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace get_turns
@@ -88,9 +103,7 @@ template
typename Geometry1, typename Geometry2,
bool Reverse1, bool Reverse2,
typename Section1, typename Section2,
- typename Turns,
- typename TurnPolicy,
- typename InterruptPolicy
+ typename TurnPolicy
>
class get_turns_in_sections
{
@@ -138,16 +151,21 @@ class get_turns_in_sections
// About first condition: will be optimized by compiler (static)
// It checks if it is areal (box,ring,(multi)polygon
int const n = int(section.range_count);
+
+ boost::ignore_unused_variable_warning(n);
+ boost::ignore_unused_variable_warning(index1);
+ boost::ignore_unused_variable_warning(index2);
+
return boost::is_same
<
typename tag_cast
<
- typename geometry::point_type<Geometry1>::type,
+ typename geometry::tag<Geometry>::type,
areal_tag
- >::type,
+ >::type,
areal_tag
>::value
- && index1 == 0
+ && index1 == 0
&& index2 >= n - 2
;
}
@@ -155,13 +173,27 @@ class get_turns_in_sections
public :
// Returns true if terminated, false if interrupted
+ template <typename Turns, typename RobustPolicy, typename InterruptPolicy>
static inline bool apply(
int source_id1, Geometry1 const& geometry1, Section1 const& sec1,
int source_id2, Geometry2 const& geometry2, Section2 const& sec2,
bool skip_larger,
+ RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy)
{
+ boost::ignore_unused_variable_warning(interrupt_policy);
+
+ if ((sec1.duplicate && (sec1.count + 1) < sec1.range_count)
+ || (sec2.duplicate && (sec2.count + 1) < sec2.range_count))
+ {
+ // Skip sections containig only duplicates.
+ // They are still important (can indicate non-disjointness)
+ // but they will be found processing adjacent sections.
+ // Do NOT skip if they are the ONLY section
+ return true;
+ }
+
cview_type1 cview1(range_by_section(geometry1, sec1));
cview_type2 cview2(range_by_section(geometry2, sec2));
view_type1 view1(cview1);
@@ -186,7 +218,7 @@ public :
range1_iterator prev1, it1, end1;
get_start_point_iterator(sec1, view1, prev1, it1, end1,
- index1, ndi1, dir1, sec2.bounding_box);
+ index1, ndi1, dir1, sec2.bounding_box, robust_policy);
// We need a circular iterator because it might run through the closing point.
// One circle is actually enough but this one is just convenient.
@@ -197,12 +229,12 @@ public :
// section 2: [--------------]
// section 1: |----|---|---|---|---|
for (prev1 = it1++, next1++;
- it1 != end1 && ! exceeding<0>(dir1, *prev1, sec2.bounding_box);
+ it1 != end1 && ! exceeding<0>(dir1, *prev1, sec2.bounding_box, robust_policy);
++prev1, ++it1, ++index1, ++next1, ++ndi1)
{
ever_circling_iterator<range1_iterator> nd_next1(
begin_range_1, end_range_1, next1, true);
- advance_to_non_duplicate_next(nd_next1, it1, sec1);
+ advance_to_non_duplicate_next(nd_next1, it1, sec1, robust_policy);
int index2 = sec2.begin_index;
int ndi2 = sec2.non_duplicate_index;
@@ -210,12 +242,12 @@ public :
range2_iterator prev2, it2, end2;
get_start_point_iterator(sec2, view2, prev2, it2, end2,
- index2, ndi2, dir2, sec1.bounding_box);
+ index2, ndi2, dir2, sec1.bounding_box, robust_policy);
ever_circling_iterator<range2_iterator> next2(begin_range_2, end_range_2, it2, true);
next2++;
for (prev2 = it2++, next2++;
- it2 != end2 && ! exceeding<0>(dir2, *prev2, sec1.bounding_box);
+ it2 != end2 && ! exceeding<0>(dir2, *prev2, sec1.bounding_box, robust_policy);
++prev2, ++it2, ++index2, ++next2, ++ndi2)
{
bool skip = same_source;
@@ -241,24 +273,28 @@ public :
// Move to the "non duplicate next"
ever_circling_iterator<range2_iterator> nd_next2(
begin_range_2, end_range_2, next2, true);
- advance_to_non_duplicate_next(nd_next2, it2, sec2);
+ advance_to_non_duplicate_next(nd_next2, it2, sec2, robust_policy);
typedef typename boost::range_value<Turns>::type turn_info;
- typedef typename turn_info::point_type ip;
turn_info ti;
- ti.operations[0].seg_id = segment_identifier(source_id1,
- sec1.ring_id.multi_index, sec1.ring_id.ring_index, index1),
- ti.operations[1].seg_id = segment_identifier(source_id2,
- sec2.ring_id.multi_index, sec2.ring_id.ring_index, index2),
-
- ti.operations[0].other_id = ti.operations[1].seg_id;
- ti.operations[1].other_id = ti.operations[0].seg_id;
+ ti.operations[0].seg_id
+ = segment_identifier(source_id1, sec1.ring_id.multi_index,
+ sec1.ring_id.ring_index, index1);
+ ti.operations[1].seg_id
+ = segment_identifier(source_id2, sec2.ring_id.multi_index,
+ sec2.ring_id.ring_index, index2);
std::size_t const size_before = boost::size(turns);
+ bool const is_1_first = sec1.is_non_duplicate_first && index1 == sec1.begin_index;
+ bool const is_1_last = sec1.is_non_duplicate_last && index1+1 >= sec1.end_index;
+ bool const is_2_first = sec2.is_non_duplicate_first && index2 == sec2.begin_index;
+ bool const is_2_last = sec2.is_non_duplicate_last && index2+1 >= sec2.end_index;
+
TurnPolicy::apply(*prev1, *it1, *nd_next1, *prev2, *it2, *nd_next2,
- ti, std::back_inserter(turns));
+ is_1_first, is_1_last, is_2_first, is_2_last,
+ ti, robust_policy, std::back_inserter(turns));
if (InterruptPolicy::enabled)
{
@@ -283,24 +319,34 @@ private :
typedef typename model::referring_segment<point2_type const> segment2_type;
- template <size_t Dim, typename Point, typename Box>
- static inline bool preceding(int dir, Point const& point, Box const& box)
+ template <size_t Dim, typename Point, typename Box, typename RobustPolicy>
+ static inline bool preceding(int dir, Point const& point, Box const& box, RobustPolicy const& robust_policy)
{
- return (dir == 1 && get<Dim>(point) < get<min_corner, Dim>(box))
- || (dir == -1 && get<Dim>(point) > get<max_corner, Dim>(box));
+ typename robust_point_type<Point, RobustPolicy>::type robust_point;
+ geometry::recalculate(robust_point, point, robust_policy);
+ return (dir == 1 && get<Dim>(robust_point) < get<min_corner, Dim>(box))
+ || (dir == -1 && get<Dim>(robust_point) > get<max_corner, Dim>(box));
}
- template <size_t Dim, typename Point, typename Box>
- static inline bool exceeding(int dir, Point const& point, Box const& box)
+ template <size_t Dim, typename Point, typename Box, typename RobustPolicy>
+ static inline bool exceeding(int dir, Point const& point, Box const& box, RobustPolicy const& robust_policy)
{
- return (dir == 1 && get<Dim>(point) > get<max_corner, Dim>(box))
- || (dir == -1 && get<Dim>(point) < get<min_corner, Dim>(box));
+ typename robust_point_type<Point, RobustPolicy>::type robust_point;
+ geometry::recalculate(robust_point, point, robust_policy);
+ return (dir == 1 && get<Dim>(robust_point) > get<max_corner, Dim>(box))
+ || (dir == -1 && get<Dim>(robust_point) < get<min_corner, Dim>(box));
}
- template <typename Iterator, typename RangeIterator, typename Section>
+ template <typename Iterator, typename RangeIterator, typename Section, typename RobustPolicy>
static inline void advance_to_non_duplicate_next(Iterator& next,
- RangeIterator const& it, Section const& section)
+ RangeIterator const& it, Section const& section, RobustPolicy const& robust_policy)
{
+ typedef typename robust_point_type<point1_type, RobustPolicy>::type robust_point_type;
+ robust_point_type robust_point_from_it;
+ robust_point_type robust_point_from_next;
+ geometry::recalculate(robust_point_from_it, *it, robust_policy);
+ geometry::recalculate(robust_point_from_next, *next, robust_policy);
+
// To see where the next segments bend to, in case of touch/intersections
// on end points, we need (in case of degenerate/duplicate points) an extra
// iterator which moves to the REAL next point, so non duplicate.
@@ -311,10 +357,14 @@ private :
// So advance to the "non duplicate next"
// (the check is defensive, to avoid endless loops)
std::size_t check = 0;
- while(! detail::disjoint::disjoint_point_point(*it, *next)
+ while(! detail::disjoint::disjoint_point_point
+ (
+ robust_point_from_it, robust_point_from_next
+ )
&& check++ < section.range_count)
{
next++;
+ geometry::recalculate(robust_point_from_next, *next, robust_policy);
}
}
@@ -322,14 +372,14 @@ private :
// because of the logistics of "index" (the section-iterator automatically
// skips to the begin-point, we loose the index or have to recalculate it)
// So we mimic it here
- template <typename Range, typename Section, typename Box>
+ template <typename Range, typename Section, typename Box, typename RobustPolicy>
static inline void get_start_point_iterator(Section & section,
Range const& range,
typename boost::range_iterator<Range const>::type& it,
typename boost::range_iterator<Range const>::type& prev,
typename boost::range_iterator<Range const>::type& end,
int& index, int& ndi,
- int dir, Box const& other_bounding_box)
+ int dir, Box const& other_bounding_box, RobustPolicy const& robust_policy)
{
it = boost::begin(range) + section.begin_index;
end = boost::begin(range) + section.end_index + 1;
@@ -337,7 +387,7 @@ private :
// Mimic section-iterator:
// Skip to point such that section interects other box
prev = it++;
- for(; it != end && preceding<0>(dir, *it, other_bounding_box);
+ for(; it != end && preceding<0>(dir, *it, other_bounding_box, robust_policy);
prev = it++, index++, ndi++)
{}
// Go back one step because we want to start completely preceding
@@ -369,6 +419,7 @@ template
bool Reverse1, bool Reverse2,
typename Turns,
typename TurnPolicy,
+ typename RobustPolicy,
typename InterruptPolicy
>
struct section_visitor
@@ -377,14 +428,17 @@ struct section_visitor
Geometry1 const& m_geometry1;
int m_source_id2;
Geometry2 const& m_geometry2;
+ RobustPolicy const& m_rescale_policy;
Turns& m_turns;
InterruptPolicy& m_interrupt_policy;
section_visitor(int id1, Geometry1 const& g1,
int id2, Geometry2 const& g2,
+ RobustPolicy const& robust_policy,
Turns& turns, InterruptPolicy& ip)
: m_source_id1(id1), m_geometry1(g1)
, m_source_id2(id2), m_geometry2(g2)
+ , m_rescale_policy(robust_policy)
, m_turns(turns)
, m_interrupt_policy(ip)
{}
@@ -400,13 +454,12 @@ struct section_visitor
Geometry2,
Reverse1, Reverse2,
Section, Section,
- Turns,
- TurnPolicy,
- InterruptPolicy
+ TurnPolicy
>::apply(
m_source_id1, m_geometry1, sec1,
m_source_id2, m_geometry2, sec2,
false,
+ m_rescale_policy,
m_turns, m_interrupt_policy);
}
return true;
@@ -418,37 +471,45 @@ template
<
typename Geometry1, typename Geometry2,
bool Reverse1, bool Reverse2,
- typename Turns,
- typename TurnPolicy,
- typename InterruptPolicy
+ typename TurnPolicy
>
class get_turns_generic
{
public:
+ template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Geometry1 const& geometry1,
int source_id2, Geometry2 const& geometry2,
- Turns& turns, InterruptPolicy& interrupt_policy)
+ RobustPolicy const& robust_policy,
+ Turns& turns,
+ InterruptPolicy& interrupt_policy)
{
// First create monotonic sections...
typedef typename boost::range_value<Turns>::type ip_type;
typedef typename ip_type::point_type point_type;
- typedef model::box<point_type> box_type;
+
+ typedef model::box
+ <
+ typename geometry::robust_point_type
+ <
+ point_type, RobustPolicy
+ >::type
+ > box_type;
typedef typename geometry::sections<box_type, 2> sections_type;
sections_type sec1, sec2;
- geometry::sectionalize<Reverse1>(geometry1, sec1, 0);
- geometry::sectionalize<Reverse2>(geometry2, sec2, 1);
+ geometry::sectionalize<Reverse1>(geometry1, robust_policy, true, sec1, 0);
+ geometry::sectionalize<Reverse2>(geometry2, robust_policy, true, sec2, 1);
// ... and then partition them, intersecting overlapping sections in visitor method
section_visitor
<
Geometry1, Geometry2,
Reverse1, Reverse2,
- Turns, TurnPolicy, InterruptPolicy
- > visitor(source_id1, geometry1, source_id2, geometry2, turns, interrupt_policy);
+ Turns, TurnPolicy, RobustPolicy, InterruptPolicy
+ > visitor(source_id1, geometry1, source_id2, geometry2, robust_policy, turns, interrupt_policy);
geometry::partition
<
@@ -463,13 +524,10 @@ template
<
typename Range, typename Box,
bool ReverseRange, bool ReverseBox,
- typename Turns,
- typename TurnPolicy,
- typename InterruptPolicy
+ typename TurnPolicy
>
struct get_turns_cs
{
- typedef typename boost::range_value<Turns>::type turn_info;
typedef typename geometry::point_type<Range>::type point_type;
typedef typename geometry::point_type<Box>::type box_point_type;
@@ -491,14 +549,16 @@ struct get_turns_cs
>::type iterator_type;
+ template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Range const& range,
int source_id2, Box const& box,
+ RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy,
int multi_index = -1, int ring_index = -1)
{
- if (boost::size(range) <= 1)
+ if ( boost::size(range) <= 1)
{
return;
}
@@ -509,6 +569,8 @@ struct get_turns_cs
cview_type cview(range);
view_type view(cview);
+ typename boost::range_size<view_type>::type segments_count1 = boost::size(view) - 1;
+
iterator_type it = boost::begin(view);
ever_circling_iterator<iterator_type> next(
@@ -557,9 +619,13 @@ struct get_turns_cs
get_turns_with_box(seg_id, source_id2,
*prev, *it, *next,
bp[0], bp[1], bp[2], bp[3],
+ // NOTE: some dummy values could be passed below since this would be called only for Polygons and Boxes
+ index == 0,
+ unsigned(index) == segments_count1,
+ robust_policy,
turns, interrupt_policy);
- // Future performance enhancement:
- // return if told by the interrupt policy
+ // Future performance enhancement:
+ // return if told by the interrupt policy
}
}
}
@@ -585,6 +651,7 @@ private:
else return 0;
}
+ template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void get_turns_with_box(segment_identifier const& seg_id, int source_id2,
// Points from a range:
point_type const& rp0,
@@ -595,34 +662,45 @@ private:
box_point_type const& bp1,
box_point_type const& bp2,
box_point_type const& bp3,
+ bool const is_range_first,
+ bool const is_range_last,
+ RobustPolicy const& robust_policy,
// Output
Turns& turns,
InterruptPolicy& interrupt_policy)
{
+ boost::ignore_unused_variable_warning(interrupt_policy);
+
// Depending on code some relations can be left out
typedef typename boost::range_value<Turns>::type turn_info;
turn_info ti;
ti.operations[0].seg_id = seg_id;
- ti.operations[0].other_id = ti.operations[1].seg_id;
- ti.operations[1].other_id = seg_id;
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 0);
TurnPolicy::apply(rp0, rp1, rp2, bp0, bp1, bp2,
- ti, std::back_inserter(turns));
+ is_range_first, is_range_last,
+ true, false,
+ ti, robust_policy, std::back_inserter(turns));
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 1);
TurnPolicy::apply(rp0, rp1, rp2, bp1, bp2, bp3,
- ti, std::back_inserter(turns));
+ is_range_first, is_range_last,
+ false, false,
+ ti, robust_policy, std::back_inserter(turns));
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 2);
TurnPolicy::apply(rp0, rp1, rp2, bp2, bp3, bp0,
- ti, std::back_inserter(turns));
+ is_range_first, is_range_last,
+ false, false,
+ ti, robust_policy, std::back_inserter(turns));
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 3);
TurnPolicy::apply(rp0, rp1, rp2, bp3, bp0, bp1,
- ti, std::back_inserter(turns));
+ is_range_first, is_range_last,
+ false, true,
+ ti, robust_policy, std::back_inserter(turns));
if (InterruptPolicy::enabled)
{
@@ -638,15 +716,15 @@ template
<
typename Polygon, typename Box,
bool Reverse, bool ReverseBox,
- typename Turns,
- typename TurnPolicy,
- typename InterruptPolicy
+ typename TurnPolicy
>
struct get_turns_polygon_cs
{
+ template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Polygon const& polygon,
int source_id2, Box const& box,
+ RobustPolicy const& robust_policy,
Turns& turns, InterruptPolicy& interrupt_policy,
int multi_index = -1)
{
@@ -656,32 +734,118 @@ struct get_turns_polygon_cs
<
ring_type, Box,
Reverse, ReverseBox,
- Turns,
- TurnPolicy,
- InterruptPolicy
+ TurnPolicy
> intersector_type;
intersector_type::apply(
source_id1, geometry::exterior_ring(polygon),
- source_id2, box, turns, interrupt_policy,
+ source_id2, box,
+ robust_policy,
+ turns, interrupt_policy,
multi_index, -1);
int i = 0;
- typename interior_return_type<Polygon const>::type rings
- = interior_rings(polygon);
- for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings);
- ++it, ++i)
+ typename interior_return_type<Polygon const>::type
+ rings = interior_rings(polygon);
+ for (typename detail::interior_iterator<Polygon const>::type
+ it = boost::begin(rings); it != boost::end(rings); ++it, ++i)
{
intersector_type::apply(
source_id1, *it,
- source_id2, box, turns, interrupt_policy,
+ source_id2, box,
+ robust_policy,
+ turns, interrupt_policy,
multi_index, i);
}
}
};
+
+template
+<
+ typename Multi, typename Box,
+ bool Reverse, bool ReverseBox,
+ typename TurnPolicy
+>
+struct get_turns_multi_polygon_cs
+{
+ template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
+ static inline void apply(
+ int source_id1, Multi const& multi,
+ int source_id2, Box const& box,
+ RobustPolicy const& robust_policy,
+ Turns& turns, InterruptPolicy& interrupt_policy)
+ {
+ typedef typename boost::range_iterator
+ <
+ Multi const
+ >::type iterator_type;
+
+ int i = 0;
+ for (iterator_type it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it, ++i)
+ {
+ // Call its single version
+ get_turns_polygon_cs
+ <
+ typename boost::range_value<Multi>::type, Box,
+ Reverse, ReverseBox,
+ TurnPolicy
+ >::apply(source_id1, *it, source_id2, box,
+ robust_policy, turns, interrupt_policy, i);
+ }
+ }
+};
+
+
+// GET_TURN_INFO_TYPE
+
+template <typename Geometry>
+struct topological_tag_base
+{
+ typedef typename tag_cast<typename tag<Geometry>::type, pointlike_tag, linear_tag, areal_tag>::type type;
+};
+
+template <typename Geometry1, typename Geometry2, typename AssignPolicy,
+ typename Tag1 = typename tag<Geometry1>::type, typename Tag2 = typename tag<Geometry2>::type,
+ typename TagBase1 = typename topological_tag_base<Geometry1>::type, typename TagBase2 = typename topological_tag_base<Geometry2>::type>
+struct get_turn_info_type
+ : overlay::get_turn_info<AssignPolicy>
+{};
+
+template <typename Geometry1, typename Geometry2, typename AssignPolicy, typename Tag1, typename Tag2>
+struct get_turn_info_type<Geometry1, Geometry2, AssignPolicy, Tag1, Tag2, linear_tag, linear_tag>
+ : overlay::get_turn_info_linear_linear<AssignPolicy>
+{};
+
+template <typename Geometry1, typename Geometry2, typename AssignPolicy, typename Tag1, typename Tag2>
+struct get_turn_info_type<Geometry1, Geometry2, AssignPolicy, Tag1, Tag2, linear_tag, areal_tag>
+ : overlay::get_turn_info_linear_areal<AssignPolicy>
+{};
+
+template <typename Geometry1, typename Geometry2, typename SegmentRatio,
+ typename Tag1 = typename tag<Geometry1>::type, typename Tag2 = typename tag<Geometry2>::type,
+ typename TagBase1 = typename topological_tag_base<Geometry1>::type, typename TagBase2 = typename topological_tag_base<Geometry2>::type>
+struct turn_operation_type
+{
+ typedef overlay::turn_operation<SegmentRatio> type;
+};
+
+template <typename Geometry1, typename Geometry2, typename SegmentRatio, typename Tag1, typename Tag2>
+struct turn_operation_type<Geometry1, Geometry2, SegmentRatio, Tag1, Tag2, linear_tag, linear_tag>
+{
+ typedef overlay::turn_operation_linear<SegmentRatio> type;
+};
+
+template <typename Geometry1, typename Geometry2, typename SegmentRatio, typename Tag1, typename Tag2>
+struct turn_operation_type<Geometry1, Geometry2, SegmentRatio, Tag1, Tag2, linear_tag, areal_tag>
+{
+ typedef overlay::turn_operation_linear<SegmentRatio> type;
+};
+
}} // namespace detail::get_turns
#endif // DOXYGEN_NO_DETAIL
@@ -697,18 +861,14 @@ template
typename GeometryTag1, typename GeometryTag2,
typename Geometry1, typename Geometry2,
bool Reverse1, bool Reverse2,
- typename Turns,
- typename TurnPolicy,
- typename InterruptPolicy
+ typename TurnPolicy
>
struct get_turns
: detail::get_turns::get_turns_generic
<
Geometry1, Geometry2,
Reverse1, Reverse2,
- Turns,
- TurnPolicy,
- InterruptPolicy
+ TurnPolicy
>
{};
@@ -717,23 +877,19 @@ template
<
typename Polygon, typename Box,
bool ReversePolygon, bool ReverseBox,
- typename Turns,
- typename TurnPolicy,
- typename InterruptPolicy
+ typename TurnPolicy
>
struct get_turns
<
polygon_tag, box_tag,
Polygon, Box,
ReversePolygon, ReverseBox,
- Turns,
- TurnPolicy,
- InterruptPolicy
+ TurnPolicy
> : detail::get_turns::get_turns_polygon_cs
<
Polygon, Box,
ReversePolygon, ReverseBox,
- Turns, TurnPolicy, InterruptPolicy
+ TurnPolicy
>
{};
@@ -742,22 +898,18 @@ template
<
typename Ring, typename Box,
bool ReverseRing, bool ReverseBox,
- typename Turns,
- typename TurnPolicy,
- typename InterruptPolicy
+ typename TurnPolicy
>
struct get_turns
<
ring_tag, box_tag,
Ring, Box,
ReverseRing, ReverseBox,
- Turns,
- TurnPolicy,
- InterruptPolicy
+ TurnPolicy
> : detail::get_turns::get_turns_cs
<
Ring, Box, ReverseRing, ReverseBox,
- Turns, TurnPolicy, InterruptPolicy
+ TurnPolicy
>
{};
@@ -765,28 +917,52 @@ struct get_turns
template
<
+ typename MultiPolygon,
+ typename Box,
+ bool ReverseMultiPolygon, bool ReverseBox,
+ typename TurnPolicy
+>
+struct get_turns
+ <
+ multi_polygon_tag, box_tag,
+ MultiPolygon, Box,
+ ReverseMultiPolygon, ReverseBox,
+ TurnPolicy
+ >
+ : detail::get_turns::get_turns_multi_polygon_cs
+ <
+ MultiPolygon, Box,
+ ReverseMultiPolygon, ReverseBox,
+ TurnPolicy
+ >
+{};
+
+
+template
+<
typename GeometryTag1, typename GeometryTag2,
typename Geometry1, typename Geometry2,
bool Reverse1, bool Reverse2,
- typename Turns,
- typename TurnPolicy,
- typename InterruptPolicy
+ typename TurnPolicy
>
struct get_turns_reversed
{
+ template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Geometry1 const& g1,
int source_id2, Geometry2 const& g2,
- Turns& turns, InterruptPolicy& interrupt_policy)
+ RobustPolicy const& robust_policy,
+ Turns& turns,
+ InterruptPolicy& interrupt_policy)
{
get_turns
<
GeometryTag2, GeometryTag1,
Geometry2, Geometry1,
Reverse2, Reverse1,
- Turns, TurnPolicy,
- InterruptPolicy
- >::apply(source_id2, g2, source_id1, g1, turns, interrupt_policy);
+ TurnPolicy
+ >::apply(source_id2, g2, source_id1, g1, robust_policy,
+ turns, interrupt_policy);
}
};
@@ -804,6 +980,7 @@ struct get_turns_reversed
\tparam Turns type of turn-container (e.g. vector of "intersection/turn point"'s)
\param geometry1 \param_geometry
\param geometry2 \param_geometry
+\param robust_policy policy to handle robustness issues
\param turns container which will contain turn points
\param interrupt_policy policy determining if process is stopped
when intersection is found
@@ -814,31 +991,20 @@ template
typename AssignPolicy,
typename Geometry1,
typename Geometry2,
+ typename RobustPolicy,
typename Turns,
typename InterruptPolicy
>
inline void get_turns(Geometry1 const& geometry1,
Geometry2 const& geometry2,
+ RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy)
{
concept::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2 const>();
- typedef typename strategy_intersection
- <
- typename cs_tag<Geometry1>::type,
- Geometry1,
- Geometry2,
- typename boost::range_value<Turns>::type
- >::segment_intersection_strategy_type segment_intersection_strategy_type;
-
- typedef detail::overlay::get_turn_info
- <
- typename point_type<Geometry1>::type,
- typename point_type<Geometry2>::type,
- typename boost::range_value<Turns>::type,
- AssignPolicy
- > TurnPolicy;
+ typedef detail::overlay::get_turn_info<AssignPolicy> TurnPolicy;
+ //typedef detail::get_turns::get_turn_info_type<Geometry1, Geometry2, AssignPolicy> TurnPolicy;
boost::mpl::if_c
<
@@ -849,8 +1015,7 @@ inline void get_turns(Geometry1 const& geometry1,
typename tag<Geometry2>::type,
Geometry1, Geometry2,
Reverse1, Reverse2,
- Turns, TurnPolicy,
- InterruptPolicy
+ TurnPolicy
>,
dispatch::get_turns
<
@@ -858,15 +1023,18 @@ inline void get_turns(Geometry1 const& geometry1,
typename tag<Geometry2>::type,
Geometry1, Geometry2,
Reverse1, Reverse2,
- Turns, TurnPolicy,
- InterruptPolicy
+ TurnPolicy
>
>::type::apply(
0, geometry1,
1, geometry2,
+ robust_policy,
turns, interrupt_policy);
}
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
}} // namespace boost::geometry