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 962c68be69..350fc284d1 100644 --- a/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp @@ -487,7 +487,7 @@ inline void enrich_intersection_points(Turns& turns, Reverse2, OverlayType >(clusters, turns, target_operation, - geometry1, geometry2, strategy.side()); // TODO: pass strategy + geometry1, geometry2, strategy); detail::overlay::cleanup_clusters(turns, clusters); } diff --git a/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp b/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp index b41697477d..bb1618ab3e 100644 --- a/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp @@ -427,12 +427,12 @@ template typename Clusters, typename Geometry1, typename Geometry2, - typename SideStrategy + typename Strategy > inline void gather_cluster_properties(Clusters& clusters, Turns& turns, operation_type for_operation, Geometry1 const& geometry1, Geometry2 const& geometry2, - SideStrategy const& strategy) + Strategy const& strategy) { typedef typename boost::range_value::type turn_type; typedef typename turn_type::point_type point_type; @@ -442,7 +442,7 @@ inline void gather_cluster_properties(Clusters& clusters, Turns& turns, // right side typedef sort_by_side::side_sorter < - Reverse1, Reverse2, OverlayType, point_type, SideStrategy, std::less + Reverse1, Reverse2, OverlayType, point_type, Strategy, std::less > sbs_type; for (auto& pair : clusters) diff --git a/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp b/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp index 7e31a9fa9d..dddb810a08 100644 --- a/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp @@ -39,35 +39,22 @@ namespace boost { namespace geometry namespace detail { namespace overlay { namespace sort_by_side { +// From means: from intersecting-segment-begin-point to cluster +// To means: from cluster to intersecting-segment-end-point enum direction_type { dir_unknown = -1, dir_from = 0, dir_to = 1 }; -typedef signed_size_type rank_type; - +using rank_type = signed_size_type; // Point-wrapper, adding some properties template struct ranked_point { - ranked_point() - : rank(0) - , turn_index(-1) - , operation_index(-1) - , direction(dir_unknown) - , count_left(0) - , count_right(0) - , operation(operation_none) - {} - ranked_point(Point const& p, signed_size_type ti, int oi, direction_type d, operation_type op, segment_identifier const& si) : point(p) - , rank(0) - , zone(-1) , turn_index(ti) , operation_index(oi) , direction(d) - , count_left(0) - , count_right(0) , operation(op) , seg_id(si) {} @@ -75,14 +62,19 @@ struct ranked_point using point_type = Point; Point point; - rank_type rank; - signed_size_type zone; // index of closed zone, in uu turn there would be 2 zones - signed_size_type turn_index; - int operation_index; // 0,1 - direction_type direction; - std::size_t count_left; - std::size_t count_right; - operation_type operation; + rank_type rank{0}; + signed_size_type zone{-1}; // index of closed zone, in uu turn there would be 2 zones + signed_size_type turn_index{-1}; + int operation_index{-1}; // 0,1 + direction_type direction{dir_unknown}; + + // The number of polygons on the left side + std::size_t count_left{0}; + + // The number of polygons on the right side + std::size_t count_right{0}; + + operation_type operation{operation_none}; segment_identifier seg_id; }; @@ -91,10 +83,8 @@ struct less_by_turn_index template inline bool operator()(T const& first, T const& second) const { - return first.turn_index == second.turn_index - ? first.index < second.index - : first.turn_index < second.turn_index - ; + return std::tie(first.turn_index, first.index) + < std::tie(second.turn_index, second.index); } }; @@ -103,20 +93,13 @@ struct less_by_index template inline bool operator()(T const& first, T const& second) const { - // Length might be considered too - // First order by from/to - if (first.direction != second.direction) - { - return first.direction < second.direction; - } + // First order by direction (from/to) // Then by turn index - if (first.turn_index != second.turn_index) - { - return first.turn_index < second.turn_index; - } // This can also be the same (for example in buffer), but seg_id is // never the same - return first.seg_id < second.seg_id; + // (Length might be considered too) + return std::tie(first.direction, first.turn_index, first.seg_id) + < std::tie(second.direction, second.turn_index, second.seg_id); } }; @@ -129,10 +112,10 @@ struct less_false } }; -template +template struct less_by_side { - less_by_side(PointOrigin const& p1, PointTurn const& p2, SideStrategy const& strategy) + less_by_side(PointOrigin const& p1, PointTurn const& p2, Strategy const& strategy) : m_origin(p1) , m_turn_point(p2) , m_strategy(strategy) @@ -141,13 +124,14 @@ struct less_by_side template inline bool operator()(T const& first, T const& second) const { - typedef typename SideStrategy::cs_tag cs_tag; + using cs_tag = typename Strategy::cs_tag; LessOnSame on_same; Compare compare; - int const side_first = m_strategy.apply(m_origin, m_turn_point, first.point); - int const side_second = m_strategy.apply(m_origin, m_turn_point, second.point); + auto const side_strategy = m_strategy.side(); + int const side_first = side_strategy.apply(m_origin, m_turn_point, first.point); + int const side_second = side_strategy.apply(m_origin, m_turn_point, second.point); if (side_first == 0 && side_second == 0) { @@ -187,14 +171,14 @@ struct less_by_side // They are both left, both right, and/or both collinear (with each other and/or with p1,p2) // Check mutual side - int const side_second_wrt_first = m_strategy.apply(m_turn_point, first.point, second.point); + int const side_second_wrt_first = side_strategy.apply(m_turn_point, first.point, second.point); if (side_second_wrt_first == 0) { return on_same(first, second); } - int const side_first_wrt_second = m_strategy.apply(m_turn_point, second.point, first.point); + int const side_first_wrt_second = side_strategy.apply(m_turn_point, second.point, first.point); if (side_second_wrt_first != -side_first_wrt_second) { // (FP) accuracy error in side calculation, the sides are not opposite. @@ -213,22 +197,28 @@ struct less_by_side private : PointOrigin const& m_origin; PointTurn const& m_turn_point; - SideStrategy const& m_strategy; + + // Umbrella strategy containing side strategy + Strategy const& m_strategy; }; // Sorts vectors in counter clockwise order (by default) +// Purposes: +// - from one entry vector, find the next exit vector +// - find the open counts +// - find zones template < bool Reverse1, bool Reverse2, overlay_type OverlayType, typename Point, - typename SideStrategy, + typename Strategy, typename Compare > struct side_sorter { - typedef ranked_point rp; + using rp = ranked_point; private : struct include_union @@ -254,7 +244,7 @@ private : }; public : - side_sorter(SideStrategy const& strategy) + side_sorter(Strategy const& strategy) : m_origin_count(0) , m_origin_segment_distance(0) , m_strategy(strategy) @@ -289,6 +279,17 @@ public : Point const& point_from, Point const& point_to, Operation const& op, bool is_origin) { + // The segment is added in two parts (sub-segment). + // In picture: + // + // from -----> * -----> to + // + // where * means: cluster point (intersection point) + // from means: start point of original segment + // to means: end point of original segment + // So from/to is from the perspective of the segment. + // From the perspective of the cluster, it is the other way round + // (from means: from-segment-to-cluster, to means: from-cluster-to-segment) add_segment_from(turn_index, op_index, point_from, op, is_origin); add_segment_to(turn_index, op_index, point_to, op); } @@ -356,7 +357,7 @@ public : Geometry2 const& geometry2, bool is_departure) { - Point potential_origin = add(turn, op, turn_index, op_index, geometry1, geometry2, false); + auto const potential_origin = add(turn, op, turn_index, op_index, geometry1, geometry2, false); if (is_departure) { @@ -392,8 +393,8 @@ public : // to give colinear points // Sort by side and assign rank - less_by_side less_unique(m_origin, turn_point, m_strategy); - less_by_side less_non_unique(m_origin, turn_point, m_strategy); + less_by_side less_unique(m_origin, turn_point, m_strategy); + less_by_side less_non_unique(m_origin, turn_point, m_strategy); std::sort(m_ranked_points.begin(), m_ranked_points.end(), less_unique); @@ -512,12 +513,14 @@ public : //private : - typedef std::vector container_type; + using container_type = std::vector; container_type m_ranked_points; Point m_origin; std::size_t m_origin_count; signed_size_type m_origin_segment_distance; - SideStrategy m_strategy; + + // Umbrella strategy containing side strategy + Strategy m_strategy; private : @@ -724,13 +727,13 @@ struct side_compare {}; template <> struct side_compare { - typedef std::greater type; + using type = std::greater; }; template <> struct side_compare { - typedef std::less type; + using type = std::less; }; diff --git a/include/boost/geometry/algorithms/detail/overlay/traversal.hpp b/include/boost/geometry/algorithms/detail/overlay/traversal.hpp index 82cfb86a83..b5a5d2eae4 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traversal.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traversal.hpp @@ -84,7 +84,7 @@ template typename Turns, typename Clusters, typename RobustPolicy, - typename SideStrategy, + typename Strategy, typename Visitor > struct traversal @@ -101,13 +101,13 @@ private : typedef sort_by_side::side_sorter < Reverse1, Reverse2, OverlayType, - point_type, SideStrategy, side_compare_type + point_type, Strategy, side_compare_type > sbs_type; public : inline traversal(Geometry1 const& geometry1, Geometry2 const& geometry2, Turns& turns, Clusters const& clusters, - RobustPolicy const& robust_policy, SideStrategy const& strategy, + RobustPolicy const& robust_policy, Strategy const& strategy, Visitor& visitor) : m_geometry1(geometry1) , m_geometry2(geometry2) @@ -656,7 +656,7 @@ public : int current_priority = 0; for (std::size_t i = 1; i < sbs.m_ranked_points.size(); i++) { - typename sbs_type::rp const& ranked_point = sbs.m_ranked_points[i]; + auto const& ranked_point = sbs.m_ranked_points[i]; if (ranked_point.rank > selected_rank) { @@ -1037,7 +1037,7 @@ private : Turns& m_turns; Clusters const& m_clusters; RobustPolicy const& m_robust_policy; - SideStrategy m_strategy; + Strategy m_strategy; Visitor& m_visitor; }; diff --git a/include/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp b/include/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp index 692de7345a..e3ee6bb23b 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp @@ -56,7 +56,7 @@ struct traversal_ring_creator Reverse1, Reverse2, OverlayType, Geometry1, Geometry2, Turns, Clusters, RobustPolicy, - decltype(std::declval().side()), + Strategy, Visitor > traversal_type; @@ -72,7 +72,7 @@ struct traversal_ring_creator Strategy const& strategy, RobustPolicy const& robust_policy, Visitor& visitor) : m_trav(geometry1, geometry2, turns, clusters, - robust_policy, strategy.side(), visitor) + robust_policy, strategy, visitor) , m_geometry1(geometry1) , m_geometry2(geometry2) , m_turns(turns) diff --git a/test/algorithms/overlay/copy_segment_point.cpp b/test/algorithms/overlay/copy_segment_point.cpp index 33c3f9536d..5a85c2080b 100644 --- a/test/algorithms/overlay/copy_segment_point.cpp +++ b/test/algorithms/overlay/copy_segment_point.cpp @@ -9,7 +9,7 @@ #include -#include +#include #include #include diff --git a/test/algorithms/overlay/sort_by_side.cpp b/test/algorithms/overlay/sort_by_side.cpp index 5776d70404..389588b528 100644 --- a/test/algorithms/overlay/sort_by_side.cpp +++ b/test/algorithms/overlay/sort_by_side.cpp @@ -51,13 +51,13 @@ template typename Turns, typename Geometry1, typename Geometry2, - typename SideStrategy + typename Strategy > std::vector gather_cluster_properties( Clusters& clusters, Turns& turns, bg::detail::overlay::operation_type for_operation, Geometry1 const& geometry1, Geometry2 const& geometry2, - SideStrategy const& strategy) + Strategy const& strategy) { using namespace boost::geometry; using namespace boost::geometry::detail::overlay; @@ -72,7 +72,7 @@ std::vector gather_cluster_properties( // right side typedef sort_by_side::side_sorter < - Reverse1, Reverse2, OverlayType, point_type, SideStrategy, std::less + Reverse1, Reverse2, OverlayType, point_type, Strategy, std::less > sbs_type; for (typename Clusters::iterator mit = clusters.begin(); @@ -165,7 +165,7 @@ std::vector apply_overlay( // Gather cluster properties, with test option return ::gather_cluster_properties( clusters, turns, bg::detail::overlay::operation_from_overlay::value, - geometry1, geometry2, strategy.side()); + geometry1, geometry2, strategy); } diff --git a/test/algorithms/overlay/sort_by_side_basic.cpp b/test/algorithms/overlay/sort_by_side_basic.cpp index 4ce87c7248..dc863e591b 100644 --- a/test/algorithms/overlay/sort_by_side_basic.cpp +++ b/test/algorithms/overlay/sort_by_side_basic.cpp @@ -85,14 +85,13 @@ std::vector apply_get_turns(std::string const& case_id, // Define sorter, sorting counter-clockwise such that polygons are on the // right side - typedef decltype(strategy.side()) side_strategy; - typedef bg::detail::overlay::sort_by_side::side_sorter + using sbs_type = bg::detail::overlay::sort_by_side::side_sorter < false, false, overlay_union, - point_type, side_strategy, std::less - > sbs_type; + point_type, Strategy, std::less + >; - sbs_type sbs(strategy.side()); + sbs_type sbs(strategy); std::cout << "Case: " << case_id << std::endl;