diff --git a/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp b/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp index c969b8f18..afc24e067 100644 --- a/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include namespace boost { namespace geometry @@ -29,9 +30,21 @@ namespace detail { namespace copy_segments { -template +template struct copy_segment_point_range { + typedef typename closeable_view + < + Range const, + closure::value + >::type cview_type; + + typedef typename reversible_view + < + cview_type const, + Reverse ? iterate_reverse : iterate_forward + >::type rview_type; + static inline bool apply(Range const& range, SegmentIdentifier const& seg_id, bool second, PointOut& point) @@ -52,13 +65,17 @@ struct copy_segment_point_range return false; } - geometry::copy_coordinates(range[index], point); + cview_type cview(range); + rview_type view(cview); + + + geometry::copy_coordinates(*(boost::begin(view) + index), point); return true; } }; -template +template struct copy_segment_point_polygon { static inline bool apply(Polygon const& polygon, @@ -69,6 +86,7 @@ struct copy_segment_point_polygon return copy_segment_point_range < typename geometry::ring_type::type, + Reverse, SegmentIdentifier, PointOut >::apply @@ -126,6 +144,7 @@ template < typename Tag, typename GeometryIn, + bool Reverse, typename SegmentIdentifier, typename PointOut > @@ -139,34 +158,34 @@ struct copy_segment_point }; -template -struct copy_segment_point +template +struct copy_segment_point : detail::copy_segments::copy_segment_point_range < - LineString, SegmentIdentifier, PointOut + LineString, Reverse, SegmentIdentifier, PointOut > {}; -template -struct copy_segment_point +template +struct copy_segment_point : detail::copy_segments::copy_segment_point_range < - Ring, SegmentIdentifier, PointOut + Ring, Reverse, SegmentIdentifier, PointOut > {}; -template -struct copy_segment_point +template +struct copy_segment_point : detail::copy_segments::copy_segment_point_polygon < - Polygon, SegmentIdentifier, PointOut + Polygon, Reverse, SegmentIdentifier, PointOut > {}; -template -struct copy_segment_point +template +struct copy_segment_point : detail::copy_segments::copy_segment_point_box < Box, SegmentIdentifier, PointOut @@ -186,7 +205,7 @@ struct copy_segment_point \brief Helper function, copies a point from a segment \ingroup overlay */ -template +template inline bool copy_segment_point(Geometry const& geometry, SegmentIdentifier const& seg_id, bool second, PointOut& point_out) @@ -197,6 +216,7 @@ inline bool copy_segment_point(Geometry const& geometry, < typename tag::type, Geometry, + Reverse, SegmentIdentifier, PointOut >::apply(geometry, seg_id, second, point_out); @@ -210,8 +230,8 @@ inline bool copy_segment_point(Geometry const& geometry, */ template < - typename Geometry1, - typename Geometry2, + bool Reverse1, bool Reverse2, + typename Geometry1, typename Geometry2, typename SegmentIdentifier, typename PointOut > @@ -228,6 +248,7 @@ inline bool copy_segment_point(Geometry1 const& geometry1, Geometry2 const& geom < typename tag::type, Geometry1, + Reverse1, SegmentIdentifier, PointOut >::apply(geometry1, seg_id, second, point_out); @@ -238,6 +259,7 @@ inline bool copy_segment_point(Geometry1 const& geometry1, Geometry2 const& geom < typename tag::type, Geometry2, + Reverse2, SegmentIdentifier, PointOut >::apply(geometry2, seg_id, second, point_out); @@ -254,8 +276,8 @@ inline bool copy_segment_point(Geometry1 const& geometry1, Geometry2 const& geom */ template < - typename Geometry1, - typename Geometry2, + bool Reverse1, bool Reverse2, + typename Geometry1, typename Geometry2, typename SegmentIdentifier, typename PointOut > @@ -266,8 +288,8 @@ inline bool copy_segment_points(Geometry1 const& geometry1, Geometry2 const& geo concept::check(); concept::check(); - return copy_segment_point(geometry1, geometry2, seg_id, false, point1) - && copy_segment_point(geometry1, geometry2, seg_id, true, point2); + return copy_segment_point(geometry1, geometry2, seg_id, false, point1) + && copy_segment_point(geometry1, geometry2, seg_id, true, point2); } diff --git a/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp b/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp index a48bf715d..9e3ca398d 100644 --- a/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp @@ -79,8 +79,8 @@ template < typename TurnPoints, typename Indexed, - typename Geometry1, - typename Geometry2, + typename Geometry1, typename Geometry2, + bool Reverse1, bool Reverse2, typename Strategy > struct sort_on_segment_and_distance @@ -112,13 +112,13 @@ private : typedef typename geometry::point_type::type point_type; point_type pi, pj, ri, rj, si, sj; - geometry::copy_segment_points(m_geometry1, m_geometry2, + geometry::copy_segment_points(m_geometry1, m_geometry2, left.subject.seg_id, pi, pj); - geometry::copy_segment_points(m_geometry1, m_geometry2, + geometry::copy_segment_points(m_geometry1, m_geometry2, left.subject.other_id, ri, rj); - geometry::copy_segment_points(m_geometry1, m_geometry2, + geometry::copy_segment_points(m_geometry1, m_geometry2, right.subject.other_id, si, sj); @@ -196,10 +196,10 @@ inline void update_discarded(Turns& turn_points, Operations& operations) template < typename IndexType, + bool Reverse1, bool Reverse2, typename Container, typename TurnPoints, - typename Geometry1, - typename Geometry2, + typename Geometry1, typename Geometry2, typename Strategy > inline void enrich_sort(Container& operations, @@ -218,6 +218,7 @@ inline void enrich_sort(Container& operations, TurnPoints, IndexType, Geometry1, Geometry2, + Reverse1, Reverse2, Strategy >(turn_points, geometry1, geometry2, strategy, clustered)); @@ -252,14 +253,14 @@ inline void enrich_sort(Container& operations, } else if (begin_cluster != boost::end(operations)) { - handle_cluster(begin_cluster, it, turn_points, + handle_cluster(begin_cluster, it, turn_points, for_operation, geometry1, geometry2, strategy); begin_cluster = boost::end(operations); } } if (begin_cluster != boost::end(operations)) { - handle_cluster(begin_cluster, it, turn_points, + handle_cluster(begin_cluster, it, turn_points, for_operation, geometry1, geometry2, strategy); } } @@ -429,9 +430,9 @@ inline void create_map(TurnPoints const& turn_points, MappedVector& mapped_vecto */ template < + bool Reverse1, bool Reverse2, typename TurnPoints, - typename Geometry1, - typename Geometry2, + typename Geometry1, typename Geometry2, typename Strategy > inline void enrich_intersection_points(TurnPoints& turn_points, @@ -486,7 +487,7 @@ inline void enrich_intersection_points(TurnPoints& turn_points, std::cout << "ENRICH-sort Ring " << mit->first << std::endl; #endif - detail::overlay::enrich_sort(mit->second, turn_points, for_operation, + detail::overlay::enrich_sort(mit->second, turn_points, for_operation, geometry1, geometry2, strategy); } diff --git a/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp b/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp index 8e3f883cc..c58d54105 100644 --- a/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp @@ -27,8 +27,8 @@ template < typename TurnPoints, typename Indexed, - typename Geometry1, - typename Geometry2, + typename Geometry1, typename Geometry2, + bool Reverse1, bool Reverse2, typename Strategy > struct sort_in_cluster @@ -101,13 +101,13 @@ private : #ifdef BOOST_GEOMETRY_DEBUG_ENRICH point_type pi, pj, ri, rj, si, sj; - geometry::copy_segment_points(m_geometry1, m_geometry2, + geometry::copy_segment_points(m_geometry1, m_geometry2, left.subject.seg_id, pi, pj); - geometry::copy_segment_points(m_geometry1, m_geometry2, + geometry::copy_segment_points(m_geometry1, m_geometry2, left.subject.other_id, ri, rj); - geometry::copy_segment_points(m_geometry1, m_geometry2, + geometry::copy_segment_points(m_geometry1, m_geometry2, right.subject.other_id, si, sj); @@ -121,8 +121,8 @@ private : int const side_si_r = m_strategy.apply(ri, rj, si); int const side_sj_r = m_strategy.apply(ri, rj, sj); -#ifdef BOOST_GEOMETRY_DEBUG_ENRICH std::cout << "Case: " << header << " for " << left.index << " / " << right.index << std::endl; +#ifdef BOOST_GEOMETRY_DEBUG_ENRICH_MORE std::cout << " Segment p:" << geometry::wkt(pi) << " .. " << geometry::wkt(pj) << std::endl; std::cout << " Segment r:" << geometry::wkt(ri) << " .. " << geometry::wkt(rj) << std::endl; std::cout << " Segment s:" << geometry::wkt(si) << " .. " << geometry::wkt(sj) << std::endl; @@ -174,9 +174,9 @@ private : } else { -#ifdef BOOST_GEOMETRY_DEBUG_ENRICH +//#ifdef BOOST_GEOMETRY_DEBUG_ENRICH std::cout << "ux/ux unhandled" << std::endl; -#endif +//#endif } //debug_consider(0, left, right, header, false, "-> return ", ret); @@ -217,9 +217,9 @@ private : } else { -#ifdef BOOST_GEOMETRY_DEBUG_ENRICH +//#ifdef BOOST_GEOMETRY_DEBUG_ENRICH std::cout << " iu/ux unhandled" << std::endl; -#endif +//#endif ret = order == 1; } @@ -263,13 +263,13 @@ private : } point_type pi, pj, ri, rj, si, sj; - geometry::copy_segment_points(m_geometry1, m_geometry2, + geometry::copy_segment_points(m_geometry1, m_geometry2, left.subject.seg_id, pi, pj); - geometry::copy_segment_points(m_geometry1, m_geometry2, + geometry::copy_segment_points(m_geometry1, m_geometry2, left.subject.other_id, ri, rj); - geometry::copy_segment_points(m_geometry1, m_geometry2, + geometry::copy_segment_points(m_geometry1, m_geometry2, right.subject.other_id, si, sj); @@ -301,9 +301,9 @@ private : debug_consider(0, left, right, header, false, "opp.", ret); return ret; } -#ifdef BOOST_GEOMETRY_DEBUG_ENRICH +//#ifdef BOOST_GEOMETRY_DEBUG_ENRICH std::cout << " iu/iu coming from opposite unhandled" << std::endl; -#endif +//#endif } // We need EXTRA information here: are p/r/s overlapping? @@ -369,13 +369,13 @@ private : debug_consider(0, left, right, header); point_type pi, pj, ri, rj, si, sj; - geometry::copy_segment_points(m_geometry1, m_geometry2, + geometry::copy_segment_points(m_geometry1, m_geometry2, left.subject.seg_id, pi, pj); - geometry::copy_segment_points(m_geometry1, m_geometry2, + geometry::copy_segment_points(m_geometry1, m_geometry2, left.subject.other_id, ri, rj); - geometry::copy_segment_points(m_geometry1, m_geometry2, + geometry::copy_segment_points(m_geometry1, m_geometry2, right.subject.other_id, si, sj); @@ -482,7 +482,8 @@ public : << operation_char(m_turn_points[left.index].operations[1].operation) << "/" << operation_char(m_turn_points[right.index].operations[0].operation) << operation_char(m_turn_points[right.index].operations[1].operation) - << " " << " Take " << left.index << " < " << right.index; + << " " << " Take " << left.index << " < " << right.index + << std::cout; #endif return default_order; @@ -586,6 +587,7 @@ inline void inspect_cluster(Iterator begin_cluster, Iterator end_cluster, template < typename IndexType, + bool Reverse1, bool Reverse2, typename Iterator, typename TurnPoints, typename Geometry1, @@ -610,6 +612,7 @@ inline void handle_cluster(Iterator begin_cluster, Iterator end_cluster, TurnPoints, IndexType, Geometry1, Geometry2, + Reverse1, Reverse2, Strategy >(turn_points, geometry1, geometry2, strategy)); diff --git a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp index bb81b979f..caba0a4d2 100644 --- a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp @@ -109,7 +109,7 @@ std::cout << "get turns" << std::endl; std::cout << "enrich" << std::endl; #endif typename Strategy::side_strategy_type side_strategy; - geometry::enrich_intersection_points(turn_points, + geometry::enrich_intersection_points(turn_points, Direction == -1 ? boost::geometry::detail::overlay::operation_intersection : boost::geometry::detail::overlay::operation_union, diff --git a/include/boost/geometry/algorithms/dissolve.hpp b/include/boost/geometry/algorithms/dissolve.hpp index 6e97257d5..635c50a10 100644 --- a/include/boost/geometry/algorithms/dissolve.hpp +++ b/include/boost/geometry/algorithms/dissolve.hpp @@ -76,7 +76,7 @@ struct dissolve_ring_or_polygon typename cs_tag::type >::type side_strategy_type; - enrich_intersection_points(turns, + enrich_intersection_points(turns, detail::overlay::operation_union, geometry, geometry, side_strategy_type()); @@ -89,7 +89,7 @@ struct dissolve_ring_or_polygon clear_visit_info(turns); - enrich_intersection_points(turns, + enrich_intersection_points(turns, detail::overlay::operation_intersection, geometry, geometry, side_strategy_type()); diff --git a/include/boost/geometry/algorithms/intersection.hpp b/include/boost/geometry/algorithms/intersection.hpp index c4f287362..2a289ddd7 100644 --- a/include/boost/geometry/algorithms/intersection.hpp +++ b/include/boost/geometry/algorithms/intersection.hpp @@ -352,8 +352,8 @@ inline OutputIterator inserter(Geometry1 const& geometry1, geometry::is_areal::value, geometry::is_areal::value, Geometry1, Geometry2, - overlay::do_reverse::value, Reverse1>::value, - overlay::do_reverse::value, Reverse2>::value, + overlay::do_reverse::value, Reverse1>::value, + overlay::do_reverse::value, Reverse2>::value, ReverseOut, OutputIterator, GeometryOut, Strategy @@ -370,8 +370,8 @@ inline OutputIterator inserter(Geometry1 const& geometry1, geometry::is_areal::value, geometry::is_areal::value, Geometry1, Geometry2, - overlay::do_reverse::value, Reverse1>::value, - overlay::do_reverse::value, Reverse2>::value, + overlay::do_reverse::value, Reverse1>::value, + overlay::do_reverse::value, Reverse2>::value, ReverseOut, OutputIterator, GeometryOut, Strategy diff --git a/include/boost/geometry/algorithms/union.hpp b/include/boost/geometry/algorithms/union.hpp index fc1fe8610..e730e5056 100644 --- a/include/boost/geometry/algorithms/union.hpp +++ b/include/boost/geometry/algorithms/union.hpp @@ -134,8 +134,8 @@ inline OutputIterator inserter(Geometry1 const& geometry1, geometry::is_areal::value, geometry::is_areal::value, Geometry1, Geometry2, - overlay::do_reverse::value, Reverse1>::value, - overlay::do_reverse::value, Reverse2>::value, + overlay::do_reverse::value, Reverse1>::value, + overlay::do_reverse::value, Reverse2>::value, ReverseOut, OutputIterator, GeometryOut, Strategy @@ -149,8 +149,8 @@ inline OutputIterator inserter(Geometry1 const& geometry1, geometry::is_areal::value, geometry::is_areal::value, Geometry1, Geometry2, - overlay::do_reverse::value, Reverse1>::value, - overlay::do_reverse::value, Reverse2>::value, + overlay::do_reverse::value, Reverse1>::value, + overlay::do_reverse::value, Reverse2>::value, ReverseOut, OutputIterator, GeometryOut, Strategy diff --git a/include/boost/geometry/core/point_order.hpp b/include/boost/geometry/core/point_order.hpp index e0564a083..0d0d9be0b 100644 --- a/include/boost/geometry/core/point_order.hpp +++ b/include/boost/geometry/core/point_order.hpp @@ -9,6 +9,7 @@ #define BOOST_GEOMETRY_CORE_POINT_ORDER_HPP +#include #include #include @@ -43,6 +44,21 @@ struct point_order } // namespace traits +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace point_order +{ + +struct clockwise +{ + static const order_selector value = geometry::clockwise; +}; + + +}} // namespace detail::point_order +#endif // DOXYGEN_NO_DETAIL + + + #ifndef DOXYGEN_NO_DISPATCH namespace core_dispatch { @@ -50,9 +66,29 @@ namespace core_dispatch template struct point_order { - static const order_selector value = clockwise; + BOOST_MPL_ASSERT_MSG + ( + false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE + , (types) + ); }; +template +struct point_order + : public detail::point_order::clockwise {}; + +template +struct point_order + : public detail::point_order::clockwise {}; + + +template +struct point_order + : public detail::point_order::clockwise {}; + +template +struct point_order + : public detail::point_order::clockwise {}; template diff --git a/include/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp b/include/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp index cf1d14c46..30dd0a5e1 100644 --- a/include/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp +++ b/include/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp @@ -62,6 +62,7 @@ namespace dispatch template < typename MultiGeometry, + bool Reverse, typename SegmentIdentifier, typename PointOut > @@ -69,6 +70,7 @@ struct copy_segment_point < multi_polygon_tag, MultiGeometry, + Reverse, SegmentIdentifier, PointOut > @@ -80,6 +82,7 @@ struct copy_segment_point detail::copy_segments::copy_segment_point_polygon < typename boost::range_value::type, + Reverse, SegmentIdentifier, PointOut > diff --git a/include/boost/geometry/multi/core/point_order.hpp b/include/boost/geometry/multi/core/point_order.hpp index 7a051422a..6695948cc 100644 --- a/include/boost/geometry/multi/core/point_order.hpp +++ b/include/boost/geometry/multi/core/point_order.hpp @@ -23,6 +23,15 @@ namespace boost { namespace geometry namespace core_dispatch { +template +struct point_order + : public detail::point_order::clockwise {}; + +template +struct point_order + : public detail::point_order::clockwise {}; + + // Specialization for multi_polygon: the order is the order of its polygons template struct point_order