]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/buffer.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / buffer.hpp
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
7 // This file was modified by Oracle on 2017-2020.
8 // Modifications copyright (c) 2017-2020 Oracle and/or its affiliates.
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10
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
25 #include <boost/range/value_type.hpp>
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
40 #include <boost/geometry/algorithms/detail/buffer/buffer_box.hpp>
41 #include <boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp>
42
43 namespace boost { namespace geometry
44 {
45
46 #ifndef DOXYGEN_NO_DISPATCH
47 namespace dispatch
48 {
49
50 template
51 <
52 typename Input,
53 typename Output,
54 typename TagIn = typename tag<Input>::type,
55 typename TagOut = typename tag<Output>::type
56 >
57 struct buffer: not_implemented<TagIn, TagOut>
58 {};
59
60
61 template <typename BoxIn, typename BoxOut>
62 struct 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
76 namespace resolve_variant {
77
78 template <typename Geometry>
79 struct 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
91 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
92 struct 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 */
145 template <typename Input, typename Output, typename Distance>
146 inline 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 */
168 template <typename Output, typename Input, typename Distance>
169 Output 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 */
204 template
205 <
206 typename GeometryIn,
207 typename MultiPolygon,
208 typename DistanceStrategy,
209 typename SideStrategy,
210 typename JoinStrategy,
211 typename EndStrategy,
212 typename PointStrategy
213 >
214 inline 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;
227 typedef typename rescale_policy_type
228 <
229 point_type,
230 typename geometry::cs_tag<point_type>::type
231 >::type rescale_policy_type;
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
245 typename strategy::intersection::services::default_strategy
246 <
247 typename cs_tag<GeometryIn>::type
248 >::type intersection_strategy;
249
250 rescale_policy_type rescale_policy
251 = boost::geometry::get_rescale_policy<rescale_policy_type>(
252 box, intersection_strategy);
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,
260 intersection_strategy,
261 rescale_policy);
262 }
263
264
265 }} // namespace boost::geometry
266
267 #endif // BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP