summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp')
-rw-r--r--boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp69
1 files changed, 57 insertions, 12 deletions
diff --git a/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp b/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
index a26f54e008..0a7c3bc469 100644
--- a/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
+++ b/boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp
@@ -1,5 +1,7 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
+
// Copyright (c) 2015-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -127,25 +129,57 @@ class multipoint_linear_point
{
private:
// structs for partition -- start
- struct expand_box
+ struct expand_box_point
{
- template <typename Box, typename Geometry>
- static inline void apply(Box& total, Geometry const& geometry)
+ template <typename Box, typename Point>
+ static inline void apply(Box& total, Point const& point)
{
- geometry::expand(total, geometry::return_envelope<Box>(geometry));
+ geometry::expand(total, point);
}
+ };
+
+ template <typename EnvelopeStrategy>
+ struct expand_box_segment
+ {
+ explicit expand_box_segment(EnvelopeStrategy 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));
+ }
+
+ EnvelopeStrategy const& m_strategy;
};
- struct overlaps_box
+ struct overlaps_box_point
{
- template <typename Box, typename Geometry>
- static inline bool apply(Box const& box, Geometry const& geometry)
+ template <typename Box, typename Point>
+ static inline bool apply(Box const& box, Point const& point)
{
- return ! geometry::disjoint(geometry, box);
+ return ! geometry::disjoint(point, box);
}
};
+ template <typename DisjointStrategy>
+ struct overlaps_box_segment
+ {
+ explicit overlaps_box_segment(DisjointStrategy 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);
+ }
+
+ DisjointStrategy const& m_strategy;
+ };
+
template <typename OutputIterator, typename Strategy>
class item_visitor_type
{
@@ -156,12 +190,14 @@ private:
{}
template <typename Item1, typename Item2>
- inline void apply(Item1 const& item1, Item2 const& item2)
+ inline bool apply(Item1 const& item1, Item2 const& item2)
{
action_selector_pl_l
<
PointOut, overlay_intersection
>::apply(item1, Policy::apply(item1, item2, m_strategy), m_oit);
+
+ return true;
}
private:
@@ -202,16 +238,25 @@ private:
{
item_visitor_type<OutputIterator, Strategy> item_visitor(oit, strategy);
- segment_range rng(linear);
+ typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
+ typedef typename Strategy::disjoint_strategy_type disjoint_strategy_type;
+ // 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
<
typename boost::range_value<MultiPoint>::type
>
- >::apply(multipoint, rng, item_visitor,
- expand_box(), overlaps_box());
+ >::apply(multipoint, segment_range(linear), item_visitor,
+ expand_box_point(),
+ overlaps_box_point(),
+ expand_box_segment<envelope_strategy_type>(strategy.get_envelope_strategy()),
+ overlaps_box_segment<disjoint_strategy_type>(strategy.get_disjoint_strategy()));
return oit;
}