1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
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
11 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
12 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
18 #ifndef BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
19 #define BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
23 #include <boost/numeric/conversion/cast.hpp>
25 #include <boost/range/value_type.hpp>
27 #include <boost/variant/apply_visitor.hpp>
28 #include <boost/variant/static_visitor.hpp>
29 #include <boost/variant/variant_fwd.hpp>
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>
40 #include <boost/geometry/algorithms/detail/buffer/buffer_box.hpp>
41 #include <boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp>
43 namespace boost { namespace geometry
46 #ifndef DOXYGEN_NO_DISPATCH
54 typename TagIn = typename tag<Input>::type,
55 typename TagOut = typename tag<Output>::type
57 struct buffer: not_implemented<TagIn, TagOut>
61 template <typename BoxIn, typename BoxOut>
62 struct buffer<BoxIn, BoxOut, box_tag, box_tag>
64 template <typename Distance>
65 static inline void apply(BoxIn const& box_in, Distance const& distance,
66 Distance const& , BoxOut& box_out)
68 detail::buffer::buffer_box(box_in, distance, box_out);
72 } // namespace dispatch
73 #endif // DOXYGEN_NO_DISPATCH
76 namespace resolve_variant {
78 template <typename Geometry>
81 template <typename Distance, typename GeometryOut>
82 static inline void apply(Geometry const& geometry,
83 Distance const& distance,
84 Distance const& chord_length,
87 dispatch::buffer<Geometry, GeometryOut>::apply(geometry, distance, chord_length, out);
91 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
92 struct buffer<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
94 template <typename Distance, typename GeometryOut>
95 struct visitor: boost::static_visitor<void>
97 Distance const& m_distance;
98 Distance const& m_chord_length;
101 visitor(Distance const& distance,
102 Distance const& chord_length,
104 : m_distance(distance),
105 m_chord_length(chord_length),
109 template <typename Geometry>
110 void operator()(Geometry const& geometry) const
112 buffer<Geometry>::apply(geometry, m_distance, m_chord_length, m_out);
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,
124 boost::apply_visitor(visitor<Distance, GeometryOut>(distance, chord_length, out), geometry);
128 } // namespace resolve_variant
132 \brief \brief_calc{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
143 \qbk{[include reference/algorithms/buffer.qbk]}
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)
149 concepts::check<Input const>();
150 concepts::check<Output>();
152 resolve_variant::buffer<Input>::apply(geometry_in, distance, chord_length, geometry_out);
156 \brief \brief_calc{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}
168 template <typename Output, typename Input, typename Distance>
169 Output return_buffer(Input const& geometry, Distance const& distance, Distance const& chord_length = -1)
171 concepts::check<Input const>();
172 concepts::check<Output>();
176 resolve_variant::buffer<Input>::apply(geometry, distance, chord_length, geometry_out);
182 \brief \brief_calc{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
201 \qbk{distinguish,with strategies}
202 \qbk{[include reference/algorithms/buffer_with_strategies.qbk]}
207 typename MultiPolygon,
208 typename DistanceStrategy,
209 typename SideStrategy,
210 typename JoinStrategy,
211 typename EndStrategy,
212 typename PointStrategy
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)
222 typedef typename boost::range_value<MultiPolygon>::type polygon_type;
223 concepts::check<GeometryIn const>();
224 concepts::check<polygon_type>();
226 typedef typename point_type<GeometryIn>::type point_type;
227 typedef typename rescale_policy_type
230 typename geometry::cs_tag<point_type>::type
231 >::type rescale_policy_type;
233 geometry_out.clear();
235 if (geometry::is_empty(geometry_in))
237 // Then output geometry is kept empty as well
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));
245 typename strategy::intersection::services::default_strategy
247 typename cs_tag<GeometryIn>::type
248 >::type intersection_strategy;
250 rescale_policy_type rescale_policy
251 = boost::geometry::get_rescale_policy<rescale_policy_type>(
252 box, intersection_strategy);
254 detail::buffer::buffer_inserter<polygon_type>(geometry_in, range::back_inserter(geometry_out),
260 intersection_strategy,
265 }} // namespace boost::geometry
267 #endif // BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP