Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pass strategy to sort by side #1242

Merged
merged 1 commit into from
Feb 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Turns>::type turn_type;
typedef typename turn_type::point_type point_type;
Expand All @@ -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<int>
Reverse1, Reverse2, OverlayType, point_type, Strategy, std::less<int>
> sbs_type;

for (auto& pair : clusters)
Expand Down
117 changes: 60 additions & 57 deletions include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,50 +39,42 @@ 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 <typename Point>
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)
{}

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;
};

Expand All @@ -91,10 +83,8 @@ struct less_by_turn_index
template <typename T>
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);
}
};

Expand All @@ -103,20 +93,13 @@ struct less_by_index
template <typename T>
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);
}
};

Expand All @@ -129,10 +112,10 @@ struct less_false
}
};

template <typename PointOrigin, typename PointTurn, typename SideStrategy, typename LessOnSame, typename Compare>
template <typename PointOrigin, typename PointTurn, typename Strategy, typename LessOnSame, typename Compare>
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)
Expand All @@ -141,13 +124,14 @@ struct less_by_side
template <typename T>
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)
{
Expand Down Expand Up @@ -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.
Expand All @@ -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<Point> rp;
using rp = ranked_point<Point>;

private :
struct include_union
Expand All @@ -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)
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -392,8 +393,8 @@ public :
// to give colinear points

// Sort by side and assign rank
less_by_side<Point, PointTurn, SideStrategy, less_by_index, Compare> less_unique(m_origin, turn_point, m_strategy);
less_by_side<Point, PointTurn, SideStrategy, less_false, Compare> less_non_unique(m_origin, turn_point, m_strategy);
less_by_side<Point, PointTurn, Strategy, less_by_index, Compare> less_unique(m_origin, turn_point, m_strategy);
less_by_side<Point, PointTurn, Strategy, less_false, Compare> less_non_unique(m_origin, turn_point, m_strategy);

std::sort(m_ranked_points.begin(), m_ranked_points.end(), less_unique);

Expand Down Expand Up @@ -512,12 +513,14 @@ public :

//private :

typedef std::vector<rp> container_type;
using container_type = std::vector<rp>;
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 :

Expand Down Expand Up @@ -724,13 +727,13 @@ struct side_compare {};
template <>
struct side_compare<operation_union>
{
typedef std::greater<int> type;
using type = std::greater<int>;
};

template <>
struct side_compare<operation_intersection>
{
typedef std::less<int> type;
using type = std::less<int>;
};


Expand Down
10 changes: 5 additions & 5 deletions include/boost/geometry/algorithms/detail/overlay/traversal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ template
typename Turns,
typename Clusters,
typename RobustPolicy,
typename SideStrategy,
typename Strategy,
typename Visitor
>
struct traversal
Expand All @@ -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)
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct traversal_ring_creator
Reverse1, Reverse2, OverlayType,
Geometry1, Geometry2, Turns, Clusters,
RobustPolicy,
decltype(std::declval<Strategy>().side()),
Strategy,
Visitor
> traversal_type;

Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion test/algorithms/overlay/copy_segment_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

#include <geometry_test_common.hpp>

#include <boost/geometry/algorithms/detail/overlay/sort_by_side.hpp>
#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>

#include <boost/geometry/strategies/strategies.hpp>
#include <boost/geometry/algorithms/disjoint.hpp>
Expand Down
Loading
Loading