diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/overlay/get_turns.hpp')
-rw-r--r-- | boost/geometry/algorithms/detail/overlay/get_turns.hpp | 422 |
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 |