Skip to content

Commit

Permalink
use partition_lambda for overlay pointlike with linear or areal
Browse files Browse the repository at this point in the history
  • Loading branch information
barendgehrels committed Oct 4, 2023
1 parent e7f1905 commit 31e4145
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 209 deletions.
138 changes: 32 additions & 106 deletions include/boost/geometry/algorithms/detail/overlay/pointlike_areal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <boost/geometry/algorithms/not_implemented.hpp>

#include <boost/geometry/algorithms/detail/not.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/partition_lambda.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
Expand Down Expand Up @@ -63,103 +63,6 @@ template
class multipoint_multipolygon_point
{
private:
template <typename Strategy>
struct expand_box_point
{
explicit expand_box_point(Strategy const& strategy)
: m_strategy(strategy)
{}

template <typename Box, typename Point>
inline void apply(Box& total, Point const& point) const
{
geometry::expand(total, point, m_strategy);
}

Strategy const& m_strategy;
};

template <typename Strategy>
struct expand_box_boxpair
{
explicit expand_box_boxpair(Strategy const& strategy)
: m_strategy(strategy)
{}

template <typename Box1, typename Box2, typename SizeT>
inline void apply(Box1& total, std::pair<Box2, SizeT> const& box_pair) const
{
geometry::expand(total, box_pair.first, m_strategy);
}

Strategy const& m_strategy;
};

template <typename Strategy>
struct overlaps_box_point
{
explicit overlaps_box_point(Strategy const& strategy)
: m_strategy(strategy)
{}

template <typename Box, typename Point>
inline bool apply(Box const& box, Point const& point) const
{
return ! geometry::disjoint(point, box, m_strategy);
}

Strategy const& m_strategy;
};

template <typename Strategy>
struct overlaps_box_boxpair
{
explicit overlaps_box_boxpair(Strategy const& strategy)
: m_strategy(strategy)
{}

template <typename Box1, typename Box2, typename SizeT>
inline bool apply(Box1 const& box, std::pair<Box2, SizeT> const& box_pair) const
{
return ! geometry::disjoint(box, box_pair.first, m_strategy);
}

Strategy const& m_strategy;
};

template <typename OutputIterator, typename Strategy>
class item_visitor_type
{
public:
item_visitor_type(MultiPolygon const& multipolygon,
OutputIterator& oit,
Strategy const& strategy)
: m_multipolygon(multipolygon)
, m_oit(oit)
, m_strategy(strategy)
{}

template <typename Point, typename Box, typename SizeT>
inline bool apply(Point const& item1, std::pair<Box, SizeT> const& item2)
{
action_selector_pl
<
PointOut, overlay_intersection
>::apply(item1,
Policy::apply(item1,
range::at(m_multipolygon,
item2.second),
m_strategy),
m_oit);

return true;
}

private:
MultiPolygon const& m_multipolygon;
OutputIterator& m_oit;
Strategy const& m_strategy;
};

template <typename Iterator, typename Box, typename SizeT, typename Strategy>
static inline void fill_box_pairs(Iterator first, Iterator last,
Expand All @@ -181,8 +84,6 @@ class multipoint_multipolygon_point
OutputIterator oit,
Strategy const& strategy)
{
item_visitor_type<OutputIterator, Strategy> item_visitor(multipolygon, oit, strategy);

typedef geometry::model::point
<
typename geometry::coordinate_type<MultiPoint>::type,
Expand All @@ -198,14 +99,39 @@ class multipoint_multipolygon_point
boost::end(multipolygon),
box_pairs, strategy);

geometry::partition
partition_lambda
<
box_type
>::apply(multipoint, box_pairs, item_visitor,
expand_box_point<Strategy>(strategy),
overlaps_box_point<Strategy>(strategy),
expand_box_boxpair<Strategy>(strategy),
overlaps_box_boxpair<Strategy>(strategy));
>(multipoint, box_pairs,
[&strategy](auto& box, auto const& point)
{
geometry::expand(box, point, strategy);
},
[&strategy](auto const& box, auto const& point)
{
return ! geometry::disjoint(point, box, strategy);
},
[&strategy](auto& box, auto const& pair)
{
geometry::expand(box, pair.first, strategy);
},
[&strategy](auto const& box, auto const& pair)
{
return ! geometry::disjoint(box, pair.first, strategy);
},
[&](auto const& point, auto const& pair)
{
action_selector_pl
<
PointOut, overlay_intersection
>::apply(point,
Policy::apply(point,
range::at(multipolygon, pair.second),
strategy),
oit);
return true;
}
);

return oit;
}
Expand Down
136 changes: 33 additions & 103 deletions include/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include <boost/geometry/algorithms/not_implemented.hpp>

#include <boost/geometry/algorithms/detail/not.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/partition_lambda.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
Expand Down Expand Up @@ -123,98 +123,6 @@ template
class multipoint_linear_point
{
private:
// structs for partition -- start
template <typename Strategy>
struct expand_box_point
{
expand_box_point(Strategy const& strategy)
: m_strategy(strategy)
{}

template <typename Box, typename Point>
inline void apply(Box& total, Point const& point) const
{
geometry::expand(total, point, m_strategy);
}

Strategy const& m_strategy;
};

template <typename Strategy>
struct expand_box_segment
{
explicit expand_box_segment(Strategy const& strategy)
: m_strategy(strategy)
{}

template <typename Box, typename Segment>
inline void apply(Box& total, Segment const& segment) const
{
geometry::expand(total,
geometry::return_envelope<Box>(segment, m_strategy),
m_strategy);
}

Strategy const& m_strategy;
};

template <typename Strategy>
struct overlaps_box_point
{
explicit overlaps_box_point(Strategy const& strategy)
: m_strategy(strategy)
{}

template <typename Box, typename Point>
inline bool apply(Box const& box, Point const& point) const
{
return ! geometry::disjoint(point, box, m_strategy);
}

Strategy const& m_strategy;
};

template <typename Strategy>
struct overlaps_box_segment
{
explicit overlaps_box_segment(Strategy const& strategy)
: m_strategy(strategy)
{}

template <typename Box, typename Segment>
inline bool apply(Box const& box, Segment const& segment) const
{
return ! geometry::disjoint(segment, box, m_strategy);
}

Strategy const& m_strategy;
};

template <typename OutputIterator, typename Strategy>
class item_visitor_type
{
public:
item_visitor_type(OutputIterator& oit, Strategy const& strategy)
: m_oit(oit)
, m_strategy(strategy)
{}

template <typename Item1, typename Item2>
inline bool apply(Item1 const& item1, Item2 const& item2)
{
action_selector_pl
<
PointOut, overlay_intersection
>::apply(item1, Policy::apply(item1, item2, m_strategy), m_oit);

return true;
}

private:
OutputIterator& m_oit;
Strategy const& m_strategy;
};
// structs for partition -- end

class segment_range
{
Expand Down Expand Up @@ -246,24 +154,46 @@ class multipoint_linear_point
OutputIterator oit,
Strategy const& strategy)
{
item_visitor_type<OutputIterator, Strategy> item_visitor(oit, strategy);

// TODO: disjoint Segment/Box may be called in partition multiple times
// possibly for non-cartesian segments which could be slow. We should consider
// passing a range of bounding boxes of segments after calculating them once.
// Alternatively instead of a range of segments a range of Segment/Envelope pairs
// should be passed, where envelope would be lazily calculated when needed the first time
geometry::partition
<
geometry::model::box
using box_type = geometry::model::box
<
typename boost::range_value<MultiPoint>::type
>
>::apply(multipoint, segment_range(linear), item_visitor,
expand_box_point<Strategy>(strategy),
overlaps_box_point<Strategy>(strategy),
expand_box_segment<Strategy>(strategy),
overlaps_box_segment<Strategy>(strategy));
>;

partition_lambda
<
box_type
>(multipoint, segment_range(linear),
[&strategy](auto& box, auto const& point)
{
geometry::expand(box, point, strategy);
},
[&strategy](auto const& box, auto const& point)
{
return ! geometry::disjoint(point, box, strategy);
},
[&strategy](auto& box, auto const& segment)
{
geometry::expand(box, geometry::return_envelope<box_type>(segment, strategy), strategy);
},
[&strategy](auto const& box, auto const& segment)
{
return ! geometry::disjoint(box, segment, strategy);
},
[&](auto const& point, auto const& segment)
{
action_selector_pl
<
PointOut, overlay_intersection
>::apply(point, Policy::apply(point, segment, strategy), oit);
return true;
}
);

return oit;
}
Expand Down

0 comments on commit 31e4145

Please sign in to comment.