summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp')
-rw-r--r--boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp221
1 files changed, 125 insertions, 96 deletions
diff --git a/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp b/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
index 029053dda3..a149f1dd46 100644
--- a/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
+++ b/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp
@@ -122,7 +122,8 @@ struct buffer_range
typename DistanceStrategy,
typename JoinStrategy,
typename EndStrategy,
- typename RobustPolicy
+ typename RobustPolicy,
+ typename Strategy
>
static inline
void add_join(Collection& collection,
@@ -133,18 +134,19 @@ struct buffer_range
Point const& input,
output_point_type const& perp1,
output_point_type const& perp2,
- strategy::buffer::buffer_side_selector side,
+ geometry::strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
- RobustPolicy const& )
+ RobustPolicy const& ,
+ Strategy const& strategy) // side strategy
{
output_point_type intersection_point;
geometry::assign_zero(intersection_point);
- strategy::buffer::join_selector join
- = get_join_type(penultimate_input, previous_input, input);
- if (join == strategy::buffer::join_convex)
+ geometry::strategy::buffer::join_selector join
+ = get_join_type(penultimate_input, previous_input, input, strategy);
+ if (join == geometry::strategy::buffer::join_convex)
{
// Calculate the intersection-point formed by the two sides.
// It might be that the two sides are not convex, but continue
@@ -157,23 +159,23 @@ struct buffer_range
switch(join)
{
- case strategy::buffer::join_continue :
+ case geometry::strategy::buffer::join_continue :
// No join, we get two consecutive sides
break;
- case strategy::buffer::join_concave :
+ case geometry::strategy::buffer::join_concave :
{
std::vector<output_point_type> range_out;
range_out.push_back(prev_perp2);
range_out.push_back(previous_input);
- collection.add_piece(strategy::buffer::buffered_concave, previous_input, range_out);
+ collection.add_piece(geometry::strategy::buffer::buffered_concave, previous_input, range_out);
range_out.clear();
range_out.push_back(previous_input);
range_out.push_back(perp1);
- collection.add_piece(strategy::buffer::buffered_concave, previous_input, range_out);
+ collection.add_piece(geometry::strategy::buffer::buffered_concave, previous_input, range_out);
}
break;
- case strategy::buffer::join_spike :
+ case geometry::strategy::buffer::join_spike :
{
// For linestrings, only add spike at one side to avoid
// duplicates
@@ -183,7 +185,7 @@ struct buffer_range
collection.set_current_ring_concave();
}
break;
- case strategy::buffer::join_convex :
+ case geometry::strategy::buffer::join_convex :
{
// The corner is convex, we create a join
// TODO (future) - avoid a separate vector, add the piece directly
@@ -193,7 +195,7 @@ struct buffer_range
distance.apply(previous_input, input, side),
range_out))
{
- collection.add_piece(strategy::buffer::buffered_join,
+ collection.add_piece(geometry::strategy::buffer::buffered_join,
previous_input, range_out);
}
}
@@ -201,27 +203,24 @@ struct buffer_range
}
}
- static inline strategy::buffer::join_selector get_join_type(
+ template <typename Strategy>
+ static inline geometry::strategy::buffer::join_selector get_join_type(
output_point_type const& p0,
output_point_type const& p1,
- output_point_type const& p2)
+ output_point_type const& p2,
+ Strategy const& strategy) // side strategy
{
- typedef typename strategy::side::services::default_strategy
- <
- typename cs_tag<output_point_type>::type
- >::type side_strategy;
-
- int const side = side_strategy::apply(p0, p1, p2);
- return side == -1 ? strategy::buffer::join_convex
- : side == 1 ? strategy::buffer::join_concave
+ int const side = strategy.apply(p0, p1, p2);
+ return side == -1 ? geometry::strategy::buffer::join_convex
+ : side == 1 ? geometry::strategy::buffer::join_concave
: parallel_continue
(
get<0>(p2) - get<0>(p1),
get<1>(p2) - get<1>(p1),
get<0>(p1) - get<0>(p0),
get<1>(p1) - get<1>(p0)
- ) ? strategy::buffer::join_continue
- : strategy::buffer::join_spike;
+ ) ? geometry::strategy::buffer::join_continue
+ : geometry::strategy::buffer::join_spike;
}
template
@@ -232,16 +231,18 @@ struct buffer_range
typename SideStrategy,
typename JoinStrategy,
typename EndStrategy,
- typename RobustPolicy
+ typename RobustPolicy,
+ typename Strategy
>
- static inline strategy::buffer::result_code iterate(Collection& collection,
+ static inline geometry::strategy::buffer::result_code iterate(Collection& collection,
Iterator begin, Iterator end,
- strategy::buffer::buffer_side_selector side,
+ geometry::strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
RobustPolicy const& robust_policy,
+ Strategy const& strategy, // side strategy
output_point_type& first_p1,
output_point_type& first_p2,
output_point_type& last_p1,
@@ -273,7 +274,7 @@ struct buffer_range
* pup: penultimate_point
*/
- strategy::buffer::result_code result = strategy::buffer::result_no_output;
+ geometry::strategy::buffer::result_code result = geometry::strategy::buffer::result_no_output;
bool first = true;
Iterator it = begin;
@@ -284,25 +285,25 @@ struct buffer_range
for (Iterator prev = it++; it != end; ++it)
{
generated_side.clear();
- strategy::buffer::result_code error_code
+ geometry::strategy::buffer::result_code error_code
= side_strategy.apply(*prev, *it, side,
distance_strategy, generated_side);
- if (error_code == strategy::buffer::result_no_output)
+ if (error_code == geometry::strategy::buffer::result_no_output)
{
// Because input is simplified, this is improbable,
// but it can happen for degenerate geometries
// Further handling of this side is skipped
continue;
}
- else if (error_code == strategy::buffer::result_error_numerical)
+ else if (error_code == geometry::strategy::buffer::result_error_numerical)
{
return error_code;
}
BOOST_GEOMETRY_ASSERT(! generated_side.empty());
- result = strategy::buffer::result_normal;
+ result = geometry::strategy::buffer::result_normal;
if (! first)
{
@@ -312,7 +313,7 @@ struct buffer_range
*it, generated_side.front(), generated_side.back(),
side,
distance_strategy, join_strategy, end_strategy,
- robust_policy);
+ robust_policy, strategy);
}
collection.add_side_piece(*prev, *it, generated_side, first);
@@ -350,7 +351,8 @@ struct buffer_multi
typename JoinStrategy,
typename EndStrategy,
typename PointStrategy,
- typename RobustPolicy
+ typename RobustPolicy,
+ typename Strategy
>
static inline void apply(Multi const& multi,
Collection& collection,
@@ -359,7 +361,8 @@ struct buffer_multi
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
PointStrategy const& point_strategy,
- RobustPolicy const& robust_policy)
+ RobustPolicy const& robust_policy,
+ Strategy const& strategy) // side strategy
{
for (typename boost::range_iterator<Multi const>::type
it = boost::begin(multi);
@@ -369,7 +372,7 @@ struct buffer_multi
Policy::apply(*it, collection,
distance_strategy, side_strategy,
join_strategy, end_strategy, point_strategy,
- robust_policy);
+ robust_policy, strategy);
}
}
};
@@ -396,9 +399,9 @@ inline void buffer_point(Point const& point, Collection& collection,
collection.start_new_ring();
std::vector<OutputPointType> range_out;
point_strategy.apply(point, distance_strategy, range_out);
- collection.add_piece(strategy::buffer::buffered_point, range_out, false);
+ collection.add_piece(geometry::strategy::buffer::buffered_point, range_out, false);
collection.set_piece_center(point);
- collection.finish_ring(strategy::buffer::result_normal);
+ collection.finish_ring(geometry::strategy::buffer::result_normal);
}
@@ -436,7 +439,8 @@ struct buffer_inserter<point_tag, Point, RingOutput>
typename JoinStrategy,
typename EndStrategy,
typename PointStrategy,
- typename RobustPolicy
+ typename RobustPolicy,
+ typename Strategy
>
static inline void apply(Point const& point, Collection& collection,
DistanceStrategy const& distance_strategy,
@@ -444,7 +448,8 @@ struct buffer_inserter<point_tag, Point, RingOutput>
JoinStrategy const& ,
EndStrategy const& ,
PointStrategy const& point_strategy,
- RobustPolicy const& )
+ RobustPolicy const& ,
+ Strategy const& ) // side strategy
{
detail::buffer::buffer_point
<
@@ -472,29 +477,32 @@ struct buffer_inserter_ring
typename SideStrategy,
typename JoinStrategy,
typename EndStrategy,
- typename RobustPolicy
+ typename RobustPolicy,
+ typename Strategy
>
- static inline strategy::buffer::result_code iterate(Collection& collection,
+ static inline geometry::strategy::buffer::result_code iterate(Collection& collection,
Iterator begin, Iterator end,
- strategy::buffer::buffer_side_selector side,
+ geometry::strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
- RobustPolicy const& robust_policy)
+ RobustPolicy const& robust_policy,
+ Strategy const& strategy) // side strategy
{
output_point_type first_p1, first_p2, last_p1, last_p2;
typedef detail::buffer::buffer_range<RingOutput> buffer_range;
- strategy::buffer::result_code result
+ geometry::strategy::buffer::result_code result
= buffer_range::iterate(collection, begin, end,
side,
- distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
+ distance_strategy, side_strategy, join_strategy, end_strategy,
+ robust_policy, strategy,
first_p1, first_p2, last_p1, last_p2);
// Generate closing join
- if (result == strategy::buffer::result_normal)
+ if (result == geometry::strategy::buffer::result_normal)
{
buffer_range::add_join(collection,
*(end - 2),
@@ -502,7 +510,7 @@ struct buffer_inserter_ring
*(begin + 1), first_p1, first_p2,
side,
distance_strategy, join_strategy, end_strategy,
- robust_policy);
+ robust_policy, strategy);
}
// Buffer is closed automatically by last closing corner
@@ -517,21 +525,23 @@ struct buffer_inserter_ring
typename JoinStrategy,
typename EndStrategy,
typename PointStrategy,
- typename RobustPolicy
+ typename RobustPolicy,
+ typename Strategy
>
- static inline strategy::buffer::result_code apply(RingInput const& ring,
+ static inline geometry::strategy::buffer::result_code apply(RingInput const& ring,
Collection& collection,
DistanceStrategy const& distance,
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
PointStrategy const& point_strategy,
- RobustPolicy const& robust_policy)
+ RobustPolicy const& robust_policy,
+ Strategy const& strategy) // side strategy
{
RingInput simplified;
detail::buffer::simplify_input(ring, distance, simplified);
- strategy::buffer::result_code code = strategy::buffer::result_no_output;
+ geometry::strategy::buffer::result_code code = geometry::strategy::buffer::result_no_output;
std::size_t n = boost::size(simplified);
std::size_t const min_points = core_detail::closure::minimum_ring_size
@@ -546,18 +556,20 @@ struct buffer_inserter_ring
{
// Walk backwards (rings will be reversed afterwards)
code = iterate(collection, boost::rbegin(view), boost::rend(view),
- strategy::buffer::buffer_side_right,
- distance, side_strategy, join_strategy, end_strategy, robust_policy);
+ geometry::strategy::buffer::buffer_side_right,
+ distance, side_strategy, join_strategy, end_strategy,
+ robust_policy, strategy);
}
else
{
code = iterate(collection, boost::begin(view), boost::end(view),
- strategy::buffer::buffer_side_left,
- distance, side_strategy, join_strategy, end_strategy, robust_policy);
+ geometry::strategy::buffer::buffer_side_left,
+ distance, side_strategy, join_strategy, end_strategy,
+ robust_policy, strategy);
}
}
- if (code == strategy::buffer::result_no_output && n >= 1)
+ if (code == geometry::strategy::buffer::result_no_output && n >= 1)
{
// Use point_strategy to buffer degenerated ring
detail::buffer::buffer_point<output_point_type>
@@ -586,23 +598,25 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
typename JoinStrategy,
typename EndStrategy,
typename PointStrategy,
- typename RobustPolicy
+ typename RobustPolicy,
+ typename Strategy
>
- static inline strategy::buffer::result_code apply(RingInput const& ring,
+ static inline geometry::strategy::buffer::result_code apply(RingInput const& ring,
Collection& collection,
DistanceStrategy const& distance,
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
PointStrategy const& point_strategy,
- RobustPolicy const& robust_policy)
+ RobustPolicy const& robust_policy,
+ Strategy const& strategy) // side strategy
{
collection.start_new_ring();
- strategy::buffer::result_code const code
+ geometry::strategy::buffer::result_code const code
= buffer_inserter_ring<RingInput, RingOutput>::apply(ring,
collection, distance,
side_strategy, join_strategy, end_strategy, point_strategy,
- robust_policy);
+ robust_policy, strategy);
collection.finish_ring(code);
return code;
}
@@ -627,16 +641,18 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
typename SideStrategy,
typename JoinStrategy,
typename EndStrategy,
- typename RobustPolicy
+ typename RobustPolicy,
+ typename Strategy
>
- static inline strategy::buffer::result_code iterate(Collection& collection,
+ static inline geometry::strategy::buffer::result_code iterate(Collection& collection,
Iterator begin, Iterator end,
- strategy::buffer::buffer_side_selector side,
+ geometry::strategy::buffer::buffer_side_selector side,
DistanceStrategy const& distance_strategy,
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
RobustPolicy const& robust_policy,
+ Strategy const& strategy, // side strategy
output_point_type& first_p1)
{
input_point_type const& ultimate_point = *(end - 1);
@@ -647,18 +663,18 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
// we have it already from the first phase (left).
// But for the first pass, we have to generate it
output_point_type reverse_p1;
- if (side == strategy::buffer::buffer_side_right)
+ if (side == geometry::strategy::buffer::buffer_side_right)
{
reverse_p1 = first_p1;
}
else
{
std::vector<output_point_type> generated_side;
- strategy::buffer::result_code code
+ geometry::strategy::buffer::result_code code
= side_strategy.apply(ultimate_point, penultimate_point,
- strategy::buffer::buffer_side_right,
+ geometry::strategy::buffer::buffer_side_right,
distance_strategy, generated_side);
- if (code != strategy::buffer::result_normal)
+ if (code != geometry::strategy::buffer::result_normal)
{
// No output or numerical error
return code;
@@ -668,16 +684,18 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
output_point_type first_p2, last_p1, last_p2;
- strategy::buffer::result_code result
+ geometry::strategy::buffer::result_code result
= detail::buffer::buffer_range<output_ring_type>::iterate(collection,
begin, end, side,
- distance_strategy, side_strategy, join_strategy, end_strategy, robust_policy,
+ distance_strategy, side_strategy, join_strategy, end_strategy,
+ robust_policy, strategy,
first_p1, first_p2, last_p1, last_p2);
- if (result == strategy::buffer::result_normal)
+ if (result == geometry::strategy::buffer::result_normal)
{
std::vector<output_point_type> range_out;
- end_strategy.apply(penultimate_point, last_p2, ultimate_point, reverse_p1, side, distance_strategy, range_out);
+ end_strategy.apply(penultimate_point, last_p2, ultimate_point, reverse_p1,
+ side, distance_strategy, range_out);
collection.add_endcap(end_strategy, range_out, ultimate_point);
}
return result;
@@ -691,20 +709,23 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
typename JoinStrategy,
typename EndStrategy,
typename PointStrategy,
- typename RobustPolicy
+ typename RobustPolicy,
+ typename Strategy
>
- static inline strategy::buffer::result_code apply(Linestring const& linestring, Collection& collection,
+ static inline geometry::strategy::buffer::result_code apply(Linestring const& linestring,
+ Collection& collection,
DistanceStrategy const& distance,
SideStrategy const& side_strategy,
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
PointStrategy const& point_strategy,
- RobustPolicy const& robust_policy)
+ RobustPolicy const& robust_policy,
+ Strategy const& strategy) // side strategy
{
Linestring simplified;
detail::buffer::simplify_input(linestring, distance, simplified);
- strategy::buffer::result_code code = strategy::buffer::result_no_output;
+ geometry::strategy::buffer::result_code code = geometry::strategy::buffer::result_no_output;
std::size_t n = boost::size(simplified);
if (n > 1)
{
@@ -712,21 +733,23 @@ struct buffer_inserter<linestring_tag, Linestring, Polygon>
output_point_type first_p1;
code = iterate(collection,
boost::begin(simplified), boost::end(simplified),
- strategy::buffer::buffer_side_left,
- distance, side_strategy, join_strategy, end_strategy, robust_policy,
+ geometry::strategy::buffer::buffer_side_left,
+ distance, side_strategy, join_strategy, end_strategy,
+ robust_policy, strategy,
first_p1);
- if (code == strategy::buffer::result_normal)
+ if (code == geometry::strategy::buffer::result_normal)
{
code = iterate(collection,
boost::rbegin(simplified), boost::rend(simplified),
- strategy::buffer::buffer_side_right,
- distance, side_strategy, join_strategy, end_strategy, robust_policy,
+ geometry::strategy::buffer::buffer_side_right,
+ distance, side_strategy, join_strategy, end_strategy,
+ robust_policy, strategy,
first_p1);
}
collection.finish_ring(code);
}
- if (code == strategy::buffer::result_no_output && n >= 1)
+ if (code == geometry::strategy::buffer::result_no_output && n >= 1)
{
// Use point_strategy to buffer degenerated linestring
detail::buffer::buffer_point<output_point_type>
@@ -763,7 +786,8 @@ private:
typename JoinStrategy,
typename EndStrategy,
typename PointStrategy,
- typename RobustPolicy
+ typename RobustPolicy,
+ typename Strategy
>
static inline
void iterate(Iterator begin, Iterator end,
@@ -774,15 +798,16 @@ private:
EndStrategy const& end_strategy,
PointStrategy const& point_strategy,
RobustPolicy const& robust_policy,
+ Strategy const& strategy, // side strategy
bool is_interior)
{
for (Iterator it = begin; it != end; ++it)
{
collection.start_new_ring();
- strategy::buffer::result_code const code
+ geometry::strategy::buffer::result_code const code
= policy::apply(*it, collection, distance, side_strategy,
join_strategy, end_strategy, point_strategy,
- robust_policy);
+ robust_policy, strategy);
collection.finish_ring(code, is_interior);
}
@@ -797,7 +822,8 @@ private:
typename JoinStrategy,
typename EndStrategy,
typename PointStrategy,
- typename RobustPolicy
+ typename RobustPolicy,
+ typename Strategy
>
static inline
void apply_interior_rings(InteriorRings const& interior_rings,
@@ -807,12 +833,13 @@ private:
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
PointStrategy const& point_strategy,
- RobustPolicy const& robust_policy)
+ RobustPolicy const& robust_policy,
+ Strategy const& strategy) // side strategy
{
iterate(boost::begin(interior_rings), boost::end(interior_rings),
collection, distance, side_strategy,
join_strategy, end_strategy, point_strategy,
- robust_policy, true);
+ robust_policy, strategy, true);
}
public:
@@ -824,7 +851,8 @@ public:
typename JoinStrategy,
typename EndStrategy,
typename PointStrategy,
- typename RobustPolicy
+ typename RobustPolicy,
+ typename Strategy
>
static inline void apply(PolygonInput const& polygon,
Collection& collection,
@@ -833,16 +861,17 @@ public:
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
PointStrategy const& point_strategy,
- RobustPolicy const& robust_policy)
+ RobustPolicy const& robust_policy,
+ Strategy const& strategy) // side strategy
{
{
collection.start_new_ring();
- strategy::buffer::result_code const code
+ geometry::strategy::buffer::result_code const code
= policy::apply(exterior_ring(polygon), collection,
distance, side_strategy,
join_strategy, end_strategy, point_strategy,
- robust_policy);
+ robust_policy, strategy);
collection.finish_ring(code, false,
geometry::num_interior_rings(polygon) > 0u);
@@ -851,7 +880,7 @@ public:
apply_interior_rings(interior_rings(polygon),
collection, distance, side_strategy,
join_strategy, end_strategy, point_strategy,
- robust_policy);
+ robust_policy, strategy);
}
};
@@ -945,7 +974,7 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
>::apply(geometry_input, collection,
distance_strategy, side_strategy, join_strategy,
end_strategy, point_strategy,
- robust_policy);
+ robust_policy, intersection_strategy.get_side_strategy());
collection.get_turns();
collection.classify_turns(linear);