Skip to content

Commit aa9ccbe

Browse files
committed
WL#7929 GIS: Implement ST_Buffer and ST_Distance with Boost.Geometry
Implement ST_Buffer using Boost.Geometry, remove old implementation. Extra configurations enabled for ST_Buffer() as provided by Boost.Geometry. Completely use Boost.Geometry to implement ST_Distance(), and remove old implementation.
1 parent 667983a commit aa9ccbe

File tree

113 files changed

+22368
-2097
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+22368
-2097
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
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+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
8+
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
9+
10+
// Use, modification and distribution is subject to the Boost Software License,
11+
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12+
// http://www.boost.org/LICENSE_1_0.txt)
13+
14+
#ifndef BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
15+
#define BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
16+
17+
#include <cstddef>
18+
19+
#include <boost/numeric/conversion/cast.hpp>
20+
21+
#include <boost/variant/apply_visitor.hpp>
22+
#include <boost/variant/static_visitor.hpp>
23+
#include <boost/variant/variant_fwd.hpp>
24+
25+
#include <boost/geometry/algorithms/clear.hpp>
26+
#include <boost/geometry/algorithms/envelope.hpp>
27+
#include <boost/geometry/algorithms/not_implemented.hpp>
28+
#include <boost/geometry/arithmetic/arithmetic.hpp>
29+
#include <boost/geometry/geometries/concepts/check.hpp>
30+
#include <boost/geometry/geometries/box.hpp>
31+
#include <boost/geometry/util/math.hpp>
32+
33+
#include <boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp>
34+
35+
namespace boost { namespace geometry
36+
{
37+
38+
39+
#ifndef DOXYGEN_NO_DETAIL
40+
namespace detail { namespace buffer
41+
{
42+
43+
template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t D, std::size_t N>
44+
struct box_loop
45+
{
46+
typedef typename coordinate_type<BoxOut>::type coordinate_type;
47+
48+
static inline void apply(BoxIn const& box_in, T const& distance, BoxOut& box_out)
49+
{
50+
coordinate_type d = distance;
51+
set<C, D>(box_out, get<C, D>(box_in) + d);
52+
box_loop<BoxIn, BoxOut, T, C, D + 1, N>::apply(box_in, distance, box_out);
53+
}
54+
};
55+
56+
template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t N>
57+
struct box_loop<BoxIn, BoxOut, T, C, N, N>
58+
{
59+
static inline void apply(BoxIn const&, T const&, BoxOut&) {}
60+
};
61+
62+
// Extends a box with the same amount in all directions
63+
template<typename BoxIn, typename BoxOut, typename T>
64+
inline void buffer_box(BoxIn const& box_in, T const& distance, BoxOut& box_out)
65+
{
66+
assert_dimension_equal<BoxIn, BoxOut>();
67+
68+
static const std::size_t N = dimension<BoxIn>::value;
69+
70+
box_loop<BoxIn, BoxOut, T, min_corner, 0, N>::apply(box_in, -distance, box_out);
71+
box_loop<BoxIn, BoxOut, T, max_corner, 0, N>::apply(box_in, distance, box_out);
72+
}
73+
74+
75+
76+
}} // namespace detail::buffer
77+
#endif // DOXYGEN_NO_DETAIL
78+
79+
#ifndef DOXYGEN_NO_DISPATCH
80+
namespace dispatch
81+
{
82+
83+
template
84+
<
85+
typename Input,
86+
typename Output,
87+
typename TagIn = typename tag<Input>::type,
88+
typename TagOut = typename tag<Output>::type
89+
>
90+
struct buffer: not_implemented<TagIn, TagOut>
91+
{};
92+
93+
94+
template <typename BoxIn, typename BoxOut>
95+
struct buffer<BoxIn, BoxOut, box_tag, box_tag>
96+
{
97+
template <typename Distance>
98+
static inline void apply(BoxIn const& box_in, Distance const& distance,
99+
Distance const& , BoxOut& box_out)
100+
{
101+
detail::buffer::buffer_box(box_in, distance, box_out);
102+
}
103+
};
104+
105+
} // namespace dispatch
106+
#endif // DOXYGEN_NO_DISPATCH
107+
108+
109+
namespace resolve_variant {
110+
111+
template <typename Geometry>
112+
struct buffer
113+
{
114+
template <typename Distance, typename GeometryOut>
115+
static inline void apply(Geometry const& geometry,
116+
Distance const& distance,
117+
Distance const& chord_length,
118+
GeometryOut& out)
119+
{
120+
dispatch::buffer<Geometry, GeometryOut>::apply(geometry, distance, chord_length, out);
121+
}
122+
};
123+
124+
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
125+
struct buffer<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
126+
{
127+
template <typename Distance, typename GeometryOut>
128+
struct visitor: boost::static_visitor<void>
129+
{
130+
Distance const& m_distance;
131+
Distance const& m_chord_length;
132+
GeometryOut& m_out;
133+
134+
visitor(Distance const& distance,
135+
Distance const& chord_length,
136+
GeometryOut& out)
137+
: m_distance(distance),
138+
m_chord_length(chord_length),
139+
m_out(out)
140+
{}
141+
142+
template <typename Geometry>
143+
void operator()(Geometry const& geometry) const
144+
{
145+
buffer<Geometry>::apply(geometry, m_distance, m_chord_length, m_out);
146+
}
147+
};
148+
149+
template <typename Distance, typename GeometryOut>
150+
static inline void apply(
151+
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
152+
Distance const& distance,
153+
Distance const& chord_length,
154+
GeometryOut& out
155+
)
156+
{
157+
boost::apply_visitor(visitor<Distance, GeometryOut>(distance, chord_length, out), geometry);
158+
}
159+
};
160+
161+
} // namespace resolve_variant
162+
163+
164+
/*!
165+
\brief \brief_calc{buffer}
166+
\ingroup buffer
167+
\details \details_calc{buffer, \det_buffer}.
168+
\tparam Input \tparam_geometry
169+
\tparam Output \tparam_geometry
170+
\tparam Distance \tparam_numeric
171+
\param geometry_in \param_geometry
172+
\param geometry_out \param_geometry
173+
\param distance The distance to be used for the buffer
174+
\param chord_length (optional) The length of the chord's in the generated arcs around points or bends
175+
176+
\qbk{[include reference/algorithms/buffer.qbk]}
177+
*/
178+
template <typename Input, typename Output, typename Distance>
179+
inline void buffer(Input const& geometry_in, Output& geometry_out,
180+
Distance const& distance, Distance const& chord_length = -1)
181+
{
182+
concept::check<Input const>();
183+
concept::check<Output>();
184+
185+
resolve_variant::buffer<Input>::apply(geometry_in, distance, chord_length, geometry_out);
186+
}
187+
188+
/*!
189+
\brief \brief_calc{buffer}
190+
\ingroup buffer
191+
\details \details_calc{return_buffer, \det_buffer}. \details_return{buffer}.
192+
\tparam Input \tparam_geometry
193+
\tparam Output \tparam_geometry
194+
\tparam Distance \tparam_numeric
195+
\param geometry \param_geometry
196+
\param distance The distance to be used for the buffer
197+
\param chord_length (optional) The length of the chord's in the generated arcs
198+
around points or bends (RESERVED, NOT YET USED)
199+
\return \return_calc{buffer}
200+
*/
201+
template <typename Output, typename Input, typename Distance>
202+
Output return_buffer(Input const& geometry, Distance const& distance, Distance const& chord_length = -1)
203+
{
204+
concept::check<Input const>();
205+
concept::check<Output>();
206+
207+
Output geometry_out;
208+
209+
resolve_variant::buffer<Input>::apply(geometry, distance, chord_length, geometry_out);
210+
211+
return geometry_out;
212+
}
213+
214+
/*!
215+
\brief \brief_calc{buffer}
216+
\ingroup buffer
217+
\details \details_calc{buffer, \det_buffer}.
218+
\tparam GeometryIn \tparam_geometry
219+
\tparam MultiPolygon \tparam_geometry{MultiPolygon}
220+
\tparam DistanceStrategy A strategy defining distance (or radius)
221+
\tparam SideStrategy A strategy defining creation along sides
222+
\tparam JoinStrategy A strategy defining creation around convex corners
223+
\tparam EndStrategy A strategy defining creation at linestring ends
224+
\tparam PointStrategy A strategy defining creation around points
225+
\param geometry_in \param_geometry
226+
\param geometry_out output multi polygon (or std:: collection of polygons),
227+
will contain a buffered version of the input geometry
228+
\param distance_strategy The distance strategy to be used
229+
\param side_strategy The side strategy to be used
230+
\param join_strategy The join strategy to be used
231+
\param end_strategy The end strategy to be used
232+
\param point_strategy The point strategy to be used
233+
234+
\qbk{distinguish,with strategies}
235+
\qbk{[include reference/algorithms/buffer_with_strategies.qbk]}
236+
*/
237+
template
238+
<
239+
typename GeometryIn,
240+
typename MultiPolygon,
241+
typename DistanceStrategy,
242+
typename SideStrategy,
243+
typename JoinStrategy,
244+
typename EndStrategy,
245+
typename PointStrategy
246+
>
247+
inline void buffer(GeometryIn const& geometry_in,
248+
MultiPolygon& geometry_out,
249+
DistanceStrategy const& distance_strategy,
250+
SideStrategy const& side_strategy,
251+
JoinStrategy const& join_strategy,
252+
EndStrategy const& end_strategy,
253+
PointStrategy const& point_strategy)
254+
{
255+
typedef typename boost::range_value<MultiPolygon>::type polygon_type;
256+
concept::check<GeometryIn const>();
257+
concept::check<polygon_type>();
258+
259+
typedef typename point_type<GeometryIn>::type point_type;
260+
typedef typename rescale_policy_type<point_type>::type rescale_policy_type;
261+
262+
geometry_out.clear();
263+
264+
model::box<point_type> box;
265+
envelope(geometry_in, box);
266+
buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy));
267+
268+
rescale_policy_type rescale_policy
269+
= boost::geometry::get_rescale_policy<rescale_policy_type>(box);
270+
271+
detail::buffer::buffer_inserter<polygon_type>(geometry_in, std::back_inserter(geometry_out),
272+
distance_strategy,
273+
side_strategy,
274+
join_strategy,
275+
end_strategy,
276+
point_strategy,
277+
rescale_policy);
278+
}
279+
280+
281+
}} // namespace boost::geometry
282+
283+
#endif // BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP

0 commit comments

Comments
 (0)