]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/geometry/algorithms/buffer.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / buffer.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
6
20effc67
TL
7// This file was modified by Oracle on 2017-2020.
8// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates.
b32b8144
FG
9// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10
7c673cae
FG
11// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
12// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
13
14// Use, modification and distribution is subject to the Boost Software License,
15// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
16// http://www.boost.org/LICENSE_1_0.txt)
17
18#ifndef BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
19#define BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
20
21#include <cstddef>
22
23#include <boost/numeric/conversion/cast.hpp>
24
20effc67 25#include <boost/range/value_type.hpp>
7c673cae
FG
26
27#include <boost/variant/apply_visitor.hpp>
28#include <boost/variant/static_visitor.hpp>
29#include <boost/variant/variant_fwd.hpp>
30
31#include <boost/geometry/algorithms/clear.hpp>
32#include <boost/geometry/algorithms/envelope.hpp>
33#include <boost/geometry/algorithms/is_empty.hpp>
34#include <boost/geometry/algorithms/not_implemented.hpp>
35#include <boost/geometry/arithmetic/arithmetic.hpp>
36#include <boost/geometry/geometries/concepts/check.hpp>
37#include <boost/geometry/geometries/box.hpp>
38#include <boost/geometry/util/math.hpp>
39
92f5a8d4 40#include <boost/geometry/algorithms/detail/buffer/buffer_box.hpp>
7c673cae
FG
41#include <boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp>
42
43namespace boost { namespace geometry
44{
45
7c673cae
FG
46#ifndef DOXYGEN_NO_DISPATCH
47namespace dispatch
48{
49
50template
51<
52 typename Input,
53 typename Output,
54 typename TagIn = typename tag<Input>::type,
55 typename TagOut = typename tag<Output>::type
56>
57struct buffer: not_implemented<TagIn, TagOut>
58{};
59
60
61template <typename BoxIn, typename BoxOut>
62struct buffer<BoxIn, BoxOut, box_tag, box_tag>
63{
64 template <typename Distance>
65 static inline void apply(BoxIn const& box_in, Distance const& distance,
66 Distance const& , BoxOut& box_out)
67 {
68 detail::buffer::buffer_box(box_in, distance, box_out);
69 }
70};
71
72} // namespace dispatch
73#endif // DOXYGEN_NO_DISPATCH
74
75
76namespace resolve_variant {
77
78template <typename Geometry>
79struct buffer
80{
81 template <typename Distance, typename GeometryOut>
82 static inline void apply(Geometry const& geometry,
83 Distance const& distance,
84 Distance const& chord_length,
85 GeometryOut& out)
86 {
87 dispatch::buffer<Geometry, GeometryOut>::apply(geometry, distance, chord_length, out);
88 }
89};
90
91template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
92struct buffer<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
93{
94 template <typename Distance, typename GeometryOut>
95 struct visitor: boost::static_visitor<void>
96 {
97 Distance const& m_distance;
98 Distance const& m_chord_length;
99 GeometryOut& m_out;
100
101 visitor(Distance const& distance,
102 Distance const& chord_length,
103 GeometryOut& out)
104 : m_distance(distance),
105 m_chord_length(chord_length),
106 m_out(out)
107 {}
108
109 template <typename Geometry>
110 void operator()(Geometry const& geometry) const
111 {
112 buffer<Geometry>::apply(geometry, m_distance, m_chord_length, m_out);
113 }
114 };
115
116 template <typename Distance, typename GeometryOut>
117 static inline void apply(
118 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
119 Distance const& distance,
120 Distance const& chord_length,
121 GeometryOut& out
122 )
123 {
124 boost::apply_visitor(visitor<Distance, GeometryOut>(distance, chord_length, out), geometry);
125 }
126};
127
128} // namespace resolve_variant
129
130
131/*!
132\brief \brief_calc{buffer}
133\ingroup buffer
134\details \details_calc{buffer, \det_buffer}.
135\tparam Input \tparam_geometry
136\tparam Output \tparam_geometry
137\tparam Distance \tparam_numeric
138\param geometry_in \param_geometry
139\param geometry_out \param_geometry
140\param distance The distance to be used for the buffer
141\param chord_length (optional) The length of the chord's in the generated arcs around points or bends
142
143\qbk{[include reference/algorithms/buffer.qbk]}
144 */
145template <typename Input, typename Output, typename Distance>
146inline void buffer(Input const& geometry_in, Output& geometry_out,
147 Distance const& distance, Distance const& chord_length = -1)
148{
149 concepts::check<Input const>();
150 concepts::check<Output>();
151
152 resolve_variant::buffer<Input>::apply(geometry_in, distance, chord_length, geometry_out);
153}
154
155/*!
156\brief \brief_calc{buffer}
157\ingroup buffer
158\details \details_calc{return_buffer, \det_buffer}. \details_return{buffer}.
159\tparam Input \tparam_geometry
160\tparam Output \tparam_geometry
161\tparam Distance \tparam_numeric
162\param geometry \param_geometry
163\param distance The distance to be used for the buffer
164\param chord_length (optional) The length of the chord's in the generated arcs
165 around points or bends (RESERVED, NOT YET USED)
166\return \return_calc{buffer}
167 */
168template <typename Output, typename Input, typename Distance>
169Output return_buffer(Input const& geometry, Distance const& distance, Distance const& chord_length = -1)
170{
171 concepts::check<Input const>();
172 concepts::check<Output>();
173
174 Output geometry_out;
175
176 resolve_variant::buffer<Input>::apply(geometry, distance, chord_length, geometry_out);
177
178 return geometry_out;
179}
180
181/*!
182\brief \brief_calc{buffer}
183\ingroup buffer
184\details \details_calc{buffer, \det_buffer}.
185\tparam GeometryIn \tparam_geometry
186\tparam MultiPolygon \tparam_geometry{MultiPolygon}
187\tparam DistanceStrategy A strategy defining distance (or radius)
188\tparam SideStrategy A strategy defining creation along sides
189\tparam JoinStrategy A strategy defining creation around convex corners
190\tparam EndStrategy A strategy defining creation at linestring ends
191\tparam PointStrategy A strategy defining creation around points
192\param geometry_in \param_geometry
193\param geometry_out output multi polygon (or std:: collection of polygons),
194 will contain a buffered version of the input geometry
195\param distance_strategy The distance strategy to be used
196\param side_strategy The side strategy to be used
197\param join_strategy The join strategy to be used
198\param end_strategy The end strategy to be used
199\param point_strategy The point strategy to be used
200
201\qbk{distinguish,with strategies}
202\qbk{[include reference/algorithms/buffer_with_strategies.qbk]}
203 */
204template
205<
206 typename GeometryIn,
207 typename MultiPolygon,
208 typename DistanceStrategy,
209 typename SideStrategy,
210 typename JoinStrategy,
211 typename EndStrategy,
212 typename PointStrategy
213>
214inline void buffer(GeometryIn const& geometry_in,
215 MultiPolygon& geometry_out,
216 DistanceStrategy const& distance_strategy,
217 SideStrategy const& side_strategy,
218 JoinStrategy const& join_strategy,
219 EndStrategy const& end_strategy,
220 PointStrategy const& point_strategy)
221{
222 typedef typename boost::range_value<MultiPolygon>::type polygon_type;
223 concepts::check<GeometryIn const>();
224 concepts::check<polygon_type>();
225
226 typedef typename point_type<GeometryIn>::type point_type;
92f5a8d4
TL
227 typedef typename rescale_policy_type
228 <
229 point_type,
230 typename geometry::cs_tag<point_type>::type
231 >::type rescale_policy_type;
7c673cae
FG
232
233 geometry_out.clear();
234
235 if (geometry::is_empty(geometry_in))
236 {
237 // Then output geometry is kept empty as well
238 return;
239 }
240
241 model::box<point_type> box;
242 geometry::envelope(geometry_in, box);
243 geometry::buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy));
244
b32b8144
FG
245 typename strategy::intersection::services::default_strategy
246 <
247 typename cs_tag<GeometryIn>::type
248 >::type intersection_strategy;
249
7c673cae 250 rescale_policy_type rescale_policy
92f5a8d4
TL
251 = boost::geometry::get_rescale_policy<rescale_policy_type>(
252 box, intersection_strategy);
7c673cae
FG
253
254 detail::buffer::buffer_inserter<polygon_type>(geometry_in, range::back_inserter(geometry_out),
255 distance_strategy,
256 side_strategy,
257 join_strategy,
258 end_strategy,
259 point_strategy,
b32b8144 260 intersection_strategy,
7c673cae
FG
261 rescale_policy);
262}
263
264
265}} // namespace boost::geometry
266
267#endif // BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP